reduce-precision 0.0.3 → 1.0.0

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,399 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- function isENotation(input) {
4
- return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)$/.test(input);
5
- }
6
- function convertENotationToRegularNumber(eNotation) {
7
- const [coefficientStr, exponentStr] = eNotation.toString().split('e');
8
- const coefficientLength = coefficientStr
9
- .replace('.', '')
10
- .replace('-', '').length;
11
- const exponent = parseFloat(exponentStr);
12
- const precision = Math.max(coefficientLength - exponent, 1);
13
- return eNotation.toFixed(precision);
14
- }
15
- function format(input, options = {
16
- precision: 'high',
17
- template: 'number',
18
- language: 'en',
19
- outputFormat: 'plain',
20
- prefixMarker: 'i',
21
- postfixMarker: 'i',
22
- prefix: '',
23
- postfix: '',
24
- }) {
25
- let { precision, template } = options;
26
- const { language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, } = options;
27
- if (!input)
28
- return 0;
29
- if (!(template === null || template === void 0 ? void 0 : template.match(/^(number|usd|irt|irr|percent)$/g)))
30
- template = 'number';
31
- if (isENotation(input.toString())) {
32
- input = convertENotationToRegularNumber(Number(input));
33
- }
34
- // Replace each Persian/Arabic numeral in the string with its English counterpart and strip all non-numeric chars
35
- let numberString = input
36
- .toString()
37
- .replace(/[\u0660-\u0669\u06F0-\u06F9]/g, function (match) {
38
- return String(match.charCodeAt(0) & 0xf);
39
- })
40
- .replace(/[^\d.-]/g, '');
41
- // Stripping leading zeros and trailing zeros after a decimal point
42
- numberString = numberString
43
- .replace(/^0+(?=\d)/g, '')
44
- .replace(/(?<=\.\d*)0+$|(?<=\.\d)0+\b/g, '');
45
- const number = Math.abs(Number(numberString));
46
- let p, d, r, c;
47
- let f = 0;
48
- // Auto precision selection
49
- if (precision === 'auto') {
50
- if (template.match(/^(usd|irt|irr)$/g)) {
51
- if (number >= 0.0001 && number < 100000000000) {
52
- precision = 'high';
53
- }
54
- else {
55
- precision = 'medium';
56
- }
57
- }
58
- else if (template === 'number') {
59
- precision = 'medium';
60
- }
61
- else if (template === 'percent') {
62
- precision = 'low';
63
- }
64
- }
65
- if (precision === 'medium') {
66
- if (number >= 0 && number < 0.0001) {
67
- p = 33;
68
- d = 4;
69
- r = false;
70
- c = true;
71
- }
72
- else if (number >= 0.0001 && number < 0.001) {
73
- p = 7;
74
- d = 4;
75
- r = false;
76
- c = false;
77
- }
78
- else if (number >= 0.001 && number < 0.01) {
79
- p = 5;
80
- d = 3;
81
- r = false;
82
- c = false;
83
- }
84
- else if (number >= 0.001 && number < 0.1) {
85
- p = 3;
86
- d = 2;
87
- r = false;
88
- c = false;
89
- }
90
- else if (number >= 0.1 && number < 1) {
91
- p = 1;
92
- d = 1;
93
- r = false;
94
- c = false;
95
- }
96
- else if (number >= 1 && number < 10) {
97
- p = 3;
98
- d = 3;
99
- r = false;
100
- c = false;
101
- }
102
- else if (number >= 10 && number < 100) {
103
- p = 2;
104
- d = 2;
105
- r = false;
106
- c = false;
107
- }
108
- else if (number >= 100 && number < 1000) {
109
- p = 1;
110
- d = 1;
111
- r = false;
112
- c = false;
113
- }
114
- else if (number >= 1000) {
115
- const x = Math.floor(Math.log10(number)) % 3;
116
- p = 2 - x;
117
- d = 2 - x;
118
- r = true;
119
- c = true;
120
- }
121
- else {
122
- p = 0;
123
- d = 0;
124
- r = true;
125
- c = true;
126
- }
127
- }
128
- else if (precision === 'low') {
129
- if (number >= 0 && number < 0.01) {
130
- p = 2;
131
- d = 0;
132
- r = true;
133
- c = false;
134
- f = 2;
135
- }
136
- else if (number >= 0.01 && number < 0.1) {
137
- p = 2;
138
- d = 1;
139
- r = true;
140
- c = false;
141
- }
142
- else if (number >= 0.1 && number < 1) {
143
- p = 2;
144
- d = 2;
145
- r = true;
146
- c = false;
147
- }
148
- else if (number >= 1 && number < 10) {
149
- p = 2;
150
- d = 2;
151
- r = true;
152
- c = false;
153
- f = 2;
154
- }
155
- else if (number >= 10 && number < 100) {
156
- p = 1;
157
- d = 1;
158
- r = true;
159
- c = false;
160
- f = 1;
161
- }
162
- else if (number >= 100 && number < 1000) {
163
- p = 0;
164
- d = 0;
165
- r = true;
166
- c = false;
167
- }
168
- else if (number >= 1000) {
169
- const x = Math.floor(Math.log10(number)) % 3;
170
- p = 1 - x;
171
- d = 1 - x;
172
- r = true;
173
- c = true;
174
- }
175
- else {
176
- p = 0;
177
- d = 0;
178
- r = true;
179
- c = true;
180
- f = 2;
181
- }
182
- }
183
- else {
184
- // precision === "high"
185
- if (number >= 0 && number < 1) {
186
- p = 33;
187
- d = 4;
188
- r = false;
189
- c = false;
190
- }
191
- else if (number >= 1 && number < 10) {
192
- p = 3;
193
- d = 3;
194
- r = true;
195
- c = false;
196
- }
197
- else if (number >= 10 && number < 100) {
198
- p = 2;
199
- d = 2;
200
- r = true;
201
- c = false;
202
- }
203
- else if (number >= 100 && number < 1000) {
204
- p = 2;
205
- d = 2;
206
- r = true;
207
- c = false;
208
- }
209
- else if (number >= 1000 && number < 10000) {
210
- p = 1;
211
- d = 1;
212
- r = true;
213
- c = false;
214
- }
215
- else {
216
- p = 0;
217
- d = 0;
218
- r = true;
219
- c = false;
220
- }
221
- }
222
- return reducePrecision(numberString, p, d, r, c, f, template, language, outputFormat, prefixMarker, postfixMarker, prefix, postfix);
223
- }
224
- function reducePrecision(numberString, precision = 30, nonZeroDigits = 4, round = false, compress = false, fixedDecimalZeros = 0, template = 'number', language = 'en', outputFormat = 'plain', prefixMarker = 'span', postfixMarker = 'span', prefix = '', postfix = '') {
225
- if (!numberString)
226
- return 0;
227
- numberString = numberString.toString();
228
- const maxPrecision = 30;
229
- const maxIntegerDigits = 21;
230
- const scaleUnits = template.match(/^(number|percent)$/g)
231
- ? {
232
- '': '',
233
- K: ' هزار',
234
- M: ' میلیون',
235
- B: ' میلیارد',
236
- T: ' تریلیون',
237
- Qd: ' کادریلیون',
238
- Qt: ' کنتیلیون',
239
- }
240
- : {
241
- '': '',
242
- K: ' هزار ت',
243
- M: ' میلیون ت',
244
- B: ' میلیارد ت',
245
- T: ' همت',
246
- Qd: ' هزار همت',
247
- Qt: ' میلیون همت',
248
- };
249
- let parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(numberString);
250
- if (!parts) {
251
- return 0;
252
- }
253
- const sign = parts[1] || '';
254
- let wholeNumberStr = parts[2];
255
- let fractionalZeroStr = parts[3];
256
- let fractionalNonZeroStr = parts[4];
257
- let unitPrefix = '';
258
- let unitPostfix = '';
259
- if (fractionalZeroStr.length >= maxPrecision) {
260
- // Number is smaller than maximum precision
261
- fractionalZeroStr = '0'.padEnd(maxPrecision - 1, '0');
262
- fractionalNonZeroStr = '1';
263
- }
264
- else if (fractionalZeroStr.length + nonZeroDigits > precision) {
265
- // decrease non-zero digits
266
- nonZeroDigits = precision - fractionalZeroStr.length;
267
- if (nonZeroDigits < 1)
268
- nonZeroDigits = 1;
269
- }
270
- else if (wholeNumberStr.length > maxIntegerDigits) {
271
- wholeNumberStr = '0';
272
- fractionalZeroStr = '';
273
- fractionalNonZeroStr = '';
274
- }
275
- // compress large numbers
276
- if (compress && wholeNumberStr.length >= 4) {
277
- const scaleUnitKeys = Object.keys(scaleUnits);
278
- let scaledWholeNumber = wholeNumberStr;
279
- let unitIndex = 0;
280
- while (+scaledWholeNumber > 999 && unitIndex < scaleUnitKeys.length - 1) {
281
- scaledWholeNumber = (+scaledWholeNumber / 1000).toFixed(2);
282
- unitIndex++;
283
- }
284
- unitPostfix = scaleUnitKeys[unitIndex];
285
- parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(scaledWholeNumber.toString());
286
- if (!parts) {
287
- return 0;
288
- }
289
- // sign = parts[1] || "";
290
- wholeNumberStr = parts[2];
291
- fractionalZeroStr = parts[3];
292
- fractionalNonZeroStr = parts[4];
293
- }
294
- // Truncate the fractional part or round it
295
- // if (precision > 0 && nonZeroDigits > 0 && fractionalNonZeroStr.length > nonZeroDigits) {
296
- if (fractionalNonZeroStr.length > nonZeroDigits) {
297
- if (!round) {
298
- fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
299
- }
300
- else {
301
- if (parseInt(fractionalNonZeroStr[nonZeroDigits]) < 5) {
302
- fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
303
- }
304
- else {
305
- fractionalNonZeroStr = (parseInt(fractionalNonZeroStr.substring(0, nonZeroDigits)) + 1).toString();
306
- // If overflow occurs (e.g., 999 + 1 = 1000), adjust the substring length
307
- if (fractionalNonZeroStr.length > nonZeroDigits) {
308
- if (fractionalZeroStr.length > 0) {
309
- fractionalZeroStr = fractionalZeroStr.substring(0, fractionalZeroStr.length - 1);
310
- }
311
- else {
312
- wholeNumberStr = (Number(wholeNumberStr) + 1).toString();
313
- fractionalNonZeroStr = fractionalNonZeroStr.substring(1);
314
- }
315
- }
316
- }
317
- }
318
- }
319
- // Using dex style
320
- if (compress && fractionalZeroStr !== '' && unitPostfix === '') {
321
- fractionalZeroStr =
322
- '0' +
323
- fractionalZeroStr.length.toString().replace(/\d/g, function (match) {
324
- return [
325
- '₀',
326
- '₁',
327
- '₂',
328
- '₃',
329
- '₄',
330
- '₅',
331
- '₆',
332
- '₇',
333
- '₈',
334
- '₉',
335
- ][parseInt(match, 10)];
336
- });
337
- }
338
- let fractionalPartStr = `${fractionalZeroStr}${fractionalNonZeroStr}`;
339
- fractionalPartStr = fractionalPartStr.substring(0, precision);
340
- fractionalPartStr = fractionalPartStr.replace(/^(\d*[1-9])0+$/g, '$1');
341
- // Output Formating, Prefix, Postfix
342
- if (template === 'usd') {
343
- unitPrefix = language === 'en' ? '$' : '';
344
- }
345
- else if (template === 'irr') {
346
- if (!unitPostfix)
347
- unitPostfix = language === 'fa' ? ' ر' : ' R';
348
- }
349
- else if (template === 'irt') {
350
- if (!unitPostfix)
351
- unitPostfix = language === 'fa' ? ' ت' : ' T';
352
- }
353
- else if (template === 'percent') {
354
- if (language === 'en') {
355
- unitPostfix += '%';
356
- }
357
- else {
358
- unitPostfix += !unitPostfix ? '٪' : ' درصد';
359
- }
360
- }
361
- unitPrefix = prefix + unitPrefix;
362
- unitPostfix += postfix;
363
- if (outputFormat === 'html') {
364
- if (unitPrefix)
365
- unitPrefix = `<${prefixMarker}>${unitPrefix}</${prefixMarker}>`;
366
- if (unitPostfix)
367
- unitPostfix = `<${postfixMarker}>${unitPostfix}</${postfixMarker}>`;
368
- }
369
- else if (outputFormat === 'markdown') {
370
- if (unitPrefix)
371
- unitPrefix = `${prefixMarker}${unitPrefix}${prefixMarker}`;
372
- if (unitPostfix)
373
- unitPostfix = `${postfixMarker}${unitPostfix}${postfixMarker}`;
374
- }
375
- const thousandSeparatorRegex = /\B(?=(\d{3})+(?!\d))/g;
376
- const fixedDecimalZeroStr = fixedDecimalZeros
377
- ? '.'.padEnd(fixedDecimalZeros + 1, '0')
378
- : '';
379
- let out = '';
380
- if (precision <= 0 || nonZeroDigits <= 0 || !fractionalNonZeroStr) {
381
- out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}${fixedDecimalZeroStr}${unitPostfix}`;
382
- }
383
- else {
384
- out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}.${fractionalPartStr}${unitPostfix}`;
385
- }
386
- // Convert output to Persian numerals if language is "fa"
387
- if (language === 'fa') {
388
- out = out
389
- .replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
390
- .replace(/,/g, '٬')
391
- .replace(/\./g, '٫')
392
- .replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
393
- return String(scaleUnits[c]);
394
- });
395
- }
396
- return out;
397
- }
398
- console.log(format('0.000024160785036984196', { precision: 'medium', template: 'usd' }));
399
- exports.default = format;