reduce-precision 0.0.3 → 1.0.1

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/lib/index.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import format from './format';
2
- export { format };
1
+ import NumberFormatter from './format';
2
+ export { NumberFormatter };
package/lib/index.js CHANGED
@@ -3,6 +3,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.format = void 0;
6
+ exports.NumberFormatter = void 0;
7
7
  const format_1 = __importDefault(require("./format"));
8
- exports.format = format_1.default;
8
+ exports.NumberFormatter = format_1.default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reduce-precision",
3
- "version": "0.0.3",
3
+ "version": "1.0.1",
4
4
  "description": "",
5
5
  "main": "./lib/index.js",
6
6
  "files": [
@@ -1,667 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- type;
4
- this.options.Precision = 'auto' | 'high' | 'medium' | 'low';
5
- class NumberFormatter {
6
- constructor(options) {
7
- this.options = {
8
- precision: 'high',
9
- template: 'number',
10
- language: 'en',
11
- outputFormat: 'plain',
12
- prefixMarker: 'i',
13
- postfixMarker: 'i',
14
- prefix: '',
15
- postfix: '',
16
- };
17
- if (options) {
18
- this.options = Object.assign(Object.assign({}, this.options), options);
19
- }
20
- }
21
- format(input) {
22
- if (!input)
23
- return 0;
24
- let { precision, template } = this.options;
25
- const { language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, } = this.options;
26
- if (!(template === null || template === void 0 ? void 0 : template.match(/^(number|usd|irt|irr|percent)$/g))) {
27
- template = 'number';
28
- }
29
- if (NumberFormatter.isENotation(input.toString())) {
30
- input = NumberFormatter.convertENotationToRegularNumber(Number(input));
31
- }
32
- // Replace each Persian/Arabic numeral in the string with its English counterpart and strip all non-numeric chars
33
- let numberString = input
34
- .toString()
35
- .replace(/[\u0660-\u0669\u06F0-\u06F9]/g, function (match) {
36
- return String(match.charCodeAt(0) & 0xf);
37
- })
38
- .replace(/[^\d.-]/g, '');
39
- // Stripping leading zeros and trailing zeros after a decimal point
40
- numberString = numberString
41
- .replace(/^0+(?=\d)/g, '')
42
- .replace(/(?<=\.\d*)0+$|(?<=\.\d)0+\b/g, '');
43
- const number = Math.abs(Number(numberString));
44
- let p, d, r, c;
45
- let f = 0;
46
- // Auto precision selection
47
- if (precision === 'auto') {
48
- if (template.match(/^(usd|irt|irr)$/g)) {
49
- if (number >= 0.0001 && number < 100000000000) {
50
- precision = 'high';
51
- }
52
- else {
53
- precision = 'medium';
54
- }
55
- }
56
- else if (template === 'number') {
57
- precision = 'medium';
58
- }
59
- else if (template === 'percent') {
60
- precision = 'low';
61
- }
62
- }
63
- if (precision === 'medium') {
64
- if (number >= 0 && number < 0.0001) {
65
- p = 33;
66
- d = 4;
67
- r = false;
68
- c = true;
69
- }
70
- else if (number >= 0.0001 && number < 0.001) {
71
- p = 7;
72
- d = 4;
73
- r = false;
74
- c = false;
75
- }
76
- else if (number >= 0.001 && number < 0.01) {
77
- p = 5;
78
- d = 3;
79
- r = false;
80
- c = false;
81
- }
82
- else if (number >= 0.001 && number < 0.1) {
83
- p = 3;
84
- d = 2;
85
- r = false;
86
- c = false;
87
- }
88
- else if (number >= 0.1 && number < 1) {
89
- p = 1;
90
- d = 1;
91
- r = false;
92
- c = false;
93
- }
94
- else if (number >= 1 && number < 10) {
95
- p = 3;
96
- d = 3;
97
- r = false;
98
- c = false;
99
- }
100
- else if (number >= 10 && number < 100) {
101
- p = 2;
102
- d = 2;
103
- r = false;
104
- c = false;
105
- }
106
- else if (number >= 100 && number < 1000) {
107
- p = 1;
108
- d = 1;
109
- r = false;
110
- c = false;
111
- }
112
- else if (number >= 1000) {
113
- const x = Math.floor(Math.log10(number)) % 3;
114
- p = 2 - x;
115
- d = 2 - x;
116
- r = true;
117
- c = true;
118
- }
119
- else {
120
- p = 0;
121
- d = 0;
122
- r = true;
123
- c = true;
124
- }
125
- }
126
- else if (precision === 'low') {
127
- if (number >= 0 && number < 0.01) {
128
- p = 2;
129
- d = 0;
130
- r = true;
131
- c = false;
132
- f = 2;
133
- }
134
- else if (number >= 0.01 && number < 0.1) {
135
- p = 2;
136
- d = 1;
137
- r = true;
138
- c = false;
139
- }
140
- else if (number >= 0.1 && number < 1) {
141
- p = 2;
142
- d = 2;
143
- r = true;
144
- c = false;
145
- }
146
- else if (number >= 1 && number < 10) {
147
- p = 2;
148
- d = 2;
149
- r = true;
150
- c = false;
151
- f = 2;
152
- }
153
- else if (number >= 10 && number < 100) {
154
- p = 1;
155
- d = 1;
156
- r = true;
157
- c = false;
158
- f = 1;
159
- }
160
- else if (number >= 100 && number < 1000) {
161
- p = 0;
162
- d = 0;
163
- r = true;
164
- c = false;
165
- }
166
- else if (number >= 1000) {
167
- const x = Math.floor(Math.log10(number)) % 3;
168
- p = 1 - x;
169
- d = 1 - x;
170
- r = true;
171
- c = true;
172
- }
173
- else {
174
- p = 0;
175
- d = 0;
176
- r = true;
177
- c = true;
178
- f = 2;
179
- }
180
- }
181
- else {
182
- // precision === "high"
183
- if (number >= 0 && number < 1) {
184
- p = 33;
185
- d = 4;
186
- r = false;
187
- c = false;
188
- }
189
- else if (number >= 1 && number < 10) {
190
- p = 3;
191
- d = 3;
192
- r = true;
193
- c = false;
194
- }
195
- else if (number >= 10 && number < 100) {
196
- p = 2;
197
- d = 2;
198
- r = true;
199
- c = false;
200
- }
201
- else if (number >= 100 && number < 1000) {
202
- p = 2;
203
- d = 2;
204
- r = true;
205
- c = false;
206
- }
207
- else if (number >= 1000 && number < 10000) {
208
- p = 1;
209
- d = 1;
210
- r = true;
211
- c = false;
212
- }
213
- else {
214
- p = 0;
215
- d = 0;
216
- r = true;
217
- c = false;
218
- }
219
- }
220
- return NumberFormatter.reducePrecision(numberString, p, d, r, c, f, template, language, outputFormat, prefixMarker, postfixMarker, prefix, postfix);
221
- }
222
- setPrecision(precision) {
223
- this.options.this.options.precision = precision;
224
- return this;
225
- }
226
- setTemplate(template) {
227
- this.options.template = template;
228
- return this;
229
- }
230
- setLanguage(language) {
231
- this.options.language = language;
232
- return this;
233
- }
234
- setOutputFormat(outputFormat) {
235
- this.options.outputFormat = outputFormat;
236
- return this;
237
- }
238
- setPrefixMarker(prefixMarker) {
239
- this.options.prefixMarker = prefixMarker;
240
- return this;
241
- }
242
- setPostfixMarker(postfixMarker) {
243
- this.options.postfixMarker = postfixMarker;
244
- return this;
245
- }
246
- setPrefix(prefix) {
247
- this.options.prefix = prefix;
248
- return this;
249
- }
250
- setPostfix(postfix) {
251
- this.options.postfix = postfix;
252
- return this;
253
- }
254
- static isENotation(input) {
255
- return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(input);
256
- }
257
- static convertENotationToRegularNumber(eNotation) {
258
- const [coefficientStr, exponentStr] = eNotation.toString().split('e');
259
- const coefficientLength = coefficientStr
260
- .replace('.', '')
261
- .replace('-', '').length;
262
- const exponent = parseFloat(exponentStr);
263
- const ;
264
- this.options.precision = Math.max(coefficientLength - exponent, 1);
265
- return eNotation.toFixed(precision);
266
- }
267
- static reducePrecision(numberString, options, precision = 30, nonZeroDigits = 4, round = false, compress = false, fixedDecimalZeros = 0, template = 'number', language = 'en', outputFormat = 'plain', prefixMarker = 'span', postfixMarker = 'span', prefix = '', postfix = '') {
268
- // ... (implementation remains the same)
269
- }
270
- }
271
- function isENotation(input) {
272
- return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?$/.test(input);
273
- }
274
- function convertENotationToRegularNumber(eNotation) {
275
- const [coefficientStr, exponentStr] = eNotation.toString().split('e');
276
- const coefficientLength = coefficientStr
277
- .replace('.', '')
278
- .replace('-', '').length;
279
- const exponent = parseFloat(exponentStr);
280
- const ;
281
- this.options.precision = Math.max(coefficientLength - exponent, 1);
282
- return eNotation.toFixed(precision);
283
- }
284
- function format(input, options = {
285
- precision: 'high',
286
- template: 'number',
287
- language: 'en',
288
- outputFormat: 'plain',
289
- prefixMarker: 'i',
290
- postfixMarker: 'i',
291
- prefix: '',
292
- postfix: '',
293
- }) {
294
- let { precision, template } = options;
295
- const { language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, } = options;
296
- if (!input)
297
- return 0;
298
- if (!(template === null || template === void 0 ? void 0 : template.match(/^(number|usd|irt|irr|percent)$/g)))
299
- template = 'number';
300
- if (isENotation(input.toString())) {
301
- input = convertENotationToRegularNumber(Number(input));
302
- }
303
- // Replace each Persian/Arabic numeral in the string with its English counterpart and strip all non-numeric chars
304
- let numberString = input
305
- .toString()
306
- .replace(/[\u0660-\u0669\u06F0-\u06F9]/g, function (match) {
307
- return String(match.charCodeAt(0) & 0xf);
308
- })
309
- .replace(/[^\d.-]/g, '');
310
- // Stripping leading zeros and trailing zeros after a decimal point
311
- numberString = numberString
312
- .replace(/^0+(?=\d)/g, '')
313
- .replace(/(?<=\.\d*)0+$|(?<=\.\d)0+\b/g, '');
314
- const number = Math.abs(Number(numberString));
315
- let p, d, r, c;
316
- let f = 0;
317
- // Auto precision selection
318
- if (precision === 'auto') {
319
- if (template.match(/^(usd|irt|irr)$/g)) {
320
- if (number >= 0.0001 && number < 100000000000) {
321
- this.options.precision = 'high';
322
- }
323
- else {
324
- this.options.precision = 'medium';
325
- }
326
- }
327
- else if (template === 'number') {
328
- this.options.precision = 'medium';
329
- }
330
- else if (template === 'percent') {
331
- this.options.precision = 'low';
332
- }
333
- }
334
- if (precision === 'medium') {
335
- if (number >= 0 && number < 0.0001) {
336
- p = 33;
337
- d = 4;
338
- r = false;
339
- c = true;
340
- }
341
- else if (number >= 0.0001 && number < 0.001) {
342
- p = 7;
343
- d = 4;
344
- r = false;
345
- c = false;
346
- }
347
- else if (number >= 0.001 && number < 0.01) {
348
- p = 5;
349
- d = 3;
350
- r = false;
351
- c = false;
352
- }
353
- else if (number >= 0.001 && number < 0.1) {
354
- p = 3;
355
- d = 2;
356
- r = false;
357
- c = false;
358
- }
359
- else if (number >= 0.1 && number < 1) {
360
- p = 1;
361
- d = 1;
362
- r = false;
363
- c = false;
364
- }
365
- else if (number >= 1 && number < 10) {
366
- p = 3;
367
- d = 3;
368
- r = false;
369
- c = false;
370
- }
371
- else if (number >= 10 && number < 100) {
372
- p = 2;
373
- d = 2;
374
- r = false;
375
- c = false;
376
- }
377
- else if (number >= 100 && number < 1000) {
378
- p = 1;
379
- d = 1;
380
- r = false;
381
- c = false;
382
- }
383
- else if (number >= 1000) {
384
- const x = Math.floor(Math.log10(number)) % 3;
385
- p = 2 - x;
386
- d = 2 - x;
387
- r = true;
388
- c = true;
389
- }
390
- else {
391
- p = 0;
392
- d = 0;
393
- r = true;
394
- c = true;
395
- }
396
- }
397
- else if (precision === 'low') {
398
- if (number >= 0 && number < 0.01) {
399
- p = 2;
400
- d = 0;
401
- r = true;
402
- c = false;
403
- f = 2;
404
- }
405
- else if (number >= 0.01 && number < 0.1) {
406
- p = 2;
407
- d = 1;
408
- r = true;
409
- c = false;
410
- }
411
- else if (number >= 0.1 && number < 1) {
412
- p = 2;
413
- d = 2;
414
- r = true;
415
- c = false;
416
- }
417
- else if (number >= 1 && number < 10) {
418
- p = 2;
419
- d = 2;
420
- r = true;
421
- c = false;
422
- f = 2;
423
- }
424
- else if (number >= 10 && number < 100) {
425
- p = 1;
426
- d = 1;
427
- r = true;
428
- c = false;
429
- f = 1;
430
- }
431
- else if (number >= 100 && number < 1000) {
432
- p = 0;
433
- d = 0;
434
- r = true;
435
- c = false;
436
- }
437
- else if (number >= 1000) {
438
- const x = Math.floor(Math.log10(number)) % 3;
439
- p = 1 - x;
440
- d = 1 - x;
441
- r = true;
442
- c = true;
443
- }
444
- else {
445
- p = 0;
446
- d = 0;
447
- r = true;
448
- c = true;
449
- f = 2;
450
- }
451
- }
452
- else {
453
- // precision === "high"
454
- if (number >= 0 && number < 1) {
455
- p = 33;
456
- d = 4;
457
- r = false;
458
- c = false;
459
- }
460
- else if (number >= 1 && number < 10) {
461
- p = 3;
462
- d = 3;
463
- r = true;
464
- c = false;
465
- }
466
- else if (number >= 10 && number < 100) {
467
- p = 2;
468
- d = 2;
469
- r = true;
470
- c = false;
471
- }
472
- else if (number >= 100 && number < 1000) {
473
- p = 2;
474
- d = 2;
475
- r = true;
476
- c = false;
477
- }
478
- else if (number >= 1000 && number < 10000) {
479
- p = 1;
480
- d = 1;
481
- r = true;
482
- c = false;
483
- }
484
- else {
485
- p = 0;
486
- d = 0;
487
- r = true;
488
- c = false;
489
- }
490
- }
491
- return reducePrecision(numberString, p, d, r, c, f, template, language, outputFormat, prefixMarker, postfixMarker, prefix, postfix);
492
- }
493
- function reducePrecision(numberString, options, precision = 30, nonZeroDigits = 4, round = false, compress = false, fixedDecimalZeros = 0, template = 'number', language = 'en', outputFormat = 'plain', prefixMarker = 'span', postfixMarker = 'span', prefix = '', postfix = '') {
494
- if (!numberString)
495
- return 0;
496
- numberString = numberString.toString();
497
- const maxthis, options, Precision = 30;
498
- const maxIntegerDigits = 21;
499
- const scaleUnits = template.match(/^(number|percent)$/g)
500
- ? {
501
- '': '',
502
- K: ' هزار',
503
- M: ' میلیون',
504
- B: ' میلیارد',
505
- T: ' تریلیون',
506
- Qd: ' کادریلیون',
507
- Qt: ' کنتیلیون',
508
- }
509
- : {
510
- '': '',
511
- K: ' هزار ت',
512
- M: ' میلیون ت',
513
- B: ' میلیارد ت',
514
- T: ' همت',
515
- Qd: ' هزار همت',
516
- Qt: ' میلیون همت',
517
- };
518
- let parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(numberString);
519
- if (!parts) {
520
- return 0;
521
- }
522
- const sign = parts[1] || '';
523
- let wholeNumberStr = parts[2];
524
- let fractionalZeroStr = parts[3];
525
- let fractionalNonZeroStr = parts[4];
526
- let unitPrefix = '';
527
- let unitPostfix = '';
528
- if (fractionalZeroStr.length >= maxPrecision) {
529
- // Number is smaller than maximum precision
530
- fractionalZeroStr = '0'.padEnd(maxPrecision - 1, '0');
531
- fractionalNonZeroStr = '1';
532
- }
533
- else if (fractionalZeroStr.length + nonZeroDigits > precision) {
534
- // decrease non-zero digits
535
- nonZeroDigits = precision - fractionalZeroStr.length;
536
- if (nonZeroDigits < 1)
537
- nonZeroDigits = 1;
538
- }
539
- else if (wholeNumberStr.length > maxIntegerDigits) {
540
- wholeNumberStr = '0';
541
- fractionalZeroStr = '';
542
- fractionalNonZeroStr = '';
543
- }
544
- // compress large numbers
545
- if (compress && wholeNumberStr.length >= 4) {
546
- const scaleUnitKeys = Object.keys(scaleUnits);
547
- let scaledWholeNumber = wholeNumberStr;
548
- let unitIndex = 0;
549
- while (+scaledWholeNumber > 999 && unitIndex < scaleUnitKeys.length - 1) {
550
- scaledWholeNumber = (+scaledWholeNumber / 1000).toFixed(2);
551
- unitIndex++;
552
- }
553
- unitPostfix = scaleUnitKeys[unitIndex];
554
- parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(scaledWholeNumber.toString());
555
- if (!parts) {
556
- return 0;
557
- }
558
- // sign = parts[1] || "";
559
- wholeNumberStr = parts[2];
560
- fractionalZeroStr = parts[3];
561
- fractionalNonZeroStr = parts[4];
562
- }
563
- // Truncate the fractional part or round it
564
- // if (precision > 0 && nonZeroDigits > 0 && fractionalNonZeroStr.length > nonZeroDigits) {
565
- if (fractionalNonZeroStr.length > nonZeroDigits) {
566
- if (!round) {
567
- fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
568
- }
569
- else {
570
- if (parseInt(fractionalNonZeroStr[nonZeroDigits]) < 5) {
571
- fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
572
- }
573
- else {
574
- fractionalNonZeroStr = (parseInt(fractionalNonZeroStr.substring(0, nonZeroDigits)) + 1).toString();
575
- // If overflow occurs (e.g., 999 + 1 = 1000), adjust the substring length
576
- if (fractionalNonZeroStr.length > nonZeroDigits) {
577
- if (fractionalZeroStr.length > 0) {
578
- fractionalZeroStr = fractionalZeroStr.substring(0, fractionalZeroStr.length - 1);
579
- }
580
- else {
581
- wholeNumberStr = (Number(wholeNumberStr) + 1).toString();
582
- fractionalNonZeroStr = fractionalNonZeroStr.substring(1);
583
- }
584
- }
585
- }
586
- }
587
- }
588
- // Using dex style
589
- if (compress && fractionalZeroStr !== '' && unitPostfix === '') {
590
- fractionalZeroStr =
591
- '0' +
592
- fractionalZeroStr.length.toString().replace(/\d/g, function (match) {
593
- return [
594
- '₀',
595
- '₁',
596
- '₂',
597
- '₃',
598
- '₄',
599
- '₅',
600
- '₆',
601
- '₇',
602
- '₈',
603
- '₉',
604
- ][parseInt(match, 10)];
605
- });
606
- }
607
- let fractionalPartStr = `${fractionalZeroStr}${fractionalNonZeroStr}`;
608
- fractionalPartStr = fractionalPartStr.substring(0, precision);
609
- fractionalPartStr = fractionalPartStr.replace(/^(\d*[1-9])0+$/g, '$1');
610
- // Output Formating, Prefix, Postfix
611
- if (template === 'usd') {
612
- unitPrefix = language === 'en' ? '$' : '';
613
- }
614
- else if (template === 'irr') {
615
- if (!unitPostfix)
616
- unitPostfix = language === 'fa' ? ' ر' : ' R';
617
- }
618
- else if (template === 'irt') {
619
- if (!unitPostfix)
620
- unitPostfix = language === 'fa' ? ' ت' : ' T';
621
- }
622
- else if (template === 'percent') {
623
- if (language === 'en') {
624
- unitPostfix += '%';
625
- }
626
- else {
627
- unitPostfix += !unitPostfix ? '٪' : ' درصد';
628
- }
629
- }
630
- unitPrefix = prefix + unitPrefix;
631
- unitPostfix += postfix;
632
- if (outputFormat === 'html') {
633
- if (unitPrefix)
634
- unitPrefix = `<${prefixMarker}>${unitPrefix}</${prefixMarker}>`;
635
- if (unitPostfix)
636
- unitPostfix = `<${postfixMarker}>${unitPostfix}</${postfixMarker}>`;
637
- }
638
- else if (outputFormat === 'markdown') {
639
- if (unitPrefix)
640
- unitPrefix = `${prefixMarker}${unitPrefix}${prefixMarker}`;
641
- if (unitPostfix)
642
- unitPostfix = `${postfixMarker}${unitPostfix}${postfixMarker}`;
643
- }
644
- const thousandSeparatorRegex = /\B(?=(\d{3})+(?!\d))/g;
645
- const fixedDecimalZeroStr = fixedDecimalZeros
646
- ? '.'.padEnd(fixedDecimalZeros + 1, '0')
647
- : '';
648
- let out = '';
649
- if (precision <= 0 || nonZeroDigits <= 0 || !fractionalNonZeroStr) {
650
- out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}${fixedDecimalZeroStr}${unitPostfix}`;
651
- }
652
- else {
653
- out = `${sign}${unitPrefix}${wholeNumberStr.replace(thousandSeparatorRegex, ',')}.${fractionalPartStr}${unitPostfix}`;
654
- }
655
- // Convert output to Persian numerals if language is "fa"
656
- if (language === 'fa') {
657
- out = out
658
- .replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
659
- .replace(/,/g, '٬')
660
- .replace(/\./g, '٫')
661
- .replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
662
- return String(scaleUnits[c]);
663
- });
664
- }
665
- return out;
666
- }
667
- exports.default = format;