@fw-components/formula-editor 2.0.7-formula-editor-enhancements.11 → 2.0.7-formula-editor.21

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.
@@ -6,89 +6,41 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
6
6
  };
7
7
  import { html, LitElement } from "lit";
8
8
  import { customElement, property, state, query } from "lit/decorators.js";
9
- import { FormulaEditorStyles } from "./styles/formula-editor-styles.js";
10
- import { Parser } from "./parser.js";
11
9
  import "./suggestion-menu.js";
10
+ import { Parser } from "./utils/parser.js";
11
+ import { FormulaEditorStyles } from "./styles/editor.js";
12
12
  let FormulaEditor = class FormulaEditor extends LitElement {
13
13
  constructor() {
14
- super();
14
+ super(...arguments);
15
+ this.recommendations = [];
16
+ this.currentCursorPosition = 0;
17
+ this.isFocused = false;
15
18
  /**
16
- * These `states` and `properties` can't be defined as `static get properties`,
17
- * because TS doesn't support that.
18
- * @see https://github.com/lit/lit-element/issues/414
19
+ * Text area input value
19
20
  */
20
- this._formattedContent = null;
21
- this._recommendations = null;
22
- this._calculatedResult = undefined;
23
- /**
24
- * If `parseInput` is called to add a recommendation, say by clicking,
25
- * browser removes focus from the input box. In that case, we have no way
26
- * of knowing where the cursor previously was, other than storing it somewhere.
27
- */
28
- this.currentCursorPosition = null;
29
- this.currentCursorRect = undefined;
30
- this.lastInputType = "";
31
- this.isFocus = false;
32
21
  this.content = "";
33
22
  this.placeholder = "Type your formula...";
34
23
  this.variables = new Map();
35
24
  this.minSuggestionLen = 2;
36
- this.errorString = null;
37
- this._parser = new Parser(this.variables, this.minSuggestionLen);
25
+ this.errorString = "";
38
26
  }
39
27
  firstUpdated(_changedProperties) {
40
- this._parser = new Parser(this.variables, this.minSuggestionLen);
41
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
42
28
  const inputListener = this.handleContentUpdate.bind(this);
43
- editor.addEventListener("input", inputListener);
44
- editor.focus();
29
+ this.editor.addEventListener("input", inputListener);
30
+ this.editor.focus();
45
31
  }
46
- navigateRecommendations(direction) {
47
- if (!this._recommendations)
48
- return;
49
- const currentIndex = this._recommendations.indexOf(this._selectedRecommendation);
50
- const newIndex = direction === "ArrowDown"
51
- ? (currentIndex + 1) % this._recommendations.length
52
- : direction === "ArrowUp"
53
- ? (currentIndex - 1 + this._recommendations.length) % this._recommendations.length
54
- : currentIndex;
55
- this._selectedRecommendation = this._recommendations[newIndex];
56
- this.scrollToSelectedRecommendation(newIndex);
57
- }
58
- scrollToSelectedRecommendation(index) {
59
- const suggestionMenu = this.shadowRoot?.querySelector("suggestion-menu");
60
- if (suggestionMenu) {
61
- const listItem = suggestionMenu.shadowRoot?.querySelectorAll("li")[index];
62
- if (listItem) {
63
- listItem.scrollIntoView({
64
- block: "nearest",
65
- inline: "nearest",
66
- });
32
+ updated(_changedProperties) {
33
+ if (_changedProperties.has("content")) {
34
+ if (!this.content?.trim()) {
35
+ this.recommendations = Array.from(this.variables.keys());
67
36
  }
37
+ this._adjustTextAreaHeight();
68
38
  }
69
- }
70
- handleKeyboardEvents(event) {
71
- if (event.code == "Tab" && this._recommendations?.length == 1) {
72
- this._selectedRecommendation = null;
73
- event.preventDefault();
74
- this.parseInput(this._recommendations[0]);
75
- }
76
- else if (event.code === "ArrowDown" || event.code === "ArrowUp") {
77
- if (this._recommendations)
78
- event.preventDefault();
79
- this.navigateRecommendations(event.code);
80
- this.requestUpdate();
81
- }
82
- else if (event.code === "Enter" && this._selectedRecommendation) {
83
- event.preventDefault();
84
- this.parseInput(this._selectedRecommendation);
85
- this._selectedRecommendation = null;
39
+ if (_changedProperties.has("variables") && this.variables.size) {
40
+ this._parser = new Parser(this.variables, this.minSuggestionLen);
86
41
  }
87
42
  }
88
43
  onClickRecommendation(recommendation) {
89
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
90
- if (!editor)
91
- return;
92
44
  this.parseInput(recommendation);
93
45
  }
94
46
  handleContentUpdate(event) {
@@ -97,149 +49,94 @@ let FormulaEditor = class FormulaEditor extends LitElement {
97
49
  this.content = event.target.value;
98
50
  this.parseInput();
99
51
  }
100
- _adjustInputHeight() {
101
- const editor = this.shadowRoot?.getElementById("wysiwyg-editor");
52
+ _adjustTextAreaHeight() {
102
53
  if (!this.content)
103
- editor.style.height = "var(--fe-height, 30px)";
104
- if (editor.scrollHeight > editor.clientHeight)
105
- editor.style.height = (editor.scrollHeight + 5) + "px";
54
+ this.editor.style.height = "var(--fe-height, 30px)";
55
+ if (this.editor.scrollHeight > this.editor.clientHeight)
56
+ this.editor.style.height = String(this.editor.scrollHeight + 5).concat("px");
106
57
  }
107
58
  /**
108
- *
109
59
  * @param recommendation The recommendation which needs to be inserted
110
60
  * at the current cursor position
111
- * @param manageCursor Whether or not cursor management is needed. Not
112
- * needed when manual insertion of text is required (eg: during initialization)
113
61
  * @returns void
114
62
  */
115
- parseInput(recommendation = null) {
116
- let editor = this.shadowRoot?.getElementById("wysiwyg-editor");
117
- if (!editor)
118
- return;
119
- this.currentCursorPosition = editor.selectionStart;
63
+ parseInput(recommendation = "") {
64
+ this.currentCursorPosition = this.editor.selectionStart;
120
65
  const parseOutput = this._parser.parseInput(this.content, this.currentCursorPosition, recommendation);
121
- this._recommendations = parseOutput.recommendations;
122
- this._formattedContent = parseOutput.formattedContent;
66
+ this.recommendations = parseOutput.recommendations;
123
67
  this.errorString = parseOutput.errorString;
124
68
  /**
125
69
  * Don't modify the text stream manually if the text is being composed,
126
- * unless the user manually chooses to do so by selecting a suggestion.
70
+ * unless the user manually chooses to do so by selecting a recommendation.
127
71
  * @see https://github.com/w3c/input-events/issues/86
128
72
  * @see https://github.com/w3c/input-events/pull/122
129
73
  * @see https://bugs.chromium.org/p/chromium/issues/detail?id=689541
130
- * */
74
+ */
131
75
  if (this.lastInputType !== "insertCompositionText" || recommendation) {
132
- const formattedString = parseOutput.formattedString;
133
- this.content = formattedString;
76
+ this.content = parseOutput.formattedString;
134
77
  }
135
- if (recommendation) {
136
- this._recommendations = null;
78
+ if (Boolean(recommendation)) {
79
+ this.recommendations = [];
137
80
  this.currentCursorPosition = parseOutput.newCursorPosition;
81
+ /**
82
+ * update cursor position in text area
83
+ */
138
84
  setTimeout(() => {
139
- editor.setSelectionRange(this.currentCursorPosition, this.currentCursorPosition);
85
+ this.editor.setSelectionRange(this.currentCursorPosition, this.currentCursorPosition);
140
86
  }, 0);
141
87
  }
142
88
  this.dispatchEvent(new CustomEvent("fw-formula-content-changed", {
143
89
  detail: {
144
90
  formulaString: this.content,
145
91
  error: this.errorString,
146
- recommendations: this._recommendations
92
+ recommendations: this.recommendations,
147
93
  },
148
94
  bubbles: true,
149
95
  }));
150
- editor.focus();
151
96
  }
152
- requestCalculate() {
153
- if (this._parser.parseInput(this.content).errorString) {
97
+ formatFormula() {
98
+ if (!Boolean(this.content))
154
99
  return;
155
- }
156
- const calculatedResult = this._parser.calculate(this.content);
157
100
  this.content = this._parser.addParentheses(this.content) ?? this.content;
158
101
  this.parseInput();
159
- this._calculatedResult = calculatedResult.result;
160
- this.errorString = calculatedResult.errorString;
161
- this._recommendations = null;
162
- this.requestUpdate();
102
+ this.recommendations = [];
163
103
  }
164
- requestFormat() {
165
- if (!Boolean(this.content)) {
166
- return;
167
- }
168
- this.content = this._parser.addParentheses(this.content) ?? this.content;
169
- this.parseInput();
170
- this._recommendations = null;
171
- this.requestUpdate();
172
- }
173
- async updated(_changedProperties) {
174
- if (_changedProperties.has("content")) {
175
- if (!this.content.trim()) {
176
- this._recommendations = Array.from(this.variables.keys());
177
- }
178
- this._adjustInputHeight();
179
- }
180
- if (_changedProperties.has("variables")) {
181
- this._parser = new Parser(this.variables, this.minSuggestionLen);
182
- }
183
- }
184
- handleFocusOut(e) {
185
- this.isFocus = false;
186
- this._recommendations = null;
187
- this.requestUpdate();
188
- }
189
- handleFocus(e) {
190
- this.isFocus = true;
191
- if (!this.content.trim()) {
192
- this._recommendations = Array.from(this.variables.keys());
193
- }
104
+ handleFocus(focus) {
105
+ this.isFocused = focus;
194
106
  }
195
107
  render() {
196
108
  return html `
197
- <style>
198
- ${FormulaEditorStyles}
199
- </style>
109
+ <style>${FormulaEditorStyles}</style>
110
+
111
+ ${this.label ? html `<label for="wysiwyg-editor" class="editor-label">${this.label}</label>` : ""}
112
+
113
+ <textarea
114
+ id="wysiwyg-editor"
115
+ class=${this.errorString?.length ? "error" : ""}
116
+ .value=${this.content}
117
+ .placeholder=${this.placeholder}
118
+ spellcheck="false"
119
+ autocomplete="off"
120
+ @blur=${() => this.handleFocus(false)}
121
+ @focus=${() => this.handleFocus(true)}
122
+ ></textarea>
200
123
 
201
- ${this.label
202
- ? html `<label for="wysiwyg-editor" class="formula-editor-label">
203
- ${this.label}
204
- </label>`
205
- : ""}
206
-
207
- <textarea
208
- placeholder=${this.placeholder}
209
- id="wysiwyg-editor"
210
- class=${this.errorString?.length ? "error" : ""}
211
- .value=${this.content}
212
- @keydown=${this.handleKeyboardEvents}
213
- @blur=${this.handleFocusOut}
214
- @focus=${this.handleFocus}
215
- ></textarea>
216
- ${this._recommendations && this.isFocus
217
- ? html ` <suggestion-menu
218
- .recommendations=${this._recommendations}
219
- .currentSelection=${this._selectedRecommendation}
220
- .onClickRecommendation=${(e) => this.onClickRecommendation(e)}
221
- @mousedown=${(e) => e.preventDefault()}
222
- ></suggestion-menu>`
223
- : html ``}
224
- <p>${this._calculatedResult}</p>
124
+ ${this.isFocused && this.recommendations?.length
125
+ ? html `<suggestion-menu
126
+ .recommendations=${this.recommendations}
127
+ .currentSelection=${this._selectedRecommendation}
128
+ .onClickRecommendation=${this.onClickRecommendation.bind(this)}
129
+ ></suggestion-menu>`
130
+ : ''}
225
131
  `;
226
132
  }
227
133
  };
228
134
  __decorate([
229
135
  state()
230
- ], FormulaEditor.prototype, "_formattedContent", void 0);
231
- __decorate([
232
- state()
233
- ], FormulaEditor.prototype, "_recommendations", void 0);
234
- __decorate([
235
- state()
236
- ], FormulaEditor.prototype, "_calculatedResult", void 0);
136
+ ], FormulaEditor.prototype, "recommendations", void 0);
237
137
  __decorate([
238
138
  state()
239
139
  ], FormulaEditor.prototype, "currentCursorPosition", void 0);
240
- __decorate([
241
- state()
242
- ], FormulaEditor.prototype, "currentCursorRect", void 0);
243
140
  __decorate([
244
141
  state()
245
142
  ], FormulaEditor.prototype, "lastInputType", void 0);
@@ -248,7 +145,7 @@ __decorate([
248
145
  ], FormulaEditor.prototype, "_selectedRecommendation", void 0);
249
146
  __decorate([
250
147
  state()
251
- ], FormulaEditor.prototype, "isFocus", void 0);
148
+ ], FormulaEditor.prototype, "isFocused", void 0);
252
149
  __decorate([
253
150
  property()
254
151
  ], FormulaEditor.prototype, "content", void 0);
@@ -259,19 +156,7 @@ __decorate([
259
156
  property()
260
157
  ], FormulaEditor.prototype, "label", void 0);
261
158
  __decorate([
262
- property({
263
- type: (Map),
264
- converter: {
265
- fromAttribute: (value) => {
266
- if (value) {
267
- return new Map(JSON.parse(value));
268
- }
269
- },
270
- toAttribute: (value) => {
271
- return JSON.stringify(Array.from(value.entries()));
272
- },
273
- },
274
- })
159
+ property()
275
160
  ], FormulaEditor.prototype, "variables", void 0);
276
161
  __decorate([
277
162
  property()
@@ -280,7 +165,7 @@ __decorate([
280
165
  property()
281
166
  ], FormulaEditor.prototype, "errorString", void 0);
282
167
  __decorate([
283
- query("wysiwyg-editor")
168
+ query("#wysiwyg-editor")
284
169
  ], FormulaEditor.prototype, "editor", void 0);
285
170
  FormulaEditor = __decorate([
286
171
  customElement("formula-editor")
@@ -1,6 +1,6 @@
1
1
  import { css } from "lit";
2
2
  export const FormulaEditorStyles = css `
3
- .formula-editor-label {
3
+ .editor-label {
4
4
  display: block;
5
5
  font-size: var(--fe-label-font-size, 0.8rem);
6
6
  color: var(--fe-label-color, #515151);
@@ -13,7 +13,7 @@ export const FormulaEditorStyles = css `
13
13
  padding: var(--fe-padding, 4px);
14
14
  caret-color: var(--fe-caret-color, #fff);
15
15
  color: var(--fe-text-color, #f7f1ff);
16
- font-size: var(--fe-text-font-size, 12px);
16
+ font-size: var(--fe-text-font-size, 14px);
17
17
  min-width: 100%;
18
18
  min-height: 30px;
19
19
  height: var(--fe-height, 30px);
@@ -0,0 +1,58 @@
1
+ import { css } from "lit";
2
+ export const SuggestionMenuStyles = css `
3
+ ul {
4
+ position: relative;
5
+ border: 1px solid var(--fe-suggestion-color, white);
6
+ color: var(--fe-suggestion-color, #bab6c0);
7
+ background-color: var(--fe-suggestion-background-color, white);
8
+ box-sizing: border-box;
9
+ width: var(--fe-suggestion-width, 20vw);
10
+ max-height: 25vh;
11
+ overflow-x: auto;
12
+ overflow-y: auto;
13
+ list-style-type: none;
14
+ padding: 0;
15
+ margin: 0;
16
+ box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
17
+ border-radius: 5px;
18
+ z-index: 99999;
19
+ }
20
+
21
+ li {
22
+ margin: 0;
23
+ padding: 0.5em 1rem;
24
+ cursor: pointer;
25
+ font-family: var(--theme-font);
26
+ font-size: var(--secondary-font-size, 16px);
27
+ color: var(--secondary-color, #bab6c0);
28
+ }
29
+
30
+ li:hover, li:focus-visible, li.selected {
31
+ color: var(--fe-suggestion-focus-color, #69676c);
32
+ background: rgba(var(--fe-suggestion-focus-background, 86, 86, 86), 0.1);
33
+ }
34
+
35
+
36
+ /* Scrollbar styling */
37
+ ::-webkit-scrollbar {
38
+ width: 10px;
39
+ }
40
+
41
+ ::-webkit-scrollbar-track {
42
+ background: transparent;
43
+ }
44
+
45
+ ::-webkit-scrollbar-thumb {
46
+ background: #ccc;
47
+ border-radius: 5px;
48
+ }
49
+
50
+ ::-webkit-scrollbar-thumb:hover {
51
+ background: #aaa;
52
+ }
53
+
54
+ /* Optional shadow for the dropdown */
55
+ .content {
56
+ box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
57
+ }
58
+ `;
@@ -4,101 +4,81 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
4
4
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
5
  return c > 3 && r && Object.defineProperty(target, key, r), r;
6
6
  };
7
- import { css, html, LitElement } from "lit";
8
- import { customElement, property } from "lit/decorators.js";
7
+ import { html, LitElement } from "lit";
8
+ import { customElement, property, query, state } from "lit/decorators.js";
9
+ import { SuggestionMenuStyles } from "./styles/suggestion-menu";
9
10
  let SuggestionMenu = class SuggestionMenu extends LitElement {
10
11
  constructor() {
11
12
  super(...arguments);
12
13
  this.recommendations = [];
13
14
  this.onClickRecommendation = (recommendation) => { };
14
- this.currentSelection = "";
15
+ this._selectedRecommendationIndex = 0;
15
16
  }
16
- static { this.styles = css `
17
- ul {
18
- position: relative;
19
- border: 1px solid var(--fe-suggestion-color, white);
20
- color: var(--fe-suggestion-color, #bab6c0);
21
- background-color: var(--fe-suggestion-background-color, white);
22
- box-sizing: border-box;
23
- width: var(--fe-suggestion-width, 20vw);
24
- max-height: 25vh;
25
- overflow-x: auto;
26
- overflow-y: auto;
27
- list-style-type: none;
28
- padding: 0;
29
- margin: 0;
30
- box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
31
- border-radius: 5px;
32
- z-index: 99999
33
- }
34
-
35
- li {
36
- margin: 0;
37
- padding: 0.5em 1rem;
38
- cursor: pointer;
39
- font-family: var(--theme-font);
40
- font-size: var(--secondary-font-size, 16px);
41
- color: var(--secondary-color, #bab6c0);
42
- }
43
-
44
- li:hover,
45
- li:focus-visible {
46
- font-weight: bold;
47
- color: var(--fe-suggestion-focus-color, #69676c);
48
- }
49
-
50
- li.selected {
51
- color: var(--fe-suggestion-focus-color, #69676c);
52
- font-weight: bold;
53
- }
54
-
55
- li[focused] {
56
- font-weight: bold;
57
- }
58
-
59
- /* Scrollbar styling */
60
- ::-webkit-scrollbar {
61
- width: 10px;
62
- }
63
-
64
- ::-webkit-scrollbar-track {
65
- background: transparent;
66
- }
67
-
68
- ::-webkit-scrollbar-thumb {
69
- background: #ccc;
70
- border-radius: 5px;
71
- }
72
-
73
- ::-webkit-scrollbar-thumb:hover {
74
- background: #aaa;
75
- }
76
-
77
- /* Optional shadow for the dropdown */
78
- .content {
79
- box-shadow: 1px 2px 5px rgba(0, 0, 0, 0.13);
80
- }
81
- `; }
82
- handleKeydown(event, recommendation) {
83
- if (event.code == "Enter") {
17
+ firstUpdated(_changedProperties) {
18
+ this.abortController = new AbortController();
19
+ const handleKeydown = this.handleKeydown.bind(this);
20
+ document.addEventListener("keydown", handleKeydown, { signal: this.abortController?.signal });
21
+ }
22
+ scrollToSelectedRecommendation(index) {
23
+ const listItem = this.suggestionList?.querySelectorAll("li")[index];
24
+ if (!listItem)
25
+ return;
26
+ listItem.scrollIntoView({
27
+ block: "nearest",
28
+ inline: "nearest",
29
+ behavior: "smooth"
30
+ });
31
+ }
32
+ navigate(direction) {
33
+ if (!this.recommendations)
34
+ return;
35
+ let newIndex = this._selectedRecommendationIndex;
36
+ if (direction === "down")
37
+ newIndex = (this._selectedRecommendationIndex + 1) % this.recommendations.length;
38
+ else if (direction === "up")
39
+ newIndex = (this._selectedRecommendationIndex - 1 + this.recommendations.length) % this.recommendations.length;
40
+ this._selectedRecommendationIndex = newIndex;
41
+ this.scrollToSelectedRecommendation(newIndex);
42
+ }
43
+ handleKeydown(event) {
44
+ if (event.code === "Tab") {
45
+ event.preventDefault();
46
+ if (this.recommendations?.length === 1) {
47
+ this._handleRecommendationSelect();
48
+ }
49
+ else {
50
+ const direction = event.shiftKey ? "up" : "down";
51
+ this.navigate(direction);
52
+ }
53
+ }
54
+ else if (event.code === "ArrowDown" || event.code === "ArrowUp") {
55
+ event.preventDefault();
56
+ const direction = event.code === "ArrowDown" ? "down" : "up";
57
+ this.navigate(direction);
58
+ }
59
+ else if (event.code === "Enter") {
84
60
  event.preventDefault();
85
- event.stopPropagation();
86
- this.onClickRecommendation(recommendation);
61
+ this._handleRecommendationSelect();
87
62
  }
88
63
  }
64
+ _handleRecommendationSelect(index = this._selectedRecommendationIndex) {
65
+ const recommendation = this.recommendations[index];
66
+ if (!recommendation)
67
+ return;
68
+ this.onClickRecommendation(recommendation);
69
+ this._selectedRecommendationIndex = -1;
70
+ }
71
+ disconnectedCallback() {
72
+ this.abortController?.abort();
73
+ }
89
74
  render() {
90
75
  return html `
91
- <ul class="wysiwyg-suggestion-menu">
92
- ${this.recommendations.map((recommendation) => {
93
- return html `<li
94
- class="${this.currentSelection === recommendation ? 'selected' : ''}"
95
- tabindex="0"
96
- @click=${(e) => this.onClickRecommendation(recommendation)}
97
- @keydown=${(e) => this.handleKeydown(e, recommendation)}
98
- >
99
- ${recommendation}
100
- </li>`;
101
- })}
76
+ <style>${SuggestionMenuStyles}</style>
77
+ <ul class="wysiwyg-suggestion-menu" @mousedown=${(e) => e.preventDefault()}>
78
+ ${this.recommendations.map((recommendation, index) => html `<li
79
+ class="${this._selectedRecommendationIndex === index ? "selected" : ""}"
80
+ @click=${(e) => this._handleRecommendationSelect(index)}
81
+ >${recommendation}</li>`)}
102
82
  </ul>
103
83
  `;
104
84
  }
@@ -110,8 +90,14 @@ __decorate([
110
90
  property()
111
91
  ], SuggestionMenu.prototype, "onClickRecommendation", void 0);
112
92
  __decorate([
113
- property()
114
- ], SuggestionMenu.prototype, "currentSelection", void 0);
93
+ state()
94
+ ], SuggestionMenu.prototype, "_selectedRecommendationIndex", void 0);
95
+ __decorate([
96
+ state()
97
+ ], SuggestionMenu.prototype, "abortController", void 0);
98
+ __decorate([
99
+ query(".wysiwyg-suggestion-menu")
100
+ ], SuggestionMenu.prototype, "suggestionList", void 0);
115
101
  SuggestionMenu = __decorate([
116
102
  customElement("suggestion-menu")
117
103
  ], SuggestionMenu);
@@ -1,3 +1,9 @@
1
+ export var Expectation;
2
+ (function (Expectation) {
3
+ Expectation[Expectation["VARIABLE"] = 0] = "VARIABLE";
4
+ Expectation[Expectation["OPERATOR"] = 1] = "OPERATOR";
5
+ Expectation[Expectation["UNDEFINED"] = 2] = "UNDEFINED";
6
+ })(Expectation || (Expectation = {}));
1
7
  export var Operator;
2
8
  (function (Operator) {
3
9
  Operator["PLUS"] = "+";
@@ -0,0 +1,8 @@
1
+ export const mathematicalOperators = new Set(["^", "+", "-", "*", "/"]);
2
+ export const operatorPrecedence = {
3
+ "^": 3,
4
+ "/": 2,
5
+ "*": 2,
6
+ "+": 1,
7
+ "-": 1,
8
+ };