@ape.swap/bonds-sdk 6.2.1 → 6.2.3

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.
Files changed (263) hide show
  1. package/dist/components/MenuSelect/MenuSelect.d.ts +1 -1
  2. package/dist/components/MenuSelect/MenuSelect.js.map +1 -1
  3. package/dist/components/ProgressBar/ProgressBarWrapper.d.ts +1 -1
  4. package/dist/components/ProgressBar/ProgressBarWrapper.js.map +1 -1
  5. package/dist/components/TokenInfoAndName/index.d.ts +0 -1
  6. package/dist/components/TokenInfoAndName/index.js +1 -1
  7. package/dist/components/TokenInfoAndName/index.js.map +1 -1
  8. package/dist/components/TokenSelectorModal/TokenRow.js +2 -2
  9. package/dist/components/TokenSelectorModal/TokenRow.js.map +1 -1
  10. package/dist/components/TokenSelectorPanel/index.js +3 -3
  11. package/dist/components/TokenSelectorPanel/index.js.map +1 -1
  12. package/dist/components/Tooltip/Tooltip.d.ts +1 -1
  13. package/dist/components/Tooltip/Tooltip.js.map +1 -1
  14. package/dist/components/uikit-sdk/Button/Button.js +0 -36
  15. package/dist/components/uikit-sdk/Button/Button.js.map +1 -1
  16. package/dist/components/uikit-sdk/Button/types.d.ts +6 -10
  17. package/dist/components/uikit-sdk/Button/types.js +0 -5
  18. package/dist/components/uikit-sdk/Button/types.js.map +1 -1
  19. package/dist/components/uikit-sdk/Checkbox/types.d.ts +2 -1
  20. package/dist/components/uikit-sdk/Checkbox/types.js.map +1 -1
  21. package/dist/components/uikit-sdk/Skeleton/styles.d.ts +0 -12
  22. package/dist/components/uikit-sdk/Skeleton/styles.js +1 -1
  23. package/dist/components/uikit-sdk/Skeleton/styles.js.map +1 -1
  24. package/dist/components/uikit-sdk/Svg/Icons/ZapIcon.d.ts +2 -2
  25. package/dist/components/uikit-sdk/Svg/styles.d.ts +0 -2
  26. package/dist/components/uikit-sdk/Svg/styles.js.map +1 -1
  27. package/dist/components/uikit-sdk/Text/types.d.ts +1 -1
  28. package/dist/components/uikit-sdk/Text/types.js +1 -1
  29. package/dist/components/uikit-sdk/Text/types.js.map +1 -1
  30. package/dist/components/uikit-sdk/TooltipBubble/types.d.ts +2 -1
  31. package/dist/components/uikit-sdk/TooltipBubble/types.js.map +1 -1
  32. package/dist/config/constants/aptosZapTokens.d.ts +0 -9
  33. package/dist/config/constants/aptosZapTokens.js +1 -2
  34. package/dist/config/constants/aptosZapTokens.js.map +1 -1
  35. package/dist/config/constants/networks.d.ts +0 -2
  36. package/dist/config/constants/networks.js +1 -1
  37. package/dist/config/constants/networks.js.map +1 -1
  38. package/dist/config/constants/tokens.d.ts +1 -2
  39. package/dist/constants/aptosConstants.d.ts +0 -6
  40. package/dist/constants/aptosConstants.js +15 -1
  41. package/dist/constants/aptosConstants.js.map +1 -1
  42. package/dist/constants/solanaConstants.d.ts +0 -6
  43. package/dist/constants/solanaConstants.js +0 -21
  44. package/dist/constants/solanaConstants.js.map +1 -1
  45. package/dist/constants/suiConstants.d.ts +0 -5
  46. package/dist/constants/suiConstants.js +11 -0
  47. package/dist/constants/suiConstants.js.map +1 -1
  48. package/dist/hooks/useSortedZapList.d.ts +1 -1
  49. package/dist/hooks/useSortedZapList.js +1 -2
  50. package/dist/hooks/useSortedZapList.js.map +1 -1
  51. package/dist/hooks/useTokenFromZapList.js +0 -1
  52. package/dist/hooks/useTokenFromZapList.js.map +1 -1
  53. package/dist/providers/index.d.ts +11 -0
  54. package/dist/providers/index.js +0 -6
  55. package/dist/providers/index.js.map +1 -1
  56. package/dist/state/allowance/useAllowance.js +2 -3
  57. package/dist/state/allowance/useAllowance.js.map +1 -1
  58. package/dist/state/balance/useCurrencyBalance.js +2 -3
  59. package/dist/state/balance/useCurrencyBalance.js.map +1 -1
  60. package/dist/state/balance/useCurrencyBalanceAptos.js +5 -5
  61. package/dist/state/balance/useCurrencyBalanceAptos.js.map +1 -1
  62. package/dist/state/balance/useCurrencyBalanceSolana.d.ts +0 -2
  63. package/dist/state/balance/useCurrencyBalanceSolana.js +3 -6
  64. package/dist/state/balance/useCurrencyBalanceSolana.js.map +1 -1
  65. package/dist/state/balance/useCurrencyBalanceSui.js +2 -2
  66. package/dist/state/balance/useCurrencyBalanceSui.js.map +1 -1
  67. package/dist/state/balance/useUserTokensBalance.js +3 -5
  68. package/dist/state/balance/useUserTokensBalance.js.map +1 -1
  69. package/dist/state/bondApiStats/useGetBondApiStats.d.ts +0 -1
  70. package/dist/state/bondApiStats/useGetBondApiStats.js +1 -1
  71. package/dist/state/bondApiStats/useGetBondApiStats.js.map +1 -1
  72. package/dist/state/bonds/fetchBondsData/cleanBillsData.js +16 -13
  73. package/dist/state/bonds/fetchBondsData/cleanBillsData.js.map +1 -1
  74. package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.d.ts +1 -1
  75. package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.js +4 -6
  76. package/dist/state/bonds/fetchBondsData/fetchBondsDataAptos.js.map +1 -1
  77. package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.d.ts +1 -1
  78. package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.js +4 -3
  79. package/dist/state/bonds/fetchBondsData/fetchBondsDataEVM.js.map +1 -1
  80. package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.d.ts +1 -1
  81. package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.js +2 -3
  82. package/dist/state/bonds/fetchBondsData/fetchBondsDataSOL.js.map +1 -1
  83. package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.d.ts +1 -1
  84. package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.js +5 -7
  85. package/dist/state/bonds/fetchBondsData/fetchBondsDataSui.js.map +1 -1
  86. package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.d.ts +1 -2
  87. package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.js +2 -5
  88. package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsEVM.js.map +1 -1
  89. package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsSOL.js +2 -5
  90. package/dist/state/bonds/fetchUsersBonds/fetchUsersBondsSOL.js.map +1 -1
  91. package/dist/state/bonds/useBondsList.d.ts +1 -2
  92. package/dist/state/bonds/useBondsList.js +1 -1
  93. package/dist/state/bonds/useBondsList.js.map +1 -1
  94. package/dist/state/bonds/useBondsListPreTGE.d.ts +1 -2
  95. package/dist/state/bonds/useBondsListPreTGE.js +1 -1
  96. package/dist/state/bonds/useBondsListPreTGE.js.map +1 -1
  97. package/dist/state/bonds/useTierProofSignature.d.ts +0 -1
  98. package/dist/state/bonds/useTierProofSignature.js +1 -1
  99. package/dist/state/bonds/useTierProofSignature.js.map +1 -1
  100. package/dist/state/bonds/useUserBondsPreTGE.d.ts +3 -4
  101. package/dist/state/bonds/useUserBondsPreTGE.js +4 -7
  102. package/dist/state/bonds/useUserBondsPreTGE.js.map +1 -1
  103. package/dist/state/historicalPrice/useHistoricalPrice.d.ts +1 -2
  104. package/dist/state/historicalPrice/useHistoricalPrice.js +1 -1
  105. package/dist/state/historicalPrice/useHistoricalPrice.js.map +1 -1
  106. package/dist/state/hotBonds/useHotBonds.d.ts +0 -2
  107. package/dist/state/hotBonds/useHotBonds.js +1 -1
  108. package/dist/state/hotBonds/useHotBonds.js.map +1 -1
  109. package/dist/state/price/useCurrencyPrice.js +1 -2
  110. package/dist/state/price/useCurrencyPrice.js.map +1 -1
  111. package/dist/state/recommendations/useGetBondRecommendations.d.ts +0 -1
  112. package/dist/state/recommendations/useGetBondRecommendations.js +1 -1
  113. package/dist/state/recommendations/useGetBondRecommendations.js.map +1 -1
  114. package/dist/state/tiers/useTierPoints.d.ts +0 -6
  115. package/dist/state/tiers/useTierPoints.js +16 -17
  116. package/dist/state/tiers/useTierPoints.js.map +1 -1
  117. package/dist/state/zap/useAptosZapQuote.d.ts +1 -16
  118. package/dist/state/zap/useAptosZapQuote.js +4 -4
  119. package/dist/state/zap/useAptosZapQuote.js.map +1 -1
  120. package/dist/state/zap/useJupiterSolanaQuote.js +4 -11
  121. package/dist/state/zap/useJupiterSolanaQuote.js.map +1 -1
  122. package/dist/state/zap/useSoulZapBondQuote.js +12 -21
  123. package/dist/state/zap/useSoulZapBondQuote.js.map +1 -1
  124. package/dist/state/zap/useSuiZapQuote.d.ts +1 -1
  125. package/dist/state/zap/useSuiZapQuote.js +9 -14
  126. package/dist/state/zap/useSuiZapQuote.js.map +1 -1
  127. package/dist/theme/base.d.ts +1 -4
  128. package/dist/theme/base.js +1 -1
  129. package/dist/theme/base.js.map +1 -1
  130. package/dist/theme/components.d.ts +0 -20
  131. package/dist/theme/components.js +1 -1
  132. package/dist/theme/components.js.map +1 -1
  133. package/dist/types/aptosBonds.d.ts +0 -60
  134. package/dist/types/bondIssuanceCodec.d.ts +0 -1
  135. package/dist/types/bondIssuanceCodec.js.map +1 -1
  136. package/dist/types/bondTermCodec.d.ts +0 -1
  137. package/dist/types/bondTermCodec.js.map +1 -1
  138. package/dist/types/solanaBonds.d.ts +4 -3
  139. package/dist/utils/aptosHelpers.d.ts +1 -14
  140. package/dist/utils/aptosHelpers.js +30 -2
  141. package/dist/utils/aptosHelpers.js.map +1 -1
  142. package/dist/utils/bondPriceHelpers.d.ts +1 -1
  143. package/dist/utils/bondPriceHelpers.js +5 -11
  144. package/dist/utils/bondPriceHelpers.js.map +1 -1
  145. package/dist/utils/calculateSolanaTrueBillPrice.d.ts +0 -4
  146. package/dist/utils/calculateSolanaTrueBillPrice.js +33 -32
  147. package/dist/utils/calculateSolanaTrueBillPrice.js.map +1 -1
  148. package/dist/utils/convertToBigish.d.ts +0 -1
  149. package/dist/utils/convertToBigish.js +3 -18
  150. package/dist/utils/convertToBigish.js.map +1 -1
  151. package/dist/utils/displayHelpers.d.ts +3 -9
  152. package/dist/utils/displayHelpers.js +63 -47
  153. package/dist/utils/displayHelpers.js.map +1 -1
  154. package/dist/utils/fixedPoint.d.ts +28 -0
  155. package/dist/utils/fixedPoint.js +239 -0
  156. package/dist/utils/fixedPoint.js.map +1 -0
  157. package/dist/utils/formatNumber.d.ts +0 -7
  158. package/dist/utils/formatNumber.js +6 -12
  159. package/dist/utils/formatNumber.js.map +1 -1
  160. package/dist/utils/getBalanceNumber.d.ts +1 -2
  161. package/dist/utils/getBalanceNumber.js +5 -3
  162. package/dist/utils/getBalanceNumber.js.map +1 -1
  163. package/dist/utils/getNativeTicker.js +0 -1
  164. package/dist/utils/getNativeTicker.js.map +1 -1
  165. package/dist/utils/suiHelpers.d.ts +0 -2
  166. package/dist/utils/suiHelpers.js +13 -15
  167. package/dist/utils/suiHelpers.js.map +1 -1
  168. package/dist/views/Bonds/Bonds.d.ts +0 -4
  169. package/dist/views/Bonds/Bonds.js.map +1 -1
  170. package/dist/views/Bonds/components/BondRows/ActiveBondRows.d.ts +1 -1
  171. package/dist/views/Bonds/components/BondRows/ActiveBondRows.js +2 -3
  172. package/dist/views/Bonds/components/BondRows/ActiveBondRows.js.map +1 -1
  173. package/dist/views/Bonds/components/BonusComponents/BonusComponent.js +1 -2
  174. package/dist/views/Bonds/components/BonusComponents/BonusComponent.js.map +1 -1
  175. package/dist/views/Bonds/components/BonusComponents/BonusTable.js +1 -2
  176. package/dist/views/Bonds/components/BonusComponents/BonusTable.js.map +1 -1
  177. package/dist/views/Bonds/components/BuyAgainRow/index.js +2 -4
  178. package/dist/views/Bonds/components/BuyAgainRow/index.js.map +1 -1
  179. package/dist/views/Bonds/components/RecommendationCards/SmallRecommendationCard.d.ts +1 -1
  180. package/dist/views/Bonds/components/RecommendationCards/SmallRecommendationCard.js.map +1 -1
  181. package/dist/views/Bonds/utils.d.ts +0 -2
  182. package/dist/views/Bonds/utils.js +2 -3
  183. package/dist/views/Bonds/utils.js.map +1 -1
  184. package/dist/views/BuyBond/BuyBondModal.d.ts +1 -1
  185. package/dist/views/BuyBond/BuyBondModal.js.map +1 -1
  186. package/dist/views/BuyBond/BuyComponent.js +16 -17
  187. package/dist/views/BuyBond/BuyComponent.js.map +1 -1
  188. package/dist/views/BuyBond/BuyComponentAptos.d.ts +1 -1
  189. package/dist/views/BuyBond/BuyComponentAptos.js +20 -33
  190. package/dist/views/BuyBond/BuyComponentAptos.js.map +1 -1
  191. package/dist/views/BuyBond/BuyComponentPreTGE.js +6 -8
  192. package/dist/views/BuyBond/BuyComponentPreTGE.js.map +1 -1
  193. package/dist/views/BuyBond/BuyComponentSolana.d.ts +1 -1
  194. package/dist/views/BuyBond/BuyComponentSolana.js +20 -27
  195. package/dist/views/BuyBond/BuyComponentSolana.js.map +1 -1
  196. package/dist/views/BuyBond/BuyComponentSui.d.ts +1 -1
  197. package/dist/views/BuyBond/BuyComponentSui.js +15 -28
  198. package/dist/views/BuyBond/BuyComponentSui.js.map +1 -1
  199. package/dist/views/BuyBond/components/NewRateModal/NewRateModal.js +2 -2
  200. package/dist/views/BuyBond/components/NewRateModal/NewRateModal.js.map +1 -1
  201. package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js +6 -9
  202. package/dist/views/BuyBond/components/PointsLeftForNextTier/PointsLeftForNextTier.js.map +1 -1
  203. package/dist/views/ProjectView/components/BondLeaderboard/components/SalesTable.d.ts +1 -1
  204. package/dist/views/ProjectView/components/BondLeaderboard/components/SalesTable.js.map +1 -1
  205. package/dist/views/ProjectView/components/BondLeaderboard/components/TopSaleCard.d.ts +1 -1
  206. package/dist/views/ProjectView/components/BondLeaderboard/components/TopSaleCard.js.map +1 -1
  207. package/dist/views/ProjectView/components/BondLeaderboard/components/TopThreeSalesCards.d.ts +1 -1
  208. package/dist/views/ProjectView/components/BondLeaderboard/components/TopThreeSalesCards.js.map +1 -1
  209. package/dist/views/ProjectView/components/BondStats/index.js +2 -4
  210. package/dist/views/ProjectView/components/BondStats/index.js.map +1 -1
  211. package/dist/views/ProjectView/components/BondStats/types.d.ts +2 -1
  212. package/dist/views/ProjectView/components/BondStats/types.js.map +1 -1
  213. package/dist/views/SingleBond/SoldOutBuyBondPlaceholder.d.ts +1 -1
  214. package/dist/views/SingleBond/SoldOutBuyBondPlaceholder.js.map +1 -1
  215. package/dist/views/YourBonds/components/UserBondRow/UserBondRowPreTGE.js +4 -5
  216. package/dist/views/YourBonds/components/UserBondRow/UserBondRowPreTGE.js.map +1 -1
  217. package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.d.ts +8 -0
  218. package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.js +43 -0
  219. package/dist/views/YourBondsModal/components/LinkShare/htmlToJpeg.js.map +1 -0
  220. package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.d.ts +8 -1
  221. package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.js +172 -15
  222. package/dist/views/YourBondsModal/components/LinkShare/templateImageShare.js.map +1 -1
  223. package/dist/views/YourBondsModal/components/LinkShare/utils.js +19 -10
  224. package/dist/views/YourBondsModal/components/LinkShare/utils.js.map +1 -1
  225. package/dist/views/YourBondsModal/components/TransferBondModal/index.js +1 -2
  226. package/dist/views/YourBondsModal/components/TransferBondModal/index.js.map +1 -1
  227. package/package.json +6 -8
  228. package/dist/components/AccordionText/index.d.ts +0 -6
  229. package/dist/components/RestrictedRegionModal/index.d.ts +0 -5
  230. package/dist/components/TabNavigation/index.d.ts +0 -8
  231. package/dist/components/uikit-sdk/Input/NumericInput.d.ts +0 -9
  232. package/dist/components/uikit-sdk/Modal/ModalFooter.d.ts +0 -4
  233. package/dist/components/uikit-sdk/Svg/Icons/Audit.d.ts +0 -4
  234. package/dist/components/uikit-sdk/Svg/Icons/Fire.d.ts +0 -4
  235. package/dist/components/uikit-sdk/Svg/Icons/FullLogo.d.ts +0 -4
  236. package/dist/components/uikit-sdk/Svg/Icons/Instagram.d.ts +0 -4
  237. package/dist/components/uikit-sdk/Svg/Icons/Language.d.ts +0 -4
  238. package/dist/components/uikit-sdk/Svg/Icons/Medium.d.ts +0 -4
  239. package/dist/components/uikit-sdk/Svg/Icons/Pool.d.ts +0 -4
  240. package/dist/components/uikit-sdk/Svg/Icons/Reddit.d.ts +0 -4
  241. package/dist/components/uikit-sdk/Svg/Icons/Telegram.d.ts +0 -4
  242. package/dist/components/uikit-sdk/Svg/Icons/Website.d.ts +0 -4
  243. package/dist/components/uikit-sdk/Svg/tokens/BSC.d.ts +0 -4
  244. package/dist/components/uikit-sdk/Svg/tokens/CELO.d.ts +0 -4
  245. package/dist/components/uikit-sdk/Svg/tokens/CRONOS.d.ts +0 -4
  246. package/dist/components/uikit-sdk/Svg/tokens/FANTOM.d.ts +0 -4
  247. package/dist/components/uikit-sdk/Svg/tokens/GNOSIS.d.ts +0 -4
  248. package/dist/components/uikit-sdk/Svg/tokens/OKX.d.ts +0 -4
  249. package/dist/components/uikit-sdk/Svg/tokens/OPTIMISM.d.ts +0 -4
  250. package/dist/components/uikit-sdk/Svg/tokens/POLYGONZK.d.ts +0 -4
  251. package/dist/config/constants/tokens.js +0 -36
  252. package/dist/config/constants/tokens.js.map +0 -1
  253. package/dist/contexts/RefreshContext.d.ts +0 -10
  254. package/dist/hooks/useRefresh.d.ts +0 -6
  255. package/dist/hooks/useTimer.d.ts +0 -2
  256. package/dist/state/bondApiStats/useUserApiStats.d.ts +0 -22
  257. package/dist/state/bonds/aptosBondsConfig.d.ts +0 -4
  258. package/dist/state/bonds/fetchUsersBonds/getBillNftData.d.ts +0 -9
  259. package/dist/state/geoFencing/useGeoFencing.d.ts +0 -5
  260. package/dist/state/zap/useSoulZapTokenQuote.d.ts +0 -3
  261. package/dist/state/zap/useTierOptimizationPreview.d.ts +0 -27
  262. package/dist/views/ZapModal/index.d.ts +0 -13
  263. package/dist/views/ZapModal/styles.d.ts +0 -2
@@ -1,4 +1,3 @@
1
- import { BigNumber } from 'bignumber.js';
2
1
  import { getBalanceNumber } from './getBalanceNumber.js';
3
2
  import { getFirstNonZeroDigits } from './roundNumber.js';
4
3
  import { getTimePeriods } from './getTimePeriods.js';
@@ -6,9 +5,15 @@ import { formatNumberSI } from './formatNumber.js';
6
5
  import { LaunchBondTiers } from '@ape.swap/apeswap-lists';
7
6
  import { TIERS_WEIGHT } from '../state/tiers/useTierPoints.js';
8
7
  import { findHighestTrueBondPrice } from './bondPriceHelpers.js';
8
+ import { toFixedString, parseUnits, mulDivRound } from './fixedPoint.js';
9
9
 
10
+ const PRECISION_18 = 10n ** 18n;
11
+ // Scale used to carry percentage ratios (tier boost, fee) into integer math alongside
12
+ // wei-scale trueBondPrice values, so the huge integer never round-trips through a float.
13
+ const RATIO_SCALE = 1000000000000n; // 1e12
14
+ const scaleRatio = (ratio) => parseUnits(ratio.toString(), 12);
10
15
  const claimable = (userBill) => {
11
- return getBalanceNumber(new BigNumber(userBill?.pendingRewards ?? '0'), userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
16
+ return getBalanceNumber(userBill?.pendingRewards ?? '0', userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
12
17
  };
13
18
  const claimableUSD = (userBill) => {
14
19
  const claimableTokens = claimable(userBill);
@@ -19,14 +24,15 @@ const earnTokenPrice = (bond) => {
19
24
  };
20
25
  // Amount of unvested (locked) tokens
21
26
  const pending = (userBill) => {
22
- return (getBalanceNumber(new BigNumber(userBill?.payout ?? 0), userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18) - claimable(userBill));
27
+ return (getBalanceNumber(userBill?.payout ?? 0, userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18) -
28
+ claimable(userBill));
23
29
  };
24
30
  const pendingUSD = (userBill) => {
25
31
  const pendingTokens = pending(userBill);
26
32
  return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0');
27
33
  };
28
34
  const claimed = (userBill) => {
29
- return getBalanceNumber(new BigNumber(userBill?.payoutClaimed ?? '0'), userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
35
+ return getBalanceNumber(userBill?.payoutClaimed ?? '0', userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18);
30
36
  };
31
37
  const claimedUSD = (userBill) => {
32
38
  const claimedTokens = claimed(userBill);
@@ -80,12 +86,20 @@ const getVestingTermsTooltipString = (bond) => {
80
86
  }
81
87
  return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`;
82
88
  };
89
+ // Applies tier-boost and fee percentage multipliers to a wei-scale (1e18) trueBondPrice,
90
+ // keeping the huge integer exact until the final getBalanceNumber() conversion.
91
+ const trueBondPriceWithFeeNumber = (trueBondPrice, tierBoostRate, feeInPayout) => {
92
+ const priceBig = BigInt(trueBondPrice ?? '0');
93
+ const tierAdjusted = mulDivRound(priceBig, scaleRatio((100 + tierBoostRate) / 100), RATIO_SCALE);
94
+ const feeAdjusted = mulDivRound(tierAdjusted, scaleRatio((100 + feeInPayout) / 100), RATIO_SCALE);
95
+ return getBalanceNumber(feeAdjusted);
96
+ };
83
97
  const discountEarnTokenPrice = (bond, useTiers) => {
84
98
  const feeInPayout = bond?.feeInPayout ?? 0;
85
99
  const tierBoostRate = bond?.tierBoostRate ?? 0;
86
100
  const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0');
87
101
  const trueBondPrice = findHighestTrueBondPrice(useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0', bond?.trueBondPrices)?.trueBondPrice;
88
- const trueBondPriceWithFee = getBalanceNumber(new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100));
102
+ const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout);
89
103
  return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3);
90
104
  };
91
105
  const discountEarnTokenPriceForUser = (bond, useTiers, userTier) => {
@@ -93,50 +107,49 @@ const discountEarnTokenPriceForUser = (bond, useTiers, userTier) => {
93
107
  const tierBoostRate = bond?.tierBoostRate ?? 0;
94
108
  const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0');
95
109
  const trueBondPrice = findHighestTrueBondPrice(useTiers && userTier ? TIERS_WEIGHT[userTier] : '0', bond?.trueBondPrices)?.trueBondPrice;
96
- const trueBondPriceWithFee = getBalanceNumber(new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100));
110
+ const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout);
97
111
  return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee);
98
112
  };
99
113
  const SAFETY_THRESHOLD = 5; // in USD
114
+ // bond?.tokensRemaining is already a human-decimal string (divided by decimals upstream);
115
+ // bond?.maxPayout is a raw wei-scale integer.
100
116
  const getSafetyAvailable = (bond, allowLowValueBonds) => {
101
- const available = new BigNumber(bond?.tokensRemaining ?? '0');
102
- const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0);
117
+ const available = Number(bond?.tokensRemaining ?? '0');
118
+ const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0);
103
119
  const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD;
104
- const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0);
120
+ const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0;
105
121
  const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100;
106
- let safeAvailable = available.times(feeInPayoutAdjuster).minus(thresholdToShow);
107
- if (safeAvailable.lt(0))
108
- safeAvailable = new BigNumber(0);
109
- if (available.isZero())
110
- return new BigNumber(0);
111
- return safeAvailable;
122
+ const safeAvailable = available * feeInPayoutAdjuster - thresholdToShow;
123
+ if (available === 0)
124
+ return 0;
125
+ return safeAvailable < 0 ? 0 : safeAvailable;
112
126
  };
113
127
  const getSafetyPurchaseLimit = (bond, allowLowValueBonds) => {
114
128
  const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD;
115
- const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0);
116
- const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0);
117
- return new BigNumber(bond?.maxPayout ?? 0)
118
- .div(new BigNumber(10).pow(bond?.earnToken?.decimals?.[bond?.chainId] ?? 18))
119
- .minus(thresholdToShow);
129
+ const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0);
130
+ const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0;
131
+ const maxPayout = getBalanceNumber(bond?.maxPayout ?? 0, bond?.earnToken?.decimals?.[bond?.chainId] ?? 18);
132
+ return maxPayout - thresholdToShow;
120
133
  };
121
134
  const getMaxBuy = (bond, allowLowValueBonds) => {
122
135
  const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds);
123
136
  const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds);
124
- return safePurchaseLimit.lt(safeAvailable) ? safePurchaseLimit : safeAvailable;
137
+ return safePurchaseLimit < safeAvailable ? safePurchaseLimit : safeAvailable;
125
138
  };
126
139
  function formatUSDNumber(input) {
127
- const number = new BigNumber(input);
128
- if (number.isNaN())
140
+ const number = Number(input);
141
+ if (Number.isNaN(number))
129
142
  return '0';
130
143
  // If the number is greater than 0 but less than 0.01
131
- if (number.gt(0) && number.lt(0.01)) {
144
+ if (number > 0 && number < 0.01) {
132
145
  return '< 0.01';
133
146
  }
134
147
  // If the number is greater than 1k, round to no decimals.
135
- if (number.gt(1000)) {
136
- return number.toNumber().toLocaleString('en-US', { maximumFractionDigits: 0 });
148
+ if (number > 1000) {
149
+ return number.toLocaleString('en-US', { maximumFractionDigits: 0 });
137
150
  }
138
151
  // Note: Between 1k and 0.01 show 2 decimals
139
- return parseFloat(number.toFixed(2)).toLocaleString('en-US');
152
+ return parseFloat(toFixedString(number, 2)).toLocaleString('en-US');
140
153
  }
141
154
  const youSpendUSD = (bond, inputValue) => {
142
155
  return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString();
@@ -145,13 +158,16 @@ const youSpendUSD = (bond, inputValue) => {
145
158
  const getPayoutAmount = (bond, inputValue, userPoints) => {
146
159
  if (!inputValue || !bond || !userPoints || !bond.trueBondPrices)
147
160
  return 0;
148
- const bigValue = new BigNumber(inputValue).times(new BigNumber(10).pow(18));
161
+ const bigValue = parseUnits(inputValue, 18);
149
162
  const fee = bond?.feeInPayout ?? 0;
150
163
  const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices);
151
- const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0');
152
- const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100));
153
- const billValue = bigValue.div(trueBondPrice.plus(trueBondPrice.times(reverseFee)));
154
- return billValue.toNumber();
164
+ const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0');
165
+ const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18);
166
+ const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18);
167
+ if (trueBondPriceWithFee === 0n)
168
+ return 0;
169
+ const billValueScaled = mulDivRound(bigValue, PRECISION_18, trueBondPriceWithFee);
170
+ return getBalanceNumber(billValueScaled, 18);
155
171
  };
156
172
  const youGetUSD = (bond, inputValue, userPoints) => {
157
173
  if (!inputValue || !bond || !userPoints || !bond.trueBondPrices)
@@ -175,35 +191,35 @@ const getBonusColor = (premiumString) => {
175
191
  * @param bond - The bond data
176
192
  * @param targetPayoutAmount - The desired payout amount in payout tokens
177
193
  * @param userPoints - User's tier points
178
- * @returns The principal token amount needed, or '0' if calculation cannot be performed
194
+ * @returns The principal token amount needed, or 0 if calculation cannot be performed
179
195
  */
180
196
  const getPrincipalAmount = (bond, targetPayoutAmount, userPoints) => {
181
197
  if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices)
182
- return new BigNumber(0);
183
- const billValue = new BigNumber(targetPayoutAmount);
198
+ return 0;
199
+ const billValue = parseUnits(targetPayoutAmount.toString(), 18);
184
200
  const fee = bond?.feeInPayout ?? 0;
185
201
  const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices);
186
- const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0');
187
- if (trueBondPrice.isZero())
188
- return new BigNumber(0);
189
- const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100));
190
- const trueBondPriceWithFee = trueBondPrice.plus(trueBondPrice.times(reverseFee));
202
+ const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0');
203
+ if (trueBondPrice === 0n)
204
+ return 0;
205
+ const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18);
206
+ const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18);
191
207
  // Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)
192
- const bigValue = billValue.times(trueBondPriceWithFee);
208
+ const bigValueScaled = mulDivRound(billValue, trueBondPriceWithFee, PRECISION_18);
193
209
  // Convert from 18 decimals back to regular amount
194
- return bigValue.div(new BigNumber(10).pow(18));
210
+ return getBalanceNumber(bigValueScaled, 18);
195
211
  };
196
212
  const getRemainingTokensString = (bond, allowLowValueBonds) => {
197
- const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds).toNumber();
213
+ const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds);
198
214
  // const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')
199
215
  const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0');
200
216
  return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`;
201
217
  };
202
218
  const remainingPercentage = (bond) => {
203
- const totalMaxPayout = new BigNumber(bond.maxTotalPayout ?? '0').div(new BigNumber(10).pow(bond.earnToken.decimals?.[bond.chainId] ?? 18));
204
- const remainingTokens = new BigNumber(bond.tokensRemaining ?? '0');
205
- return remainingTokens.div(totalMaxPayout).times(100).toNumber();
219
+ const totalMaxPayout = getBalanceNumber(bond.maxTotalPayout ?? '0', bond.earnToken.decimals?.[bond.chainId] ?? 18);
220
+ const remainingTokens = Number(bond.tokensRemaining ?? '0');
221
+ return (remainingTokens / totalMaxPayout) * 100;
206
222
  };
207
223
 
208
- export { SAFETY_THRESHOLD, claimable, claimableUSD, claimed, claimedUSD, discountEarnTokenPrice, discountEarnTokenPriceForUser, earnTokenPrice, formatUSDNumber, getBonusColor, getMaxBuy, getPayoutAmount, getPendingVestingString, getPercentageVested, getPrincipalAmount, getRawBonus, getRemainingTokensString, getSafetyAvailable, getSafetyPurchaseLimit, getTimeLeftForFullyVested, getVestingTermsString, getVestingTermsTooltipString, pending, pendingUSD, remainingPercentage, youGetUSD, youSpendUSD };
224
+ export { claimable, claimableUSD, claimed, claimedUSD, discountEarnTokenPrice, discountEarnTokenPriceForUser, earnTokenPrice, formatUSDNumber, getBonusColor, getMaxBuy, getPayoutAmount, getPendingVestingString, getPercentageVested, getPrincipalAmount, getRawBonus, getRemainingTokensString, getTimeLeftForFullyVested, getVestingTermsString, getVestingTermsTooltipString, pending, pendingUSD, remainingPercentage };
209
225
  //# sourceMappingURL=displayHelpers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"displayHelpers.js","sources":["../../src/utils/displayHelpers.ts"],"sourcesContent":["import { BigNumber } from 'bignumber.js'\nimport { UserBill } from '../types/yourbonds'\nimport { getBalanceNumber } from './getBalanceNumber'\nimport { BondsData } from '../types/bonds'\nimport { getFirstNonZeroDigits } from './roundNumber'\nimport { getTimePeriods } from './getTimePeriods'\nimport { formatNumberSI } from './formatNumber'\nimport { BillsConfig, LaunchBondTiers } from '@ape.swap/apeswap-lists'\nimport { TIERS_WEIGHT } from '../state/tiers/useTierPoints'\nimport { findHighestTrueBondPrice } from './bondPriceHelpers'\n\nexport const claimable = (userBill?: UserBill) => {\n return getBalanceNumber(\n new BigNumber(userBill?.pendingRewards ?? '0'),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimableUSD = (userBill?: UserBill) => {\n const claimableTokens = claimable(userBill)\n return claimableTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const earnTokenPrice = (bond: BondsData) => {\n return formatNumberSI(bond?.payoutTokenPrice ?? '0')\n}\n\n// Amount of unvested (locked) tokens\nexport const pending = (userBill?: UserBill) => {\n return (\n getBalanceNumber(\n new BigNumber(userBill?.payout ?? 0),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n ) - claimable(userBill)\n )\n}\n\nexport const pendingUSD = (userBill?: UserBill) => {\n const pendingTokens = pending(userBill)\n return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const claimed = (userBill?: UserBill) => {\n return getBalanceNumber(\n new BigNumber(userBill?.payoutClaimed ?? '0'),\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimedUSD = (userBill?: UserBill) => {\n const claimedTokens = claimed(userBill)\n return claimedTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getPercentageVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n if (timeLeftForFullyVested <= 0) return 100\n return ((vestingTerm - timeLeftForFullyVested) / vestingTerm) * 100\n}\n\nexport const getTimeLeftForFullyVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const purchaseTimestamp = parseInt(bond?.vestingStartTimestamp ?? '0')\n const now = Math.round(Date.now() / 1000)\n return purchaseTimestamp + vestingTerm - now\n}\n\nexport const getPendingVestingString = (bond?: UserBill) => {\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n const vestingTime = getTimePeriods(timeLeftForFullyVested, true)\n return `${vestingTime.days}d, ${vestingTime.hours}h, ${vestingTime.minutes}m`\n}\n\nexport const getVestingTermsString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff ?? 0\n if (!vestingCliff) {\n const vestingTime = getTimePeriods(vestingTerm, true)\n return `${vestingTime.days} D`\n } else if (vestingCliff) {\n // TODO: remove this hardcoded shit\n if (bond?.earnToken.symbol === 'AIX') {\n return `${getTimePeriods(vestingCliff, true).days} D`\n }\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n return `${vestingCliffString.days + vestingTime.days} D`\n }\n return '-'\n}\n\nexport const getVestingTermsTooltipString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff\n if (!vestingCliff) return undefined\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n if (vestingTerm - vestingCliff === 0) {\n return `${vestingCliffString.days}-day cliff, then instant release of all tokens.`\n }\n return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`\n}\n\nexport const discountEarnTokenPrice = (bond: BondsData, useTiers?: boolean) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = getBalanceNumber(\n new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100),\n )\n return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3)\n}\n\nexport const discountEarnTokenPriceForUser = (bond: BondsData, useTiers?: boolean, userTier?: LaunchBondTiers) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers && userTier ? TIERS_WEIGHT[userTier] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = getBalanceNumber(\n new BigNumber(trueBondPrice ?? '0').times((100 + tierBoostRate) / 100).times((100 + feeInPayout) / 100),\n )\n return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee)\n}\n\nexport const SAFETY_THRESHOLD = 5 // in USD\n\nexport const getSafetyAvailable = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const available = new BigNumber(bond?.tokensRemaining ?? '0')\n const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0)\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0)\n const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100\n let safeAvailable = available.times(feeInPayoutAdjuster).minus(thresholdToShow)\n if (safeAvailable.lt(0)) safeAvailable = new BigNumber(0)\n if (available.isZero()) return new BigNumber(0)\n return safeAvailable\n}\n\nexport const getSafetyPurchaseLimit = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const payoutTokenPrice = new BigNumber(bond?.payoutTokenPrice ?? 0)\n const thresholdToShow = payoutTokenPrice.gt(0) ? new BigNumber(threshold).div(payoutTokenPrice) : new BigNumber(0)\n return new BigNumber(bond?.maxPayout ?? 0)\n .div(new BigNumber(10).pow(bond?.earnToken?.decimals?.[bond?.chainId] ?? 18))\n .minus(thresholdToShow)\n}\n\nexport const getMaxBuy = (bond?: BondsData, allowLowValueBonds?: boolean): BigNumber => {\n const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds)\n const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds)\n\n return safePurchaseLimit.lt(safeAvailable) ? safePurchaseLimit : safeAvailable\n}\n\nexport function formatUSDNumber(input: string): string {\n const number = new BigNumber(input)\n if (number.isNaN()) return '0'\n\n // If the number is greater than 0 but less than 0.01\n if (number.gt(0) && number.lt(0.01)) {\n return '< 0.01'\n }\n // If the number is greater than 1k, round to no decimals.\n if (number.gt(1000)) {\n return number.toNumber().toLocaleString('en-US', { maximumFractionDigits: 0 })\n }\n // Note: Between 1k and 0.01 show 2 decimals\n return parseFloat(number.toFixed(2)).toLocaleString('en-US')\n}\n\nexport const youSpendUSD = (bond: BondsData, inputValue: string) => {\n return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString()\n}\n\n// receives depositAmount and returns the payoutTokens the user will receive. IT DOES SUBTRACT FEE IN PAYOUT\nexport const getPayoutAmount = (bond?: BondsData, inputValue?: string, userPoints?: string | null) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const bigValue = new BigNumber(inputValue).times(new BigNumber(10).pow(18))\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0')\n const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100))\n const billValue = bigValue.div(trueBondPrice.plus(trueBondPrice.times(reverseFee)))\n return billValue.toNumber()\n}\n\nexport const youGetUSD = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n const payoutAmount = getPayoutAmount(bond, inputValue, userPoints)\n return payoutAmount * parseFloat(bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getRawBonus = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!bond || !inputValue || !userPoints) return '0'\n const premiumUSD = youGetUSD(bond, inputValue, userPoints) - parseFloat(youSpendUSD(bond, inputValue))\n return premiumUSD.toString()\n}\n\nexport const getFeeAmount = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n const fee = bond?.feeInPayout\n if (!bond || !inputValue || !fee || !userPoints) return 0\n const billValue = new BigNumber(inputValue).times(new BigNumber(10).pow(18))\n const trueBondPrice = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const feeAmount = billValue.div(new BigNumber(trueBondPrice?.trueBondPrice ?? 0).div(fee / 100))\n return feeAmount.toNumber()\n}\n\nexport const getBonusColor = (premiumString: string): string => {\n return parseFloat(premiumString) < 0 ? 'premium-negative' : 'premium-positive'\n}\n\n/**\n * Calculates the principal token amount needed to receive a target payout amount.\n * This is the reverse of getRawPayoutAmount function (does NOT include fees).\n *\n * @param bond - The bond data\n * @param targetPayoutAmount - The desired payout amount in payout tokens\n * @param userPoints - User's tier points\n * @returns The principal token amount needed, or '0' if calculation cannot be performed\n */\nexport const getPrincipalAmount = (\n bond?: BondsData,\n targetPayoutAmount?: number | string,\n userPoints?: string | null,\n): BigNumber => {\n if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices) return new BigNumber(0)\n\n const billValue = new BigNumber(targetPayoutAmount)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = new BigNumber(trueBondPriceObject?.trueBondPrice ?? '0')\n\n if (trueBondPrice.isZero()) return new BigNumber(0)\n\n const reverseFee = new BigNumber(fee / 100 / (1 - fee / 100))\n const trueBondPriceWithFee = trueBondPrice.plus(trueBondPrice.times(reverseFee))\n\n // Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)\n const bigValue = billValue.times(trueBondPriceWithFee)\n\n // Convert from 18 decimals back to regular amount\n return bigValue.div(new BigNumber(10).pow(18))\n}\n\nexport const getRemainingTokensString = (bond: BondsData, allowLowValueBonds?: boolean) => {\n const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds).toNumber()\n // const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')\n const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0')\n\n return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`\n}\n\nexport const remainingPercentage = (bond: BondsData): number => {\n const totalMaxPayout = new BigNumber(bond.maxTotalPayout ?? '0').div(\n new BigNumber(10).pow(bond.earnToken.decimals?.[bond.chainId] ?? 18),\n )\n const remainingTokens = new BigNumber(bond.tokensRemaining ?? '0')\n\n return remainingTokens.div(totalMaxPayout).times(100).toNumber()\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"displayHelpers.js","sources":["../../src/utils/displayHelpers.ts"],"sourcesContent":["import { UserBill } from '../types/yourbonds'\nimport { getBalanceNumber } from './getBalanceNumber'\nimport { BondsData } from '../types/bonds'\nimport { getFirstNonZeroDigits } from './roundNumber'\nimport { getTimePeriods } from './getTimePeriods'\nimport { formatNumberSI } from './formatNumber'\nimport { BillsConfig, LaunchBondTiers } from '@ape.swap/apeswap-lists'\nimport { TIERS_WEIGHT } from '../state/tiers/useTierPoints'\nimport { findHighestTrueBondPrice } from './bondPriceHelpers'\nimport { mulDivRound, parseUnits, toFixedString } from './fixedPoint'\n\nconst PRECISION_18 = 10n ** 18n\n// Scale used to carry percentage ratios (tier boost, fee) into integer math alongside\n// wei-scale trueBondPrice values, so the huge integer never round-trips through a float.\nconst RATIO_SCALE = 1_000_000_000_000n // 1e12\nconst scaleRatio = (ratio: number): bigint => parseUnits(ratio.toString(), 12)\n\nexport const claimable = (userBill?: UserBill) => {\n return getBalanceNumber(\n userBill?.pendingRewards ?? '0',\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimableUSD = (userBill?: UserBill) => {\n const claimableTokens = claimable(userBill)\n return claimableTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const earnTokenPrice = (bond: BondsData) => {\n return formatNumberSI(bond?.payoutTokenPrice ?? '0')\n}\n\n// Amount of unvested (locked) tokens\nexport const pending = (userBill?: UserBill) => {\n return (\n getBalanceNumber(userBill?.payout ?? 0, userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18) -\n claimable(userBill)\n )\n}\n\nexport const pendingUSD = (userBill?: UserBill) => {\n const pendingTokens = pending(userBill)\n return pendingTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const claimed = (userBill?: UserBill) => {\n return getBalanceNumber(\n userBill?.payoutClaimed ?? '0',\n userBill?.bond?.earnToken?.decimals?.[userBill?.bond?.chainId] ?? 18,\n )\n}\n\nexport const claimedUSD = (userBill?: UserBill) => {\n const claimedTokens = claimed(userBill)\n return claimedTokens * parseFloat(userBill?.bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getPercentageVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n if (timeLeftForFullyVested <= 0) return 100\n return ((vestingTerm - timeLeftForFullyVested) / vestingTerm) * 100\n}\n\nexport const getTimeLeftForFullyVested = (bond?: UserBill) => {\n const vestingTerm = parseInt(bond?.vestingTerm ?? '0')\n const purchaseTimestamp = parseInt(bond?.vestingStartTimestamp ?? '0')\n const now = Math.round(Date.now() / 1000)\n return purchaseTimestamp + vestingTerm - now\n}\n\nexport const getPendingVestingString = (bond?: UserBill) => {\n const timeLeftForFullyVested = getTimeLeftForFullyVested(bond)\n const vestingTime = getTimePeriods(timeLeftForFullyVested, true)\n return `${vestingTime.days}d, ${vestingTime.hours}h, ${vestingTime.minutes}m`\n}\n\nexport const getVestingTermsString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff ?? 0\n if (!vestingCliff) {\n const vestingTime = getTimePeriods(vestingTerm, true)\n return `${vestingTime.days} D`\n } else if (vestingCliff) {\n // TODO: remove this hardcoded shit\n if (bond?.earnToken.symbol === 'AIX') {\n return `${getTimePeriods(vestingCliff, true).days} D`\n }\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n return `${vestingCliffString.days + vestingTime.days} D`\n }\n return '-'\n}\n\nexport const getVestingTermsTooltipString = (bond?: BondsData | BillsConfig) => {\n const vestingTerm = bond?.vestingTerm ?? 0\n const vestingCliff = bond?.vestingCliff\n if (!vestingCliff) return undefined\n const vestingTime = getTimePeriods(vestingTerm - vestingCliff, true)\n const vestingCliffString = getTimePeriods(vestingCliff, true)\n if (vestingTerm - vestingCliff === 0) {\n return `${vestingCliffString.days}-day cliff, then instant release of all tokens.`\n }\n return `${vestingCliffString.days}-day cliff + ${vestingTime.days}-day linear vesting.`\n}\n\n// Applies tier-boost and fee percentage multipliers to a wei-scale (1e18) trueBondPrice,\n// keeping the huge integer exact until the final getBalanceNumber() conversion.\nconst trueBondPriceWithFeeNumber = (\n trueBondPrice: string | undefined,\n tierBoostRate: number,\n feeInPayout: number,\n): number => {\n const priceBig = BigInt(trueBondPrice ?? '0')\n const tierAdjusted = mulDivRound(priceBig, scaleRatio((100 + tierBoostRate) / 100), RATIO_SCALE)\n const feeAdjusted = mulDivRound(tierAdjusted, scaleRatio((100 + feeInPayout) / 100), RATIO_SCALE)\n return getBalanceNumber(feeAdjusted)\n}\n\nexport const discountEarnTokenPrice = (bond: BondsData, useTiers?: boolean) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers ? TIERS_WEIGHT[LaunchBondTiers.Legend] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout)\n return formatNumberSI(principalTokenPrice * trueBondPriceWithFee, 3)\n}\n\nexport const discountEarnTokenPriceForUser = (bond: BondsData, useTiers?: boolean, userTier?: LaunchBondTiers) => {\n const feeInPayout = bond?.feeInPayout ?? 0\n const tierBoostRate = bond?.tierBoostRate ?? 0\n const principalTokenPrice = parseFloat(bond.principalTokenPrice ?? '0')\n const trueBondPrice = findHighestTrueBondPrice(\n useTiers && userTier ? TIERS_WEIGHT[userTier] : '0',\n bond?.trueBondPrices,\n )?.trueBondPrice\n const trueBondPriceWithFee = trueBondPriceWithFeeNumber(trueBondPrice, tierBoostRate, feeInPayout)\n return getFirstNonZeroDigits(principalTokenPrice * trueBondPriceWithFee)\n}\n\nconst SAFETY_THRESHOLD = 5 // in USD\n\n// bond?.tokensRemaining is already a human-decimal string (divided by decimals upstream);\n// bond?.maxPayout is a raw wei-scale integer.\nconst getSafetyAvailable = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const available = Number(bond?.tokensRemaining ?? '0')\n const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0)\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0\n const feeInPayoutAdjuster = (100 - (bond?.feeInPayout ?? 0)) / 100\n const safeAvailable = available * feeInPayoutAdjuster - thresholdToShow\n if (available === 0) return 0\n return safeAvailable < 0 ? 0 : safeAvailable\n}\n\nconst getSafetyPurchaseLimit = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const threshold = allowLowValueBonds ? 0 : SAFETY_THRESHOLD\n const payoutTokenPrice = Number(bond?.payoutTokenPrice ?? 0)\n const thresholdToShow = payoutTokenPrice > 0 ? threshold / payoutTokenPrice : 0\n const maxPayout = getBalanceNumber(bond?.maxPayout ?? 0, bond?.earnToken?.decimals?.[bond?.chainId] ?? 18)\n return maxPayout - thresholdToShow\n}\n\nexport const getMaxBuy = (bond?: BondsData, allowLowValueBonds?: boolean): number => {\n const safeAvailable = getSafetyAvailable(bond, allowLowValueBonds)\n const safePurchaseLimit = getSafetyPurchaseLimit(bond, allowLowValueBonds)\n\n return safePurchaseLimit < safeAvailable ? safePurchaseLimit : safeAvailable\n}\n\nexport function formatUSDNumber(input: string): string {\n const number = Number(input)\n if (Number.isNaN(number)) return '0'\n\n // If the number is greater than 0 but less than 0.01\n if (number > 0 && number < 0.01) {\n return '< 0.01'\n }\n // If the number is greater than 1k, round to no decimals.\n if (number > 1000) {\n return number.toLocaleString('en-US', { maximumFractionDigits: 0 })\n }\n // Note: Between 1k and 0.01 show 2 decimals\n return parseFloat(toFixedString(number, 2)).toLocaleString('en-US')\n}\n\nconst youSpendUSD = (bond: BondsData, inputValue: string) => {\n return (parseFloat(inputValue) * parseFloat(bond?.principalTokenPrice ?? '0')).toString()\n}\n\n// receives depositAmount and returns the payoutTokens the user will receive. IT DOES SUBTRACT FEE IN PAYOUT\nexport const getPayoutAmount = (bond?: BondsData, inputValue?: string, userPoints?: string | null) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const bigValue = parseUnits(inputValue, 18)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0')\n\n const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18)\n const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18)\n if (trueBondPriceWithFee === 0n) return 0\n\n const billValueScaled = mulDivRound(bigValue, PRECISION_18, trueBondPriceWithFee)\n return getBalanceNumber(billValueScaled, 18)\n}\n\nconst youGetUSD = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!inputValue || !bond || !userPoints || !bond.trueBondPrices) return 0\n const payoutAmount = getPayoutAmount(bond, inputValue, userPoints)\n return payoutAmount * parseFloat(bond?.payoutTokenPrice ?? '0')\n}\n\nexport const getRawBonus = (bond?: BondsData, inputValue?: string, userPoints?: string) => {\n if (!bond || !inputValue || !userPoints) return '0'\n const premiumUSD = youGetUSD(bond, inputValue, userPoints) - parseFloat(youSpendUSD(bond, inputValue))\n return premiumUSD.toString()\n}\n\nexport const getBonusColor = (premiumString: string): string => {\n return parseFloat(premiumString) < 0 ? 'premium-negative' : 'premium-positive'\n}\n\n/**\n * Calculates the principal token amount needed to receive a target payout amount.\n * This is the reverse of getRawPayoutAmount function (does NOT include fees).\n *\n * @param bond - The bond data\n * @param targetPayoutAmount - The desired payout amount in payout tokens\n * @param userPoints - User's tier points\n * @returns The principal token amount needed, or 0 if calculation cannot be performed\n */\nexport const getPrincipalAmount = (\n bond?: BondsData,\n targetPayoutAmount?: number | string,\n userPoints?: string | null,\n): number => {\n if (!targetPayoutAmount || !bond || !userPoints || !bond.trueBondPrices) return 0\n\n const billValue = parseUnits(targetPayoutAmount.toString(), 18)\n const fee = bond?.feeInPayout ?? 0\n const trueBondPriceObject = findHighestTrueBondPrice(userPoints, bond?.trueBondPrices)\n const trueBondPrice = BigInt(trueBondPriceObject?.trueBondPrice ?? '0')\n\n if (trueBondPrice === 0n) return 0\n\n const reverseFeeScaled = parseUnits((fee / 100 / (1 - fee / 100)).toString(), 18)\n const trueBondPriceWithFee = trueBondPrice + mulDivRound(trueBondPrice, reverseFeeScaled, PRECISION_18)\n\n // Reverse the formula: bigValue = billValue * (trueBondPrice + trueBondPrice * reverseFee)\n const bigValueScaled = mulDivRound(billValue, trueBondPriceWithFee, PRECISION_18)\n\n // Convert from 18 decimals back to regular amount\n return getBalanceNumber(bigValueScaled, 18)\n}\n\nexport const getRemainingTokensString = (bond: BondsData, allowLowValueBonds?: boolean) => {\n const remainingTokens = getSafetyAvailable(bond, allowLowValueBonds)\n // const remainingTokens = parseFloat(bond?.tokensRemaining ?? '0')\n const remainingTokensUsd = remainingTokens * parseFloat(bond.payoutTokenPrice ?? '0')\n\n return `${formatNumberSI(remainingTokens, 0)} ${bond.earnToken.symbol} ($${formatNumberSI(remainingTokensUsd, 0)})`\n}\n\nexport const remainingPercentage = (bond: BondsData): number => {\n const totalMaxPayout = getBalanceNumber(bond.maxTotalPayout ?? '0', bond.earnToken.decimals?.[bond.chainId] ?? 18)\n const remainingTokens = Number(bond.tokensRemaining ?? '0')\n\n return (remainingTokens / totalMaxPayout) * 100\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ export type Rounding = 'floor' | 'ceil' | 'trunc';
2
+ export type DecimalRounding = Rounding | 'halfUp';
3
+ /**
4
+ * Parses a human decimal string/number into a raw integer scaled by 10^decimals.
5
+ * `rounding` controls what happens when the input has more fractional digits than
6
+ * `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass
7
+ * 'floor'/'ceil' where overspending or underspending the user's typed amount matters
8
+ * (e.g. converting a typed amount to atomic units for a transaction).
9
+ */
10
+ export declare const parseUnits: (value: string | number | undefined | null, decimals: number, rounding?: DecimalRounding) => bigint;
11
+ /** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */
12
+ export declare const formatUnits: (value: bigint | string | number | undefined | null, decimals: number) => string;
13
+ /** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */
14
+ export declare const mulDivRound: (value: bigint, numerator: bigint, denominator: bigint, rounding?: DecimalRounding) => bigint;
15
+ /**
16
+ * Rounds a human-scale decimal value to `dp` decimal places, returned as a string.
17
+ * Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt
18
+ * based, so it doesn't inherit float rounding artifacts.
19
+ */
20
+ export declare const toFixedString: (value: string | number, dp: number, rounding?: DecimalRounding) => string;
21
+ /**
22
+ * Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.
23
+ * Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics
24
+ * (does not strip trailing zeros, and never switches to exponential notation — callers that
25
+ * want trimmed output should trim the result themselves, matching prior call sites that did
26
+ * `.toFixed().replace(/\.?0+$/, '')` after `.sd()`).
27
+ */
28
+ export declare const toSignificantDigitsString: (value: string | number, sigDigits: number) => string;
@@ -0,0 +1,239 @@
1
+ // Fixed-point / decimal-string math built on native BigInt.
2
+ //
3
+ // Two distinct jobs, kept separate:
4
+ // - parseUnits/formatUnits/mulDivRound operate on raw on-chain integer amounts
5
+ // (wei-style, scaled by 10^decimals) — exact BigInt arithmetic.
6
+ // - toFixedString/toSignificantDigitsString operate on already-human-scale
7
+ // decimal numbers (prices, percentages) for display formatting/rounding.
8
+ // BigInt has no notion of decimals, so these round via string/BigInt digit
9
+ // manipulation instead of float scaling, to avoid classic float rounding
10
+ // artifacts (e.g. naive `Math.round(x * 100) / 100`).
11
+ const DIGITS_RE = /^\d*\.?\d*$/;
12
+ const hasNonZeroDigit = (digits) => /[1-9]/.test(digits);
13
+ const shouldRoundUp = (discarded, rounding, negative) => {
14
+ if (rounding === 'trunc')
15
+ return false;
16
+ if (rounding === 'floor')
17
+ return negative && hasNonZeroDigit(discarded);
18
+ if (rounding === 'ceil')
19
+ return !negative && hasNonZeroDigit(discarded);
20
+ // halfUp (round half away from zero): only the first discarded digit matters.
21
+ const firstDiscarded = discarded.charCodeAt(0) - 48;
22
+ return firstDiscarded >= 5;
23
+ };
24
+ /**
25
+ * Parses a human decimal string/number into a raw integer scaled by 10^decimals.
26
+ * `rounding` controls what happens when the input has more fractional digits than
27
+ * `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass
28
+ * 'floor'/'ceil' where overspending or underspending the user's typed amount matters
29
+ * (e.g. converting a typed amount to atomic units for a transaction).
30
+ */
31
+ const parseUnits = (value, decimals, rounding = 'halfUp') => {
32
+ if (value === undefined || value === null || value === '')
33
+ return 0n;
34
+ const raw = typeof value === 'number' ? value.toString() : value.trim();
35
+ if (!raw)
36
+ return 0n;
37
+ let negative = false;
38
+ let str = raw;
39
+ if (str.startsWith('-')) {
40
+ negative = true;
41
+ str = str.slice(1);
42
+ }
43
+ else if (str.startsWith('+')) {
44
+ str = str.slice(1);
45
+ }
46
+ if (!DIGITS_RE.test(str) || str === '' || str === '.')
47
+ return 0n;
48
+ const [intPartRaw, fracPartRaw = ''] = str.split('.');
49
+ const intPart = intPartRaw || '0';
50
+ let combined;
51
+ if (fracPartRaw.length > decimals) {
52
+ const keep = fracPartRaw.slice(0, decimals);
53
+ const discarded = fracPartRaw.slice(decimals);
54
+ combined = BigInt(intPart + keep || '0');
55
+ if (shouldRoundUp(discarded, rounding, negative))
56
+ combined += 1n;
57
+ }
58
+ else {
59
+ const fracPart = fracPartRaw.padEnd(decimals, '0');
60
+ combined = BigInt(intPart + fracPart || '0');
61
+ }
62
+ return negative && combined !== 0n ? -combined : combined;
63
+ };
64
+ /** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */
65
+ const formatUnits = (value, decimals) => {
66
+ let big;
67
+ try {
68
+ if (typeof value === 'bigint')
69
+ big = value;
70
+ else if (value === undefined || value === null || value === '')
71
+ big = 0n;
72
+ else if (typeof value === 'number')
73
+ big = BigInt(Math.trunc(value));
74
+ else
75
+ big = BigInt(value.trim());
76
+ }
77
+ catch {
78
+ big = 0n;
79
+ }
80
+ const negative = big < 0n;
81
+ const abs = negative ? -big : big;
82
+ const base = 10n ** BigInt(decimals);
83
+ const intPart = abs / base;
84
+ const fracPart = abs % base;
85
+ let fracStr = decimals > 0 ? fracPart.toString().padStart(decimals, '0') : '';
86
+ fracStr = fracStr.replace(/0+$/, '');
87
+ const result = fracStr.length > 0 ? `${intPart}.${fracStr}` : `${intPart}`;
88
+ return negative && big !== 0n ? `-${result}` : result;
89
+ };
90
+ /** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */
91
+ const mulDivRound = (value, numerator, denominator, rounding = 'trunc') => {
92
+ if (denominator === 0n)
93
+ throw new Error('mulDivRound: division by zero');
94
+ const product = value * numerator;
95
+ const quotient = product / denominator;
96
+ const remainder = product % denominator;
97
+ if (remainder === 0n || rounding === 'trunc')
98
+ return quotient;
99
+ // Sign of the true (unrounded) mathematical quotient.
100
+ const isNegative = product < 0n !== denominator < 0n;
101
+ if (rounding === 'floor')
102
+ return isNegative ? quotient - 1n : quotient;
103
+ if (rounding === 'ceil')
104
+ return isNegative ? quotient : quotient + 1n;
105
+ // halfUp (round half away from zero)
106
+ const absRemainder = remainder < 0n ? -remainder : remainder;
107
+ const absDenominator = denominator < 0n ? -denominator : denominator;
108
+ const roundsUp = absRemainder * 2n >= absDenominator;
109
+ if (!roundsUp)
110
+ return quotient;
111
+ return isNegative ? quotient - 1n : quotient + 1n;
112
+ };
113
+ // Expands JS exponential notation ("4.56e-8") into a plain decimal string, via pure
114
+ // string manipulation (shifting the decimal point) — never re-derives digits from the
115
+ // underlying binary float, so no float-representation noise is introduced.
116
+ const expandExponential = (str) => {
117
+ const match = str.match(/^(-?)(\d+)(?:\.(\d+))?e([+-]\d+)$/i);
118
+ if (!match)
119
+ return str;
120
+ const [, sign, intDigits, fracDigits = '', expStr] = match;
121
+ const exp = parseInt(expStr, 10);
122
+ const digits = intDigits + fracDigits;
123
+ const pointPos = intDigits.length + exp;
124
+ let result;
125
+ if (pointPos <= 0) {
126
+ result = `0.${'0'.repeat(-pointPos)}${digits}`;
127
+ }
128
+ else if (pointPos >= digits.length) {
129
+ result = digits + '0'.repeat(pointPos - digits.length);
130
+ }
131
+ else {
132
+ result = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`;
133
+ }
134
+ return sign + result;
135
+ };
136
+ const toPlainDecimalString = (value) => {
137
+ if (typeof value === 'string')
138
+ return value.trim() || '0';
139
+ if (!Number.isFinite(value))
140
+ return '0';
141
+ if (value === 0)
142
+ return '0';
143
+ // .toString() gives the shortest decimal that round-trips to this float (what a user
144
+ // typing "1.005" would expect), as opposed to .toFixed(n) which re-derives the true
145
+ // (noisy) binary expansion.
146
+ const str = value.toString();
147
+ return /e/i.test(str) ? expandExponential(str) : str;
148
+ };
149
+ const splitSigned = (value) => {
150
+ const str = toPlainDecimalString(value);
151
+ const negative = str.startsWith('-');
152
+ const unsigned = negative ? str.slice(1) : str;
153
+ const [intPartRaw, fracPartRaw = ''] = unsigned.split('.');
154
+ return { negative, intPart: intPartRaw || '0', fracPart: fracPartRaw };
155
+ };
156
+ /**
157
+ * Rounds the unsigned "intPart.fracPart" digit string to `dp` decimal places.
158
+ * `dp` may be negative to round within the integer part (e.g. dp=-3 rounds to the nearest 1000).
159
+ */
160
+ const roundDigits = (intPart, fracPart, dp, roundUp) => {
161
+ if (dp >= 0) {
162
+ if (fracPart.length <= dp) {
163
+ const paddedFrac = fracPart.padEnd(dp, '0');
164
+ return dp > 0 ? `${intPart}.${paddedFrac}` : intPart;
165
+ }
166
+ const keep = fracPart.slice(0, dp);
167
+ let combined = BigInt(intPart + keep || '0');
168
+ if (roundUp)
169
+ combined += 1n;
170
+ const combinedStr = combined.toString().padStart(dp + 1, '0');
171
+ const newInt = combinedStr.slice(0, combinedStr.length - dp) || '0';
172
+ const newFrac = dp > 0 ? combinedStr.slice(combinedStr.length - dp) : '';
173
+ return dp > 0 ? `${newInt}.${newFrac}` : newInt;
174
+ }
175
+ // dp < 0: round within the integer part, discarding the fractional part entirely.
176
+ const shift = -dp;
177
+ if (intPart.length <= shift) {
178
+ const combined = roundUp ? 10n ** BigInt(shift) : 0n;
179
+ return combined.toString();
180
+ }
181
+ const keepLen = intPart.length - shift;
182
+ const keep = intPart.slice(0, keepLen);
183
+ let combined = BigInt(keep || '0');
184
+ if (roundUp)
185
+ combined += 1n;
186
+ return combined.toString() + '0'.repeat(shift);
187
+ };
188
+ /**
189
+ * Rounds a human-scale decimal value to `dp` decimal places, returned as a string.
190
+ * Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt
191
+ * based, so it doesn't inherit float rounding artifacts.
192
+ */
193
+ const toFixedString = (value, dp, rounding = 'halfUp') => {
194
+ const { negative, intPart, fracPart } = splitSigned(value);
195
+ const discarded = dp >= 0 ? fracPart.slice(dp) : intPart.slice(Math.max(intPart.length + dp, 0)) + fracPart;
196
+ const roundUp = shouldRoundUp(discarded, rounding, negative);
197
+ const result = roundDigits(intPart, fracPart, dp, roundUp);
198
+ const isZero = !hasNonZeroDigit(result);
199
+ return negative && !isZero ? `-${result}` : result;
200
+ };
201
+ const significantExponent = (intPart, fracPart) => {
202
+ const intDigits = intPart.replace(/^0+/, '');
203
+ if (intDigits.length > 0)
204
+ return intDigits.length - 1;
205
+ const leadingZeros = fracPart.match(/^0*/)?.[0].length ?? 0;
206
+ if (leadingZeros >= fracPart.length)
207
+ return 0; // value is zero
208
+ return -(leadingZeros + 1);
209
+ };
210
+ /**
211
+ * Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.
212
+ * Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics
213
+ * (does not strip trailing zeros, and never switches to exponential notation — callers that
214
+ * want trimmed output should trim the result themselves, matching prior call sites that did
215
+ * `.toFixed().replace(/\.?0+$/, '')` after `.sd()`).
216
+ */
217
+ const toSignificantDigitsString = (value, sigDigits) => {
218
+ const { negative, intPart, fracPart } = splitSigned(value);
219
+ if (!hasNonZeroDigit(intPart) && !hasNonZeroDigit(fracPart))
220
+ return '0';
221
+ const signedStr = `${negative ? '-' : ''}${intPart}.${fracPart}`;
222
+ let dp = sigDigits - 1 - significantExponent(intPart, fracPart);
223
+ // Rounding can carry into an extra digit (e.g. 9.999 -> 10.0 at what was meant to be 3 sig
224
+ // figs), which yields one more significant digit than requested; detect it and re-round
225
+ // one decimal place tighter. Bounded loop: each iteration can only shift the exponent up by
226
+ // one, so this converges immediately in all but pathological all-nines inputs.
227
+ for (let i = 0; i < 4; i++) {
228
+ const rounded = toFixedString(signedStr, dp, 'halfUp');
229
+ const { intPart: rInt, fracPart: rFrac } = splitSigned(rounded);
230
+ const expectedExponent = sigDigits - 1 - dp;
231
+ if (significantExponent(rInt, rFrac) <= expectedExponent)
232
+ return rounded;
233
+ dp -= 1;
234
+ }
235
+ return toFixedString(signedStr, dp, 'halfUp');
236
+ };
237
+
238
+ export { formatUnits, mulDivRound, parseUnits, toFixedString, toSignificantDigitsString };
239
+ //# sourceMappingURL=fixedPoint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fixedPoint.js","sources":["../../src/utils/fixedPoint.ts"],"sourcesContent":["// Fixed-point / decimal-string math built on native BigInt.\n//\n// Two distinct jobs, kept separate:\n// - parseUnits/formatUnits/mulDivRound operate on raw on-chain integer amounts\n// (wei-style, scaled by 10^decimals) — exact BigInt arithmetic.\n// - toFixedString/toSignificantDigitsString operate on already-human-scale\n// decimal numbers (prices, percentages) for display formatting/rounding.\n// BigInt has no notion of decimals, so these round via string/BigInt digit\n// manipulation instead of float scaling, to avoid classic float rounding\n// artifacts (e.g. naive `Math.round(x * 100) / 100`).\n\nexport type Rounding = 'floor' | 'ceil' | 'trunc'\nexport type DecimalRounding = Rounding | 'halfUp'\n\nconst DIGITS_RE = /^\\d*\\.?\\d*$/\n\nconst hasNonZeroDigit = (digits: string): boolean => /[1-9]/.test(digits)\n\nconst shouldRoundUp = (discarded: string, rounding: DecimalRounding, negative: boolean): boolean => {\n if (rounding === 'trunc') return false\n if (rounding === 'floor') return negative && hasNonZeroDigit(discarded)\n if (rounding === 'ceil') return !negative && hasNonZeroDigit(discarded)\n // halfUp (round half away from zero): only the first discarded digit matters.\n const firstDiscarded = discarded.charCodeAt(0) - 48\n return firstDiscarded >= 5\n}\n\n/**\n * Parses a human decimal string/number into a raw integer scaled by 10^decimals.\n * `rounding` controls what happens when the input has more fractional digits than\n * `decimals` — default 'halfUp' matches the original BigNumber-based behavior; pass\n * 'floor'/'ceil' where overspending or underspending the user's typed amount matters\n * (e.g. converting a typed amount to atomic units for a transaction).\n */\nexport const parseUnits = (\n value: string | number | undefined | null,\n decimals: number,\n rounding: DecimalRounding = 'halfUp',\n): bigint => {\n if (value === undefined || value === null || value === '') return 0n\n const raw = typeof value === 'number' ? value.toString() : value.trim()\n if (!raw) return 0n\n\n let negative = false\n let str = raw\n if (str.startsWith('-')) {\n negative = true\n str = str.slice(1)\n } else if (str.startsWith('+')) {\n str = str.slice(1)\n }\n\n if (!DIGITS_RE.test(str) || str === '' || str === '.') return 0n\n\n const [intPartRaw, fracPartRaw = ''] = str.split('.')\n const intPart = intPartRaw || '0'\n\n let combined: bigint\n if (fracPartRaw.length > decimals) {\n const keep = fracPartRaw.slice(0, decimals)\n const discarded = fracPartRaw.slice(decimals)\n combined = BigInt(intPart + keep || '0')\n if (shouldRoundUp(discarded, rounding, negative)) combined += 1n\n } else {\n const fracPart = fracPartRaw.padEnd(decimals, '0')\n combined = BigInt(intPart + fracPart || '0')\n }\n\n return negative && combined !== 0n ? -combined : combined\n}\n\n/** Formats a raw integer (scaled by 10^decimals) into a plain human decimal string, full precision. */\nexport const formatUnits = (value: bigint | string | number | undefined | null, decimals: number): string => {\n let big: bigint\n try {\n if (typeof value === 'bigint') big = value\n else if (value === undefined || value === null || value === '') big = 0n\n else if (typeof value === 'number') big = BigInt(Math.trunc(value))\n else big = BigInt(value.trim())\n } catch {\n big = 0n\n }\n\n const negative = big < 0n\n const abs = negative ? -big : big\n const base = 10n ** BigInt(decimals)\n const intPart = abs / base\n const fracPart = abs % base\n\n let fracStr = decimals > 0 ? fracPart.toString().padStart(decimals, '0') : ''\n fracStr = fracStr.replace(/0+$/, '')\n\n const result = fracStr.length > 0 ? `${intPart}.${fracStr}` : `${intPart}`\n return negative && big !== 0n ? `-${result}` : result\n}\n\n/** value * numerator / denominator with explicit rounding (BigInt division truncates toward zero). */\nexport const mulDivRound = (\n value: bigint,\n numerator: bigint,\n denominator: bigint,\n rounding: DecimalRounding = 'trunc',\n): bigint => {\n if (denominator === 0n) throw new Error('mulDivRound: division by zero')\n\n const product = value * numerator\n const quotient = product / denominator\n const remainder = product % denominator\n\n if (remainder === 0n || rounding === 'trunc') return quotient\n\n // Sign of the true (unrounded) mathematical quotient.\n const isNegative = product < 0n !== denominator < 0n\n\n if (rounding === 'floor') return isNegative ? quotient - 1n : quotient\n if (rounding === 'ceil') return isNegative ? quotient : quotient + 1n\n\n // halfUp (round half away from zero)\n const absRemainder = remainder < 0n ? -remainder : remainder\n const absDenominator = denominator < 0n ? -denominator : denominator\n const roundsUp = absRemainder * 2n >= absDenominator\n if (!roundsUp) return quotient\n return isNegative ? quotient - 1n : quotient + 1n\n}\n\n// Expands JS exponential notation (\"4.56e-8\") into a plain decimal string, via pure\n// string manipulation (shifting the decimal point) — never re-derives digits from the\n// underlying binary float, so no float-representation noise is introduced.\nconst expandExponential = (str: string): string => {\n const match = str.match(/^(-?)(\\d+)(?:\\.(\\d+))?e([+-]\\d+)$/i)\n if (!match) return str\n const [, sign, intDigits, fracDigits = '', expStr] = match\n const exp = parseInt(expStr, 10)\n const digits = intDigits + fracDigits\n const pointPos = intDigits.length + exp\n\n let result: string\n if (pointPos <= 0) {\n result = `0.${'0'.repeat(-pointPos)}${digits}`\n } else if (pointPos >= digits.length) {\n result = digits + '0'.repeat(pointPos - digits.length)\n } else {\n result = `${digits.slice(0, pointPos)}.${digits.slice(pointPos)}`\n }\n return sign + result\n}\n\nconst toPlainDecimalString = (value: string | number): string => {\n if (typeof value === 'string') return value.trim() || '0'\n if (!Number.isFinite(value)) return '0'\n if (value === 0) return '0'\n // .toString() gives the shortest decimal that round-trips to this float (what a user\n // typing \"1.005\" would expect), as opposed to .toFixed(n) which re-derives the true\n // (noisy) binary expansion.\n const str = value.toString()\n return /e/i.test(str) ? expandExponential(str) : str\n}\n\nconst splitSigned = (value: string | number): { negative: boolean; intPart: string; fracPart: string } => {\n const str = toPlainDecimalString(value)\n const negative = str.startsWith('-')\n const unsigned = negative ? str.slice(1) : str\n const [intPartRaw, fracPartRaw = ''] = unsigned.split('.')\n return { negative, intPart: intPartRaw || '0', fracPart: fracPartRaw }\n}\n\n/**\n * Rounds the unsigned \"intPart.fracPart\" digit string to `dp` decimal places.\n * `dp` may be negative to round within the integer part (e.g. dp=-3 rounds to the nearest 1000).\n */\nconst roundDigits = (intPart: string, fracPart: string, dp: number, roundUp: boolean): string => {\n if (dp >= 0) {\n if (fracPart.length <= dp) {\n const paddedFrac = fracPart.padEnd(dp, '0')\n return dp > 0 ? `${intPart}.${paddedFrac}` : intPart\n }\n const keep = fracPart.slice(0, dp)\n let combined = BigInt(intPart + keep || '0')\n if (roundUp) combined += 1n\n const combinedStr = combined.toString().padStart(dp + 1, '0')\n const newInt = combinedStr.slice(0, combinedStr.length - dp) || '0'\n const newFrac = dp > 0 ? combinedStr.slice(combinedStr.length - dp) : ''\n return dp > 0 ? `${newInt}.${newFrac}` : newInt\n }\n\n // dp < 0: round within the integer part, discarding the fractional part entirely.\n const shift = -dp\n if (intPart.length <= shift) {\n const combined = roundUp ? 10n ** BigInt(shift) : 0n\n return combined.toString()\n }\n const keepLen = intPart.length - shift\n const keep = intPart.slice(0, keepLen)\n let combined = BigInt(keep || '0')\n if (roundUp) combined += 1n\n return combined.toString() + '0'.repeat(shift)\n}\n\n/**\n * Rounds a human-scale decimal value to `dp` decimal places, returned as a string.\n * Replaces BigNumber `.toFixed(dp, mode)` / `.decimalPlaces(dp, mode)` — string/BigInt\n * based, so it doesn't inherit float rounding artifacts.\n */\nexport const toFixedString = (value: string | number, dp: number, rounding: DecimalRounding = 'halfUp'): string => {\n const { negative, intPart, fracPart } = splitSigned(value)\n const discarded = dp >= 0 ? fracPart.slice(dp) : intPart.slice(Math.max(intPart.length + dp, 0)) + fracPart\n const roundUp = shouldRoundUp(discarded, rounding, negative)\n const result = roundDigits(intPart, fracPart, dp, roundUp)\n const isZero = !hasNonZeroDigit(result)\n return negative && !isZero ? `-${result}` : result\n}\n\nconst significantExponent = (intPart: string, fracPart: string): number => {\n const intDigits = intPart.replace(/^0+/, '')\n if (intDigits.length > 0) return intDigits.length - 1\n const leadingZeros = fracPart.match(/^0*/)?.[0].length ?? 0\n if (leadingZeros >= fracPart.length) return 0 // value is zero\n return -(leadingZeros + 1)\n}\n\n/**\n * Rounds a human-scale decimal value to `sigDigits` significant digits, returned as a string.\n * Replaces BigNumber `.sd(digits)`. Mirrors native `Number.prototype.toPrecision` semantics\n * (does not strip trailing zeros, and never switches to exponential notation — callers that\n * want trimmed output should trim the result themselves, matching prior call sites that did\n * `.toFixed().replace(/\\.?0+$/, '')` after `.sd()`).\n */\nexport const toSignificantDigitsString = (value: string | number, sigDigits: number): string => {\n const { negative, intPart, fracPart } = splitSigned(value)\n if (!hasNonZeroDigit(intPart) && !hasNonZeroDigit(fracPart)) return '0'\n\n const signedStr = `${negative ? '-' : ''}${intPart}.${fracPart}`\n let dp = sigDigits - 1 - significantExponent(intPart, fracPart)\n\n // Rounding can carry into an extra digit (e.g. 9.999 -> 10.0 at what was meant to be 3 sig\n // figs), which yields one more significant digit than requested; detect it and re-round\n // one decimal place tighter. Bounded loop: each iteration can only shift the exponent up by\n // one, so this converges immediately in all but pathological all-nines inputs.\n for (let i = 0; i < 4; i++) {\n const rounded = toFixedString(signedStr, dp, 'halfUp')\n const { intPart: rInt, fracPart: rFrac } = splitSigned(rounded)\n const expectedExponent = sigDigits - 1 - dp\n if (significantExponent(rInt, rFrac) <= expectedExponent) return rounded\n dp -= 1\n }\n return toFixedString(signedStr, dp, 'halfUp')\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA,MAAM,SAAS,GAAG,aAAa;AAE/B,MAAM,eAAe,GAAG,CAAC,MAAc,KAAc,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC;AAEzE,MAAM,aAAa,GAAG,CAAC,SAAiB,EAAE,QAAyB,EAAE,QAAiB,KAAa;IACjG,IAAI,QAAQ,KAAK,OAAO;AAAE,QAAA,OAAO,KAAK;IACtC,IAAI,QAAQ,KAAK,OAAO;AAAE,QAAA,OAAO,QAAQ,IAAI,eAAe,CAAC,SAAS,CAAC;IACvE,IAAI,QAAQ,KAAK,MAAM;AAAE,QAAA,OAAO,CAAC,QAAQ,IAAI,eAAe,CAAC,SAAS,CAAC;;IAEvE,MAAM,cAAc,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,EAAE;IACnD,OAAO,cAAc,IAAI,CAAC;AAC5B,CAAC;AAED;;;;;;AAMG;AACI,MAAM,UAAU,GAAG,CACxB,KAAyC,EACzC,QAAgB,EAChB,QAAA,GAA4B,QAAQ,KAC1B;IACV,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;AAAE,QAAA,OAAO,EAAE;IACpE,MAAM,GAAG,GAAG,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC,IAAI,EAAE;AACvE,IAAA,IAAI,CAAC,GAAG;AAAE,QAAA,OAAO,EAAE;IAEnB,IAAI,QAAQ,GAAG,KAAK;IACpB,IAAI,GAAG,GAAG,GAAG;AACb,IAAA,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;QACvB,QAAQ,GAAG,IAAI;AACf,QAAA,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACpB;AAAO,SAAA,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE;AAC9B,QAAA,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;IACpB;AAEA,IAAA,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,KAAK,GAAG;AAAE,QAAA,OAAO,EAAE;AAEhE,IAAA,MAAM,CAAC,UAAU,EAAE,WAAW,GAAG,EAAE,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC;AACrD,IAAA,MAAM,OAAO,GAAG,UAAU,IAAI,GAAG;AAEjC,IAAA,IAAI,QAAgB;AACpB,IAAA,IAAI,WAAW,CAAC,MAAM,GAAG,QAAQ,EAAE;QACjC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC;QAC3C,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC;QAC7C,QAAQ,GAAG,MAAM,CAAC,OAAO,GAAG,IAAI,IAAI,GAAG,CAAC;AACxC,QAAA,IAAI,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;YAAE,QAAQ,IAAI,EAAE;IAClE;SAAO;QACL,MAAM,QAAQ,GAAG,WAAW,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC;QAClD,QAAQ,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ,IAAI,GAAG,CAAC;IAC9C;AAEA,IAAA,OAAO,QAAQ,IAAI,QAAQ,KAAK,EAAE,GAAG,CAAC,QAAQ,GAAG,QAAQ;AAC3D;AAEA;MACa,WAAW,GAAG,CAAC,KAAkD,EAAE,QAAgB,KAAY;AAC1G,IAAA,IAAI,GAAW;AACf,IAAA,IAAI;QACF,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,GAAG,GAAG,KAAK;aACrC,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE;YAAE,GAAG,GAAG,EAAE;aACnE,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;;YAC9D,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IACjC;AAAE,IAAA,MAAM;QACN,GAAG,GAAG,EAAE;IACV;AAEA,IAAA,MAAM,QAAQ,GAAG,GAAG,GAAG,EAAE;AACzB,IAAA,MAAM,GAAG,GAAG,QAAQ,GAAG,CAAC,GAAG,GAAG,GAAG;IACjC,MAAM,IAAI,GAAG,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC;AACpC,IAAA,MAAM,OAAO,GAAG,GAAG,GAAG,IAAI;AAC1B,IAAA,MAAM,QAAQ,GAAG,GAAG,GAAG,IAAI;IAE3B,IAAI,OAAO,GAAG,QAAQ,GAAG,CAAC,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,GAAG,EAAE;IAC7E,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;IAEpC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,GAAG,GAAG,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,GAAG,CAAA,EAAG,OAAO,CAAA,CAAE;AAC1E,IAAA,OAAO,QAAQ,IAAI,GAAG,KAAK,EAAE,GAAG,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,GAAG,MAAM;AACvD;AAEA;AACO,MAAM,WAAW,GAAG,CACzB,KAAa,EACb,SAAiB,EACjB,WAAmB,EACnB,QAAA,GAA4B,OAAO,KACzB;IACV,IAAI,WAAW,KAAK,EAAE;AAAE,QAAA,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC;AAExE,IAAA,MAAM,OAAO,GAAG,KAAK,GAAG,SAAS;AACjC,IAAA,MAAM,QAAQ,GAAG,OAAO,GAAG,WAAW;AACtC,IAAA,MAAM,SAAS,GAAG,OAAO,GAAG,WAAW;AAEvC,IAAA,IAAI,SAAS,KAAK,EAAE,IAAI,QAAQ,KAAK,OAAO;AAAE,QAAA,OAAO,QAAQ;;IAG7D,MAAM,UAAU,GAAG,OAAO,GAAG,EAAE,KAAK,WAAW,GAAG,EAAE;IAEpD,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,UAAU,GAAG,QAAQ,GAAG,EAAE,GAAG,QAAQ;IACtE,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,EAAE;;AAGrE,IAAA,MAAM,YAAY,GAAG,SAAS,GAAG,EAAE,GAAG,CAAC,SAAS,GAAG,SAAS;AAC5D,IAAA,MAAM,cAAc,GAAG,WAAW,GAAG,EAAE,GAAG,CAAC,WAAW,GAAG,WAAW;AACpE,IAAA,MAAM,QAAQ,GAAG,YAAY,GAAG,EAAE,IAAI,cAAc;AACpD,IAAA,IAAI,CAAC,QAAQ;AAAE,QAAA,OAAO,QAAQ;AAC9B,IAAA,OAAO,UAAU,GAAG,QAAQ,GAAG,EAAE,GAAG,QAAQ,GAAG,EAAE;AACnD;AAEA;AACA;AACA;AACA,MAAM,iBAAiB,GAAG,CAAC,GAAW,KAAY;IAChD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,oCAAoC,CAAC;AAC7D,IAAA,IAAI,CAAC,KAAK;AAAE,QAAA,OAAO,GAAG;AACtB,IAAA,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,UAAU,GAAG,EAAE,EAAE,MAAM,CAAC,GAAG,KAAK;IAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,MAAM,EAAE,EAAE,CAAC;AAChC,IAAA,MAAM,MAAM,GAAG,SAAS,GAAG,UAAU;AACrC,IAAA,MAAM,QAAQ,GAAG,SAAS,CAAC,MAAM,GAAG,GAAG;AAEvC,IAAA,IAAI,MAAc;AAClB,IAAA,IAAI,QAAQ,IAAI,CAAC,EAAE;AACjB,QAAA,MAAM,GAAG,CAAA,EAAA,EAAK,GAAG,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAA,EAAG,MAAM,CAAA,CAAE;IAChD;AAAO,SAAA,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,EAAE;AACpC,QAAA,MAAM,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;IACxD;SAAO;AACL,QAAA,MAAM,GAAG,CAAA,EAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA,CAAA,EAAI,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE;IACnE;IACA,OAAO,IAAI,GAAG,MAAM;AACtB,CAAC;AAED,MAAM,oBAAoB,GAAG,CAAC,KAAsB,KAAY;IAC9D,IAAI,OAAO,KAAK,KAAK,QAAQ;AAAE,QAAA,OAAO,KAAK,CAAC,IAAI,EAAE,IAAI,GAAG;AACzD,IAAA,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,GAAG;IACvC,IAAI,KAAK,KAAK,CAAC;AAAE,QAAA,OAAO,GAAG;;;;AAI3B,IAAA,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,EAAE;AAC5B,IAAA,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,GAAG,GAAG;AACtD,CAAC;AAED,MAAM,WAAW,GAAG,CAAC,KAAsB,KAA8D;AACvG,IAAA,MAAM,GAAG,GAAG,oBAAoB,CAAC,KAAK,CAAC;IACvC,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;AACpC,IAAA,MAAM,QAAQ,GAAG,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG;AAC9C,IAAA,MAAM,CAAC,UAAU,EAAE,WAAW,GAAG,EAAE,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;AAC1D,IAAA,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,IAAI,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE;AACxE,CAAC;AAED;;;AAGG;AACH,MAAM,WAAW,GAAG,CAAC,OAAe,EAAE,QAAgB,EAAE,EAAU,EAAE,OAAgB,KAAY;AAC9F,IAAA,IAAI,EAAE,IAAI,CAAC,EAAE;AACX,QAAA,IAAI,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE;YACzB,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,CAAC;AAC3C,YAAA,OAAO,EAAE,GAAG,CAAC,GAAG,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,UAAU,CAAA,CAAE,GAAG,OAAO;QACtD;QACA,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAClC,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,GAAG,IAAI,IAAI,GAAG,CAAC;AAC5C,QAAA,IAAI,OAAO;YAAE,QAAQ,IAAI,EAAE;AAC3B,QAAA,MAAM,WAAW,GAAG,QAAQ,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,GAAG,CAAC;AAC7D,QAAA,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,GAAG;QACnE,MAAM,OAAO,GAAG,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,GAAG,EAAE;AACxE,QAAA,OAAO,EAAE,GAAG,CAAC,GAAG,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,GAAG,MAAM;IACjD;;AAGA,IAAA,MAAM,KAAK,GAAG,CAAC,EAAE;AACjB,IAAA,IAAI,OAAO,CAAC,MAAM,IAAI,KAAK,EAAE;AAC3B,QAAA,MAAM,QAAQ,GAAG,OAAO,GAAG,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;AACpD,QAAA,OAAO,QAAQ,CAAC,QAAQ,EAAE;IAC5B;AACA,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,KAAK;IACtC,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC;IACtC,IAAI,QAAQ,GAAG,MAAM,CAAC,IAAI,IAAI,GAAG,CAAC;AAClC,IAAA,IAAI,OAAO;QAAE,QAAQ,IAAI,EAAE;IAC3B,OAAO,QAAQ,CAAC,QAAQ,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC;AAChD,CAAC;AAED;;;;AAIG;AACI,MAAM,aAAa,GAAG,CAAC,KAAsB,EAAE,EAAU,EAAE,QAAA,GAA4B,QAAQ,KAAY;AAChH,IAAA,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC;AAC1D,IAAA,MAAM,SAAS,GAAG,EAAE,IAAI,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,QAAQ;IAC3G,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,EAAE,QAAQ,EAAE,QAAQ,CAAC;AAC5D,IAAA,MAAM,MAAM,GAAG,WAAW,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,CAAC;AAC1D,IAAA,MAAM,MAAM,GAAG,CAAC,eAAe,CAAC,MAAM,CAAC;AACvC,IAAA,OAAO,QAAQ,IAAI,CAAC,MAAM,GAAG,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,GAAG,MAAM;AACpD;AAEA,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAE,QAAgB,KAAY;IACxE,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC;AAC5C,IAAA,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC;AAAE,QAAA,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC;AACrD,IAAA,MAAM,YAAY,GAAG,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC;AAC3D,IAAA,IAAI,YAAY,IAAI,QAAQ,CAAC,MAAM;QAAE,OAAO,CAAC,CAAA;AAC7C,IAAA,OAAO,EAAE,YAAY,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;AAMG;MACU,yBAAyB,GAAG,CAAC,KAAsB,EAAE,SAAiB,KAAY;AAC7F,IAAA,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,GAAG,WAAW,CAAC,KAAK,CAAC;IAC1D,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,GAAG;AAEvE,IAAA,MAAM,SAAS,GAAG,CAAA,EAAG,QAAQ,GAAG,GAAG,GAAG,EAAE,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,QAAQ,EAAE;AAChE,IAAA,IAAI,EAAE,GAAG,SAAS,GAAG,CAAC,GAAG,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC;;;;;AAM/D,IAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;QAC1B,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,QAAQ,CAAC;AACtD,QAAA,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC;AAC/D,QAAA,MAAM,gBAAgB,GAAG,SAAS,GAAG,CAAC,GAAG,EAAE;AAC3C,QAAA,IAAI,mBAAmB,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,gBAAgB;AAAE,YAAA,OAAO,OAAO;QACxE,EAAE,IAAI,CAAC;IACT;IACA,OAAO,aAAa,CAAC,SAAS,EAAE,EAAE,EAAE,QAAQ,CAAC;AAC/C;;;;"}