@fileverse-dev/formulajs 4.4.11-mod-15-patch-2 → 4.4.11-mod-17

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/cjs/index.cjs CHANGED
@@ -5182,39 +5182,65 @@ Z.TEST = (array, x, sigma) => {
5182
5182
  return 1 - NORM.S.DIST((AVERAGE(array) - x) / (sigma / Math.sqrt(n)), true)
5183
5183
  };
5184
5184
 
5185
- function PNL(){
5186
- const [A, B] = argsToArray(arguments);
5185
+ function PNL() {
5186
+ const [A, B] = argsToArray(arguments);
5187
5187
 
5188
- // Handle single numbers
5188
+ const toNumberOrThrow = (val) => {
5189
+ const num = Number(val);
5190
+ if (isNaN(num)) throw new Error(`Invalid number value: ${val}`);
5191
+ return num;
5192
+ };
5193
+
5194
+ // Single numbers
5189
5195
  if (typeof A === "number" && typeof B === "number") {
5190
5196
  return A - B;
5191
5197
  }
5192
5198
 
5193
- // Handle 1D arrays
5194
- if (Array.isArray(A) && Array.isArray(B) && typeof A[0] === "number") {
5195
- if (A.length !== B.length) throw new Error("1D arrays must match in length");
5196
- return A.reduce((sum, val, i) => sum + (val - B[i]), 0);
5199
+ // 1D arrays
5200
+ if (Array.isArray(A) && Array.isArray(B) && typeof A[0] !== "object") {
5201
+ const maxLen = Math.max(A.length, B.length);
5202
+ let total = 0;
5203
+ for (let i = 0; i < maxLen; i++) {
5204
+ const aVal = i < A.length ? toNumberOrThrow(A[i]) : 0;
5205
+ const bVal = i < B.length ? toNumberOrThrow(B[i]) : 0;
5206
+ total += aVal - bVal;
5207
+ }
5208
+ return total;
5197
5209
  }
5198
5210
 
5199
- // Handle 2D arrays
5200
- if (Array.isArray(A[0]) && typeof A[0][0] === "number") {
5211
+ // 2D arrays
5212
+ if (Array.isArray(A[0]) && typeof A[0][0] !== "object") {
5201
5213
  let total = 0;
5202
- for (let i = 0; i < A.length; i++) {
5203
- if (A[i].length !== B[i].length) throw new Error(`Row ${i} length mismatch`);
5204
- for (let j = 0; j < A[i].length; j++) {
5205
- total += A[i][j] - B[i][j];
5214
+ const maxRows = Math.max(A.length, B.length);
5215
+ for (let i = 0; i < maxRows; i++) {
5216
+ const rowA = A[i] || [];
5217
+ const rowB = B[i] || [];
5218
+ const maxCols = Math.max(rowA.length, rowB.length);
5219
+ for (let j = 0; j < maxCols; j++) {
5220
+ const aVal = j < rowA.length ? toNumberOrThrow(rowA[j]) : 0;
5221
+ const bVal = j < rowB.length ? toNumberOrThrow(rowB[j]) : 0;
5222
+ total += aVal - bVal;
5206
5223
  }
5207
5224
  }
5208
5225
  return total;
5209
5226
  }
5210
5227
 
5211
- // Handle 3D arrays
5228
+ // 3D arrays
5212
5229
  if (Array.isArray(A[0][0])) {
5213
5230
  let total = 0;
5214
- for (let i = 0; i < A.length; i++) {
5215
- for (let j = 0; j < A[i].length; j++) {
5216
- for (let k = 0; k < A[i][j].length; k++) {
5217
- total += A[i][j][k] - B[i][j][k];
5231
+ const maxX = Math.max(A.length, B.length);
5232
+ for (let i = 0; i < maxX; i++) {
5233
+ const matA = A[i] || [];
5234
+ const matB = B[i] || [];
5235
+ const maxY = Math.max(matA.length, matB.length);
5236
+ for (let j = 0; j < maxY; j++) {
5237
+ const rowA = matA[j] || [];
5238
+ const rowB = matB[j] || [];
5239
+ const maxZ = Math.max(rowA.length, rowB.length);
5240
+ for (let k = 0; k < maxZ; k++) {
5241
+ const aVal = k < rowA.length ? toNumberOrThrow(rowA[k]) : 0;
5242
+ const bVal = k < rowB.length ? toNumberOrThrow(rowB[k]) : 0;
5243
+ total += aVal - bVal;
5218
5244
  }
5219
5245
  }
5220
5246
  }
@@ -5222,9 +5248,10 @@ function PNL(){
5222
5248
  }
5223
5249
 
5224
5250
  throw new Error("Unsupported or mismatched structure");
5225
-
5226
5251
  }
5227
5252
 
5253
+
5254
+
5228
5255
  /**
5229
5256
  * Returns the absolute value of a number.
5230
5257
  *
@@ -12997,29 +13024,22 @@ function SWITCH() {
12997
13024
  const SERVICE_API_KEY = {
12998
13025
  Etherscan: "ETHERSCAN_API_KEY",
12999
13026
  Coingecko: "COINGECKO_API_KEY",
13000
- Gnosisscan: 'GNOSISSSCAN',
13001
- BASESCAN: 'Basescan'
13002
13027
  };
13003
13028
 
13004
- const CHAIN_API_BASE = {
13005
- ethereum: 'https://api.etherscan.io/api',
13006
- gnosis: 'https://api.gnosisscan.io/api',
13007
- base: 'https://api.basescan.org/api',
13008
- };
13029
+ const CHAIN_ID_MAP = {
13030
+ ethereum: 1,
13031
+ gnosis: 100,
13032
+ base: 8453,
13033
+ };
13009
13034
 
13010
13035
  const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
13011
- const baseUrl = CHAIN_API_BASE[chain];
13012
- if(!baseUrl){
13013
- throw new Error('Unsupported Chain')
13014
- }
13015
- try {
13016
- const url = `${baseUrl}?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}`;
13036
+ if(!timestamp || !chain || !apiKey) return
13037
+ const chainId = CHAIN_ID_MAP[chain];
13038
+ const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13017
13039
  const res = await fetch(url);
13018
13040
  const json = await res.json();
13019
13041
  return parseInt(json.result);
13020
- } catch {
13021
- return 0;
13022
- }
13042
+
13023
13043
  };
13024
13044
 
13025
13045
  async function ETHERSCAN(address, page, offset) {
@@ -13087,20 +13107,23 @@ async function OX(address, categories, chain, startTime, endTime) {
13087
13107
  gnosis: window.localStorage.getItem(SERVICE_API_KEY.Gnosisscan),
13088
13108
  base: window.localStorage.getItem(SERVICE_API_KEY.Basescan),
13089
13109
  };
13090
-
13091
13110
  const apiKey = API_KEYS[chain];
13092
- const baseUrl = CHAIN_API_BASE[chain];
13093
-
13094
- const startBlock = await fromTimeStampToBlock(startTime, chain, apiKey);
13095
- const endBlock = await fromTimeStampToBlock(endTime);
13111
+ const chainId = CHAIN_ID_MAP[chain];
13112
+ if (!apiKey || !chainId) return `${chain.toUpperCase()}_MISSING`;
13096
13113
 
13097
13114
  let action = '';
13098
- if (categories === 'txns') action = 'txlist';
13099
- else if (categories === 'balances') action = 'balance';
13100
- else if (categories === 'portfolio') action = 'tokentx';
13101
-
13102
- let url = `${baseUrl}?module=account&action=${action}&address=${address}&startblock=${startBlock}&endblock=${endBlock}&sort=asc&apikey=${apiKey}`;
13103
-
13115
+ if (categories === 'txns') action = 'account.txlist';
13116
+ else {action = 'account.balance';} let timeQuery = '';
13117
+ if(!isNaN(startTime) && !isNaN(endTime)){
13118
+ const startBlock = await fromTimeStampToBlock(startTime, chain, apiKey);
13119
+ const endBlock = await fromTimeStampToBlock(endTime, chain, apiKey);
13120
+ timeQuery = `&startblock=${startBlock}&endblock=${endBlock}`;
13121
+ } else if(categories === 'balance') {
13122
+ timeQuery = `&tag=latest`;
13123
+ } else {
13124
+ throw new Error('Start and End Time is required for querying transaction list ')
13125
+ }
13126
+ const url = `https://api.etherscan.io/v2/api?module=${action.split('.')[0]}&action=${action.split('.')[1]}&address=${address}&sort=asc&chainid=${chainId}&apikey=${apiKey}${timeQuery}`;
13104
13127
  try {
13105
13128
  const response = await fetch(url);
13106
13129
  if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
@@ -1,9 +1,7 @@
1
1
  // src/crypto-constants.js
2
2
  var SERVICE_API_KEY = {
3
3
  Etherscan: "ETHERSCAN_API_KEY",
4
- Coingecko: "COINGECKO_API_KEY",
5
- Gnosisscan: "GNOSISSSCAN",
6
- BASESCAN: "Basescan"
4
+ Coingecko: "COINGECKO_API_KEY"
7
5
  };
8
6
  var FUNCTION_LOCALE = [
9
7
  {
@@ -45,10 +43,10 @@ var FUNCTION_LOCALE = [
45
43
  LOGO: "https://raw.githubusercontent.com/mritunjayz/github-storage/refs/heads/main/1689874988430.jpeg",
46
44
  BRAND_COLOR: "#F6F7F8",
47
45
  BRAND_SECONDARY_COLOR: "#21325B",
48
- n: "Ox",
46
+ n: "0x",
49
47
  t: 20,
50
48
  d: "Fetches address data like transactions, balances, or portfolio info from multiple supported chains.",
51
- a: "Dynamically queries blockchain data such as transactions, balances, or token portfolio by resolving time ranges to block ranges.",
49
+ a: "Dynamically queries blockchain data such as transactions, balances by resolving time ranges to block ranges.",
52
50
  p: [
53
51
  {
54
52
  name: "address",
@@ -58,7 +56,7 @@ var FUNCTION_LOCALE = [
58
56
  },
59
57
  {
60
58
  name: "categories",
61
- detail: `Type of data to fetch. Supported values: "txns", "balances", "portfolio".`,
59
+ detail: `Type of data to fetch. Supported values: "txns", "balance".`,
62
60
  example: `"txns"`,
63
61
  require: "m"
64
62
  },
@@ -70,14 +68,14 @@ var FUNCTION_LOCALE = [
70
68
  },
71
69
  {
72
70
  name: "startTime",
73
- detail: "Start time in UNIX timestamp (seconds). Will be converted to a starting block.",
71
+ detail: "Start time in UNIX timestamp (seconds). Will be converted to a starting block. Required for txns category",
74
72
  example: "1680300000",
75
73
  require: "m",
76
74
  type: "rangenumber"
77
75
  },
78
76
  {
79
77
  name: "endTime",
80
- detail: "End time in UNIX timestamp (seconds). Will be converted to an ending block.",
78
+ detail: "End time in UNIX timestamp (seconds). Will be converted to an ending block. Required for txns category",
81
79
  example: "1680900000",
82
80
  require: "m",
83
81
  type: "rangenumber"
package/lib/esm/index.mjs CHANGED
@@ -5180,39 +5180,65 @@ Z.TEST = (array, x, sigma) => {
5180
5180
  return 1 - NORM.S.DIST((AVERAGE(array) - x) / (sigma / Math.sqrt(n)), true)
5181
5181
  };
5182
5182
 
5183
- function PNL(){
5184
- const [A, B] = argsToArray(arguments);
5183
+ function PNL() {
5184
+ const [A, B] = argsToArray(arguments);
5185
5185
 
5186
- // Handle single numbers
5186
+ const toNumberOrThrow = (val) => {
5187
+ const num = Number(val);
5188
+ if (isNaN(num)) throw new Error(`Invalid number value: ${val}`);
5189
+ return num;
5190
+ };
5191
+
5192
+ // Single numbers
5187
5193
  if (typeof A === "number" && typeof B === "number") {
5188
5194
  return A - B;
5189
5195
  }
5190
5196
 
5191
- // Handle 1D arrays
5192
- if (Array.isArray(A) && Array.isArray(B) && typeof A[0] === "number") {
5193
- if (A.length !== B.length) throw new Error("1D arrays must match in length");
5194
- return A.reduce((sum, val, i) => sum + (val - B[i]), 0);
5197
+ // 1D arrays
5198
+ if (Array.isArray(A) && Array.isArray(B) && typeof A[0] !== "object") {
5199
+ const maxLen = Math.max(A.length, B.length);
5200
+ let total = 0;
5201
+ for (let i = 0; i < maxLen; i++) {
5202
+ const aVal = i < A.length ? toNumberOrThrow(A[i]) : 0;
5203
+ const bVal = i < B.length ? toNumberOrThrow(B[i]) : 0;
5204
+ total += aVal - bVal;
5205
+ }
5206
+ return total;
5195
5207
  }
5196
5208
 
5197
- // Handle 2D arrays
5198
- if (Array.isArray(A[0]) && typeof A[0][0] === "number") {
5209
+ // 2D arrays
5210
+ if (Array.isArray(A[0]) && typeof A[0][0] !== "object") {
5199
5211
  let total = 0;
5200
- for (let i = 0; i < A.length; i++) {
5201
- if (A[i].length !== B[i].length) throw new Error(`Row ${i} length mismatch`);
5202
- for (let j = 0; j < A[i].length; j++) {
5203
- total += A[i][j] - B[i][j];
5212
+ const maxRows = Math.max(A.length, B.length);
5213
+ for (let i = 0; i < maxRows; i++) {
5214
+ const rowA = A[i] || [];
5215
+ const rowB = B[i] || [];
5216
+ const maxCols = Math.max(rowA.length, rowB.length);
5217
+ for (let j = 0; j < maxCols; j++) {
5218
+ const aVal = j < rowA.length ? toNumberOrThrow(rowA[j]) : 0;
5219
+ const bVal = j < rowB.length ? toNumberOrThrow(rowB[j]) : 0;
5220
+ total += aVal - bVal;
5204
5221
  }
5205
5222
  }
5206
5223
  return total;
5207
5224
  }
5208
5225
 
5209
- // Handle 3D arrays
5226
+ // 3D arrays
5210
5227
  if (Array.isArray(A[0][0])) {
5211
5228
  let total = 0;
5212
- for (let i = 0; i < A.length; i++) {
5213
- for (let j = 0; j < A[i].length; j++) {
5214
- for (let k = 0; k < A[i][j].length; k++) {
5215
- total += A[i][j][k] - B[i][j][k];
5229
+ const maxX = Math.max(A.length, B.length);
5230
+ for (let i = 0; i < maxX; i++) {
5231
+ const matA = A[i] || [];
5232
+ const matB = B[i] || [];
5233
+ const maxY = Math.max(matA.length, matB.length);
5234
+ for (let j = 0; j < maxY; j++) {
5235
+ const rowA = matA[j] || [];
5236
+ const rowB = matB[j] || [];
5237
+ const maxZ = Math.max(rowA.length, rowB.length);
5238
+ for (let k = 0; k < maxZ; k++) {
5239
+ const aVal = k < rowA.length ? toNumberOrThrow(rowA[k]) : 0;
5240
+ const bVal = k < rowB.length ? toNumberOrThrow(rowB[k]) : 0;
5241
+ total += aVal - bVal;
5216
5242
  }
5217
5243
  }
5218
5244
  }
@@ -5220,9 +5246,10 @@ function PNL(){
5220
5246
  }
5221
5247
 
5222
5248
  throw new Error("Unsupported or mismatched structure");
5223
-
5224
5249
  }
5225
5250
 
5251
+
5252
+
5226
5253
  /**
5227
5254
  * Returns the absolute value of a number.
5228
5255
  *
@@ -12995,29 +13022,22 @@ function SWITCH() {
12995
13022
  const SERVICE_API_KEY = {
12996
13023
  Etherscan: "ETHERSCAN_API_KEY",
12997
13024
  Coingecko: "COINGECKO_API_KEY",
12998
- Gnosisscan: 'GNOSISSSCAN',
12999
- BASESCAN: 'Basescan'
13000
13025
  };
13001
13026
 
13002
- const CHAIN_API_BASE = {
13003
- ethereum: 'https://api.etherscan.io/api',
13004
- gnosis: 'https://api.gnosisscan.io/api',
13005
- base: 'https://api.basescan.org/api',
13006
- };
13027
+ const CHAIN_ID_MAP = {
13028
+ ethereum: 1,
13029
+ gnosis: 100,
13030
+ base: 8453,
13031
+ };
13007
13032
 
13008
13033
  const fromTimeStampToBlock = async (timestamp, chain, apiKey) => {
13009
- const baseUrl = CHAIN_API_BASE[chain];
13010
- if(!baseUrl){
13011
- throw new Error('Unsupported Chain')
13012
- }
13013
- try {
13014
- const url = `${baseUrl}?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}`;
13034
+ if(!timestamp || !chain || !apiKey) return
13035
+ const chainId = CHAIN_ID_MAP[chain];
13036
+ const url = `https://api.etherscan.io/v2/api?module=block&action=getblocknobytime&timestamp=${timestamp}&closest=before&apikey=${apiKey}&chainId=${chainId}`;
13015
13037
  const res = await fetch(url);
13016
13038
  const json = await res.json();
13017
13039
  return parseInt(json.result);
13018
- } catch {
13019
- return 0;
13020
- }
13040
+
13021
13041
  };
13022
13042
 
13023
13043
  async function ETHERSCAN(address, page, offset) {
@@ -13085,20 +13105,23 @@ async function OX(address, categories, chain, startTime, endTime) {
13085
13105
  gnosis: window.localStorage.getItem(SERVICE_API_KEY.Gnosisscan),
13086
13106
  base: window.localStorage.getItem(SERVICE_API_KEY.Basescan),
13087
13107
  };
13088
-
13089
13108
  const apiKey = API_KEYS[chain];
13090
- const baseUrl = CHAIN_API_BASE[chain];
13091
-
13092
- const startBlock = await fromTimeStampToBlock(startTime, chain, apiKey);
13093
- const endBlock = await fromTimeStampToBlock(endTime);
13109
+ const chainId = CHAIN_ID_MAP[chain];
13110
+ if (!apiKey || !chainId) return `${chain.toUpperCase()}_MISSING`;
13094
13111
 
13095
13112
  let action = '';
13096
- if (categories === 'txns') action = 'txlist';
13097
- else if (categories === 'balances') action = 'balance';
13098
- else if (categories === 'portfolio') action = 'tokentx';
13099
-
13100
- let url = `${baseUrl}?module=account&action=${action}&address=${address}&startblock=${startBlock}&endblock=${endBlock}&sort=asc&apikey=${apiKey}`;
13101
-
13113
+ if (categories === 'txns') action = 'account.txlist';
13114
+ else {action = 'account.balance';} let timeQuery = '';
13115
+ if(!isNaN(startTime) && !isNaN(endTime)){
13116
+ const startBlock = await fromTimeStampToBlock(startTime, chain, apiKey);
13117
+ const endBlock = await fromTimeStampToBlock(endTime, chain, apiKey);
13118
+ timeQuery = `&startblock=${startBlock}&endblock=${endBlock}`;
13119
+ } else if(categories === 'balance') {
13120
+ timeQuery = `&tag=latest`;
13121
+ } else {
13122
+ throw new Error('Start and End Time is required for querying transaction list ')
13123
+ }
13124
+ const url = `https://api.etherscan.io/v2/api?module=${action.split('.')[0]}&action=${action.split('.')[1]}&address=${address}&sort=asc&chainid=${chainId}&apikey=${apiKey}${timeQuery}`;
13102
13125
  try {
13103
13126
  const response = await fetch(url);
13104
13127
  if (!response.ok) throw new Error(`HTTP error! Status: ${response.status}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fileverse-dev/formulajs",
3
- "version": "4.4.11-mod-15-patch-2",
3
+ "version": "4.4.11-mod-17",
4
4
  "description": "JavaScript implementation of most Microsoft Excel formula functions",
5
5
  "author": "Formulajs",
6
6
  "publishConfig": {
@@ -3157,7 +3157,7 @@ export function PI(): number;
3157
3157
  * @returns
3158
3158
  */
3159
3159
  export function PMT(rate: any, nper: any, pv: any, fv: any, type: any): number | Error;
3160
- export function PNL(...args: any[]): any;
3160
+ export function PNL(...args: any[]): number;
3161
3161
  export namespace POISSON {
3162
3162
  /**
3163
3163
  * Returns the Poisson distribution.
@@ -3157,7 +3157,7 @@ export function PI(): number;
3157
3157
  * @returns
3158
3158
  */
3159
3159
  export function PMT(rate: any, nper: any, pv: any, fv: any, type: any): number | Error;
3160
- export function PNL(...args: any[]): any;
3160
+ export function PNL(...args: any[]): number;
3161
3161
  export namespace POISSON {
3162
3162
  /**
3163
3163
  * Returns the Poisson distribution.