JavaScript's Math and Number lose precision at 15 digits. BigFlo doesn't.
Drop-in upgrade with 100% Math and Number API coverage. ~8 KB gzipped. Zero dependencies.
BigFlo(0.1)['+'](0.2) // = 0.3, not 0.30000000000000004
BigFlo(0.6)['*'](3) // = 1.8, not 1.7999999999999998
BigFlo(2).sqrt() // = 1.41421356237309504880168872420969807856
BigFlo(1000000).toFormat() // = "1,000,000"
BigFlo(255).toHex() // = "ff"
BigFlo.PI // = 3.1415926535897932384626433832795028841971693It's your Math and Number, upgraded. Same method names you already know. Math.sqrt() → BigFlo.sqrt(). Math.sin() → BigFlo.sin(). Nothing new to learn.
It's fast. Up to 92x faster on large numbers by leveraging low-level engine optimizations. Faster than decimal.js, bignumber.js, and big.js on every benchmark.
It's tiny. ~8 KB gzipped. Zero dependencies. Single file.
npm i bigfloconst BigFlo = require('bigflo'); // CommonJSimport BigFlo from 'bigflo'; // ES Modulesquirk = 0.1 + 0.2 // = 0.30000000000000004
bigflo = BigFlo(0.1)['+'](0.2); // = 0.3
quirk = 0.3 - 0.2 // = 0.09999999999999998
bigflo = BigFlo(0.3)['-'](0.2); // = 0.1
quirk = 0.6 * 3 // = 1.7999999999999998
bigflo = BigFlo(0.6)['*'](3); // = 1.8
quirk = 0.3 / 0.1 // = 2.9999999999999996
bigflo = BigFlo(0.3)['/'](0.1); // = 3
quirk = 0.1 / 0.3 // = 0.33333333333333337
bigflo = BigFlo(0.1)['/'](0.3); // = 0.333333333333333333333333333333333
quirk = 0.1 + 0.7 // = 0.7999999999999999
bigflo = BigFlo(0.1)['+'](0.7); // = 0.8
quirk = 0.2 * 0.2 // = 0.04000000000000001
bigflo = BigFlo(0.2)['*'](0.2); // = 0.04
quirk = 0.7 - 0.4 // = 0.29999999999999993
bigflo = BigFlo(0.7)['-'](0.4); // = 0.3
quirk = 0.3 / 0.2 // = 1.4999999999999998
bigflo = BigFlo(0.3)['/'](0.2); // = 1.5
quirk = 0.000000003 / 0.2 // = 1.5e-8
bigflo = BigFlo('0.000000003')['/'](0.2); // = 0.000000015Faster than decimal.js, bignumber.js, and big.js on every benchmark.
---
config:
themeVariables:
xyChart:
plotColorPalette: "#1565c0"
---
xychart-beta horizontal
title "200-digit x 200-digit Multiplication (us, lower = faster)"
x-axis ["BigFlo (0.76us)", "bignumber.js (9.87us)", "decimal.js (13.4us)", "big.js (70.0us)"]
y-axis "Microseconds" 0 --> 70
bar [0.76, 9.87, 13.4, 70.0]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#1565c0"
---
xychart-beta horizontal
title "sqrt(2) (us, lower = faster)"
x-axis ["BigFlo (0.38us)", "decimal.js (3.26us)", "bignumber.js (3.23us)", "big.js (20.7us)"]
y-axis "Microseconds" 0 --> 21
bar [0.38, 3.26, 3.23, 20.7]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#1565c0"
---
xychart-beta horizontal
title "Chain: a + b * c - d / e (us, lower = faster)"
x-axis ["BigFlo (0.047us)", "decimal.js (0.35us)", "big.js (0.40us)", "bignumber.js (0.58us)"]
y-axis "Microseconds" 0 --> 0.6
bar [0.047, 0.35, 0.40, 0.58]
---
config:
themeVariables:
xyChart:
plotColorPalette: "#1565c0"
---
xychart-beta horizontal
title "log10(1000) (us, lower = faster)"
x-axis ["BigFlo (0.074us)", "decimal.js (4.56us)"]
y-axis "Microseconds" 0 --> 5
bar [0.074, 4.56]
| Operation | BigFlo | decimal.js | bignumber.js | big.js |
|---|---|---|---|---|
Multiply 1234 * 8765 |
0.115 (4.2x faster) | 0.482 | 0.485 | 0.276 |
Divide 1 / 3 |
0.082 (8.7x faster) | 0.244 | 0.714 | 0.714 |
Power 2^100 |
0.199 (5.8x faster) | 1.155 | 0.819 | 1.024 |
| 200-digit * 200-digit | 0.764 (91.6x faster) | 13.41 | 9.87 | 69.99 |
Chain a+b*c-d/e |
0.047 (12.3x faster) | 0.350 | 0.578 | 0.402 |
Plus 0.1 + 0.2 |
0.090 (4.1x faster) | 0.289 | 0.365 | 0.124 |
Compare 100 > 99 |
0.017 (5.9x faster) | 0.072 | 0.032 | 0.100 |
| sqrt(2) | 0.379 (54.7x faster) | 3.257 | 3.232 | 20.73 |
| sin(0.5) | 1.671 (5.7x faster) | 9.565 | -- | -- |
| log10(1000) | 0.074 (61.7x faster) | 4.563 | -- | -- |
| atan(1) | 0.081 (8.5x faster) | 0.686 | -- | -- |
Parse "123.456" |
0.061 (3x faster) | 0.138 | 0.183 | 0.075 |
| toString | 0.089 (2.8x faster) | 0.181 | 0.247 | 0.144 |
| abs(-42) | 0.026 (3x faster) | 0.079 | 0.034 | 0.056 |
| ceil(7.004) | 0.080 (2.9x faster) | 0.209 | 0.233 | -- |
| toFixed(2) | 0.102 (3.8x faster) | 0.386 | 0.335 | 0.187 |
| Feature | BigFlo | decimal.js | bignumber.js | big.js |
|---|---|---|---|---|
| Arithmetic (+, -, *, /, %, **) | ✅ | ✅ | ✅ | ✅ |
| Trigonometric (sin, cos, tan...) | ✅ | ✅ | - | - |
| Hyperbolic (sinh, cosh, tanh...) | ✅ | ✅ | - | - |
| Logarithmic (log, ln, log2, log10) | ✅ | ✅ | - | - |
| Roots (sqrt, cbrt) | ✅ | ✅ | ✅ | sqrt |
| exp(x) | ✅ | ✅ | - | - |
| Non-integer exponents | ✅ | ✅ | - | - |
| 9 Rounding modes | ✅ | ✅ | ✅ | 4 |
| Infinity / NaN handling | ✅ | ✅ | ✅ | - |
| Constants (PI, E, LN2...) | ✅ | - | - | - |
Symbolic aliases (['+'], ['*']...) |
✅ | - | - | - |
| Base conversion (hex, bin, oct) | ✅ | ✅ | ✅ | - |
| toFraction | ✅ | ✅ | ✅ | - |
| toFormat (locale) | ✅ | - | ✅ | - |
| isSafeInteger | ✅ | - | - | - |
| parseInt / parseBigInt | ✅ | - | - | - |
| Chainable operations | ✅ | ✅ | ✅ | ✅ |
| 100% Math + Number API | ✅ | - | - | - |
| Zero dependencies | ✅ | ✅ | ✅ | ✅ |
const principal = BigFlo(10000);
const interestRate = BigFlo(0.05);
const years = 5;
const amount = principal['*'](interestRate['+'](1)['**'](years));
console.log(`Amount after ${years} years: ${amount.toFormat(2)}`);
// Amount after 5 years: 12,762.81const avogadroNumber = BigFlo('6.02214076e+23');
const molecules = avogadroNumber['*'](2);
console.log(`Molecules in 2 moles: ${molecules}`);
// Molecules in 2 moles: 1204428152000000000000000// how many of the smallest thing possible is inside the whole observable universe?
const PI = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679';
const planckLength = BigFlo('1.616255e-35');
const planckVolume = planckLength['**'](3);
const sphereVolume = r => BigFlo(4).setDivisionPrecision(100)['/'](3)['*'](PI)['*'](BigFlo(r)['**'](3));
const observableUniverseDiameter = BigFlo('8.8e26');
const observableUniverseRadius = observableUniverseDiameter['/'](2);
const observableUniverseVolume = sphereVolume(observableUniverseRadius);
const planckVolumeCountInObservableUniverse = observableUniverseVolume['/'](planckVolume).floor();
console.log(`Number of Planck volumes in the observable universe: ${planckVolumeCountInObservableUniverse}`);
// Number of Planck volumes in the observable universe: 84511730484834131206881865680639113619647108892011465350695564305272555636684111446309955229141533316023379319781575896906672933616475618801242275287976816735193410571088873930085447368import BigFlo from './BigFlo.js';
let phi = "1.618033988749894848204586834365638117720309179805762862135448622705260462818902449707207204189391137484754088075386891752126633862223536931793180060766726354433389086595939582905638322661319928290267880675208766892501711696207032221043216269548626296313614438149758701220340805887954454749246185695364864449241044320771344947049565846788509874339442212544877066478091588460749988712400765217057517978834166256249407589069";
let pi = "3.141592653589793238462643383279502884197169399375105820974944592307816";
// phi multiplied by pi
let result = BigFlo(phi)['*'](pi);
console.log(`Result: ${result}`);
// Result: 5.083203692315259815809509013242198841831839293221154120482332809249978486067803281742547878659541280894609381315647809652472437157002687253977448058691232075726017949776921866615084597175541994376144459229951222947905298133442989827323842164568914074255981755734191011699701938603520047801826678551521546780141772440935062394580909338082095329503034709027317362240861348968583169107439253654312137744324076177917817516717677490798664887072601885417667893466455668275014134080247511284863304const angle = BigFlo.PI.div(4); // 45 degrees in radians
console.log(`sin(PI/4): ${angle.sin()}`);
// sin(PI/4): 0.7071067811865475244008443621048485294259918
console.log(`cos(PI/4): ${angle.cos()}`);
// cos(PI/4): 0.7071067811865475244008443621048495491436801
console.log(`sqrt(2): ${BigFlo(2).sqrt()}`);
// sqrt(2): 1.41421356237309504880168872420969807856
console.log(`ln(2): ${BigFlo(2).log()}`);
// ln(2): 0.6931471805599453094172321214581765680754964BigFlo(255).toHex(); // "ff"
BigFlo(255).toBinary(); // "11111111"
BigFlo(255).toOctal(); // "377"
BigFlo.fromHex('ff'); // 255
BigFlo.fromBinary('1010'); // 10
BigFlo.fromBase('z', 36); // 35BigFlo(1234567890).toFormat(); // "1,234,567,890"
BigFlo('1234567.89').toFormat(2); // "1,234,567.89"
// Custom separators (European style)
BigFlo(1234567.89).toFormat(2, { groupSeparator: '.', decimalSeparator: ',' });
// "1.234.567,89"
// Currency
BigFlo(9999.99).toFormat(2, { prefix: '$' });
// "$9,999.99"BigFlo('0.5').toFraction(); // [BigFlo(1), BigFlo(2)] → 1/2
BigFlo('0.75').toFraction(); // [BigFlo(3), BigFlo(4)] → 3/4
BigFlo('0.333333333').toFraction(); // [BigFlo(333333333), BigFlo(1000000000)]// All 9 rounding modes — each shown on BigFlo('2.5') and BigFlo('-2.5')
//
// BigFlo.ROUND_UP (0) away from zero
BigFlo('2.5').toDecimalPlaces(0, BigFlo.ROUND_UP); // 3
BigFlo('-2.5').toDecimalPlaces(0, BigFlo.ROUND_UP); // -3
//
// BigFlo.ROUND_DOWN (1) toward zero (truncation)
BigFlo('2.9').toDP(0, BigFlo.ROUND_DOWN); // 2
BigFlo('-2.9').toDP(0, BigFlo.ROUND_DOWN); // -2
//
// BigFlo.ROUND_CEIL (2) toward +Infinity
BigFlo('2.1').toFixed(0, BigFlo.ROUND_CEIL); // "3"
BigFlo('-2.9').toFixed(0, BigFlo.ROUND_CEIL); // "-2"
//
// BigFlo.ROUND_FLOOR (3) toward -Infinity
BigFlo('2.9').toFixed(0, BigFlo.ROUND_FLOOR); // "2"
BigFlo('-2.1').toFixed(0, BigFlo.ROUND_FLOOR); // "-3"
//
// BigFlo.ROUND_HALF_UP (4) nearest, ties away from zero (standard rounding)
BigFlo('2.5').toDecimalPlaces(0, BigFlo.ROUND_HALF_UP); // 3
BigFlo('-2.5').toDecimalPlaces(0, BigFlo.ROUND_HALF_UP); // -3
//
// BigFlo.ROUND_HALF_DOWN (5) nearest, ties toward zero
BigFlo('2.5').toDP(0, BigFlo.ROUND_HALF_DOWN); // 2
BigFlo('-2.5').toDP(0, BigFlo.ROUND_HALF_DOWN); // -2
//
// BigFlo.ROUND_HALF_EVEN (6) nearest, ties to even (banker's rounding)
BigFlo('2.5').toDecimalPlaces(0, BigFlo.ROUND_HALF_EVEN); // 2 (even)
BigFlo('3.5').toDecimalPlaces(0, BigFlo.ROUND_HALF_EVEN); // 4 (even)
//
// BigFlo.ROUND_HALF_CEIL (7) nearest, ties toward +Infinity
BigFlo('2.5').toFixed(0, BigFlo.ROUND_HALF_CEIL); // "3"
BigFlo('-2.5').toFixed(0, BigFlo.ROUND_HALF_CEIL); // "-2"
//
// BigFlo.ROUND_HALF_FLOOR (8) nearest, ties toward -Infinity
BigFlo('2.5').toFixed(0, BigFlo.ROUND_HALF_FLOOR); // "2"
BigFlo('-2.5').toFixed(0, BigFlo.ROUND_HALF_FLOOR); // "-3"
//
// toDecimalPlaces (toDP) returns BigFlo (chainable)
// toFixed returns String (like Number.prototype.toFixed)
// toSignificantDigits (toSD) rounds to N significant digits, returns BigFlonumber = '1234567890.123234345456567678'; // (BigFlo) String (recommended for precision)
number = 123456.789; // (BigFlo) Number
number = 1234567890n; // (BigFlo) BigInt
number = BigFlo(123); // (BigFlo) BigFlo
number = '1e3'; // (BigFlo) Scientific notation
BigFlo.fromHex('ff'); // (BigFlo) 255
BigFlo.fromBinary('1010'); // (BigFlo) 10
BigFlo.fromOctal('77'); // (BigFlo) 63
BigFlo.fromBase('z', 36); // (BigFlo) any base 2 to 1,114,112BigFlo(x).plus(number) // (BigFlo) addition
BigFlo(x).minus(number) // (BigFlo) subtraction
BigFlo(x).times(number) // (BigFlo) multiplication
BigFlo(x).div(number) // (BigFlo) division
BigFlo(x).mod(number) // (BigFlo) modulo
BigFlo(x).pow(number) // (BigFlo) power
BigFlo(x).neg() // (BigFlo) negate
BigFlo(x).abs() // (BigFlo) absolute value
BigFlo(x).divToInt(number) // (BigFlo) integer division
BigFlo(x).shiftedBy(n) // (BigFlo) shift decimal point
// Symbolic aliases — same methods, operator syntax
BigFlo(x)['+'](number) // plus
BigFlo(x)['-'](number) // minus
BigFlo(x)['*'](number) // times
BigFlo(x)['/'](number) // div
BigFlo(x)['%'](number) // mod
BigFlo(x)['**'](number) // pow
// Long name aliases
BigFlo(x).multipliedBy(number) // times
BigFlo(x).dividedBy(number) // div
BigFlo(x).toThePowerOf(number) // pow
// Static — all return (BigFlo)
BigFlo.add(x, y) BigFlo.sub(x, y) BigFlo.mul(x, y)
BigFlo.div(x, y) BigFlo.mod(x, y) BigFlo.pow(x, y)
BigFlo.sum(1, 2, 3, 4, 5) // (BigFlo) = 15
BigFlo.max(1, 5, 3) // (BigFlo) = 5
BigFlo.min(5, 1, 3) // (BigFlo) = 1// Roots
BigFlo(x).sqrt() // (BigFlo) square root
BigFlo(x).cbrt() // (BigFlo) cube root
// Exponential and Logarithmic
BigFlo(x).exp() // (BigFlo) e^x
BigFlo(x).log() // (BigFlo) natural logarithm
BigFlo(x).ln() // (BigFlo) alias for log
BigFlo(x).log2() // (BigFlo) base-2 logarithm
BigFlo(x).log10() // (BigFlo) base-10 logarithm
// Trigonometric
BigFlo(x).sin() // (BigFlo) sine
BigFlo(x).cos() // (BigFlo) cosine
BigFlo(x).tan() // (BigFlo) tangent
BigFlo(x).asin() // (BigFlo) inverse sine
BigFlo(x).acos() // (BigFlo) inverse cosine
BigFlo(x).atan() // (BigFlo) inverse tangent
// Hyperbolic
BigFlo(x).sinh() // (BigFlo) hyperbolic sine
BigFlo(x).cosh() // (BigFlo) hyperbolic cosine
BigFlo(x).tanh() // (BigFlo) hyperbolic tangent
BigFlo(x).asinh() // (BigFlo) inverse hyperbolic sine
BigFlo(x).acosh() // (BigFlo) inverse hyperbolic cosine
BigFlo(x).atanh() // (BigFlo) inverse hyperbolic tangent
// Utility
BigFlo.atan2(y, x) // (BigFlo) 2-argument arctangent
BigFlo.hypot(3, 4) // (BigFlo) = 5
BigFlo.random(50) // (BigFlo) random 50-digit number in [0, 1)
// All math functions also available as static: BigFlo.sqrt(x), BigFlo.sin(x), etc.BigFlo.PI // (BigFlo) 3.1415926535897932384626433832795028841971693
BigFlo.E // (BigFlo) 2.7182818284590452353602874713526624977572453
BigFlo.LN2 // (BigFlo) 0.6931471805599453094172321214581765680754964
BigFlo.LN10 // (BigFlo) 2.302585092994045684017991454684364207601088
BigFlo.LOG2E // (BigFlo) 1.442695040888963407359924681001892
BigFlo.LOG10E // (BigFlo) 0.434294481903251827651128918916605
BigFlo.SQRT2 // (BigFlo) 1.41421356237309504880168872420969807856
BigFlo.SQRT1_2 // (BigFlo) 0.70710678118654752440084436210484903928BigFlo(x).isEqual(number) // (Boolean) equality
BigFlo(x).isDifferent(number) // (Boolean) inequality
BigFlo(x).isGreaterThan(number) // (Boolean) greater than
BigFlo(x).isLessThan(number) // (Boolean) less than
BigFlo(x).isGreaterThanOrEqual(number) // (Boolean) greater than or equal
BigFlo(x).isLessThanOrEqual(number) // (Boolean) less than or equal
BigFlo(x).cmp(number) // (Number) returns -1, 0, or 1
BigFlo(x).clamp(min, max) // (BigFlo) clamp to range
// Short aliases
BigFlo(x).eq(number) // (Boolean) isEqual
BigFlo(x).neq(number) // (Boolean) isDifferent
BigFlo(x).gt(number) // (Boolean) isGreaterThan
BigFlo(x).lt(number) // (Boolean) isLessThan
BigFlo(x).gte(number) // (Boolean) isGreaterThanOrEqual
BigFlo(x).lte(number) // (Boolean) isLessThanOrEqual
// Symbolic aliases
BigFlo(x)['=='](number) // (Boolean) isEqual
BigFlo(x)['!='](number) // (Boolean) isDifferent
BigFlo(x)['>'](number) // (Boolean) isGreaterThan
BigFlo(x)['<'](number) // (Boolean) isLessThan
BigFlo(x)['>='](number) // (Boolean) isGreaterThanOrEqual
BigFlo(x)['<='](number) // (Boolean) isLessThanOrEqualBigFlo(x).isFinite() // (Boolean) true if not NaN or Infinity
BigFlo(x).isInteger() // (Boolean) true if no fractional part
BigFlo(x).isNaN() // (Boolean) true if NaN
BigFlo(x).isNegative() // (Boolean) true if < 0
BigFlo(x).isPositive() // (Boolean) true if >= 0
BigFlo(x).isZero() // (Boolean) true if exactly 0
BigFlo(x).isSafeInteger() // (Boolean) true if within MAX_SAFE_INTEGERBigFlo(x).ceil() // (BigFlo) round toward +Infinity
BigFlo(x).floor() // (BigFlo) round toward -Infinity
BigFlo(x).round() // (BigFlo) round to nearest
BigFlo(x).trunc() // (BigFlo) round toward zero
BigFlo(x).sign() // (Number) -1, 0, or 1
// Also available as static methods
BigFlo.ceil(x) BigFlo.floor(x) BigFlo.round(x) BigFlo.trunc(x) BigFlo.sign(x)
// With explicit rounding mode
BigFlo(x).toFixed(2, roundingMode) // (String) fixed decimal places
BigFlo(x).toDecimalPlaces(2, roundingMode) // (BigFlo) round to decimal places
BigFlo(x).toSignificantDigits(3, roundingMode) // (BigFlo) round to significant digits
// Short aliases
BigFlo(x).toDP(2, roundingMode) // (BigFlo) toDecimalPlaces
BigFlo(x).toSD(3, roundingMode) // (BigFlo) toSignificantDigits
// 9 rounding modes
BigFlo.ROUND_UP // (Number) 0: away from zero
BigFlo.ROUND_DOWN // (Number) 1: toward zero (truncation)
BigFlo.ROUND_CEIL // (Number) 2: toward +Infinity
BigFlo.ROUND_FLOOR // (Number) 3: toward -Infinity
BigFlo.ROUND_HALF_UP // (Number) 4: nearest, ties away from zero (standard)
BigFlo.ROUND_HALF_DOWN // (Number) 5: nearest, ties toward zero
BigFlo.ROUND_HALF_EVEN // (Number) 6: nearest, ties to even (banker's rounding)
BigFlo.ROUND_HALF_CEIL // (Number) 7: nearest, ties toward +Infinity
BigFlo.ROUND_HALF_FLOOR // (Number) 8: nearest, ties toward -InfinityBigFlo(x).toString() // (String) exact decimal string
BigFlo(x).toJSON() // (String) JSON serialization
BigFlo(x).toFixed(precision, roundingMode) // (String) fixed decimal places
BigFlo(x).toExponential(decimalPlaces) // (String) exponential notation
BigFlo(x).toPrecision(significantDigits) // (String) significant digits
BigFlo(x).parseInt() // (Number) JavaScript Number integer
BigFlo(x).parseBigInt() // (BigInt) JavaScript BigInt integer
BigFlo(x).parseFloat() // (Number) JavaScript Number float
// Base conversion
BigFlo(x).toBinary() // (String) "11111111"
BigFlo(x).toOctal() // (String) "377"
BigFlo(x).toHex() // (String) "ff"
BigFlo(x).toBase(36) // (String) any base 2 to 1,114,112
// Fractions
BigFlo('0.75').toFraction() // (Array) [BigFlo(3), BigFlo(4)]
// Locale formatting
BigFlo(1234567).toFormat() // (String) "1,234,567"
BigFlo(1234567.89).toFormat(2) // (String) "1,234,567.89"
BigFlo(1234567).toFormat({ groupSeparator: '.', decimalSeparator: ',' })
BigFlo(1000).toFormat({ prefix: '$', suffix: ' USD' }) // (String) "$1,000 USD"// Division precision (default: 33 decimal places)
BigFlo(x).setDivisionPrecision(precision) // (BigFlo) per instance, chainable
BigFlo.setDivisionPrecision(precision) // (void) global default
// example
BigFlo(1).setDivisionPrecision(5).dividedBy(3); // 0.33333
BigFlo.setDivisionPrecision(9);
BigFlo(1).dividedBy(3); // 0.333333333// Fractional rounding precision (default: 33)
BigFlo(x).setFractionalRoundingPrecision(precision) // (BigFlo) per instance, chainable
BigFlo.setFractionalRoundingPrecision(precision) // (void) global default
BigFlo.setFractionalRoundingPrecision(false) // (void) disable
// example
BigFlo('0.333333333').times(3); // 0.999999999
BigFlo('0.333333333333333333333333333333333').times(3); // 1
BigFlo('0.333333333').setFractionalRoundingPrecision(9).times(3); // 1Every method, every edge case, every mathematical property — tested.
Test Results: 682 Passed, 0 Failed, 682 Total
Contributions are warmly welcomed. Please feel free to fork the repository, make changes, and submit a pull request.
The project is open-source and free for any use. It is licensed under the MIT License.