reduce-precision 1.1.0 → 1.2.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.
- package/package.json +20 -20
- package/ts/lib/bundle.min.js +1 -1
- package/ts/lib/src/format/index.js +4 -4
- package/ts/lib/test/format/index.spec.js +22 -22
- package/ts/lib/format/index.d.ts +0 -44
- package/ts/lib/format/index.js +0 -556
- package/ts/lib/index.d.ts +0 -2
- package/ts/lib/index.js +0 -8
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "reduce-precision",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "./ts/lib/index.js",
|
|
6
6
|
"files": [
|
|
@@ -31,26 +31,26 @@
|
|
|
31
31
|
},
|
|
32
32
|
"homepage": "https://github.com/ArzDigitalLabs/reduce-precision#readme",
|
|
33
33
|
"devDependencies": {
|
|
34
|
-
"@babel/core": "^7.
|
|
35
|
-
"@babel/preset-env": "^7.
|
|
36
|
-
"@types/jest": "^
|
|
37
|
-
"@types/node": "^
|
|
38
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
39
|
-
"@typescript-eslint/parser": "^
|
|
40
|
-
"babel-loader": "^
|
|
41
|
-
"eslint": "^
|
|
42
|
-
"eslint-config-prettier": "^
|
|
34
|
+
"@babel/core": "^7.28.0",
|
|
35
|
+
"@babel/preset-env": "^7.28.0",
|
|
36
|
+
"@types/jest": "^30.0.0",
|
|
37
|
+
"@types/node": "^24.2.1",
|
|
38
|
+
"@typescript-eslint/eslint-plugin": "^8.39.1",
|
|
39
|
+
"@typescript-eslint/parser": "^8.39.1",
|
|
40
|
+
"babel-loader": "^10.0.0",
|
|
41
|
+
"eslint": "^9.33.0",
|
|
42
|
+
"eslint-config-prettier": "^10.1.8",
|
|
43
43
|
"eslint-plugin-node": "^11.1.0",
|
|
44
|
-
"eslint-plugin-prettier": "^
|
|
45
|
-
"jest": "^
|
|
46
|
-
"lint-staged": "^
|
|
47
|
-
"prettier": "^
|
|
48
|
-
"ts-jest": "^
|
|
49
|
-
"ts-loader": "^9.5.
|
|
50
|
-
"ts-node": "^10.2
|
|
51
|
-
"typescript": "^
|
|
52
|
-
"webpack": "^5.
|
|
53
|
-
"webpack-cli": "^
|
|
44
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
45
|
+
"jest": "^30.0.5",
|
|
46
|
+
"lint-staged": "^16.1.5",
|
|
47
|
+
"prettier": "^3.6.2",
|
|
48
|
+
"ts-jest": "^29.4.1",
|
|
49
|
+
"ts-loader": "^9.5.2",
|
|
50
|
+
"ts-node": "^10.9.2",
|
|
51
|
+
"typescript": "^5.9.2",
|
|
52
|
+
"webpack": "^5.101.0",
|
|
53
|
+
"webpack-cli": "^6.0.1"
|
|
54
54
|
},
|
|
55
55
|
"lint-staged": {
|
|
56
56
|
"*.ts": "eslint --cache --cache-location .eslintcache --fix"
|
package/ts/lib/bundle.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.ReducePrecision=t():e.ReducePrecision=t()}(self,(()=>(()=>{"use strict";var e={900:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(e={}){this.languageBaseConfig={prefixMarker:"i",postfixMarker:"i",prefix:"",postfix:""},this.defaultLanguageConfig={en:Object.assign(Object.assign({},this.languageBaseConfig),{thousandSeparator:",",decimalSeparator:"."}),fa:Object.assign(Object.assign({},this.languageBaseConfig),{thousandSeparator:"٬",decimalSeparator:"٫"})},this.options=Object.assign({language:"en",template:"number",precision:"high",outputFormat:"plain"},this.defaultLanguageConfig.en),this.options=Object.assign(Object.assign({},this.options),e)}setLanguage(e,t={}){return this.options.language=e,this.options.prefixMarker=t.prefixMarker||this.defaultLanguageConfig[e].prefixMarker,this.options.postfixMarker=t.postfixMarker||this.defaultLanguageConfig[e].postfixMarker,this.options.prefix=t.prefix||this.defaultLanguageConfig[e].prefix,this.options.postfix=t.postfix||this.defaultLanguageConfig[e].postfix,this.options.thousandSeparator=t.thousandSeparator||this.defaultLanguageConfig[e].thousandSeparator,this.options.decimalSeparator=t.decimalSeparator||this.defaultLanguageConfig[e].decimalSeparator,this}setTemplate(e,t){return this.options.template=e,this.options.precision=t,this}toJson(e){const t=this.format(e);return delete t.value,t}toString(e){return this.format(e).value||""}toPlainString(e){return this.options.outputFormat="plain",this.format(e).value||""}toHtmlString(e){return this.options.outputFormat="html",this.format(e).value||""}toMdString(e){return this.options.outputFormat="markdown",this.format(e).value||""}isENotation(e){return/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)$/.test(e)}convertENotationToRegularNumber(e,t){let r=String(e);if(0===e&&t){const e=t.toLowerCase().split("e");if(2===e.length&&e[0].match(/^0\.0*$/))return e[0]}if(-1===r.toLowerCase().indexOf("e"))return r;if(Math.abs(e)<1&&0!==e){const t=r.toLowerCase().split("e");if(2===t.length){const r=parseInt(t[1],10);if(r<0){let i=Math.abs(r);return t[0].includes(".")&&(i+=t[0].split(".")[1].length),e.toFixed(Math.min(i,100))}}}const i=r.toLowerCase().split("e");if(2===i.length){const t=i[0],r=parseInt(i[1],10);let[n,o]=t.split(".");if(o=o||"",r>0){const e=n.startsWith("-")?"-":"";return e&&(n=n.substring(1)),o.length<=r?e+n+o.padEnd(r,"0"):e+n+o.substring(0,r)+"."+o.substring(r)}if(r<0){let i=Math.abs(r);return t.includes(".")&&(i+=t.split(".")[1].length),e.toFixed(Math.min(i,100))}return t}return r}format(e){var t;let{precision:r,template:i}=this.options;const{language:n,outputFormat:o,prefixMarker:s,postfixMarker:a,prefix:l,postfix:u,thousandSeparator:g,decimalSeparator:f}=this.options;if(null==e||""===e)return{};const p=e.toString();if("liveformat"===i){let e=this._sanitizeLiveInput(p);const r=g||",",i=f||".";let n=p.replace(/[٠-٩۰-۹]/g,(function(e){return String(15&e.charCodeAt(0))}));if("fa"===(null!==(t=this.options.language)&&void 0!==t?t:"en")){const e=this.defaultLanguageConfig.fa.decimalSeparator||"٫";n=n.replace(new RegExp(e,"g"),".")}if(this.isENotation(n)&&0===Number(n)){const t=p.toLowerCase().indexOf("e");if(t>-1){const r=p.substring(0,t).replace(/[٠-٩۰-۹]/g,(function(e){return String(15&e.charCodeAt(0))}));let n=r;r.includes(".")&&"."!==i?n=r.replace(".",i):r.includes("٫")&&"٫"!==i&&(n=r.replace("٫",i));const o=new RegExp(`^0\\${i}0*$`);n.match(o)&&(e=n)}}let o="";if(e.startsWith("-")&&(o="-",e=e.substring(1)),""===e)return{value:"",prefix:"",postfix:"",sign:"",wholeNumber:""};if("0"===e){let e="0";return"fa"===this.options.language&&(e=String.fromCharCode("0".charCodeAt(0)+1728)),{value:e,prefix:"",postfix:"",sign:"",wholeNumber:e}}e===i&&(e="0"+i);let s="",a="",l=!1;if(e.includes(i)){l=!0;const t=e.split(i);s=t[0],a=t.length>1?t[1]:""}else if("."!==i&&e.includes(".")){l=!0;const t=e.split(".");s=t[0],a=t.length>1?t[1]:""}else s=e;if(""===s)s="0";else if("0"!==s){const e=s.replace(/^0+/,"");s=""===e?"0":e}let u=s.replace(/\B(?=(\d{3})+(?!\d))/g,r);l&&(u+=i+a);const c=u;let h="",d=c;"-"===o&&(0!==parseFloat(c)||c.includes(".")?(h="-",d=o+c):h="");const m=this._convertToFarsiDigits(u);let b="";return"-"===o&&(b="0"===u?"":"-"),{value:b+m,prefix:"",postfix:"",sign:b,wholeNumber:m}}(null==i?void 0:i.match(/^(number|usd|irt|irr|percent|liveformat)$/g))||(i="number"),this.isENotation(p)&&(e=this.convertENotationToRegularNumber(Number(e)));let c=e.toString().replace(/[\u0660-\u0669\u06F0-\u06F9]/g,(function(e){return String(15&e.charCodeAt(0))})).replace(/[^\d.-]/g,"");c=c.replace(/^0+(?=\d)/g,"");const h=Math.abs(Number(c));let d,m,b,x,v=0;if("auto"===r&&(i.match(/^(usd|irt|irr|number)$/g)?r=h>=1e-4&&h<1e11?"high":"medium":"percent"===i&&(r="low")),"medium"===r)if(h>=0&&h<1e-4)d=33,m=4,b=!1,x=!0;else if(h>=1e-4&&h<.001)d=7,m=4,b=!1,x=!1;else if(h>=.001&&h<.01)d=5,m=3,b=!1,x=!1;else if(h>=.001&&h<.1)d=3,m=2,b=!1,x=!1;else if(h>=.1&&h<1)d=1,m=1,b=!1,x=!1;else if(h>=1&&h<10)d=3,m=3,b=!1,x=!1;else if(h>=10&&h<100)d=2,m=2,b=!1,x=!1;else if(h>=100&&h<1e3)d=1,m=1,b=!1,x=!1;else if(h>=1e3){const e=Math.floor(Math.log10(h))%3;d=2-e,m=2-e,b=!0,x=!0}else d=0,m=0,b=!0,x=!0;else if("low"===r)if(h>=0&&h<.01)d=2,m=0,b=!0,x=!1,v=2;else if(h>=.01&&h<.1)d=2,m=1,b=!0,x=!1;else if(h>=.1&&h<1)d=2,m=2,b=!0,x=!1;else if(h>=1&&h<10)d=2,m=2,b=!0,x=!1,v=2;else if(h>=10&&h<100)d=1,m=1,b=!0,x=!1,v=1;else if(h>=100&&h<1e3)d=0,m=0,b=!0,x=!1;else if(h>=1e3){const e=Math.floor(Math.log10(h))%3;d=1-e,m=1-e,b=!0,x=!0}else d=0,m=0,b=!0,x=!0,v=2;else h>=0&&h<1?(d=33,m=4,b=!1,x=!1):h>=1&&h<10?(d=3,m=3,b=!0,x=!1):h>=10&&h<100||h>=100&&h<1e3?(d=2,m=2,b=!0,x=!1):h>=1e3&&h<1e4?(d=1,m=1,b=!0,x=!1):(d=0,m=0,b=!0,x=!1);return this.isENotation(p)&&(d=Math.max(d,20),b=!1),this.reducePrecision(c,d,m,b,x,v,i,n,o,s,a,l,u,g,f,p)}reducePrecision(e,t=30,r=4,i=!1,n=!1,o=0,s="number",a="en",l="plain",u="span",g="span",f="",p="",c=",",h=".",d=""){var m,b;if(null==e||""===e.trim())return{};"-0"!==e&&"-0.0"!==e||(e=e.substring(1)),e=e.toString();const x=s.match(/^(number|percent)$/g)?{"":"",K:" هزار",M:" میلیون",B:" میلیارد",T:" تریلیون",Qd:" کادریلیون",Qt:" کنتیلیون"}:{"":"",K:" هزار ت",M:" میلیون ت",B:" میلیارد ت",T:" همت",Qd:" هزار همت",Qt:" میلیون همت"},v=s.match(/^(number|percent)$/g)?{"":"",K:" هزار",M:" میلیون",B:" میلیارد",T:" تریلیون",Qd:" کادریلیون",Qt:" کنتیلیون"}:{"":"",K:" هزار تومان",M:" میلیون تومان",B:" میلیارد تومان",T:" هزار میلیارد تومان",Qd:" کادریلیون تومان",Qt:" کنتیلیون تومان"};let C=/^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(e);if(!C)return{};const S=C[1]||"";let M=C[2],$=C[3],N=C[4],w="",L="";if($.length>=30?($="0".padEnd(29,"0"),N="1"):$.length+r>t?(r=t-$.length)<1&&(r=1):M.length>21&&(M="0",$="",N=""),n&&M.length>=4){const e=Object.keys(x);let t=M,r=0;for(;+t>999&&r<e.length-1;)t=(+t/1e3).toFixed(2),r++;if(L=e[r],C=/^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(t.toString()),!C)return{};M=C[2],$=C[3],N=C[4]}N.length>r&&(i?parseInt(N[r])<5?N=N.substring(0,r):(N=(parseInt(N.substring(0,r))+1).toString(),N.length>r&&($.length>0?$=$.substring(0,$.length-1):(M=(Number(M)+1).toString(),N=N.substring(1)))):N=N.substring(0,r)),n&&""!==$&&""===L&&($="0"+$.length.toString().replace(/\d/g,(function(e){return["₀","₁","₂","₃","₄","₅","₆","₇","₈","₉"][parseInt(e,10)]})));let E=`${$}${N}`;if(E.length>t&&!d.includes("e")&&(E=E.substring(0,t)),d.includes("e")||d.includes("E"));else if(d.includes(".")){const e=d.split(".");if(2===e.length){const t=e[1];if(t.length>E.length&&t.endsWith("0")){let e=0;for(let r=t.length-1;r>=0&&"0"===t[r];r--)e++;e>0&&(E=E.padEnd(E.length+e,"0"))}}}"usd"===s?(w="en"===a?"$":"",L||(L="fa"===a?" دلار":"")):"irr"===s?L||(L="fa"===a?" ر":" R"):"irt"===s?L||(L="fa"===a?" ت":" T"):"percent"===s&&(L+="en"===a?"%":L?" درصد":"٪"),w=f+w,L+=p,"html"===l?(w&&(w=`<${u}>${w}</${u}>`),L&&(L=`<${g}>${L}</${g}>`)):"markdown"===l&&(w&&(w=`${u}${w}${u}`),L&&(L=`${g}${L}${g}`));const Q=/\B(?=(\d{3})+(?!\d))/g,F=o?".".padEnd(o+1,"0"):"";let T,j="";T=t<=0||r<=0||""===N&&""===$?`${M.replace(Q,",")}${F}`:`${M.replace(Q,",")}.${E}`,j=`${S}${w}${T}${L}`;const k={value:j,prefix:w,postfix:L,sign:S,wholeNumber:T};return k.value=(null!==(m=null==k?void 0:k.value)&&void 0!==m?m:"").replace(/,/g,c).replace(/\./g,h),"fa"===a&&(k.value=(null!==(b=null==k?void 0:k.value)&&void 0!==b?b:"").replace(/[0-9]/g,(e=>String.fromCharCode(e.charCodeAt(0)+1728))).replace(/(K|M|B|T|Qt|Qd)/g,(function(e){return String(x[e])})),k.fullPostfix=L.replace(/[0-9]/g,(e=>String.fromCharCode(e.charCodeAt(0)+1728))).replace(/(K|M|B|T|Qt|Qd)/g,(function(e){return String(v[e])})),k.postfix=k.postfix.replace(/[0-9]/g,(e=>String.fromCharCode(e.charCodeAt(0)+1728))).replace(/(K|M|B|T|Qt|Qd)/g,(function(e){return String(x[e])})),k.wholeNumber=k.wholeNumber.replace(/[0-9]/g,(e=>String.fromCharCode(e.charCodeAt(0)+1728))).replace(/(K|M|B|T|Qt|Qd)/g,(function(e){return String(x[e])}))),k}_sanitizeLiveInput(e){var t;let r=e;r=r.replace(/[٠-٩۰-۹]/g,(function(e){return String(15&e.charCodeAt(0))}));let i=r,n=null;if("fa"===(null!==(t=this.options.language)&&void 0!==t?t:"en")){const e=this.defaultLanguageConfig.fa.decimalSeparator||"٫";r.includes(e)&&(n=e,i=r.replace(new RegExp(e,"g"),"."))}if(this.isENotation(i)){const e=this.convertENotationToRegularNumber(Number(i),i);r=n&&e.includes(".")?e.replace(/\./g,n):e}return r}_convertToFarsiDigits(e){if("fa"!==this.options.language||null==e)return e;let t="";for(let r=0;r<e.length;r++){const i=e[r];t+=i>="0"&&i<="9"?String.fromCharCode(i.charCodeAt(0)+1728):i}return t}}},986:function(e,t,r){var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.NumberFormatter=void 0;const n=i(r(900));t.NumberFormatter=n.default}},t={};return function r(i){var n=t[i];if(void 0!==n)return n.exports;var o=t[i]={exports:{}};return e[i].call(o.exports,o,o.exports,r),o.exports}(986)})()));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.ReducePrecision=t():e.ReducePrecision=t()}(self,()=>(()=>{"use strict";var e={900:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.default=class{constructor(e={}){this.languageBaseConfig={prefixMarker:"i",postfixMarker:"i",prefix:"",postfix:""},this.defaultLanguageConfig={en:Object.assign(Object.assign({},this.languageBaseConfig),{thousandSeparator:",",decimalSeparator:"."}),fa:Object.assign(Object.assign({},this.languageBaseConfig),{thousandSeparator:"٬",decimalSeparator:"٫"})},this.options=Object.assign({language:"en",template:"number",precision:"high",outputFormat:"plain"},this.defaultLanguageConfig.en),this.options=Object.assign(Object.assign({},this.options),e)}setLanguage(e,t={}){return this.options.language=e,this.options.prefixMarker=t.prefixMarker||this.defaultLanguageConfig[e].prefixMarker,this.options.postfixMarker=t.postfixMarker||this.defaultLanguageConfig[e].postfixMarker,this.options.prefix=t.prefix||this.defaultLanguageConfig[e].prefix,this.options.postfix=t.postfix||this.defaultLanguageConfig[e].postfix,this.options.thousandSeparator=t.thousandSeparator||this.defaultLanguageConfig[e].thousandSeparator,this.options.decimalSeparator=t.decimalSeparator||this.defaultLanguageConfig[e].decimalSeparator,this}setTemplate(e,t){return this.options.template=e,this.options.precision=t,this}toJson(e){const t=this.format(e);return delete t.value,t}toString(e){return this.format(e).value||""}toPlainString(e){return this.options.outputFormat="plain",this.format(e).value||""}toHtmlString(e){return this.options.outputFormat="html",this.format(e).value||""}toMdString(e){return this.options.outputFormat="markdown",this.format(e).value||""}isENotation(e){return/^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)$/.test(e)}convertENotationToRegularNumber(e,t){let r=String(e);if(0===e&&t){const e=t.toLowerCase().split("e");if(2===e.length&&e[0].match(/^0\.0*$/))return e[0]}if(-1===r.toLowerCase().indexOf("e"))return r;if(Math.abs(e)<1&&0!==e){const t=r.toLowerCase().split("e");if(2===t.length){const r=parseInt(t[1],10);if(r<0){let i=Math.abs(r);return t[0].includes(".")&&(i+=t[0].split(".")[1].length),e.toFixed(Math.min(i,100))}}}const i=r.toLowerCase().split("e");if(2===i.length){const t=i[0],r=parseInt(i[1],10);let[n,o]=t.split(".");if(o=o||"",r>0){const e=n.startsWith("-")?"-":"";return e&&(n=n.substring(1)),o.length<=r?e+n+o.padEnd(r,"0"):e+n+o.substring(0,r)+"."+o.substring(r)}if(r<0){let i=Math.abs(r);return t.includes(".")&&(i+=t.split(".")[1].length),e.toFixed(Math.min(i,100))}return t}return r}format(e){var t;let{precision:r,template:i}=this.options;const{language:n,outputFormat:o,prefixMarker:s,postfixMarker:a,prefix:l,postfix:u,thousandSeparator:g,decimalSeparator:f}=this.options;if(null==e||""===e)return{};const p=e.toString();if("liveformat"===i){let e=this._sanitizeLiveInput(p);const r=g||",",i=f||".";let n=p.replace(/[٠-٩۰-۹]/g,function(e){return String(15&e.charCodeAt(0))});if("fa"===(null!==(t=this.options.language)&&void 0!==t?t:"en")){const e=this.defaultLanguageConfig.fa.decimalSeparator||"٫";n=n.replace(new RegExp(e,"g"),".")}if(this.isENotation(n)&&0===Number(n)){const t=p.toLowerCase().indexOf("e");if(t>-1){const r=p.substring(0,t).replace(/[٠-٩۰-۹]/g,function(e){return String(15&e.charCodeAt(0))});let n=r;r.includes(".")&&"."!==i?n=r.replace(".",i):r.includes("٫")&&"٫"!==i&&(n=r.replace("٫",i));const o=new RegExp(`^0\\${i}0*$`);n.match(o)&&(e=n)}}let o="";if(e.startsWith("-")&&(o="-",e=e.substring(1)),""===e)return{value:"",prefix:"",postfix:"",sign:"",wholeNumber:""};if("0"===e){let e="0";return"fa"===this.options.language&&(e=String.fromCharCode("0".charCodeAt(0)+1728)),{value:e,prefix:"",postfix:"",sign:"",wholeNumber:e}}e===i&&(e="0"+i);let s="",a="",l=!1;if(e.includes(i)){l=!0;const t=e.split(i);s=t[0],a=t.length>1?t[1]:""}else if("."!==i&&e.includes(".")){l=!0;const t=e.split(".");s=t[0],a=t.length>1?t[1]:""}else s=e;if(""===s)s="0";else if("0"!==s){const e=s.replace(/^0+/,"");s=""===e?"0":e}let u=s.replace(/\B(?=(\d{3})+(?!\d))/g,r);l&&(u+=i+a);const c=u;let h="",d=c;"-"===o&&(0!==parseFloat(c)||c.includes(".")?(h="-",d=o+c):h="");const m=this._convertToFarsiDigits(u);let b="";return"-"===o&&(b="0"===u?"":"-"),{value:b+m,prefix:"",postfix:"",sign:b,wholeNumber:m}}(null==i?void 0:i.match(/^(number|usd|irt|irr|percent|liveformat)$/g))||(i="number"),this.isENotation(p)&&(e=this.convertENotationToRegularNumber(Number(e)));let c=e.toString().replace(/[\u0660-\u0669\u06F0-\u06F9]/g,function(e){return String(15&e.charCodeAt(0))}).replace(/[^\d.-]/g,"");c=c.replace(/^0+(?=\d)/g,"");const h=Math.abs(Number(c));let d,m,b,x,v=0;if("auto"===r&&(i.match(/^(usd|irt|irr|number)$/g)?r=h>=1e-4&&h<1e11?"high":"medium":"percent"===i&&(r="low")),"medium"===r)if(h>=0&&h<1e-4)d=33,m=4,b=!1,x=!0;else if(h>=1e-4&&h<.001)d=7,m=4,b=!1,x=!1;else if(h>=.001&&h<.01)d=5,m=3,b=!1,x=!1;else if(h>=.001&&h<.1)d=3,m=2,b=!1,x=!1;else if(h>=.1&&h<1)d=1,m=1,b=!1,x=!1;else if(h>=1&&h<10)d=3,m=3,b=!1,x=!1;else if(h>=10&&h<100)d=2,m=2,b=!1,x=!1;else if(h>=100&&h<1e3)d=1,m=1,b=!1,x=!1;else if(h>=1e3){const e=Math.floor(Math.log10(h))%3;d=2-e,m=2-e,b=!0,x=!0}else d=0,m=0,b=!0,x=!0;else if("low"===r)if(h>=0&&h<.01)d=2,m=0,b=!0,x=!1,v=2;else if(h>=.01&&h<.1)d=2,m=1,b=!0,x=!1;else if(h>=.1&&h<1)d=2,m=2,b=!0,x=!1;else if(h>=1&&h<10)d=2,m=2,b=!0,x=!1,v=2;else if(h>=10&&h<100)d=1,m=1,b=!0,x=!1,v=1;else if(h>=100&&h<1e3)d=0,m=0,b=!0,x=!1;else if(h>=1e3){const e=Math.floor(Math.log10(h))%3;d=1-e,m=1-e,b=!0,x=!0}else d=0,m=0,b=!0,x=!0,v=2;else h>=0&&h<1?(d=33,m=4,b=!1,x=!1):h>=1&&h<10?(d=3,m=3,b=!0,x=!1):h>=10&&h<100||h>=100&&h<1e3?(d=2,m=2,b=!0,x=!1):h>=1e3&&h<1e4?(d=1,m=1,b=!0,x=!1):(d=0,m=0,b=!0,x=!1);return this.isENotation(p)&&(d=Math.max(d,20),b=!1),this.reducePrecision(c,d,m,b,x,v,i,n,o,s,a,l,u,g,f,p)}reducePrecision(e,t=30,r=4,i=!1,n=!1,o=0,s="number",a="en",l="plain",u="span",g="span",f="",p="",c=",",h=".",d=""){var m,b;if(null==e||""===e.trim())return{};"-0"!==e&&"-0.0"!==e||(e=e.substring(1)),e=e.toString();const x=s.match(/^(number|percent)$/g)?{"":"",K:" هزار",M:" میلیون",B:" میلیارد",T:" تریلیون",Qd:" کادریلیون",Qt:" کنتیلیون"}:{"":"",K:" هزار ت",M:" میلیون ت",B:" میلیارد ت",T:" همت",Qd:" هزار همت",Qt:" میلیون همت"},v=s.match(/^(number|percent)$/g)?{"":"",K:" هزار",M:" میلیون",B:" میلیارد",T:" تریلیون",Qd:" کادریلیون",Qt:" کنتیلیون"}:{"":"",K:" هزار تومان",M:" میلیون تومان",B:" میلیارد تومان",T:" هزار میلیارد تومان",Qd:" کادریلیون تومان",Qt:" کنتیلیون تومان"};let C=/^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(e);if(!C)return{};const S=C[1]||"";let M=C[2],$=C[3],N=C[4],w="",L="";if($.length>=30?($="0".padEnd(29,"0"),N="1"):$.length+r>t?(r=t-$.length)<1&&(r=1):M.length>21&&(M="0",$="",N=""),n&&M.length>=4){const e=Object.keys(x);let t=M,r=0;for(;+t>999&&r<e.length-1;)t=(+t/1e3).toFixed(2),r++;if(L=e[r],C=/^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(t.toString()),!C)return{};M=C[2],$=C[3],N=C[4]}N.length>r&&(i?parseInt(N[r])<5?N=N.substring(0,r):(N=(parseInt(N.substring(0,r))+1).toString(),N.length>r&&($.length>0?$=$.substring(0,$.length-1):(M=(Number(M)+1).toString(),N=N.substring(1)))):N=N.substring(0,r)),n&&""!==$&&""===L&&($="0"+$.length.toString().replace(/\d/g,function(e){return["₀","₁","₂","₃","₄","₅","₆","₇","₈","₉"][parseInt(e,10)]}));let E=`${$}${N}`;if(E.length>t&&!d.includes("e")&&(E=E.substring(0,t)),d.includes("e")||d.includes("E"));else if(d.includes(".")){const e=d.split(".");if(2===e.length){const t=e[1];if(t.length>E.length&&t.endsWith("0")){let e=0;for(let r=t.length-1;r>=0&&"0"===t[r];r--)e++;e>0&&(E=E.padEnd(E.length+e,"0"))}}}"usd"===s?(w="en"===a?"$":"",L||(L="fa"===a?" دلار":"")):"irr"===s?L||(L="fa"===a?" ر":" R"):"irt"===s?L||(L="fa"===a?" ت":" T"):"percent"===s&&(L+="en"===a?"%":L?" درصد":"٪"),w=f+w,L+=p,"html"===l?(w&&(w=`<${u}>${w}</${u}>`),L&&(L=`<${g}>${L}</${g}>`)):"markdown"===l&&(w&&(w=`${u}${w}${u}`),L&&(L=`${g}${L}${g}`));const Q=/\B(?=(\d{3})+(?!\d))/g,F=o?".".padEnd(o+1,"0"):"";let T,j="";T=t<=0||r<=0||""===N&&""===$?`${M.replace(Q,",")}${F}`:`${M.replace(Q,",")}.${E}`,j=`${S}${w}${T}${L}`;const k={value:j,prefix:w,postfix:L,sign:S,wholeNumber:T};return k.value=(null!==(m=null==k?void 0:k.value)&&void 0!==m?m:"").replace(/,/g,c).replace(/\./g,h),"fa"===a&&(k.value=(null!==(b=null==k?void 0:k.value)&&void 0!==b?b:"").replace(/[0-9]/g,e=>String.fromCharCode(e.charCodeAt(0)+1728)).replace(/(K|M|B|T|Qt|Qd)/g,function(e){return String(x[e])}),k.fullPostfix=L.replace(/[0-9]/g,e=>String.fromCharCode(e.charCodeAt(0)+1728)).replace(/(K|M|B|T|Qt|Qd)/g,function(e){return String(v[e])}),k.postfix=k.postfix.replace(/[0-9]/g,e=>String.fromCharCode(e.charCodeAt(0)+1728)).replace(/(K|M|B|T|Qt|Qd)/g,function(e){return String(x[e])}),k.wholeNumber=k.wholeNumber.replace(/[0-9]/g,e=>String.fromCharCode(e.charCodeAt(0)+1728)).replace(/(K|M|B|T|Qt|Qd)/g,function(e){return String(x[e])})),k}_sanitizeLiveInput(e){var t;let r=e;r=r.replace(/[٠-٩۰-۹]/g,function(e){return String(15&e.charCodeAt(0))});let i=r,n=null;if("fa"===(null!==(t=this.options.language)&&void 0!==t?t:"en")){const e=this.defaultLanguageConfig.fa.decimalSeparator||"٫";r.includes(e)&&(n=e,i=r.replace(new RegExp(e,"g"),"."))}if(this.isENotation(i)){const e=this.convertENotationToRegularNumber(Number(i),i);r=n&&e.includes(".")?e.replace(/\./g,n):e}return r}_convertToFarsiDigits(e){if("fa"!==this.options.language||null==e)return e;let t="";for(let r=0;r<e.length;r++){const i=e[r];t+=i>="0"&&i<="9"?String.fromCharCode(i.charCodeAt(0)+1728):i}return t}}},986:function(e,t,r){var i=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.NumberFormatter=void 0;const n=i(r(900));t.NumberFormatter=n.default}},t={};return function r(i){var n=t[i];if(void 0!==n)return n.exports;var o=t[i]={exports:{}};return e[i].call(o.exports,o,o.exports,r),o.exports}(986)})());
|
|
@@ -196,7 +196,7 @@ class NumberFormatter {
|
|
|
196
196
|
value: '',
|
|
197
197
|
prefix: '',
|
|
198
198
|
postfix: '',
|
|
199
|
-
sign: '',
|
|
199
|
+
sign: '', // Sign is empty for empty input
|
|
200
200
|
wholeNumber: ''
|
|
201
201
|
};
|
|
202
202
|
}
|
|
@@ -210,7 +210,7 @@ class NumberFormatter {
|
|
|
210
210
|
value: outputZero,
|
|
211
211
|
prefix: '',
|
|
212
212
|
postfix: '',
|
|
213
|
-
sign: '',
|
|
213
|
+
sign: '', // Sign is empty for "0"
|
|
214
214
|
wholeNumber: outputZero,
|
|
215
215
|
};
|
|
216
216
|
}
|
|
@@ -291,10 +291,10 @@ class NumberFormatter {
|
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
293
|
return {
|
|
294
|
-
value: outputSign + outputFormattedAbsoluteValue,
|
|
294
|
+
value: outputSign + outputFormattedAbsoluteValue, // Prepend sign to Farsi/Western formatted absolute value
|
|
295
295
|
prefix: '',
|
|
296
296
|
postfix: '',
|
|
297
|
-
sign: outputSign,
|
|
297
|
+
sign: outputSign, // Store the determined sign
|
|
298
298
|
wholeNumber: outputFormattedAbsoluteValue, // Store Farsi/Western formatted absolute value (unsigned)
|
|
299
299
|
};
|
|
300
300
|
}
|
|
@@ -23,44 +23,44 @@ describe('NumberFormatter - Liveformat Template', () => {
|
|
|
23
23
|
{ input: '2923123.00301', expected: '2,923,123.00301' },
|
|
24
24
|
{ input: '2923123.003012', expected: '2,923,123.003012' },
|
|
25
25
|
// Edge cases
|
|
26
|
-
{ input: '', expected: '' },
|
|
27
|
-
{ input: '.', expected: '0.' },
|
|
26
|
+
{ input: '', expected: '' }, // Empty input
|
|
27
|
+
{ input: '.', expected: '0.' }, // Just decimal separator
|
|
28
28
|
{ input: '0.0', expected: '0.0' },
|
|
29
29
|
{ input: '0.12', expected: '0.12' },
|
|
30
|
-
{ input: '.5', expected: '0.5' },
|
|
31
|
-
{ input: '007', expected: '7' },
|
|
32
|
-
{ input: '00.25', expected: '0.25' },
|
|
33
|
-
{ input: '12345.6700', expected: '12,345.6700' },
|
|
34
|
-
{ input: '000', expected: '0' },
|
|
35
|
-
{ input: '000.000', expected: '0.000' },
|
|
30
|
+
{ input: '.5', expected: '0.5' }, // Leading decimal separator
|
|
31
|
+
{ input: '007', expected: '7' }, // Multiple leading zeros, integer
|
|
32
|
+
{ input: '00.25', expected: '0.25' }, // Multiple leading zeros, decimal
|
|
33
|
+
{ input: '12345.6700', expected: '12,345.6700' }, // Trailing zeros in decimal
|
|
34
|
+
{ input: '000', expected: '0' }, // Multiple zeros
|
|
35
|
+
{ input: '000.000', expected: '0.000' }, // Multiple zeros with decimal
|
|
36
36
|
// Test cases for E-notation handling by incremental template
|
|
37
37
|
{ input: '1.23e-7', expected: '0.000000123' },
|
|
38
|
-
{ input: '1.23E-7', expected: '0.000000123' },
|
|
39
|
-
{ input: 0.000000123, expected: '0.000000123' },
|
|
40
|
-
{ input: '12345e-2', expected: '123.45' },
|
|
41
|
-
{ input: '0.00012345e+2', expected: '0.012345' },
|
|
38
|
+
{ input: '1.23E-7', expected: '0.000000123' }, // Uppercase E
|
|
39
|
+
{ input: 0.000000123, expected: '0.000000123' }, // Number input that becomes E-notation
|
|
40
|
+
{ input: '12345e-2', expected: '123.45' }, // Positive coefficient, negative exponent
|
|
41
|
+
{ input: '0.00012345e+2', expected: '0.012345' }, // Decimal coefficient, positive exponent
|
|
42
42
|
{ input: '1.23e+8', expected: '123,000,000' },
|
|
43
43
|
{ input: '1.23E+8', expected: '123,000,000' },
|
|
44
|
-
{ input: 123000000, expected: '123,000,000' },
|
|
45
|
-
{ input: '1234567.89e+3', expected: '1,234,567,890' },
|
|
46
|
-
{ input: '123456789012345', expected: '123,456,789,012,345' },
|
|
47
|
-
{ input: 123456789012345, expected: '123,456,789,012,345' },
|
|
44
|
+
{ input: 123000000, expected: '123,000,000' }, // Number input (large)
|
|
45
|
+
{ input: '1234567.89e+3', expected: '1,234,567,890' }, // Large number with decimal, positive exponent
|
|
46
|
+
{ input: '123456789012345', expected: '123,456,789,012,345' }, // Large integer string (no E)
|
|
47
|
+
{ input: 123456789012345, expected: '123,456,789,012,345' }, // Large integer number
|
|
48
48
|
{ input: '1e-3', expected: '0.001' },
|
|
49
49
|
{ input: 0.001, expected: '0.001' },
|
|
50
50
|
{ input: '1e+3', expected: '1,000' },
|
|
51
51
|
{ input: 1000, expected: '1,000' },
|
|
52
|
-
{ input: '0e0', expected: '0' },
|
|
52
|
+
{ input: '0e0', expected: '0' }, // Zero in E-notation
|
|
53
53
|
{ input: 0e0, expected: '0' },
|
|
54
54
|
{ input: '0.0e0', expected: '0.0' },
|
|
55
55
|
// Cases that might stress the convertENotationToRegularNumber
|
|
56
|
-
{ input: '123456789123456789123', expected: '123,456,789,123,456,789,123' },
|
|
57
|
-
{ input: 123456789123456789123, expected: '123,456,789,123,456,800,000' },
|
|
58
|
-
{ input: '1.0e-20', expected: '0.00000000000000000001' },
|
|
56
|
+
{ input: '123456789123456789123', expected: '123,456,789,123,456,789,123' }, // Very large integer string
|
|
57
|
+
{ input: 123456789123456789123, expected: '123,456,789,123,456,800,000' }, // Very large integer number (JS might show as E if too large for its default toString)
|
|
58
|
+
{ input: '1.0e-20', expected: '0.00000000000000000001' }, // Small number, many zeros
|
|
59
59
|
{ input: 1.0e-20, expected: '0.00000000000000000001' },
|
|
60
|
-
{ input: '1.0e+20', expected: '100,000,000,000,000,000,000' },
|
|
60
|
+
{ input: '1.0e+20', expected: '100,000,000,000,000,000,000' }, // Large number, many zeros
|
|
61
61
|
{ input: 1.0e+20, expected: '100,000,000,000,000,000,000' },
|
|
62
62
|
// Check inputs that convertENotationToRegularNumber might have previously struggled with
|
|
63
|
-
{ input: '1e21', expected: '1,000,000,000,000,000,000,000' },
|
|
63
|
+
{ input: '1e21', expected: '1,000,000,000,000,000,000,000' }, // Number that is 10^21
|
|
64
64
|
{ input: 1e21, expected: '1,000,000,000,000,000,000,000' },
|
|
65
65
|
// Test with negative numbers in E-notation
|
|
66
66
|
{ input: '-1.23e-7', expected: '-0.000000123' },
|
package/ts/lib/format/index.d.ts
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
type Template = 'number' | 'usd' | 'irt' | 'irr' | 'percent';
|
|
2
|
-
type Precision = 'auto' | 'high' | 'medium' | 'low';
|
|
3
|
-
type Language = 'en' | 'fa';
|
|
4
|
-
type OutputFormat = 'plain' | 'html' | 'markdown';
|
|
5
|
-
interface FormattedObject {
|
|
6
|
-
value?: string;
|
|
7
|
-
prefix: string;
|
|
8
|
-
postfix: string;
|
|
9
|
-
fullPostfix?: string;
|
|
10
|
-
sign: string;
|
|
11
|
-
wholeNumber: string;
|
|
12
|
-
}
|
|
13
|
-
interface LanguageConfig {
|
|
14
|
-
prefixMarker?: string;
|
|
15
|
-
postfixMarker?: string;
|
|
16
|
-
prefix?: string;
|
|
17
|
-
postfix?: string;
|
|
18
|
-
thousandSeparator?: string;
|
|
19
|
-
decimalSeparator?: string;
|
|
20
|
-
}
|
|
21
|
-
interface Options extends LanguageConfig {
|
|
22
|
-
precision?: Precision;
|
|
23
|
-
template?: Template;
|
|
24
|
-
language?: Language;
|
|
25
|
-
outputFormat?: OutputFormat;
|
|
26
|
-
}
|
|
27
|
-
declare class NumberFormatter {
|
|
28
|
-
private readonly languageBaseConfig;
|
|
29
|
-
private defaultLanguageConfig;
|
|
30
|
-
private options;
|
|
31
|
-
constructor(options?: Options);
|
|
32
|
-
setLanguage(lang: Language, config?: LanguageConfig): NumberFormatter;
|
|
33
|
-
setTemplate(template: Template, precision: Precision): NumberFormatter;
|
|
34
|
-
toJson(input: string | number): FormattedObject;
|
|
35
|
-
toString(input: string | number): string;
|
|
36
|
-
toPlainString(input: string | number): string;
|
|
37
|
-
toHtmlString(input: string | number): string;
|
|
38
|
-
toMdString(input: string | number): string;
|
|
39
|
-
private isENotation;
|
|
40
|
-
private format;
|
|
41
|
-
private convertENotationToRegularNumber;
|
|
42
|
-
private reducePrecision;
|
|
43
|
-
}
|
|
44
|
-
export default NumberFormatter;
|
package/ts/lib/format/index.js
DELETED
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
class NumberFormatter {
|
|
4
|
-
constructor(options = {}) {
|
|
5
|
-
this.languageBaseConfig = {
|
|
6
|
-
prefixMarker: 'i',
|
|
7
|
-
postfixMarker: 'i',
|
|
8
|
-
prefix: '',
|
|
9
|
-
postfix: '',
|
|
10
|
-
};
|
|
11
|
-
this.defaultLanguageConfig = {
|
|
12
|
-
en: Object.assign(Object.assign({}, this.languageBaseConfig), { thousandSeparator: ',', decimalSeparator: '.' }),
|
|
13
|
-
fa: Object.assign(Object.assign({}, this.languageBaseConfig), { thousandSeparator: '٫', decimalSeparator: '٬' }),
|
|
14
|
-
};
|
|
15
|
-
this.options = Object.assign({ language: 'en', template: 'number', precision: 'high', outputFormat: 'plain' }, this.defaultLanguageConfig['en']);
|
|
16
|
-
this.options = Object.assign(Object.assign({}, this.options), options);
|
|
17
|
-
}
|
|
18
|
-
setLanguage(lang, config = {}) {
|
|
19
|
-
this.options.language = lang;
|
|
20
|
-
this.options.prefixMarker =
|
|
21
|
-
config.prefixMarker || this.defaultLanguageConfig[lang].prefixMarker;
|
|
22
|
-
this.options.postfixMarker =
|
|
23
|
-
config.postfixMarker || this.defaultLanguageConfig[lang].postfixMarker;
|
|
24
|
-
this.options.prefix =
|
|
25
|
-
config.prefix || this.defaultLanguageConfig[lang].prefix;
|
|
26
|
-
this.options.postfix =
|
|
27
|
-
config.postfix || this.defaultLanguageConfig[lang].postfix;
|
|
28
|
-
this.options.thousandSeparator =
|
|
29
|
-
config.thousandSeparator ||
|
|
30
|
-
this.defaultLanguageConfig[lang].thousandSeparator;
|
|
31
|
-
this.options.decimalSeparator =
|
|
32
|
-
config.decimalSeparator ||
|
|
33
|
-
this.defaultLanguageConfig[lang].decimalSeparator;
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
setTemplate(template, precision) {
|
|
37
|
-
this.options.template = template;
|
|
38
|
-
this.options.precision = precision;
|
|
39
|
-
return this;
|
|
40
|
-
}
|
|
41
|
-
toJson(input) {
|
|
42
|
-
const formattedObject = this.format(input);
|
|
43
|
-
delete formattedObject.value;
|
|
44
|
-
return formattedObject;
|
|
45
|
-
}
|
|
46
|
-
toString(input) {
|
|
47
|
-
const formattedObject = this.format(input);
|
|
48
|
-
return formattedObject.value || '';
|
|
49
|
-
}
|
|
50
|
-
toPlainString(input) {
|
|
51
|
-
this.options.outputFormat = 'plain';
|
|
52
|
-
const formattedObject = this.format(input);
|
|
53
|
-
return formattedObject.value || '';
|
|
54
|
-
}
|
|
55
|
-
toHtmlString(input) {
|
|
56
|
-
this.options.outputFormat = 'html';
|
|
57
|
-
const formattedObject = this.format(input);
|
|
58
|
-
return formattedObject.value || '';
|
|
59
|
-
}
|
|
60
|
-
toMdString(input) {
|
|
61
|
-
this.options.outputFormat = 'markdown';
|
|
62
|
-
const formattedObject = this.format(input);
|
|
63
|
-
return formattedObject.value || '';
|
|
64
|
-
}
|
|
65
|
-
// Private methods...
|
|
66
|
-
isENotation(input) {
|
|
67
|
-
return /^[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)$/.test(input);
|
|
68
|
-
}
|
|
69
|
-
format(input) {
|
|
70
|
-
let { precision, template } = this.options;
|
|
71
|
-
const { language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, thousandSeparator, decimalSeparator, } = this.options;
|
|
72
|
-
if (input === undefined || input === null || input === '') {
|
|
73
|
-
return {};
|
|
74
|
-
}
|
|
75
|
-
if (!(template === null || template === void 0 ? void 0 : template.match(/^(number|usd|irt|irr|percent)$/g)))
|
|
76
|
-
template = 'number';
|
|
77
|
-
// Store original input string to preserve format for trailing zeros
|
|
78
|
-
const originalInput = input.toString();
|
|
79
|
-
if (this.isENotation(originalInput)) {
|
|
80
|
-
input = this.convertENotationToRegularNumber(Number(input));
|
|
81
|
-
}
|
|
82
|
-
// Replace each Persian/Arabic numeral in the string with its English counterpart and strip all non-numeric chars
|
|
83
|
-
let numberString = input
|
|
84
|
-
.toString()
|
|
85
|
-
.replace(/[\u0660-\u0669\u06F0-\u06F9]/g, function (match) {
|
|
86
|
-
return String(match.charCodeAt(0) & 0xf);
|
|
87
|
-
})
|
|
88
|
-
.replace(/[^\d.-]/g, '');
|
|
89
|
-
// Stripping leading zeros only, preserve trailing zeros
|
|
90
|
-
numberString = numberString
|
|
91
|
-
.replace(/^0+(?=\d)/g, '');
|
|
92
|
-
const number = Math.abs(Number(numberString));
|
|
93
|
-
let p, d, r, c;
|
|
94
|
-
let f = 0;
|
|
95
|
-
// Auto precision selection
|
|
96
|
-
if (precision === 'auto') {
|
|
97
|
-
if (template.match(/^(usd|irt|irr|number)$/g)) {
|
|
98
|
-
if (number >= 0.0001 && number < 100000000000) {
|
|
99
|
-
precision = 'high';
|
|
100
|
-
}
|
|
101
|
-
else {
|
|
102
|
-
precision = 'medium';
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
else if (template === 'percent') {
|
|
106
|
-
precision = 'low';
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
if (precision === 'medium') {
|
|
110
|
-
if (number >= 0 && number < 0.0001) {
|
|
111
|
-
p = 33;
|
|
112
|
-
d = 4;
|
|
113
|
-
r = false;
|
|
114
|
-
c = true;
|
|
115
|
-
}
|
|
116
|
-
else if (number >= 0.0001 && number < 0.001) {
|
|
117
|
-
p = 7;
|
|
118
|
-
d = 4;
|
|
119
|
-
r = false;
|
|
120
|
-
c = false;
|
|
121
|
-
}
|
|
122
|
-
else if (number >= 0.001 && number < 0.01) {
|
|
123
|
-
p = 5;
|
|
124
|
-
d = 3;
|
|
125
|
-
r = false;
|
|
126
|
-
c = false;
|
|
127
|
-
}
|
|
128
|
-
else if (number >= 0.001 && number < 0.1) {
|
|
129
|
-
p = 3;
|
|
130
|
-
d = 2;
|
|
131
|
-
r = false;
|
|
132
|
-
c = false;
|
|
133
|
-
}
|
|
134
|
-
else if (number >= 0.1 && number < 1) {
|
|
135
|
-
p = 1;
|
|
136
|
-
d = 1;
|
|
137
|
-
r = false;
|
|
138
|
-
c = false;
|
|
139
|
-
}
|
|
140
|
-
else if (number >= 1 && number < 10) {
|
|
141
|
-
p = 3;
|
|
142
|
-
d = 3;
|
|
143
|
-
r = false;
|
|
144
|
-
c = false;
|
|
145
|
-
}
|
|
146
|
-
else if (number >= 10 && number < 100) {
|
|
147
|
-
p = 2;
|
|
148
|
-
d = 2;
|
|
149
|
-
r = false;
|
|
150
|
-
c = false;
|
|
151
|
-
}
|
|
152
|
-
else if (number >= 100 && number < 1000) {
|
|
153
|
-
p = 1;
|
|
154
|
-
d = 1;
|
|
155
|
-
r = false;
|
|
156
|
-
c = false;
|
|
157
|
-
}
|
|
158
|
-
else if (number >= 1000) {
|
|
159
|
-
const x = Math.floor(Math.log10(number)) % 3;
|
|
160
|
-
p = 2 - x;
|
|
161
|
-
d = 2 - x;
|
|
162
|
-
r = true;
|
|
163
|
-
c = true;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
p = 0;
|
|
167
|
-
d = 0;
|
|
168
|
-
r = true;
|
|
169
|
-
c = true;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
else if (precision === 'low') {
|
|
173
|
-
if (number >= 0 && number < 0.01) {
|
|
174
|
-
p = 2;
|
|
175
|
-
d = 0;
|
|
176
|
-
r = true;
|
|
177
|
-
c = false;
|
|
178
|
-
f = 2;
|
|
179
|
-
}
|
|
180
|
-
else if (number >= 0.01 && number < 0.1) {
|
|
181
|
-
p = 2;
|
|
182
|
-
d = 1;
|
|
183
|
-
r = true;
|
|
184
|
-
c = false;
|
|
185
|
-
}
|
|
186
|
-
else if (number >= 0.1 && number < 1) {
|
|
187
|
-
p = 2;
|
|
188
|
-
d = 2;
|
|
189
|
-
r = true;
|
|
190
|
-
c = false;
|
|
191
|
-
}
|
|
192
|
-
else if (number >= 1 && number < 10) {
|
|
193
|
-
p = 2;
|
|
194
|
-
d = 2;
|
|
195
|
-
r = true;
|
|
196
|
-
c = false;
|
|
197
|
-
f = 2;
|
|
198
|
-
}
|
|
199
|
-
else if (number >= 10 && number < 100) {
|
|
200
|
-
p = 1;
|
|
201
|
-
d = 1;
|
|
202
|
-
r = true;
|
|
203
|
-
c = false;
|
|
204
|
-
f = 1;
|
|
205
|
-
}
|
|
206
|
-
else if (number >= 100 && number < 1000) {
|
|
207
|
-
p = 0;
|
|
208
|
-
d = 0;
|
|
209
|
-
r = true;
|
|
210
|
-
c = false;
|
|
211
|
-
}
|
|
212
|
-
else if (number >= 1000) {
|
|
213
|
-
const x = Math.floor(Math.log10(number)) % 3;
|
|
214
|
-
p = 1 - x;
|
|
215
|
-
d = 1 - x;
|
|
216
|
-
r = true;
|
|
217
|
-
c = true;
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
p = 0;
|
|
221
|
-
d = 0;
|
|
222
|
-
r = true;
|
|
223
|
-
c = true;
|
|
224
|
-
f = 2;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
// precision === "high"
|
|
229
|
-
if (number >= 0 && number < 1) {
|
|
230
|
-
p = 33;
|
|
231
|
-
d = 4;
|
|
232
|
-
r = false;
|
|
233
|
-
c = false;
|
|
234
|
-
}
|
|
235
|
-
else if (number >= 1 && number < 10) {
|
|
236
|
-
p = 3;
|
|
237
|
-
d = 3;
|
|
238
|
-
r = true;
|
|
239
|
-
c = false;
|
|
240
|
-
}
|
|
241
|
-
else if (number >= 10 && number < 100) {
|
|
242
|
-
p = 2;
|
|
243
|
-
d = 2;
|
|
244
|
-
r = true;
|
|
245
|
-
c = false;
|
|
246
|
-
}
|
|
247
|
-
else if (number >= 100 && number < 1000) {
|
|
248
|
-
p = 2;
|
|
249
|
-
d = 2;
|
|
250
|
-
r = true;
|
|
251
|
-
c = false;
|
|
252
|
-
}
|
|
253
|
-
else if (number >= 1000 && number < 10000) {
|
|
254
|
-
p = 1;
|
|
255
|
-
d = 1;
|
|
256
|
-
r = true;
|
|
257
|
-
c = false;
|
|
258
|
-
}
|
|
259
|
-
else {
|
|
260
|
-
p = 0;
|
|
261
|
-
d = 0;
|
|
262
|
-
r = true;
|
|
263
|
-
c = false;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
// For scientific notation, increase precision to ensure correct representation
|
|
267
|
-
if (this.isENotation(originalInput)) {
|
|
268
|
-
p = Math.max(p, 20);
|
|
269
|
-
r = false;
|
|
270
|
-
}
|
|
271
|
-
return this.reducePrecision(numberString, p, d, r, c, f, template, language, outputFormat, prefixMarker, postfixMarker, prefix, postfix, thousandSeparator, decimalSeparator, originalInput);
|
|
272
|
-
}
|
|
273
|
-
convertENotationToRegularNumber(eNotation) {
|
|
274
|
-
// For simple cases like 1e3, directly use Number constructor
|
|
275
|
-
if (Number.isInteger(eNotation) && eNotation >= 1000) {
|
|
276
|
-
return eNotation.toString();
|
|
277
|
-
}
|
|
278
|
-
const parts = eNotation.toString().toLowerCase().split('e');
|
|
279
|
-
if (parts.length !== 2)
|
|
280
|
-
return eNotation.toString();
|
|
281
|
-
const coefficient = parseFloat(parts[0]);
|
|
282
|
-
const exponent = parseInt(parts[1], 10);
|
|
283
|
-
// Handle negative exponents (very small numbers)
|
|
284
|
-
if (exponent < 0) {
|
|
285
|
-
const absExponent = Math.abs(exponent);
|
|
286
|
-
// Determine precision needed to show all digits
|
|
287
|
-
const precision = absExponent +
|
|
288
|
-
(parts[0].includes('.') ? parts[0].split('.')[1].length : 0);
|
|
289
|
-
return eNotation.toFixed(precision);
|
|
290
|
-
}
|
|
291
|
-
// For positive exponents, let JavaScript do the conversion
|
|
292
|
-
return eNotation.toString();
|
|
293
|
-
}
|
|
294
|
-
reducePrecision(numberString, precision = 30, nonZeroDigits = 4, round = false, compress = false, fixedDecimalZeros = 0, template = 'number', language = 'en', outputFormat = 'plain', prefixMarker = 'span', postfixMarker = 'span', prefix = '', postfix = '', thousandSeparator = ',', decimalSeparator = '.', originalInput = '') {
|
|
295
|
-
var _a, _b;
|
|
296
|
-
if (numberString === undefined || numberString === null || numberString.trim() === '') {
|
|
297
|
-
return {};
|
|
298
|
-
}
|
|
299
|
-
// Handle negative zero
|
|
300
|
-
if (numberString === '-0' || numberString === '-0.0') {
|
|
301
|
-
numberString = numberString.substring(1); // Remove negative sign for zero
|
|
302
|
-
}
|
|
303
|
-
numberString = numberString.toString();
|
|
304
|
-
const maxPrecision = 30;
|
|
305
|
-
const maxIntegerDigits = 21;
|
|
306
|
-
const scaleUnits = template.match(/^(number|percent)$/g)
|
|
307
|
-
? {
|
|
308
|
-
'': '',
|
|
309
|
-
K: ' هزار',
|
|
310
|
-
M: ' میلیون',
|
|
311
|
-
B: ' میلیارد',
|
|
312
|
-
T: ' تریلیون',
|
|
313
|
-
Qd: ' کادریلیون',
|
|
314
|
-
Qt: ' کنتیلیون',
|
|
315
|
-
}
|
|
316
|
-
: {
|
|
317
|
-
'': '',
|
|
318
|
-
K: ' هزار ت',
|
|
319
|
-
M: ' میلیون ت',
|
|
320
|
-
B: ' میلیارد ت',
|
|
321
|
-
T: ' همت',
|
|
322
|
-
Qd: ' هزار همت',
|
|
323
|
-
Qt: ' میلیون همت',
|
|
324
|
-
};
|
|
325
|
-
const fullScaleUnits = template.match(/^(number|percent)$/g)
|
|
326
|
-
? {
|
|
327
|
-
'': '',
|
|
328
|
-
K: ' هزار',
|
|
329
|
-
M: ' میلیون',
|
|
330
|
-
B: ' میلیارد',
|
|
331
|
-
T: ' تریلیون',
|
|
332
|
-
Qd: ' کادریلیون',
|
|
333
|
-
Qt: ' کنتیلیون',
|
|
334
|
-
}
|
|
335
|
-
: {
|
|
336
|
-
'': '',
|
|
337
|
-
K: ' هزار تومان',
|
|
338
|
-
M: ' میلیون تومان',
|
|
339
|
-
B: ' میلیارد تومان',
|
|
340
|
-
T: ' هزار میلیارد تومان',
|
|
341
|
-
Qd: ' کادریلیون تومان',
|
|
342
|
-
Qt: ' کنتیلیون تومان',
|
|
343
|
-
};
|
|
344
|
-
let parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(numberString);
|
|
345
|
-
if (!parts) {
|
|
346
|
-
return {};
|
|
347
|
-
}
|
|
348
|
-
const sign = parts[1] || '';
|
|
349
|
-
let nonFractionalStr = parts[2];
|
|
350
|
-
let fractionalZeroStr = parts[3];
|
|
351
|
-
let fractionalNonZeroStr = parts[4];
|
|
352
|
-
let unitPrefix = '';
|
|
353
|
-
let unitPostfix = '';
|
|
354
|
-
if (fractionalZeroStr.length >= maxPrecision) {
|
|
355
|
-
// Number is smaller than maximum precision
|
|
356
|
-
fractionalZeroStr = '0'.padEnd(maxPrecision - 1, '0');
|
|
357
|
-
fractionalNonZeroStr = '1';
|
|
358
|
-
}
|
|
359
|
-
else if (fractionalZeroStr.length + nonZeroDigits > precision) {
|
|
360
|
-
// decrease non-zero digits
|
|
361
|
-
nonZeroDigits = precision - fractionalZeroStr.length;
|
|
362
|
-
if (nonZeroDigits < 1)
|
|
363
|
-
nonZeroDigits = 1;
|
|
364
|
-
}
|
|
365
|
-
else if (nonFractionalStr.length > maxIntegerDigits) {
|
|
366
|
-
nonFractionalStr = '0';
|
|
367
|
-
fractionalZeroStr = '';
|
|
368
|
-
fractionalNonZeroStr = '';
|
|
369
|
-
}
|
|
370
|
-
// compress large numbers
|
|
371
|
-
if (compress && nonFractionalStr.length >= 4) {
|
|
372
|
-
const scaleUnitKeys = Object.keys(scaleUnits);
|
|
373
|
-
let scaledWholeNumber = nonFractionalStr;
|
|
374
|
-
let unitIndex = 0;
|
|
375
|
-
while (+scaledWholeNumber > 999 && unitIndex < scaleUnitKeys.length - 1) {
|
|
376
|
-
scaledWholeNumber = (+scaledWholeNumber / 1000).toFixed(2);
|
|
377
|
-
unitIndex++;
|
|
378
|
-
}
|
|
379
|
-
unitPostfix = scaleUnitKeys[unitIndex];
|
|
380
|
-
parts = /^(-)?(\d+)\.?([0]*)(\d*)$/g.exec(scaledWholeNumber.toString());
|
|
381
|
-
if (!parts) {
|
|
382
|
-
return {};
|
|
383
|
-
}
|
|
384
|
-
// sign = parts[1] || "";
|
|
385
|
-
nonFractionalStr = parts[2];
|
|
386
|
-
fractionalZeroStr = parts[3];
|
|
387
|
-
fractionalNonZeroStr = parts[4];
|
|
388
|
-
}
|
|
389
|
-
// Truncate the fractional part or round it
|
|
390
|
-
// if (precision > 0 && nonZeroDigits > 0 && fractionalNonZeroStr.length > nonZeroDigits) {
|
|
391
|
-
if (fractionalNonZeroStr.length > nonZeroDigits) {
|
|
392
|
-
if (!round) {
|
|
393
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
|
|
394
|
-
}
|
|
395
|
-
else {
|
|
396
|
-
if (parseInt(fractionalNonZeroStr[nonZeroDigits]) < 5) {
|
|
397
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(0, nonZeroDigits);
|
|
398
|
-
}
|
|
399
|
-
else {
|
|
400
|
-
fractionalNonZeroStr = (parseInt(fractionalNonZeroStr.substring(0, nonZeroDigits)) + 1).toString();
|
|
401
|
-
// If overflow occurs (e.g., 999 + 1 = 1000), adjust the substring length
|
|
402
|
-
if (fractionalNonZeroStr.length > nonZeroDigits) {
|
|
403
|
-
if (fractionalZeroStr.length > 0) {
|
|
404
|
-
fractionalZeroStr = fractionalZeroStr.substring(0, fractionalZeroStr.length - 1);
|
|
405
|
-
}
|
|
406
|
-
else {
|
|
407
|
-
nonFractionalStr = (Number(nonFractionalStr) + 1).toString();
|
|
408
|
-
fractionalNonZeroStr = fractionalNonZeroStr.substring(1);
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
// Using dex style
|
|
415
|
-
if (compress && fractionalZeroStr !== '' && unitPostfix === '') {
|
|
416
|
-
fractionalZeroStr =
|
|
417
|
-
'0' +
|
|
418
|
-
fractionalZeroStr.length.toString().replace(/\d/g, function (match) {
|
|
419
|
-
return [
|
|
420
|
-
'₀',
|
|
421
|
-
'₁',
|
|
422
|
-
'₂',
|
|
423
|
-
'₃',
|
|
424
|
-
'₄',
|
|
425
|
-
'₅',
|
|
426
|
-
'₆',
|
|
427
|
-
'₇',
|
|
428
|
-
'₈',
|
|
429
|
-
'₉',
|
|
430
|
-
][parseInt(match, 10)];
|
|
431
|
-
});
|
|
432
|
-
}
|
|
433
|
-
// Check if the original input had trailing zeros
|
|
434
|
-
let fractionalPartStr = `${fractionalZeroStr}${fractionalNonZeroStr}`;
|
|
435
|
-
// Don't truncate trailing zeros when they're in the original string
|
|
436
|
-
if (fractionalPartStr.length > precision && !originalInput.includes('e')) {
|
|
437
|
-
fractionalPartStr = fractionalPartStr.substring(0, precision);
|
|
438
|
-
}
|
|
439
|
-
// For scientific notation and numbers with trailing zeros, preserve the format
|
|
440
|
-
if (originalInput.includes('e') || originalInput.includes('E')) {
|
|
441
|
-
// For scientific notation, use the converted string
|
|
442
|
-
}
|
|
443
|
-
else if (originalInput.includes('.')) {
|
|
444
|
-
// For regular numbers with decimal point, check for trailing zeros
|
|
445
|
-
const originalParts = originalInput.split('.');
|
|
446
|
-
if (originalParts.length === 2) {
|
|
447
|
-
const originalDecimal = originalParts[1];
|
|
448
|
-
// If original has more digits than what we have now, preserve those trailing zeros
|
|
449
|
-
if (originalDecimal.length > fractionalPartStr.length && originalDecimal.endsWith('0')) {
|
|
450
|
-
// Count trailing zeros in original
|
|
451
|
-
let trailingZeros = 0;
|
|
452
|
-
for (let i = originalDecimal.length - 1; i >= 0; i--) {
|
|
453
|
-
if (originalDecimal[i] === '0') {
|
|
454
|
-
trailingZeros++;
|
|
455
|
-
}
|
|
456
|
-
else {
|
|
457
|
-
break;
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
// Add back trailing zeros if they were in the original
|
|
461
|
-
if (trailingZeros > 0) {
|
|
462
|
-
fractionalPartStr = fractionalPartStr.padEnd(fractionalPartStr.length + trailingZeros, '0');
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
// Output Formating, Prefix, Postfix
|
|
468
|
-
if (template === 'usd') {
|
|
469
|
-
unitPrefix = language === 'en' ? '$' : '';
|
|
470
|
-
if (!unitPostfix)
|
|
471
|
-
unitPostfix = language === 'fa' ? ' دلار' : '';
|
|
472
|
-
}
|
|
473
|
-
else if (template === 'irr') {
|
|
474
|
-
if (!unitPostfix)
|
|
475
|
-
unitPostfix = language === 'fa' ? ' ر' : ' R';
|
|
476
|
-
}
|
|
477
|
-
else if (template === 'irt') {
|
|
478
|
-
if (!unitPostfix)
|
|
479
|
-
unitPostfix = language === 'fa' ? ' ت' : ' T';
|
|
480
|
-
}
|
|
481
|
-
else if (template === 'percent') {
|
|
482
|
-
if (language === 'en') {
|
|
483
|
-
unitPostfix += '%';
|
|
484
|
-
}
|
|
485
|
-
else {
|
|
486
|
-
unitPostfix += !unitPostfix ? '٪' : ' درصد';
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
unitPrefix = prefix + unitPrefix;
|
|
490
|
-
unitPostfix += postfix;
|
|
491
|
-
if (outputFormat === 'html') {
|
|
492
|
-
if (unitPrefix)
|
|
493
|
-
unitPrefix = `<${prefixMarker}>${unitPrefix}</${prefixMarker}>`;
|
|
494
|
-
if (unitPostfix)
|
|
495
|
-
unitPostfix = `<${postfixMarker}>${unitPostfix}</${postfixMarker}>`;
|
|
496
|
-
}
|
|
497
|
-
else if (outputFormat === 'markdown') {
|
|
498
|
-
if (unitPrefix)
|
|
499
|
-
unitPrefix = `${prefixMarker}${unitPrefix}${prefixMarker}`;
|
|
500
|
-
if (unitPostfix)
|
|
501
|
-
unitPostfix = `${postfixMarker}${unitPostfix}${postfixMarker}`;
|
|
502
|
-
}
|
|
503
|
-
const thousandSeparatorRegex = /\B(?=(\d{3})+(?!\d))/g;
|
|
504
|
-
const fixedDecimalZeroStr = fixedDecimalZeros
|
|
505
|
-
? '.'.padEnd(fixedDecimalZeros + 1, '0')
|
|
506
|
-
: '';
|
|
507
|
-
let out = '';
|
|
508
|
-
let wholeNumberStr;
|
|
509
|
-
// FIXED: Changed condition to correctly handle numbers with trailing zeros
|
|
510
|
-
// Old condition: if (precision <= 0 || nonZeroDigits <= 0 || !fractionalNonZeroStr) {
|
|
511
|
-
// New condition checks if both fractional parts are empty
|
|
512
|
-
if (precision <= 0 || nonZeroDigits <= 0 || (fractionalNonZeroStr === '' && fractionalZeroStr === '')) {
|
|
513
|
-
wholeNumberStr = `${nonFractionalStr.replace(thousandSeparatorRegex, ',')}${fixedDecimalZeroStr}`;
|
|
514
|
-
}
|
|
515
|
-
else {
|
|
516
|
-
wholeNumberStr = `${nonFractionalStr.replace(thousandSeparatorRegex, ',')}.${fractionalPartStr}`;
|
|
517
|
-
}
|
|
518
|
-
out = `${sign}${unitPrefix}${wholeNumberStr}${unitPostfix}`;
|
|
519
|
-
const formattedObject = {
|
|
520
|
-
value: out,
|
|
521
|
-
prefix: unitPrefix,
|
|
522
|
-
postfix: unitPostfix,
|
|
523
|
-
sign: sign,
|
|
524
|
-
wholeNumber: wholeNumberStr,
|
|
525
|
-
};
|
|
526
|
-
// replace custom config
|
|
527
|
-
formattedObject.value = ((_a = formattedObject === null || formattedObject === void 0 ? void 0 : formattedObject.value) !== null && _a !== void 0 ? _a : '')
|
|
528
|
-
.replace(/,/g, thousandSeparator)
|
|
529
|
-
.replace(/\./g, decimalSeparator);
|
|
530
|
-
// Convert output to Persian numerals if language is "fa"
|
|
531
|
-
if (language === 'fa') {
|
|
532
|
-
formattedObject.value = ((_b = formattedObject === null || formattedObject === void 0 ? void 0 : formattedObject.value) !== null && _b !== void 0 ? _b : '')
|
|
533
|
-
.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
|
|
534
|
-
.replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
|
|
535
|
-
return String(scaleUnits[c]);
|
|
536
|
-
});
|
|
537
|
-
formattedObject.fullPostfix = unitPostfix
|
|
538
|
-
.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
|
|
539
|
-
.replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
|
|
540
|
-
return String(fullScaleUnits[c]);
|
|
541
|
-
});
|
|
542
|
-
formattedObject.postfix = formattedObject.postfix
|
|
543
|
-
.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
|
|
544
|
-
.replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
|
|
545
|
-
return String(scaleUnits[c]);
|
|
546
|
-
});
|
|
547
|
-
formattedObject.wholeNumber = formattedObject.wholeNumber
|
|
548
|
-
.replace(/[0-9]/g, c => String.fromCharCode(c.charCodeAt(0) + 1728))
|
|
549
|
-
.replace(/(K|M|B|T|Qt|Qd)/g, function (c) {
|
|
550
|
-
return String(scaleUnits[c]);
|
|
551
|
-
});
|
|
552
|
-
}
|
|
553
|
-
return formattedObject;
|
|
554
|
-
}
|
|
555
|
-
}
|
|
556
|
-
exports.default = NumberFormatter;
|
package/ts/lib/index.d.ts
DELETED
package/ts/lib/index.js
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.NumberFormatter = void 0;
|
|
7
|
-
const format_1 = __importDefault(require("./format"));
|
|
8
|
-
exports.NumberFormatter = format_1.default;
|