add stats page

This commit is contained in:
Tyler Shipe 2021-04-07 19:06:02 -04:00
parent 4eccd0c74a
commit 10e4fff211
7 changed files with 526 additions and 21 deletions

View File

@ -6,9 +6,14 @@ const Wrapper = styled.div`
border: 1px solid #584f81;
`
export default function FloatingElement({ css = undefined, children }) {
export default function FloatingElement({ shrink = false, children }) {
return (
<Wrapper css={xw`m-1 p-4 h-full bg-mango-dark rounded-lg overflow-auto`}>
<Wrapper
css={[
xw`m-1 p-4 bg-mango-dark rounded-lg overflow-auto`,
shrink ? null : xw`h-full`,
]}
>
{children}
</Wrapper>
)

View File

@ -63,7 +63,7 @@ const TopBar = () => {
<div css={xw`-mr-2 flex items-center sm:hidden`}>
<button
type="button"
css={xw`inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-mango-yellow`}
css={xw`inline-flex items-center justify-center p-2 rounded-md text-mango-med-light hover:bg-mango-dark-light focus:outline-none focus:ring-2 focus:ring-inset focus:ring-mango-yellow`}
aria-controls="mobile-menu"
aria-expanded="false"
onClick={() => setShowMenu((showMenu) => !showMenu)}

View File

@ -3,7 +3,6 @@ import { Input, Radio, Switch, Select } from 'antd'
import xw from 'xwind'
import styled from '@emotion/styled'
import useMarket from '../hooks/useMarket'
import useWallet from '../hooks/useWallet'
import useIpAddress from '../hooks/useIpAddress'
import useConnection from '../hooks/useConnection'
import { PublicKey } from '@solana/web3.js'

View File

@ -22,17 +22,17 @@ const layouts = {
{ i: 'tradeForm', x: 4, y: 0, w: 1, h: 17 },
{ i: 'marginInfo', x: 4, y: 1, w: 1, h: 13 },
{ i: 'marketTrades', x: 3, y: 1, w: 1, h: 13 },
{ i: 'userInfo', x: 0, y: 2, w: 4, h: 20 },
{ i: 'userInfo', x: 0, y: 2, w: 4, h: 17 },
{ i: 'balanceInfo', x: 4, y: 2, w: 1, h: 13 },
],
lg: [
{ i: 'tvChart', x: 0, y: 0, w: 2, h: 30 },
{ i: 'balanceInfo', x: 2, y: 0, w: 1, h: 15 },
{ i: 'marginInfo', x: 2, y: 1, w: 1, h: 15 },
{ i: 'tvChart', x: 0, y: 0, w: 2, h: 24 },
{ i: 'balanceInfo', x: 2, y: 0, w: 1, h: 12 },
{ i: 'marginInfo', x: 2, y: 1, w: 1, h: 12 },
{ i: 'orderbook', x: 0, y: 2, w: 1, h: 17 },
{ i: 'tradeForm', x: 1, y: 2, w: 1, h: 17 },
{ i: 'marketTrades', x: 2, y: 2, w: 1, h: 17 },
{ i: 'userInfo', x: 0, y: 3, w: 3, h: 20 },
{ i: 'userInfo', x: 0, y: 3, w: 3, h: 17 },
],
}

View File

@ -42,8 +42,10 @@
"next": "latest",
"next-plugin-antd-less": "^0.3.0",
"react": "^17.0.1",
"react-cool-dimensions": "^2.0.1",
"react-dom": "^17.0.1",
"react-grid-layout": "^1.2.4",
"recharts": "^2.0.9",
"zustand": "^3.3.3"
},
"devDependencies": {

View File

@ -1,13 +1,320 @@
import xw from 'xwind'
import React, { useEffect, useState } from 'react'
import styled from '@emotion/styled'
import { Col, Row, Button, Divider, Select } from 'antd'
import { LineChart, Line, ReferenceLine, XAxis, YAxis, Tooltip } from 'recharts'
import useDimensions from 'react-cool-dimensions'
import { IDS, MangoClient } from '@blockworks-foundation/mango-client'
import { PublicKey, Connection } from '@solana/web3.js'
import { DEFAULT_MANGO_GROUP } from '../utils/mango'
import FloatingElement from '../components/FloatingElement'
import useConnection from '../hooks/useConnection'
import TopBar from '../components/TopBar'
const Index = () => (
<div css={xw`bg-mango-dark text-white`}>
<TopBar />
<div css={xw`grid justify-center items-center h-screen space-y-20`}>
<div>Stats page here</div>
</div>
</div>
)
const DECIMALS = {
BTC: 4,
ETH: 3,
USDT: 2,
USDC: 2,
WUSDT: 2,
}
export default Index
const icons = {
BTC: '/assets/icons/btc.svg',
ETH: '/assets/icons/eth.svg',
USDT: '/assets/icons/usdt.svg',
USDC: '/assets/icons/usdc.svg',
WUSDT: '/assets/icons/usdt.svg',
}
const Wrapper = styled.div`
height: 100%;
display: flex;
flex-direction: column;
padding: 16px 16px;
.borderNone .ant-select-selector {
border: none !important;
}
`
const SizeTitle = styled(Row)`
padding: 20px 0 14px;
color: #525a6a;
`
const ChartLayover = styled.div`
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 100%;
color: #525a6a;
`
const ChartWrapper = styled.div`
height: 100%;
width: 100%;
`
const useMangoStats = () => {
const [stats, setStats] = useState([
{
symbol: '',
depositInterest: 0,
borrowInterest: 0,
totalDeposits: 0,
totalBorrows: 0,
utilization: '0',
},
])
const [latestStats, setLatestStats] = useState<any[]>([])
const { cluster } = useConnection()
useEffect(() => {
const fetchStats = async () => {
const response = await fetch(
`https://mango-stats.herokuapp.com?mangoGroup=BTC_ETH_USDT`
)
const stats = await response.json()
setStats(stats)
}
fetchStats()
}, [])
useEffect(() => {
const getLatestStats = async () => {
const client = new MangoClient()
const connection = new Connection(
IDS.cluster_urls[cluster],
'singleGossip'
)
const assets = IDS[cluster].mango_groups?.[DEFAULT_MANGO_GROUP]?.symbols
const mangoGroupId =
IDS[cluster].mango_groups?.[DEFAULT_MANGO_GROUP]?.mango_group_pk
if (!mangoGroupId) return
const mangoGroupPk = new PublicKey(mangoGroupId)
const mangoGroup = await client.getMangoGroup(connection, mangoGroupPk)
const latestStats = Object.keys(assets).map((symbol, index) => {
const totalDeposits = mangoGroup.getUiTotalDeposit(index)
const totalBorrows = mangoGroup.getUiTotalBorrow(index)
return {
time: new Date(),
symbol,
totalDeposits,
totalBorrows,
depositInterest: mangoGroup.getDepositRate(index) * 100,
borrowInterest: mangoGroup.getBorrowRate(index) * 100,
utilization: totalDeposits > 0.0 ? totalBorrows / totalDeposits : 0.0,
}
})
setLatestStats(latestStats)
}
getLatestStats()
}, [cluster])
return { latestStats, stats }
}
const StatsChart = ({ title, xAxis, yAxis, data, labelFormat }) => {
const [mouseData, setMouseData] = useState<string | null>(null)
// @ts-ignore
const { observe, width, height } = useDimensions()
const handleMouseMove = (coords) => {
if (coords.activePayload) {
setMouseData(coords.activePayload[0].payload)
}
}
const handleMouseLeave = () => {
setMouseData(null)
}
return (
<ChartWrapper ref={observe}>
<ChartLayover>
<div>
<strong>
{title}
{mouseData ? `: ${labelFormat(mouseData[yAxis])}` : null}
</strong>
</div>
{mouseData ? (
<div>
<strong>
Date
{mouseData
? `: ${new Date(mouseData[xAxis]).toDateString()}`
: null}
</strong>
</div>
) : null}
</ChartLayover>
{width > 0 ? (
<LineChart
width={width}
height={height}
margin={{ top: 50, right: 50 }}
data={data}
onMouseMove={handleMouseMove}
onMouseLeave={handleMouseLeave}
>
<Tooltip
cursor={{
stroke: '#f7f7f7',
strokeWidth: 1.5,
strokeOpacity: 0.3,
strokeDasharray: '6 5',
}}
content={<></>}
/>
<Line
isAnimationActive={false}
type="linear"
dot={false}
dataKey={yAxis}
stroke="#f2c94c"
strokeWidth={2}
/>
{mouseData ? (
<ReferenceLine
y={mouseData[yAxis]}
strokeDasharray="6 5"
strokeWidth={1.5}
strokeOpacity={0.3}
/>
) : null}
<XAxis dataKey={xAxis} hide />
<YAxis dataKey={yAxis} hide />
</LineChart>
) : null}
</ChartWrapper>
)
}
export default function StatsPage() {
const [selectedAsset, setSelectedAsset] = useState<string>('BTC')
const { latestStats, stats } = useMangoStats()
const selectedStatsData = stats.filter(
(stat) => stat.symbol === selectedAsset
)
return (
<Wrapper>
<TopBar />
<Row justify="center">
<Col lg={24} xl={18} xxl={12}>
<FloatingElement shrink>
<React.Fragment>
<Divider>
<span css={xw`text-white`}>Mango Stats</span>
</Divider>
<SizeTitle>
<Col span={1}></Col>
<Col span={3}>Asset</Col>
<Col span={4}>Total Deposits</Col>
<Col span={4}>Total Borrows</Col>
<Col span={4}>Deposit Interest</Col>
<Col span={4}>Borrow Interest</Col>
<Col span={4}>Utilization</Col>
</SizeTitle>
{latestStats.map((stat) => (
<div key={stat.symbol}>
<Divider />
<Row>
<Col span={1}>
<img src={icons[stat.symbol]} alt={icons[stat.symbol]} />
</Col>
<Col span={3}>
<Button
type="link"
onClick={() => setSelectedAsset(stat.symbol)}
>
<div style={{ width: '100%' }}>{stat.symbol}</div>
</Button>
</Col>
<Col span={4}>
{stat.totalDeposits.toFixed(DECIMALS[stat.symbol])}
</Col>
<Col span={4}>
{stat.totalBorrows.toFixed(DECIMALS[stat.symbol])}
</Col>
<Col span={4}>{stat.depositInterest.toFixed(2)}%</Col>
<Col span={4}>{stat.borrowInterest.toFixed(2)}%</Col>
<Col span={4}>
{(parseFloat(stat.utilization) * 100).toFixed(2)}%
</Col>
</Row>
</div>
))}
</React.Fragment>
</FloatingElement>
{selectedAsset ? (
<FloatingElement shrink>
<Divider>
<span css={xw`text-white`}>Historical</span>
<Select
style={{ margin: '0px 8px', fontSize: 16 }}
value={selectedAsset}
onChange={(val) => setSelectedAsset(val)}
>
{latestStats.map(({ symbol }) => (
<Select.Option key={symbol} value={symbol}>
{symbol}
</Select.Option>
))}
</Select>
<span css={xw`text-white`}>Stats</span>
</Divider>
<Row>
<Col span={12} style={{ height: '300px' }}>
<StatsChart
title="Total Deposits"
xAxis="time"
yAxis="totalDeposits"
data={selectedStatsData}
labelFormat={(x) => x.toFixed(DECIMALS[selectedAsset])}
/>
</Col>
<Col span={12} style={{ height: '300px' }}>
<StatsChart
title="Total Borrows"
xAxis="time"
yAxis="totalBorrows"
data={selectedStatsData}
labelFormat={(x) => x.toFixed(DECIMALS[selectedAsset])}
/>
</Col>
</Row>
<Row style={{ margin: '50px 0' }}>
<Col span={12} style={{ height: '300px' }}>
<StatsChart
title="Deposit Interest"
xAxis="time"
yAxis="depositInterest"
data={selectedStatsData}
labelFormat={(x) => `${(x * 100).toFixed(5)}%`}
/>
</Col>
<Col span={12} style={{ height: '300px' }}>
<StatsChart
title="Borrow Interest"
xAxis="time"
yAxis="borrowInterest"
data={selectedStatsData}
labelFormat={(x) => `${(x * 100).toFixed(5)}%`}
/>
</Col>
</Row>
</FloatingElement>
) : null}
</Col>
</Row>
</Wrapper>
)
}

198
yarn.lock
View File

@ -930,7 +930,7 @@
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.1", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.10.5", "@babel/runtime@^7.11.1", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.3.1", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4":
version "7.13.10"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
@ -1700,6 +1700,30 @@
dependencies:
"@types/node" "*"
"@types/d3-path@^1":
version "1.0.9"
resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-1.0.9.tgz#73526b150d14cd96e701597cbf346cfd1fd4a58c"
integrity sha512-NaIeSIBiFgSC6IGUBjZWcscUJEq7vpVu7KthHN8eieTV9d9MqkSOZLH4chq1PmcKy06PNe3axLeKmRIyxJ+PZQ==
"@types/d3-scale@^3.0.0":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.2.2.tgz#5e28d0b1c599328aaec6094219f10a2570be6d74"
integrity sha512-qpQe8G02tzUwt9sdWX1h8A/W0Q1+N48wMnYXVOkrzeLUkCfvzJYV9Ee3aORCS4dN4ONRLFmMvaXdziQ29XGLjQ==
dependencies:
"@types/d3-time" "*"
"@types/d3-shape@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-2.0.0.tgz#61aa065726f3c2641aedc59c3603475ab11aeb2f"
integrity sha512-NLzD02m5PiD1KLEDjLN+MtqEcFYn4ZL9+Rqc9ZwARK1cpKZXd91zBETbe6wpBB6Ia0D0VZbpmbW3+BsGPGnCpA==
dependencies:
"@types/d3-path" "^1"
"@types/d3-time@*":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.0.0.tgz#831dd093db91f16b83ba980e194bb8e4bcef44d6"
integrity sha512-Abz8bTzy8UWDeYs9pCa3D37i29EWDjNTjemdk0ei1ApYVNqulYlGUKip/jLOpogkPSsPz/GvZCYiC7MFlEk0iQ==
"@types/express-serve-static-core@^4.17.9":
version "4.17.19"
resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.19.tgz#00acfc1632e729acac4f1530e9e16f6dd1508a1d"
@ -1807,6 +1831,11 @@
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/resize-observer-browser@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@types/resize-observer-browser/-/resize-observer-browser-0.1.5.tgz#36d897708172ac2380cd486da7a3daf1161c1e23"
integrity sha512-8k/67Z95Goa6Lznuykxkfhq9YU3l1Qe6LNZmwde1u7802a3x8v44oq0j91DICclxatTr0rNnhXx7+VTIetSrSQ==
"@types/scheduler@*":
version "0.16.1"
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
@ -3270,6 +3299,65 @@ csstype@^3.0.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b"
integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==
d3-array@^2.3.0:
version "2.12.1"
resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81"
integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==
dependencies:
internmap "^1.0.0"
"d3-color@1 - 2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e"
integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ==
"d3-format@1 - 2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-2.0.0.tgz#a10bcc0f986c372b729ba447382413aabf5b0767"
integrity sha512-Ab3S6XuE/Q+flY96HXT0jOXcM4EAClYFnRGY5zsjRGNy6qCYrQsMffs7cV5Q9xejb35zxW5hf/guKw34kvIKsA==
"d3-interpolate@1.2.0 - 2", d3-interpolate@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163"
integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ==
dependencies:
d3-color "1 - 2"
"d3-path@1 - 2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-2.0.0.tgz#55d86ac131a0548adae241eebfb56b4582dd09d8"
integrity sha512-ZwZQxKhBnv9yHaiWd6ZU4x5BtCQ7pXszEV9CU6kRgwIQVQGLMv1oiL4M+MK/n79sYzsj+gcgpPQSctJUsLN7fA==
d3-scale@^3.2.3:
version "3.2.4"
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.2.4.tgz#13d758d7cf4e4f1fc40196a63597d01f3ed81765"
integrity sha512-PG6gtpbPCFqKbvdBEswQcJcTzHC8VEd/XzezF5e68KlkT4/ggELw/nR1tv863jY6ufKTvDlzCMZvhe06codbbA==
dependencies:
d3-array "^2.3.0"
d3-format "1 - 2"
d3-interpolate "1.2.0 - 2"
d3-time "1 - 2"
d3-time-format "2 - 3"
d3-shape@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-2.1.0.tgz#3b6a82ccafbc45de55b57fcf956c584ded3b666f"
integrity sha512-PnjUqfM2PpskbSLTJvAzp2Wv4CZsnAgTfcVRTwW03QR3MkXF8Uo7B1y/lWkAsmbKwuecto++4NlsYcvYpXpTHA==
dependencies:
d3-path "1 - 2"
"d3-time-format@2 - 3":
version "3.0.0"
resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6"
integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==
dependencies:
d3-time "1 - 2"
"d3-time@1 - 2":
version "2.0.0"
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.0.0.tgz#ad7c127d17c67bd57a4c61f3eaecb81108b1e0ab"
integrity sha512-2mvhstTFcMvwStWd9Tj3e6CEqtOivtD8AUiHT8ido/xmzrI9ijrUUihZ6nHuf/vsScRBonagOdj0Vv+SEL5G3Q==
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@ -3322,6 +3410,11 @@ decamelize@^1.2.0:
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
decimal.js-light@^2.4.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934"
integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==
decimal.js@^10.2.1:
version "10.2.1"
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3"
@ -3470,6 +3563,13 @@ dom-align@^1.7.0:
resolved "https://registry.yarnpkg.com/dom-align/-/dom-align-1.12.0.tgz#56fb7156df0b91099830364d2d48f88963f5a29c"
integrity sha512-YkoezQuhp3SLFGdOlr5xkqZ640iXrnHAwVYcDg8ZKRUtO7mSzSC2BA5V0VuyAwPSJA4CLIc6EDDJh4bEsD2+zA==
dom-helpers@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8"
integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==
dependencies:
"@babel/runtime" "^7.1.2"
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@ -3847,7 +3947,7 @@ etag@1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^4.0.4, eventemitter3@^4.0.7:
eventemitter3@^4.0.1, eventemitter3@^4.0.4, eventemitter3@^4.0.7:
version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
@ -3982,6 +4082,11 @@ fast-deep-equal@^3.1.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-equals@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-2.0.1.tgz#ffc1b0746aceaa855bed91e6aa0e70968645ed7c"
integrity sha512-jIHAbyu5Txdi299DitHXr4wuvw7ajz8S4xVgShJmQOUD6TovsKzvMoHoq9G8+dO6xeKWrwH3DURT+ZDKnwjSsA==
fast-glob@^3.1.1:
version "3.2.5"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
@ -4602,6 +4707,11 @@ internal-slot@^1.0.3:
has "^1.0.3"
side-channel "^1.0.4"
internmap@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
is-accessor-descriptor@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
@ -5771,6 +5881,11 @@ lodash.sortby@^4.7.0:
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash.throttle@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4"
integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ=
lodash.toarray@^4.4.0:
version "4.4.0"
resolved "https://registry.yarnpkg.com/lodash.toarray/-/lodash.toarray-4.4.0.tgz#24c4bfcd6b2fba38bfd0594db1179d8e9b656561"
@ -6804,7 +6919,7 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.5"
prop-types@15.7.2, prop-types@15.x, prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.7.2:
prop-types@15.7.2, prop-types@15.x, prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2:
version "15.7.2"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
@ -6898,6 +7013,13 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
raf@^3.4.0:
version "3.4.1"
resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA==
dependencies:
performance-now "^2.1.0"
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0"
resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a"
@ -7266,6 +7388,11 @@ rc-virtual-list@^3.0.1, rc-virtual-list@^3.2.0:
rc-resize-observer "^1.0.0"
rc-util "^5.0.7"
react-cool-dimensions@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/react-cool-dimensions/-/react-cool-dimensions-2.0.1.tgz#afa96d1131d4dbe60384a738dc494955543a4b98"
integrity sha512-9T1j2cCGBjZtVQs5R7YVvDmr7W52wgjdRISpO5voCCRjOum/ZZNBFShquGwySswWH8XxCSR28HcRGza1J+70cw==
react-dom@^17.0.1:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23"
@ -7294,6 +7421,11 @@ react-grid-layout@^1.2.4:
react-draggable "^4.0.0"
react-resizable "^1.10.0"
react-is@16.10.2:
version "16.10.2"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.10.2.tgz#984120fd4d16800e9a738208ab1fba422d23b5ab"
integrity sha512-INBT1QEgtcCCgvccr5/86CfD71fw9EPmDxgiJX4I2Ddr6ZsV6iFXsuby+qWJPtmNuMY0zByTsG4468P7nHuNWA==
react-is@16.13.1, react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@ -7304,6 +7436,11 @@ react-is@^17.0.1:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
react-lifecycles-compat@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
react-refresh@0.8.3:
version "0.8.3"
resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.8.3.tgz#721d4657672d400c5e3c75d063c4a85fb2d5d68f"
@ -7317,6 +7454,35 @@ react-resizable@^1.10.0:
prop-types "15.x"
react-draggable "^4.0.3"
react-resize-detector@^6.6.3:
version "6.6.4"
resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-6.6.4.tgz#704a6c985d666d119d833e908cc555b186cfea0c"
integrity sha512-sAAh8TmOp59MFs2HR7D1VGbAq+zL+2klQhFbkXOH5Gy/EBEyHGiWXWMStoB+axSYr/Xw54owg6QRGSFj3z0dew==
dependencies:
"@types/resize-observer-browser" "^0.1.5"
lodash.debounce "^4.0.8"
lodash.throttle "^4.1.1"
resize-observer-polyfill "^1.5.1"
react-smooth@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.0.tgz#561647b33e498b2e25f449b3c6689b2e9111bf91"
integrity sha512-wK4dBBR6P21otowgMT9toZk+GngMplGS1O5gk+2WSiHEXIrQgDvhR5IIlT74Vtu//qpTcipkgo21dD7a7AUNxw==
dependencies:
fast-equals "^2.0.0"
raf "^3.4.0"
react-transition-group "2.9.0"
react-transition-group@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d"
integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==
dependencies:
dom-helpers "^3.4.0"
loose-envify "^1.4.0"
prop-types "^15.6.2"
react-lifecycles-compat "^3.0.4"
react@^17.0.1:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
@ -7382,6 +7548,32 @@ readdirp@~3.5.0:
dependencies:
picomatch "^2.2.1"
recharts-scale@^0.4.4:
version "0.4.5"
resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9"
integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==
dependencies:
decimal.js-light "^2.4.1"
recharts@^2.0.9:
version "2.0.9"
resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.0.9.tgz#048068eb01383291104548388712026948275f70"
integrity sha512-JNsXE80PuF3hugUCE7JqDOMSvu5xQLxtjOaqFKKZI2pCJ1PVJzhwDv4TWk0nO4AvADbeWzYEHbg8C5Hcrh42UA==
dependencies:
"@types/d3-scale" "^3.0.0"
"@types/d3-shape" "^2.0.0"
classnames "^2.2.5"
d3-interpolate "^2.0.1"
d3-scale "^3.2.3"
d3-shape "^2.0.0"
eventemitter3 "^4.0.1"
lodash "^4.17.19"
react-is "16.10.2"
react-resize-detector "^6.6.3"
react-smooth "^2.0.0"
recharts-scale "^0.4.4"
reduce-css-calc "^2.1.8"
reduce-css-calc@^2.1.8:
version "2.1.8"
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03"