@bitbybit-dev/base 1.0.0-rc.1 → 1.0.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.
@@ -1,3 +1,3 @@
1
1
  export class GlobalCDNProvider {
2
2
  }
3
- GlobalCDNProvider.BITBYBIT_CDN_URL = "https://git-cdn.bitbybit.dev/v1.0.0-rc.1";
3
+ GlobalCDNProvider.BITBYBIT_CDN_URL = "https://git-cdn.bitbybit.dev/v1.0.0-rc.2";
@@ -462,4 +462,12 @@ export declare namespace Math {
462
462
  */
463
463
  maxDelta: number;
464
464
  }
465
+ class EvalArithmeticDto {
466
+ constructor(expression?: string);
467
+ /**
468
+ * Arithmetic expression containing numbers, +, -, *, /, and parentheses
469
+ * @default "1+1"
470
+ */
471
+ expression: string;
472
+ }
465
473
  }
@@ -605,4 +605,17 @@ export var Math;
605
605
  }
606
606
  }
607
607
  Math.MoveTowardsDto = MoveTowardsDto;
608
+ class EvalArithmeticDto {
609
+ constructor(expression) {
610
+ /**
611
+ * Arithmetic expression containing numbers, +, -, *, /, and parentheses
612
+ * @default "1+1"
613
+ */
614
+ this.expression = "1+1";
615
+ if (expression !== undefined) {
616
+ this.expression = expression;
617
+ }
618
+ }
619
+ }
620
+ Math.EvalArithmeticDto = EvalArithmeticDto;
608
621
  })(Math || (Math = {}));
@@ -461,6 +461,18 @@ export declare class MathBitByBit {
461
461
  * @drawable false
462
462
  */
463
463
  moveTowards(inputs: Inputs.Math.MoveTowardsDto): number;
464
+ /**
465
+ * Safely evaluates a simple arithmetic expression containing only
466
+ * numbers, +, -, *, /, parentheses, and whitespace.
467
+ * Uses the shunting-yard algorithm — no eval/Function.
468
+ * Example: "(3+2)*4" → 20, "10/3" → 3.3333...
469
+ * @param inputs arithmetic expression string
470
+ * @returns evaluated result
471
+ * @group operations
472
+ * @shortname eval arithmetic
473
+ * @drawable false
474
+ */
475
+ evalArithmetic(inputs: Inputs.Math.EvalArithmeticDto): number;
464
476
  private easeInSine;
465
477
  private easeOutSine;
466
478
  private easeInOutSine;
@@ -660,6 +660,128 @@ export class MathBitByBit {
660
660
  }
661
661
  return inputs.current + Math.sign(delta) * inputs.maxDelta;
662
662
  }
663
+ /**
664
+ * Safely evaluates a simple arithmetic expression containing only
665
+ * numbers, +, -, *, /, parentheses, and whitespace.
666
+ * Uses the shunting-yard algorithm — no eval/Function.
667
+ * Example: "(3+2)*4" → 20, "10/3" → 3.3333...
668
+ * @param inputs arithmetic expression string
669
+ * @returns evaluated result
670
+ * @group operations
671
+ * @shortname eval arithmetic
672
+ * @drawable false
673
+ */
674
+ evalArithmetic(inputs) {
675
+ var _a;
676
+ const expr = inputs.expression;
677
+ const tokens = [];
678
+ let i = 0;
679
+ while (i < expr.length) {
680
+ const ch = expr[i];
681
+ if (ch === " ") {
682
+ i++;
683
+ continue;
684
+ }
685
+ if (ch === "(" || ch === ")") {
686
+ tokens.push(ch);
687
+ i++;
688
+ continue;
689
+ }
690
+ if (ch === "+" || ch === "*" || ch === "/") {
691
+ tokens.push(ch);
692
+ i++;
693
+ continue;
694
+ }
695
+ if (ch === "-") {
696
+ const prev = tokens.length > 0 ? tokens[tokens.length - 1] : undefined;
697
+ if (prev === undefined || prev === "(" || prev === "+" || prev === "-" || prev === "*" || prev === "/") {
698
+ let num = "-";
699
+ i++;
700
+ while (i < expr.length && (expr[i] >= "0" && expr[i] <= "9" || expr[i] === ".")) {
701
+ num += expr[i];
702
+ i++;
703
+ }
704
+ if (num === "-") {
705
+ throw new Error("Invalid expression");
706
+ }
707
+ tokens.push(num);
708
+ continue;
709
+ }
710
+ tokens.push(ch);
711
+ i++;
712
+ continue;
713
+ }
714
+ if ((ch >= "0" && ch <= "9") || ch === ".") {
715
+ let num = "";
716
+ while (i < expr.length && (expr[i] >= "0" && expr[i] <= "9" || expr[i] === ".")) {
717
+ num += expr[i];
718
+ i++;
719
+ }
720
+ tokens.push(num);
721
+ continue;
722
+ }
723
+ throw new Error("Invalid character in expression");
724
+ }
725
+ const output = [];
726
+ const ops = [];
727
+ const prec = { "+": 1, "-": 1, "*": 2, "/": 2 };
728
+ const applyOp = () => {
729
+ const op = ops.pop();
730
+ const b = output.pop();
731
+ const a = output.pop();
732
+ switch (op) {
733
+ case "+":
734
+ output.push(a + b);
735
+ break;
736
+ case "-":
737
+ output.push(a - b);
738
+ break;
739
+ case "*":
740
+ output.push(a * b);
741
+ break;
742
+ case "/":
743
+ output.push(a / b);
744
+ break;
745
+ }
746
+ };
747
+ for (const tok of tokens) {
748
+ if (tok === "(") {
749
+ ops.push(tok);
750
+ }
751
+ else if (tok === ")") {
752
+ while (ops.length > 0 && ops[ops.length - 1] !== "(") {
753
+ applyOp();
754
+ }
755
+ if (ops.length === 0) {
756
+ throw new Error("Mismatched parentheses");
757
+ }
758
+ ops.pop();
759
+ }
760
+ else if (tok in prec) {
761
+ while (ops.length > 0 && ops[ops.length - 1] !== "(" && ((_a = prec[ops[ops.length - 1]]) !== null && _a !== void 0 ? _a : 0) >= prec[tok]) {
762
+ applyOp();
763
+ }
764
+ ops.push(tok);
765
+ }
766
+ else {
767
+ const n = parseFloat(tok);
768
+ if (isNaN(n)) {
769
+ throw new Error("Invalid number");
770
+ }
771
+ output.push(n);
772
+ }
773
+ }
774
+ while (ops.length > 0) {
775
+ if (ops[ops.length - 1] === "(") {
776
+ throw new Error("Mismatched parentheses");
777
+ }
778
+ applyOp();
779
+ }
780
+ if (output.length !== 1) {
781
+ throw new Error("Invalid expression");
782
+ }
783
+ return output[0];
784
+ }
663
785
  easeInSine(x) {
664
786
  return 1 - Math.cos((x * Math.PI) / 2);
665
787
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitbybit-dev/base",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "Bit By Bit Developers Base CAD Library to Program Geometry",
5
5
  "main": "index.js",
6
6
  "repository": {