@danielsimonjr/mathts-core 0.1.2 → 0.1.4

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/dist/index.js CHANGED
@@ -757,10 +757,7 @@ var Fraction = class _Fraction {
757
757
  */
758
758
  multiply(other) {
759
759
  if (other instanceof _Fraction) {
760
- return new _Fraction(
761
- this.numerator * other.numerator,
762
- this.denominator * other.denominator
763
- );
760
+ return new _Fraction(this.numerator * other.numerator, this.denominator * other.denominator);
764
761
  }
765
762
  return this.multiply(_Fraction.fromNumber(Number(other.valueOf())));
766
763
  }
@@ -772,10 +769,7 @@ var Fraction = class _Fraction {
772
769
  if (other.numerator === 0n) {
773
770
  throw new Error("Division by zero");
774
771
  }
775
- return new _Fraction(
776
- this.numerator * other.denominator,
777
- this.denominator * other.numerator
778
- );
772
+ return new _Fraction(this.numerator * other.denominator, this.denominator * other.numerator);
779
773
  }
780
774
  return this.divide(_Fraction.fromNumber(Number(other.valueOf())));
781
775
  }
@@ -789,10 +783,7 @@ var Fraction = class _Fraction {
789
783
  * Absolute value: |a/b|
790
784
  */
791
785
  abs() {
792
- return new _Fraction(
793
- this.numerator < 0n ? -this.numerator : this.numerator,
794
- this.denominator
795
- );
786
+ return new _Fraction(this.numerator < 0n ? -this.numerator : this.numerator, this.denominator);
796
787
  }
797
788
  /**
798
789
  * Reciprocal: b/a
@@ -1019,10 +1010,7 @@ var Fraction = class _Fraction {
1019
1010
  * Used in Stern-Brocot tree and Farey sequences
1020
1011
  */
1021
1012
  mediant(other) {
1022
- return new _Fraction(
1023
- this.numerator + other.numerator,
1024
- this.denominator + other.denominator
1025
- );
1013
+ return new _Fraction(this.numerator + other.numerator, this.denominator + other.denominator);
1026
1014
  }
1027
1015
  };
1028
1016
  var FRACTION_ZERO = new Fraction(0n, 1n);
@@ -1045,6 +1033,12 @@ var defaultConfig = {
1045
1033
  var globalConfig = { ...defaultConfig };
1046
1034
  var BigNumber = class _BigNumber {
1047
1035
  type = "BigNumber";
1036
+ /**
1037
+ * Duck-typing marker for Decimal.js / mathjs formatter compatibility.
1038
+ * Allows external code that checks `obj.isBigNumber === true` to identify
1039
+ * this class without an `instanceof` check.
1040
+ */
1041
+ isBigNumber = true;
1048
1042
  // Internal representation: sign * coefficient * 10^exponent
1049
1043
  _sign;
1050
1044
  _coefficient;
@@ -1218,6 +1212,14 @@ var BigNumber = class _BigNumber {
1218
1212
  const str = this.toString();
1219
1213
  return parseFloat(str);
1220
1214
  }
1215
+ /**
1216
+ * Convert to a JS number.
1217
+ * Alias for `valueOf()` — provided for Decimal.js / mathjs formatter
1218
+ * duck-typing compatibility.
1219
+ */
1220
+ toNumber() {
1221
+ return this.valueOf();
1222
+ }
1221
1223
  toString() {
1222
1224
  if (this._isNaN) return "NaN";
1223
1225
  if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
@@ -1240,35 +1242,55 @@ var BigNumber = class _BigNumber {
1240
1242
  };
1241
1243
  }
1242
1244
  /**
1243
- * Convert to fixed-point notation
1245
+ * Convert to fixed-point notation.
1246
+ *
1247
+ * When called with no argument (or `undefined`) returns the full fixed-point
1248
+ * string representation without rounding — matching Decimal.js semantics where
1249
+ * `toFixed()` is equivalent to a lossless fixed-point stringify.
1250
+ * When called with a non-negative integer `decimalPlaces`, rounds and formats
1251
+ * to exactly that many digits after the decimal point.
1244
1252
  */
1245
- toFixed(decimalPlaces = 0) {
1253
+ toFixed(decimalPlaces) {
1254
+ if (decimalPlaces === void 0) {
1255
+ return this.toFixedInternal(void 0);
1256
+ }
1246
1257
  return this.round(decimalPlaces).toFixedInternal(decimalPlaces);
1247
1258
  }
1248
1259
  toFixedInternal(decimalPlaces) {
1249
1260
  if (this._isNaN) return "NaN";
1250
1261
  if (this._isInfinite) return this._sign === 1 ? "Infinity" : "-Infinity";
1251
- if (this._sign === 0) return decimalPlaces > 0 ? "0." + "0".repeat(decimalPlaces) : "0";
1262
+ const dp = decimalPlaces ?? -1;
1263
+ const allDigits = dp < 0;
1264
+ if (this._sign === 0) return allDigits ? "0" : dp > 0 ? "0." + "0".repeat(dp) : "0";
1252
1265
  const sign = this._sign === -1 ? "-" : "";
1253
1266
  const digits = this._coefficient.toString();
1254
1267
  if (this._exponent >= 0) {
1255
1268
  const intPart = digits + "0".repeat(this._exponent);
1256
- return sign + intPart + (decimalPlaces > 0 ? "." + "0".repeat(decimalPlaces) : "");
1269
+ if (allDigits) return sign + intPart;
1270
+ return sign + intPart + (dp > 0 ? "." + "0".repeat(dp) : "");
1257
1271
  } else if (-this._exponent <= digits.length) {
1258
1272
  const insertPos = digits.length + this._exponent;
1259
1273
  const intPart = digits.slice(0, insertPos) || "0";
1260
- let decPart = digits.slice(insertPos);
1261
- if (decPart.length < decimalPlaces) {
1262
- decPart += "0".repeat(decimalPlaces - decPart.length);
1274
+ const decPart = digits.slice(insertPos);
1275
+ if (allDigits) {
1276
+ return sign + intPart + (decPart.length > 0 ? "." + decPart : "");
1277
+ }
1278
+ let paddedDec = decPart;
1279
+ if (paddedDec.length < dp) {
1280
+ paddedDec += "0".repeat(dp - paddedDec.length);
1263
1281
  }
1264
- return sign + intPart + (decimalPlaces > 0 ? "." + decPart.slice(0, decimalPlaces) : "");
1282
+ return sign + intPart + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
1265
1283
  } else {
1266
1284
  const leadingZeros = -this._exponent - digits.length;
1267
- let decPart = "0".repeat(leadingZeros) + digits;
1268
- if (decPart.length < decimalPlaces) {
1269
- decPart += "0".repeat(decimalPlaces - decPart.length);
1285
+ const decPart = "0".repeat(leadingZeros) + digits;
1286
+ if (allDigits) {
1287
+ return sign + "0." + decPart;
1270
1288
  }
1271
- return sign + "0" + (decimalPlaces > 0 ? "." + decPart.slice(0, decimalPlaces) : "");
1289
+ let paddedDec = decPart;
1290
+ if (paddedDec.length < dp) {
1291
+ paddedDec += "0".repeat(dp - paddedDec.length);
1292
+ }
1293
+ return sign + "0" + (dp > 0 ? "." + paddedDec.slice(0, dp) : "");
1272
1294
  }
1273
1295
  }
1274
1296
  /**
@@ -1337,6 +1359,55 @@ var BigNumber = class _BigNumber {
1337
1359
  }
1338
1360
  return 0n;
1339
1361
  }
1362
+ /**
1363
+ * Binary string representation, e.g. `255 -> '0b11111111'`, `0.5 -> '0b0.1'`.
1364
+ * Mirrors Decimal.js `toBinary()`. Negatives carry a leading `-`.
1365
+ */
1366
+ toBinary() {
1367
+ return this.toRadixString(2, "0b");
1368
+ }
1369
+ /**
1370
+ * Octal string representation, e.g. `8 -> '0o10'`.
1371
+ * Mirrors Decimal.js `toOctal()`.
1372
+ */
1373
+ toOctal() {
1374
+ return this.toRadixString(8, "0o");
1375
+ }
1376
+ /**
1377
+ * Hexadecimal string representation, e.g. `255 -> '0xff'`, `10.5 -> '0xa.8'`.
1378
+ * Mirrors Decimal.js `toHexadecimal()`.
1379
+ */
1380
+ toHexadecimal() {
1381
+ return this.toRadixString(16, "0x");
1382
+ }
1383
+ /**
1384
+ * Shared radix formatter for {@link toBinary}/{@link toOctal}/{@link toHexadecimal}.
1385
+ * Integers and terminating fractions are exact; a non-terminating fraction is
1386
+ * truncated at `maxFractionDigits` radix digits (a safety bound — the common
1387
+ * use is integer formatting).
1388
+ */
1389
+ toRadixString(radix, prefix, maxFractionDigits = 1100) {
1390
+ if (this._isNaN) return "NaN";
1391
+ if (this._isInfinite) return (this._sign < 0 ? "-" : "") + "Infinity";
1392
+ if (this._sign === 0) return prefix + "0";
1393
+ const negative = this._sign < 0;
1394
+ const absVal = this.abs();
1395
+ const intPart = absVal.toBigInt();
1396
+ let out = prefix + intPart.toString(radix);
1397
+ let frac = absVal.subtract(_BigNumber.fromBigInt(intPart));
1398
+ if (!frac.isZero()) {
1399
+ const radixBN = _BigNumber.fromNumber(radix);
1400
+ let digits = "";
1401
+ for (let i = 0; i < maxFractionDigits && !frac.isZero(); i++) {
1402
+ frac = frac.multiply(radixBN);
1403
+ const digit = frac.toBigInt();
1404
+ digits += Number(digit).toString(radix);
1405
+ frac = frac.subtract(_BigNumber.fromBigInt(digit));
1406
+ }
1407
+ out += "." + digits;
1408
+ }
1409
+ return (negative ? "-" : "") + out;
1410
+ }
1340
1411
  // ============================================================
1341
1412
  // Arithmetic Operations
1342
1413
  // ============================================================
@@ -1373,6 +1444,12 @@ var BigNumber = class _BigNumber {
1373
1444
  const b = this.ensureBigNumber(other);
1374
1445
  return this.add(b.negate());
1375
1446
  }
1447
+ /**
1448
+ * Alias for subtract — mathjs / Decimal.js compatibility.
1449
+ */
1450
+ sub(other) {
1451
+ return this.subtract(other);
1452
+ }
1376
1453
  /**
1377
1454
  * Multiplication
1378
1455
  */
@@ -1390,6 +1467,12 @@ var BigNumber = class _BigNumber {
1390
1467
  const exponent = this._exponent + b._exponent;
1391
1468
  return this.normalize(sign, coefficient, exponent);
1392
1469
  }
1470
+ /**
1471
+ * Alias for multiply — mathjs / Decimal.js compatibility.
1472
+ */
1473
+ mul(other) {
1474
+ return this.multiply(other);
1475
+ }
1393
1476
  /**
1394
1477
  * Division
1395
1478
  */
@@ -1501,6 +1584,14 @@ var BigNumber = class _BigNumber {
1501
1584
  compare(other) {
1502
1585
  return this.compareTo(other);
1503
1586
  }
1587
+ /**
1588
+ * Returns true iff this > other.
1589
+ * Accepts the same argument types as `add`/`multiply` (BigNumber, number, or string).
1590
+ * Named `gt` for Decimal.js / mathjs formatter compatibility.
1591
+ */
1592
+ gt(other) {
1593
+ return this.greaterThan(this.ensureBigNumber(other));
1594
+ }
1504
1595
  // ============================================================
1505
1596
  // Rounding Methods
1506
1597
  // ============================================================
@@ -1579,6 +1670,36 @@ var BigNumber = class _BigNumber {
1579
1670
  trunc() {
1580
1671
  return this.round(0, "down");
1581
1672
  }
1673
+ /**
1674
+ * Round to `n` significant decimal digits and return a new BigNumber.
1675
+ * Delegates to `roundToPrecision`, using the global rounding mode unless
1676
+ * an explicit `roundingMode` is supplied.
1677
+ *
1678
+ * Named `toSignificantDigits` for Decimal.js / mathjs formatter compatibility.
1679
+ * When `n` is undefined the value is returned unchanged (no rounding).
1680
+ */
1681
+ toSignificantDigits(n, roundingMode) {
1682
+ if (n === void 0) return this.clone();
1683
+ return this.roundToPrecision(n, roundingMode ?? globalConfig.rounding);
1684
+ }
1685
+ /**
1686
+ * The decimal exponent of this number: `floor(log10(|x|))`.
1687
+ *
1688
+ * Matches Decimal.js semantics:
1689
+ * - `12345` → `4` (5 digits → the most-significant place is 10^4)
1690
+ * - `0.0123` → `-2` (first significant digit is at 10^-2)
1691
+ * - `100` → `2`
1692
+ * - `0.01` → `-2`
1693
+ * - `0` → `0` (by convention; `isZero()` can be used to distinguish)
1694
+ *
1695
+ * For special values (NaN, ±Infinity) returns 0 — callers check
1696
+ * `isFinite()` / `isNaN()` before using `.e`.
1697
+ */
1698
+ get e() {
1699
+ if (this._isNaN || this._isInfinite || this._sign === 0) return 0;
1700
+ const d = this._coefficient.toString().length;
1701
+ return d - 1 + this._exponent;
1702
+ }
1582
1703
  // ============================================================
1583
1704
  // Modular Arithmetic
1584
1705
  // ============================================================
@@ -1795,7 +1916,7 @@ var BigNumber = class _BigNumber {
1795
1916
  if (val > 0.5) {
1796
1917
  k = Math.ceil(Math.log2(val * 2));
1797
1918
  }
1798
- const divisor = _BigNumber.fromNumber(2 ** k);
1919
+ const divisor = _BigNumber.fromNumber(2).pow(k);
1799
1920
  const reduced = this.divide(divisor);
1800
1921
  let sum = _BigNumber.fromNumber(1);
1801
1922
  let term = _BigNumber.fromNumber(1);
@@ -1883,9 +2004,7 @@ var BigNumber = class _BigNumber {
1883
2004
  for (let i = 0; i < 100; i++) {
1884
2005
  const guessSquared = guess.multiply(guess);
1885
2006
  const newGuess = guess.multiply(_BigNumber.fromNumber(2)).add(this.divide(guessSquared)).divide(three);
1886
- if (guess.subtract(newGuess).abs().compareTo(
1887
- guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))
1888
- ) <= 0) {
2007
+ if (guess.subtract(newGuess).abs().compareTo(guess.abs().multiply(_BigNumber.parse("1e-" + (precision + 5)))) <= 0) {
1889
2008
  return newGuess.roundToPrecision(precision);
1890
2009
  }
1891
2010
  guess = newGuess;
@@ -1963,9 +2082,7 @@ var BigNumber = class _BigNumber {
1963
2082
  const xSquared = this.multiply(this);
1964
2083
  const maxIter = precision + 20;
1965
2084
  for (let n = 1; n <= maxIter; n++) {
1966
- term = term.multiply(xSquared).divide(
1967
- _BigNumber.fromNumber(2 * n * (2 * n + 1))
1968
- ).negate();
2085
+ term = term.multiply(xSquared).divide(_BigNumber.fromNumber(2 * n * (2 * n + 1))).negate();
1969
2086
  const newSum = sum.add(term);
1970
2087
  if (sum.equals(newSum)) break;
1971
2088
  sum = newSum;
@@ -1980,9 +2097,7 @@ var BigNumber = class _BigNumber {
1980
2097
  const xSquared = this.multiply(this);
1981
2098
  const maxIter = precision + 20;
1982
2099
  for (let n = 1; n <= maxIter; n++) {
1983
- term = term.multiply(xSquared).divide(
1984
- _BigNumber.fromNumber((2 * n - 1) * (2 * n))
1985
- ).negate();
2100
+ term = term.multiply(xSquared).divide(_BigNumber.fromNumber((2 * n - 1) * (2 * n))).negate();
1986
2101
  const newSum = sum.add(term);
1987
2102
  if (sum.equals(newSum)) break;
1988
2103
  sum = newSum;
@@ -2034,7 +2149,13 @@ var BigNumber = class _BigNumber {
2034
2149
  return this._sign;
2035
2150
  }
2036
2151
  clone() {
2037
- return new _BigNumber(this._sign, this._coefficient, this._exponent, this._isNaN, this._isInfinite);
2152
+ return new _BigNumber(
2153
+ this._sign,
2154
+ this._coefficient,
2155
+ this._exponent,
2156
+ this._isNaN,
2157
+ this._isInfinite
2158
+ );
2038
2159
  }
2039
2160
  // ============================================================
2040
2161
  // Private Helper Methods
@@ -2072,8 +2193,683 @@ var BIGNUMBER_NEG_ONE = BigNumber.fromNumber(-1);
2072
2193
  var BIGNUMBER_TEN = BigNumber.fromNumber(10);
2073
2194
  var BIGNUMBER_PI = BigNumber.parse("3.14159265358979323846264338327950288419716939937510");
2074
2195
  var BIGNUMBER_E = BigNumber.parse("2.71828182845904523536028747135266249775724709369995");
2075
- var BIGNUMBER_LN2 = BigNumber.parse("0.69314718055994530941723212145817656807550013436026");
2076
- var BIGNUMBER_LN10 = BigNumber.parse("2.30258509299404568401799145468436420760110148862877");
2196
+ var BIGNUMBER_LN2 = BigNumber.parse(
2197
+ "0.69314718055994530941723212145817656807550013436026"
2198
+ );
2199
+ var BIGNUMBER_LN10 = BigNumber.parse(
2200
+ "2.30258509299404568401799145468436420760110148862877"
2201
+ );
2202
+
2203
+ // src/types/unit-definitions.ts
2204
+ var DIMENSIONLESS = Object.freeze({
2205
+ length: 0,
2206
+ mass: 0,
2207
+ time: 0,
2208
+ current: 0,
2209
+ temperature: 0,
2210
+ amount: 0,
2211
+ luminosity: 0
2212
+ });
2213
+ function dim(partial) {
2214
+ return {
2215
+ length: partial.length ?? 0,
2216
+ mass: partial.mass ?? 0,
2217
+ time: partial.time ?? 0,
2218
+ current: partial.current ?? 0,
2219
+ temperature: partial.temperature ?? 0,
2220
+ amount: partial.amount ?? 0,
2221
+ luminosity: partial.luminosity ?? 0
2222
+ };
2223
+ }
2224
+ var BASE_UNITS = {
2225
+ m: { multiplier: 1, dimensions: dim({ length: 1 }), prefixable: true },
2226
+ // The base unit of mass is *kilogram*, but the prefix-able symbol is "g".
2227
+ // Internally we treat 1 kg as the canonical value, so "g" -> 0.001 kg.
2228
+ kg: { multiplier: 1, dimensions: dim({ mass: 1 }) },
2229
+ s: { multiplier: 1, dimensions: dim({ time: 1 }), prefixable: true },
2230
+ A: { multiplier: 1, dimensions: dim({ current: 1 }), prefixable: true },
2231
+ K: { multiplier: 1, dimensions: dim({ temperature: 1 }), prefixable: true },
2232
+ mol: { multiplier: 1, dimensions: dim({ amount: 1 }), prefixable: true },
2233
+ cd: { multiplier: 1, dimensions: dim({ luminosity: 1 }), prefixable: true }
2234
+ };
2235
+ var DERIVED_UNITS = {
2236
+ // --- Length ---------------------------------------------------------------
2237
+ // Note: 'm' is a base unit (above), already prefixable.
2238
+ ft: { multiplier: 0.3048, dimensions: dim({ length: 1 }) },
2239
+ foot: { multiplier: 0.3048, dimensions: dim({ length: 1 }) },
2240
+ in: { multiplier: 0.0254, dimensions: dim({ length: 1 }) },
2241
+ inch: { multiplier: 0.0254, dimensions: dim({ length: 1 }) },
2242
+ yd: { multiplier: 0.9144, dimensions: dim({ length: 1 }) },
2243
+ yard: { multiplier: 0.9144, dimensions: dim({ length: 1 }) },
2244
+ mi: { multiplier: 1609.344, dimensions: dim({ length: 1 }) },
2245
+ mile: { multiplier: 1609.344, dimensions: dim({ length: 1 }) },
2246
+ // --- Mass -----------------------------------------------------------------
2247
+ // The "g" entry is gram (0.001 kg). It is prefixable, so kg/mg/µg work via
2248
+ // prefix application on this entry rather than the base "kg".
2249
+ g: { multiplier: 1e-3, dimensions: dim({ mass: 1 }), prefixable: true },
2250
+ lb: { multiplier: 0.45359237, dimensions: dim({ mass: 1 }) },
2251
+ lbm: { multiplier: 0.45359237, dimensions: dim({ mass: 1 }) },
2252
+ oz: { multiplier: 0.028349523125, dimensions: dim({ mass: 1 }) },
2253
+ ton: { multiplier: 907.18474, dimensions: dim({ mass: 1 }) },
2254
+ // US short ton
2255
+ tonne: { multiplier: 1e3, dimensions: dim({ mass: 1 }) },
2256
+ // metric ton
2257
+ // --- Time -----------------------------------------------------------------
2258
+ min: { multiplier: 60, dimensions: dim({ time: 1 }) },
2259
+ h: { multiplier: 3600, dimensions: dim({ time: 1 }) },
2260
+ hr: { multiplier: 3600, dimensions: dim({ time: 1 }) },
2261
+ day: { multiplier: 86400, dimensions: dim({ time: 1 }) },
2262
+ week: { multiplier: 604800, dimensions: dim({ time: 1 }) },
2263
+ year: { multiplier: 31557600, dimensions: dim({ time: 1 }) },
2264
+ // Julian year
2265
+ // --- Temperature ----------------------------------------------------------
2266
+ // K is the base.
2267
+ // °C → K is offset by 273.15 (no multiplicative factor change).
2268
+ // °F → K is more complex (offset & scale).
2269
+ degC: { multiplier: 1, offset: 273.15, dimensions: dim({ temperature: 1 }) },
2270
+ degF: { multiplier: 5 / 9, offset: 459.67 * (5 / 9), dimensions: dim({ temperature: 1 }) },
2271
+ degR: { multiplier: 5 / 9, dimensions: dim({ temperature: 1 }) },
2272
+ // Rankine
2273
+ // --- Plane angle (dimensionless, but often treated as units) --------------
2274
+ rad: { multiplier: 1, dimensions: dim({}), prefixable: true },
2275
+ deg: { multiplier: Math.PI / 180, dimensions: dim({}) },
2276
+ grad: { multiplier: Math.PI / 200, dimensions: dim({}) },
2277
+ // --- Force ----------------------------------------------------------------
2278
+ // N = kg·m·s^-2 = 1 kg·m·s^-2; in our base-units representation that's
2279
+ // value=1, dim {length: 1, mass: 1, time: -2}.
2280
+ N: { multiplier: 1, dimensions: dim({ length: 1, mass: 1, time: -2 }), prefixable: true },
2281
+ dyn: { multiplier: 1e-5, dimensions: dim({ length: 1, mass: 1, time: -2 }) },
2282
+ lbf: { multiplier: 4.4482216152605, dimensions: dim({ length: 1, mass: 1, time: -2 }) },
2283
+ // --- Energy ---------------------------------------------------------------
2284
+ J: { multiplier: 1, dimensions: dim({ length: 2, mass: 1, time: -2 }), prefixable: true },
2285
+ erg: { multiplier: 1e-7, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2286
+ cal: { multiplier: 4.184, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2287
+ eV: {
2288
+ multiplier: 1602176634e-28,
2289
+ dimensions: dim({ length: 2, mass: 1, time: -2 }),
2290
+ prefixable: true
2291
+ },
2292
+ BTU: { multiplier: 1055.05585262, dimensions: dim({ length: 2, mass: 1, time: -2 }) },
2293
+ // --- Power ----------------------------------------------------------------
2294
+ W: { multiplier: 1, dimensions: dim({ length: 2, mass: 1, time: -3 }), prefixable: true },
2295
+ hp: { multiplier: 745.6998715822702, dimensions: dim({ length: 2, mass: 1, time: -3 }) },
2296
+ // --- Pressure -------------------------------------------------------------
2297
+ Pa: { multiplier: 1, dimensions: dim({ length: -1, mass: 1, time: -2 }), prefixable: true },
2298
+ bar: { multiplier: 1e5, dimensions: dim({ length: -1, mass: 1, time: -2 }), prefixable: true },
2299
+ atm: { multiplier: 101325, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2300
+ psi: { multiplier: 6894.757293168361, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2301
+ torr: { multiplier: 133.322368421, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2302
+ mmHg: { multiplier: 133.322387415, dimensions: dim({ length: -1, mass: 1, time: -2 }) },
2303
+ // --- Electric -------------------------------------------------------------
2304
+ C: {
2305
+ multiplier: 1,
2306
+ dimensions: dim({ time: 1, current: 1 }),
2307
+ prefixable: true
2308
+ },
2309
+ V: {
2310
+ multiplier: 1,
2311
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -1 }),
2312
+ prefixable: true
2313
+ },
2314
+ ohm: {
2315
+ multiplier: 1,
2316
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -2 }),
2317
+ prefixable: true
2318
+ },
2319
+ \u03A9: {
2320
+ multiplier: 1,
2321
+ dimensions: dim({ length: 2, mass: 1, time: -3, current: -2 }),
2322
+ prefixable: true
2323
+ },
2324
+ F: {
2325
+ multiplier: 1,
2326
+ dimensions: dim({ length: -2, mass: -1, time: 4, current: 2 }),
2327
+ prefixable: true
2328
+ },
2329
+ H: {
2330
+ multiplier: 1,
2331
+ dimensions: dim({ length: 2, mass: 1, time: -2, current: -2 }),
2332
+ prefixable: true
2333
+ },
2334
+ // --- Frequency ------------------------------------------------------------
2335
+ Hz: { multiplier: 1, dimensions: dim({ time: -1 }), prefixable: true },
2336
+ // --- Volume ---------------------------------------------------------------
2337
+ L: { multiplier: 1e-3, dimensions: dim({ length: 3 }), prefixable: true },
2338
+ l: { multiplier: 1e-3, dimensions: dim({ length: 3 }), prefixable: true },
2339
+ gal: { multiplier: 0.003785411784, dimensions: dim({ length: 3 }) },
2340
+ // US gallon
2341
+ // --- Area -----------------------------------------------------------------
2342
+ ha: { multiplier: 1e4, dimensions: dim({ length: 2 }) },
2343
+ // hectare
2344
+ acre: { multiplier: 4046.8564224, dimensions: dim({ length: 2 }) }
2345
+ };
2346
+ var ALL_UNITS = { ...BASE_UNITS, ...DERIVED_UNITS };
2347
+ var UNIT_ALIASES = {
2348
+ "\xB0C": "degC",
2349
+ "\xB0F": "degF",
2350
+ "\xB0R": "degR",
2351
+ "\xB0": "deg"
2352
+ // The Unicode micro sign is handled in prefixes; °K is non-standard.
2353
+ };
2354
+ function getUnitDef(name) {
2355
+ return ALL_UNITS[name];
2356
+ }
2357
+
2358
+ // src/types/unit-prefixes.ts
2359
+ var SI_PREFIXES = {
2360
+ // Positive powers of ten
2361
+ Y: 1e24,
2362
+ // yotta
2363
+ Z: 1e21,
2364
+ // zetta
2365
+ E: 1e18,
2366
+ // exa
2367
+ P: 1e15,
2368
+ // peta
2369
+ T: 1e12,
2370
+ // tera
2371
+ G: 1e9,
2372
+ // giga
2373
+ M: 1e6,
2374
+ // mega
2375
+ k: 1e3,
2376
+ // kilo
2377
+ h: 100,
2378
+ // hecto
2379
+ da: 10,
2380
+ // deka (two-letter)
2381
+ // Negative powers of ten
2382
+ d: 0.1,
2383
+ // deci
2384
+ c: 0.01,
2385
+ // centi
2386
+ m: 1e-3,
2387
+ // milli
2388
+ u: 1e-6,
2389
+ // micro (ASCII fallback)
2390
+ \u00B5: 1e-6,
2391
+ // micro (Unicode)
2392
+ n: 1e-9,
2393
+ // nano
2394
+ p: 1e-12,
2395
+ // pico
2396
+ f: 1e-15,
2397
+ // femto
2398
+ a: 1e-18,
2399
+ // atto
2400
+ z: 1e-21,
2401
+ // zepto
2402
+ y: 1e-24
2403
+ // yocto
2404
+ };
2405
+ var SI_PREFIX_KEYS = Object.keys(SI_PREFIXES).sort(
2406
+ (a, b) => b.length - a.length
2407
+ );
2408
+ var BEST_PREFIXES = [
2409
+ "Y",
2410
+ "Z",
2411
+ "E",
2412
+ "P",
2413
+ "T",
2414
+ "G",
2415
+ "M",
2416
+ "k",
2417
+ "",
2418
+ "m",
2419
+ "u",
2420
+ "n",
2421
+ "p",
2422
+ "f",
2423
+ "a",
2424
+ "z",
2425
+ "y"
2426
+ ];
2427
+ function getPrefix(name) {
2428
+ return SI_PREFIXES[name];
2429
+ }
2430
+
2431
+ // src/types/unit.ts
2432
+ var DimensionMismatchError = class extends Error {
2433
+ constructor(left, right, op) {
2434
+ super(
2435
+ `Dimension mismatch in ${op}: ${formatDimensions(left)} vs ${formatDimensions(right)}`
2436
+ );
2437
+ this.left = left;
2438
+ this.right = right;
2439
+ }
2440
+ left;
2441
+ right;
2442
+ name = "DimensionMismatchError";
2443
+ };
2444
+ var UnitParseError = class extends Error {
2445
+ name = "UnitParseError";
2446
+ constructor(notation, reason) {
2447
+ super(`Cannot parse unit notation "${notation}": ${reason}`);
2448
+ }
2449
+ };
2450
+ var DIM_KEYS = [
2451
+ "length",
2452
+ "mass",
2453
+ "time",
2454
+ "current",
2455
+ "temperature",
2456
+ "amount",
2457
+ "luminosity"
2458
+ ];
2459
+ function dimsEqual(a, b) {
2460
+ for (const k of DIM_KEYS) {
2461
+ if (a[k] !== b[k]) return false;
2462
+ }
2463
+ return true;
2464
+ }
2465
+ function dimsAdd(a, b) {
2466
+ return {
2467
+ length: a.length + b.length,
2468
+ mass: a.mass + b.mass,
2469
+ time: a.time + b.time,
2470
+ current: a.current + b.current,
2471
+ temperature: a.temperature + b.temperature,
2472
+ amount: a.amount + b.amount,
2473
+ luminosity: a.luminosity + b.luminosity
2474
+ };
2475
+ }
2476
+ function dimsSub(a, b) {
2477
+ return {
2478
+ length: a.length - b.length,
2479
+ mass: a.mass - b.mass,
2480
+ time: a.time - b.time,
2481
+ current: a.current - b.current,
2482
+ temperature: a.temperature - b.temperature,
2483
+ amount: a.amount - b.amount,
2484
+ luminosity: a.luminosity - b.luminosity
2485
+ };
2486
+ }
2487
+ function dimsScale(a, n) {
2488
+ return {
2489
+ length: a.length * n,
2490
+ mass: a.mass * n,
2491
+ time: a.time * n,
2492
+ current: a.current * n,
2493
+ temperature: a.temperature * n,
2494
+ amount: a.amount * n,
2495
+ luminosity: a.luminosity * n
2496
+ };
2497
+ }
2498
+ function isDimensionless(d) {
2499
+ return dimsEqual(d, DIMENSIONLESS);
2500
+ }
2501
+ function formatDimensions(d) {
2502
+ const parts = [];
2503
+ for (const k of DIM_KEYS) {
2504
+ const e = d[k];
2505
+ if (e !== 0) parts.push(`${k}^${e}`);
2506
+ }
2507
+ return parts.length === 0 ? "dimensionless" : parts.join("\xB7");
2508
+ }
2509
+ function resolveAtom(token) {
2510
+ const aliased = UNIT_ALIASES[token] ?? token;
2511
+ const direct = getUnitDef(aliased);
2512
+ if (direct) {
2513
+ return {
2514
+ multiplier: direct.multiplier,
2515
+ offset: direct.offset ?? 0,
2516
+ dimensions: direct.dimensions,
2517
+ prefix: "",
2518
+ base: aliased
2519
+ };
2520
+ }
2521
+ for (const prefix of SI_PREFIX_KEYS) {
2522
+ if (!aliased.startsWith(prefix) || aliased.length === prefix.length) continue;
2523
+ const rest = aliased.slice(prefix.length);
2524
+ const baseDef = getUnitDef(rest);
2525
+ if (!baseDef) continue;
2526
+ if (!baseDef.prefixable) continue;
2527
+ return {
2528
+ multiplier: baseDef.multiplier * SI_PREFIXES[prefix],
2529
+ // Offset is in base units, so prefix the multiplier but not the offset
2530
+ // (we never apply prefixes to temperature units in practice anyway).
2531
+ offset: baseDef.offset ?? 0,
2532
+ dimensions: baseDef.dimensions,
2533
+ prefix,
2534
+ base: rest
2535
+ };
2536
+ }
2537
+ throw new UnitParseError(token, `unknown unit "${token}"`);
2538
+ }
2539
+ function splitScalar(input) {
2540
+ const m = input.match(/^\s*([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\s+(.*)$/);
2541
+ if (m) {
2542
+ return { scalar: parseFloat(m[1]), rest: m[2].trim() };
2543
+ }
2544
+ const scalarOnly = input.match(/^\s*([+-]?\d+(?:\.\d+)?(?:[eE][+-]?\d+)?)\s*$/);
2545
+ if (scalarOnly) {
2546
+ return { scalar: parseFloat(scalarOnly[1]), rest: "" };
2547
+ }
2548
+ return { scalar: 1, rest: input.trim() };
2549
+ }
2550
+ function parseUnitExpr(expr) {
2551
+ if (expr === "" || expr === "1") return [];
2552
+ const normalized = expr.replace(/[·⋅]/g, "*");
2553
+ const atoms = [];
2554
+ let pos = 0;
2555
+ let nextSign = 1;
2556
+ while (pos < normalized.length) {
2557
+ while (pos < normalized.length && /\s/.test(normalized[pos])) pos++;
2558
+ if (pos >= normalized.length) break;
2559
+ const ch = normalized[pos];
2560
+ if (ch === "*") {
2561
+ pos++;
2562
+ continue;
2563
+ }
2564
+ if (ch === "/") {
2565
+ nextSign = -1;
2566
+ pos++;
2567
+ continue;
2568
+ }
2569
+ if (ch === "1") {
2570
+ const next = normalized[pos + 1];
2571
+ if (next === void 0 || next === " " || next === "/" || next === "*") {
2572
+ pos++;
2573
+ continue;
2574
+ }
2575
+ }
2576
+ if (!/[A-Za-z°µΩ]/.test(ch)) {
2577
+ throw new UnitParseError(expr, `unexpected character "${ch}" at position ${pos}`);
2578
+ }
2579
+ const idStart = pos;
2580
+ while (pos < normalized.length && /[A-Za-z°µΩ]/.test(normalized[pos])) pos++;
2581
+ const identifier = normalized.slice(idStart, pos);
2582
+ let exponent = 1;
2583
+ if (pos < normalized.length && normalized[pos] === "^") {
2584
+ pos++;
2585
+ const expMatch = normalized.slice(pos).match(/^([+-]?\d+(?:\.\d+)?)/);
2586
+ if (!expMatch) {
2587
+ throw new UnitParseError(expr, `expected exponent after "^" at position ${pos}`);
2588
+ }
2589
+ exponent = parseFloat(expMatch[1]);
2590
+ pos += expMatch[1].length;
2591
+ } else {
2592
+ const supMatch = normalized.slice(pos).match(/^([²³⁴⁵⁶⁷⁸⁹⁰¹]+)/);
2593
+ if (supMatch) {
2594
+ exponent = parseSuperscript(supMatch[1]);
2595
+ pos += supMatch[1].length;
2596
+ }
2597
+ }
2598
+ const resolved = resolveAtom(identifier);
2599
+ atoms.push({
2600
+ multiplier: resolved.multiplier,
2601
+ offset: resolved.offset,
2602
+ dimensions: resolved.dimensions,
2603
+ exponent: nextSign * exponent,
2604
+ source: identifier
2605
+ });
2606
+ nextSign = 1;
2607
+ }
2608
+ return atoms;
2609
+ }
2610
+ var SUPERSCRIPT_MAP = {
2611
+ "\u2070": "0",
2612
+ "\xB9": "1",
2613
+ "\xB2": "2",
2614
+ "\xB3": "3",
2615
+ "\u2074": "4",
2616
+ "\u2075": "5",
2617
+ "\u2076": "6",
2618
+ "\u2077": "7",
2619
+ "\u2078": "8",
2620
+ "\u2079": "9"
2621
+ };
2622
+ function parseSuperscript(s) {
2623
+ let out = "";
2624
+ for (const ch of s) out += SUPERSCRIPT_MAP[ch] ?? ch;
2625
+ return parseInt(out, 10);
2626
+ }
2627
+ function parse(input) {
2628
+ const { scalar, rest } = splitScalar(input);
2629
+ return { scalar, atoms: parseUnitExpr(rest) };
2630
+ }
2631
+ var Unit = class _Unit {
2632
+ /** Discriminator (matches the prototype-flag convention). */
2633
+ type = "Unit";
2634
+ /** Used by `isUnit()` and typed-function dispatch. */
2635
+ isUnit = true;
2636
+ /** Numeric magnitude in **SI base units**. */
2637
+ value;
2638
+ /** Dimensional signature. */
2639
+ dimensions;
2640
+ /** Original notation string, preserved for `toString()` round-trip. */
2641
+ notation;
2642
+ constructor(value, notationOrDims, notation) {
2643
+ if (typeof notationOrDims === "string") {
2644
+ const parsed = parse(notationOrDims);
2645
+ const composed = composeAtoms(parsed.atoms);
2646
+ const inputValue = parsed.scalar * value;
2647
+ let canonical;
2648
+ if (parsed.atoms.length === 1 && parsed.atoms[0].exponent === 1) {
2649
+ const a = parsed.atoms[0];
2650
+ canonical = inputValue * a.multiplier + a.offset;
2651
+ } else {
2652
+ canonical = inputValue * composed.multiplier;
2653
+ }
2654
+ this.value = canonical;
2655
+ this.dimensions = composed.dimensions;
2656
+ this.notation = notationOrDims;
2657
+ } else {
2658
+ this.value = value;
2659
+ this.dimensions = notationOrDims;
2660
+ this.notation = notation ?? "";
2661
+ }
2662
+ }
2663
+ // -------------------------------------------------------------------------
2664
+ // Arithmetic
2665
+ // -------------------------------------------------------------------------
2666
+ /**
2667
+ * Add two units. Requires identical dimensions.
2668
+ *
2669
+ * @throws {DimensionMismatchError} if dimensions differ.
2670
+ */
2671
+ add(other) {
2672
+ if (!dimsEqual(this.dimensions, other.dimensions)) {
2673
+ throw new DimensionMismatchError(this.dimensions, other.dimensions, "add");
2674
+ }
2675
+ return new _Unit(this.value + other.value, this.dimensions, this.notation);
2676
+ }
2677
+ /**
2678
+ * Subtract two units. Requires identical dimensions.
2679
+ *
2680
+ * @throws {DimensionMismatchError} if dimensions differ.
2681
+ */
2682
+ sub(other) {
2683
+ if (!dimsEqual(this.dimensions, other.dimensions)) {
2684
+ throw new DimensionMismatchError(this.dimensions, other.dimensions, "sub");
2685
+ }
2686
+ return new _Unit(this.value - other.value, this.dimensions, this.notation);
2687
+ }
2688
+ /**
2689
+ * Multiply by another unit or a scalar. Dimensions add when multiplying by
2690
+ * another unit; unchanged when multiplying by a scalar.
2691
+ */
2692
+ mul(other) {
2693
+ if (typeof other === "number") {
2694
+ return new _Unit(this.value * other, this.dimensions, this.notation);
2695
+ }
2696
+ return new _Unit(
2697
+ this.value * other.value,
2698
+ dimsAdd(this.dimensions, other.dimensions),
2699
+ composeNotation(this.notation, other.notation, "*")
2700
+ );
2701
+ }
2702
+ /**
2703
+ * Divide by another unit or a scalar. Dimensions subtract when dividing by
2704
+ * another unit; unchanged when dividing by a scalar.
2705
+ */
2706
+ div(other) {
2707
+ if (typeof other === "number") {
2708
+ return new _Unit(this.value / other, this.dimensions, this.notation);
2709
+ }
2710
+ return new _Unit(
2711
+ this.value / other.value,
2712
+ dimsSub(this.dimensions, other.dimensions),
2713
+ composeNotation(this.notation, other.notation, "/")
2714
+ );
2715
+ }
2716
+ /**
2717
+ * Raise to an integer or rational power. Dimensions scale by `n`.
2718
+ */
2719
+ pow(n) {
2720
+ return new _Unit(
2721
+ this.value ** n,
2722
+ dimsScale(this.dimensions, n),
2723
+ this.notation ? `(${this.notation})^${n}` : ""
2724
+ );
2725
+ }
2726
+ // -------------------------------------------------------------------------
2727
+ // Conversion
2728
+ // -------------------------------------------------------------------------
2729
+ /**
2730
+ * Convert to a target unit. Dimensions must match.
2731
+ *
2732
+ * @throws {DimensionMismatchError} if `targetNotation`'s dimensions differ
2733
+ * from this unit's.
2734
+ */
2735
+ to(targetNotation) {
2736
+ const parsed = parse(targetNotation);
2737
+ const composed = composeAtoms(parsed.atoms);
2738
+ if (!dimsEqual(this.dimensions, composed.dimensions)) {
2739
+ throw new DimensionMismatchError(
2740
+ this.dimensions,
2741
+ composed.dimensions,
2742
+ `to("${targetNotation}")`
2743
+ );
2744
+ }
2745
+ return new _Unit(this.value, composed.dimensions, targetNotation);
2746
+ }
2747
+ /**
2748
+ * Pick a unit (with SI prefix) that gives a magnitude closest to 1.
2749
+ *
2750
+ * Searches the unit registry for entries matching this unit's dimensions,
2751
+ * then applies each SI prefix in {@link BEST_PREFIXES} to find the
2752
+ * representation minimising `|log10(displayed value)|`.
2753
+ *
2754
+ * If no registered unit matches the dimensions, falls back to a synthetic
2755
+ * notation describing the dimensional vector.
2756
+ */
2757
+ toBest() {
2758
+ if (isDimensionless(this.dimensions)) {
2759
+ return new _Unit(this.value, this.dimensions, "");
2760
+ }
2761
+ let bestNotation;
2762
+ let bestScore = Infinity;
2763
+ for (const [name, def] of Object.entries(ALL_UNITS)) {
2764
+ if (name === "kg") continue;
2765
+ if (!dimsEqual(def.dimensions, this.dimensions)) continue;
2766
+ if (def.offset !== void 0) continue;
2767
+ const candidatePrefixes = def.prefixable ? BEST_PREFIXES : [""];
2768
+ for (const prefix of candidatePrefixes) {
2769
+ const factor = prefix === "" ? def.multiplier : def.multiplier * SI_PREFIXES[prefix];
2770
+ if (factor === 0) continue;
2771
+ const displayed = this.value / factor;
2772
+ if (displayed === 0) continue;
2773
+ const score = Math.abs(Math.log10(Math.abs(displayed)));
2774
+ if (score < bestScore) {
2775
+ bestScore = score;
2776
+ bestNotation = prefix + name;
2777
+ }
2778
+ }
2779
+ }
2780
+ if (bestNotation === void 0) {
2781
+ return new _Unit(
2782
+ this.value,
2783
+ this.dimensions,
2784
+ this.notation || formatDimensions(this.dimensions)
2785
+ );
2786
+ }
2787
+ return new _Unit(this.value, this.dimensions, bestNotation);
2788
+ }
2789
+ // -------------------------------------------------------------------------
2790
+ // Comparison
2791
+ // -------------------------------------------------------------------------
2792
+ /** True iff dimensions and canonical value are equal. */
2793
+ equals(other) {
2794
+ return dimsEqual(this.dimensions, other.dimensions) && this.value === other.value;
2795
+ }
2796
+ /** True iff dimensions match (values may differ). */
2797
+ dimensionsEqual(other) {
2798
+ return dimsEqual(this.dimensions, other.dimensions);
2799
+ }
2800
+ // -------------------------------------------------------------------------
2801
+ // Formatting
2802
+ // -------------------------------------------------------------------------
2803
+ /**
2804
+ * Pretty-print. If `notation` is set (the common case), display the value
2805
+ * in that notation — otherwise emit a dimensional signature.
2806
+ */
2807
+ toString() {
2808
+ if (this.notation === "") {
2809
+ if (isDimensionless(this.dimensions)) return String(this.value);
2810
+ return `${this.value} ${formatDimensions(this.dimensions)}`;
2811
+ }
2812
+ const displayed = displayedValue(this.value, this.notation);
2813
+ return `${formatNumber(displayed)} ${this.notation}`;
2814
+ }
2815
+ /** JSON-serialisable record. */
2816
+ toJSON() {
2817
+ return { mathts: "Unit", value: this.value, notation: this.notation };
2818
+ }
2819
+ /**
2820
+ * Rehydrate from a JSON record produced by {@link toJSON}.
2821
+ *
2822
+ * @throws {UnitParseError} if `json.notation` cannot be parsed.
2823
+ */
2824
+ static fromJSON(json) {
2825
+ const parsed = parse(json.notation);
2826
+ const composed = composeAtoms(parsed.atoms);
2827
+ return new _Unit(json.value, composed.dimensions, json.notation);
2828
+ }
2829
+ /**
2830
+ * Parse a full unit expression (with optional leading numeric coefficient).
2831
+ *
2832
+ * Example: `Unit.parse('5 km/h')`.
2833
+ */
2834
+ static parse(input) {
2835
+ const { scalar, rest } = splitScalar(input);
2836
+ return new _Unit(scalar, rest);
2837
+ }
2838
+ };
2839
+ Unit.prototype.isUnit = true;
2840
+ function composeAtoms(atoms) {
2841
+ let multiplier = 1;
2842
+ let dimensions = { ...DIMENSIONLESS };
2843
+ for (const a of atoms) {
2844
+ multiplier *= a.multiplier ** a.exponent;
2845
+ dimensions = dimsAdd(dimensions, dimsScale(a.dimensions, a.exponent));
2846
+ }
2847
+ return { multiplier, dimensions };
2848
+ }
2849
+ function displayedValue(canonical, notation) {
2850
+ const parsed = parse(notation);
2851
+ const composed = composeAtoms(parsed.atoms);
2852
+ if (parsed.atoms.length === 1 && parsed.atoms[0].exponent === 1) {
2853
+ const a = parsed.atoms[0];
2854
+ return (canonical - a.offset) / a.multiplier;
2855
+ }
2856
+ return canonical / composed.multiplier;
2857
+ }
2858
+ function formatNumber(n) {
2859
+ if (Number.isInteger(n)) return n.toString();
2860
+ const rounded = Number(n.toPrecision(12));
2861
+ return rounded.toString();
2862
+ }
2863
+ function composeNotation(a, b, op) {
2864
+ if (a === "" && b === "") return "";
2865
+ if (a === "") return op === "*" ? b : `1/${b}`;
2866
+ if (b === "") return a;
2867
+ const sep = op === "*" ? "*" : "/";
2868
+ return `${a}${sep}${b}`;
2869
+ }
2870
+ function isUnit(value) {
2871
+ return value instanceof Unit;
2872
+ }
2077
2873
 
2078
2874
  // src/typed/mathts-typed.ts
2079
2875
  import typed, { create } from "typed-function";
@@ -2115,7 +2911,14 @@ var isBigNumber2 = (x) => isBigNumber(x);
2115
2911
  var isMatrix = (x) => isObject(x) && "rows" in x && "cols" in x && "get" in x && typeof x.type === "string";
2116
2912
  var isDenseMatrix = (x) => isMatrix(x) && x.type === "DenseMatrix";
2117
2913
  var isSparseMatrix = (x) => isMatrix(x) && x.type === "SparseMatrix";
2118
- var isUnit = (x) => isObject(x) && "value" in x && "unit" in x && typeof x.type === "string";
2914
+ var isUnit2 = (x) => {
2915
+ if (!isObject(x)) return false;
2916
+ const o = x;
2917
+ if (typeof o.type !== "string") return false;
2918
+ if (o.type === "Unit" && "value" in o && "dimensions" in o) return true;
2919
+ if ("value" in o && "unit" in o) return true;
2920
+ return false;
2921
+ };
2119
2922
  var MATHTS_TYPES = [
2120
2923
  // bigint is not built into typed-function
2121
2924
  { name: "bigint", test: isBigInt },
@@ -2135,7 +2938,7 @@ var MATHTS_TYPES = [
2135
2938
  { name: "SparseMatrix", test: isSparseMatrix },
2136
2939
  { name: "Matrix", test: isMatrix },
2137
2940
  // Other types
2138
- { name: "Unit", test: isUnit }
2941
+ { name: "Unit", test: isUnit2 }
2139
2942
  ];
2140
2943
  var MATHTS_CONVERSIONS = [
2141
2944
  // -------------------------------------------------------------------------
@@ -2551,6 +3354,9 @@ var math = {
2551
3354
  // src/index.ts
2552
3355
  var VERSION = "0.1.0";
2553
3356
  export {
3357
+ ALL_UNITS,
3358
+ BASE_UNITS,
3359
+ BEST_PREFIXES,
2554
3360
  BIGNUMBER_E,
2555
3361
  BIGNUMBER_LN10,
2556
3362
  BIGNUMBER_LN2,
@@ -2565,6 +3371,9 @@ export {
2565
3371
  COMPLEX_ZERO,
2566
3372
  Complex,
2567
3373
  DEFAULT_CONFIG,
3374
+ DERIVED_UNITS,
3375
+ DIMENSIONLESS,
3376
+ DimensionMismatchError,
2568
3377
  FRACTION_HALF,
2569
3378
  FRACTION_NEG_ONE,
2570
3379
  FRACTION_ONE,
@@ -2576,12 +3385,19 @@ export {
2576
3385
  I,
2577
3386
  MATHTS_CONVERSIONS,
2578
3387
  MATHTS_TYPES,
3388
+ SI_PREFIXES,
2579
3389
  TypeRegistry,
3390
+ UNIT_ALIASES,
3391
+ Unit,
3392
+ UnitParseError,
2580
3393
  VERSION,
2581
3394
  create,
2582
3395
  createFactory,
2583
3396
  createMathTSTyped,
2584
3397
  createTypedFunction,
3398
+ dim,
3399
+ getPrefix,
3400
+ getUnitDef,
2585
3401
  initTypedWasm,
2586
3402
  isArray,
2587
3403
  isBigInt,
@@ -2599,7 +3415,8 @@ export {
2599
3415
  isString,
2600
3416
  isTypedWasmAvailable,
2601
3417
  isUndefined,
2602
- isUnit,
3418
+ isUnit2 as isUnit,
3419
+ isUnit as isUnitValue,
2603
3420
  math,
2604
3421
  mathTyped,
2605
3422
  registerNativeTypes,