diff --git a/package.json b/package.json index 1e58be6..e79abf2 100644 --- a/package.json +++ b/package.json @@ -64,8 +64,11 @@ "@real-wagmi/sdk": "1.4.0", "@real-wagmi/v3-sdk": "1.4.0", "@storybook/addon-themes": "^7.5.3", + "@tanstack/react-query": "^5.59.16", "@types/styled-system": "^5.1.15", "@types/uuid": "^9.0.7", + "echarts": "^5.5.1", + "echarts-for-react": "^3.0.2", "framer-motion": "10.11.2", "graphql": "^16.8.1", "graphql-request": "^6.1.0", diff --git a/src/components/Charts/Density/components/CustomBar.tsx b/src/components/Charts/Density/components/CustomBar.tsx deleted file mode 100644 index d706815..0000000 --- a/src/components/Charts/Density/components/CustomBar.tsx +++ /dev/null @@ -1,9 +0,0 @@ -function CustomBar({ x, y, width, height, fill }: { x: number; y: number; width: number; height: number; fill: string }) { - return ( - - - - ); -}; - -export default CustomBar; \ No newline at end of file diff --git a/src/components/Charts/Density/components/CustomTooltip/index.tsx b/src/components/Charts/Density/components/CustomTooltip/index.tsx deleted file mode 100644 index 3a14efe..0000000 --- a/src/components/Charts/Density/components/CustomTooltip/index.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import { RowBetween } from '../../../../Box'; -import { Container, Title, TooltipWrapper } from './styles'; -import { CustomToolTipProps } from './types' -import { formatNumber } from './utils/formatNumber'; - -function CustomToolTip({ chartProps, token0, token1, currentPrice }: CustomToolTipProps) { - const price0 = chartProps?.payload?.[0]?.payload.price0; - const price1 = chartProps?.payload?.[0]?.payload.price1; - const tvlToken0 = chartProps?.payload?.[0]?.payload.tvlToken0; - const tvlToken1 = chartProps?.payload?.[0]?.payload.tvlToken1; - - return ( - - - Tick stats - -
{token0?.symbol} Price:
-
- {price0 - ? Number(price0).toLocaleString(undefined, { - minimumSignificantDigits: 1, - }) - : ''}{' '} - {token1?.symbol} -
-
- -
{token1?.symbol} Price:
-
- {price1 - ? Number(price1).toLocaleString(undefined, { - minimumSignificantDigits: 1, - }) - : ''}{' '} - {token0?.symbol} -
-
- {currentPrice && price0 && currentPrice > price1 ? ( - -
{token0?.symbol} Locked:
-
- {tvlToken0 ? formatNumber(tvlToken0) : ''} {token0?.symbol} -
-
- ) : ( - -
{token1?.symbol} Locked:
-
- {tvlToken1 ? formatNumber(tvlToken1) : ''} {token1?.symbol} -
-
- )} -
-
- ); -} - -export default CustomToolTip; diff --git a/src/components/Charts/Density/components/CustomTooltip/styles.ts b/src/components/Charts/Density/components/CustomTooltip/styles.ts deleted file mode 100644 index 0d61d1a..0000000 --- a/src/components/Charts/Density/components/CustomTooltip/styles.ts +++ /dev/null @@ -1,25 +0,0 @@ -import styled from 'styled-components'; - -export const Title = styled.div` - margin-bottom: 2px; - color: #ffffff; - font-size: 14px; - font-weight: 300; - letter-spacing: 0.25px; -`; - -export const TooltipWrapper = styled.div` - padding: 8px 10px; - width: 320px; - font-size: 12px; - border-radius: 8px; - background: #1d2128; - border: 1px solid rgba(97, 105, 113, 0.2); -`; - -export const Container = styled.div` - display: grid; - grid-auto-rows: auto; - grid-row-gap: 8px; - flex-grow: 1; -`; diff --git a/src/components/Charts/Density/components/CustomTooltip/types.ts b/src/components/Charts/Density/components/CustomTooltip/types.ts deleted file mode 100644 index ca2688a..0000000 --- a/src/components/Charts/Density/components/CustomTooltip/types.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Token } from '@real-wagmi/sdk'; - -export interface CustomToolTipProps { - chartProps: any; - token0: Token; - token1: Token; - currentPrice: number | undefined; -} diff --git a/src/components/Charts/Density/components/CustomTooltip/utils/formatNumber.ts b/src/components/Charts/Density/components/CustomTooltip/utils/formatNumber.ts deleted file mode 100644 index 2dc9283..0000000 --- a/src/components/Charts/Density/components/CustomTooltip/utils/formatNumber.ts +++ /dev/null @@ -1,23 +0,0 @@ -type FormatReturnType = undefined | string; - -const genMinAmount = (decimals: number) => { - if (decimals < 1) return 1; - return Number(`0.${''.padEnd(decimals - 1, '0')}1`); -}; - -export const formatNumber = (num?: number, decimals = 4): FormatReturnType => { - let value: FormatReturnType; - const minAmount = genMinAmount(decimals); - if (typeof num === 'number' && !Number.isNaN(num)) { - if (!!num && num < minAmount) { - value = `<${minAmount}`; - } else { - value = new Intl.NumberFormat('en-US', { - style: 'decimal', - maximumFractionDigits: decimals, - minimumFractionDigits: 0, - }).format(num); - } - } - return value; -}; diff --git a/src/components/Charts/Density/constants.ts b/src/components/Charts/Density/constants.ts index e67f07c..7766d7f 100644 --- a/src/components/Charts/Density/constants.ts +++ b/src/components/Charts/Density/constants.ts @@ -1,5 +1,4 @@ export const DEFAULT_SURROUNDING_TICKS = 300; export const INITIAL_TICKS_TO_FETCH = 200; -export const ZOOM_INTERVAL = 20; export const maxUint128 = 2n ** 128n - 1n; diff --git a/src/components/Charts/Density/hooks/useChartResize.ts b/src/components/Charts/Density/hooks/useChartResize.ts new file mode 100644 index 0000000..3d75446 --- /dev/null +++ b/src/components/Charts/Density/hooks/useChartResize.ts @@ -0,0 +1,28 @@ +import ReactEcharts from 'echarts-for-react'; +import { MutableRefObject, useCallback, useEffect, useMemo, useRef } from 'react'; + +interface IUseChartResize { + chartRef: MutableRefObject; +} + +export const useChartResize = (): IUseChartResize => { + const chartRef = useRef(null); + + const resizeHandler = useCallback((): void => { + const echartsInstance = chartRef.current?.getEchartsInstance(); + echartsInstance && echartsInstance.resize(); + }, [chartRef]); + + useEffect(() => { + window.addEventListener('resize', resizeHandler); + return (): void => { + window.removeEventListener('resize', resizeHandler); + }; + }, [resizeHandler]); + + return useMemo((): IUseChartResize => { + return { + chartRef, + }; + }, []); +}; diff --git a/src/components/Charts/Density/index.tsx b/src/components/Charts/Density/index.tsx index 7eff4fc..822cd5b 100644 --- a/src/components/Charts/Density/index.tsx +++ b/src/components/Charts/Density/index.tsx @@ -1,81 +1,143 @@ -import { ReactElement, memo, useCallback, useMemo, useState } from "react"; -import { Wrapper, LoaderWrapper, ControlsWrapper, ActionButton } from "./styles"; -import { IProps } from "./types"; -import { fetchTicksSurroundingPrice } from "./helpers/fetchTicksSurroundingPrice"; -import { INITIAL_TICKS_TO_FETCH, ZOOM_INTERVAL } from "./constants"; -import useSwr from 'swr'; +import { memo, useMemo } from 'react'; +import { Wrapper, LoaderWrapper } from './styles'; +import { IProps } from './types'; +import { fetchTicksSurroundingPrice } from './helpers/fetchTicksSurroundingPrice'; +import { INITIAL_TICKS_TO_FETCH } from './constants'; import { formatData } from './helpers/formatData'; +import ReactEcharts from 'echarts-for-react'; +import { useTheme } from 'styled-components'; +import { useChartResize } from './hooks/useChartResize'; +import { getRenderTooltip } from './utils'; +import { useQuery } from '@tanstack/react-query'; import { LoadingSpinner } from '../../Loaders'; -import { ZoomIn, ZoomOut } from 'react-feather'; -import { Bar, BarChart, Cell, ResponsiveContainer, Tooltip, XAxis } from 'recharts'; -import CustomBar from './components/CustomBar'; -import CustomToolTip from "./components/CustomTooltip"; -import { useTheme } from "styled-components"; - -interface ZoomStateProps { - left: number; - right: number; - refAreaLeft: string | number; - refAreaRight: string | number; -} - -const initialState = { - left: 0, - right: INITIAL_TICKS_TO_FETCH * 2 + 1, - refAreaLeft: '', - refAreaRight: '', -}; function DensityChart({ address, client }: IProps) { const theme = useTheme(); const { colors } = theme; - const [ticksToFetch, setTicksToFetch] = useState(INITIAL_TICKS_TO_FETCH); - const amountTicks = ticksToFetch * 2 + 1; - const [zoomState, setZoomState] = useState(initialState); + const { chartRef } = useChartResize(); - const { data, isLoading } = useSwr(["densityChart", address, client, ticksToFetch], async () => { - const data = await fetchTicksSurroundingPrice(address, client, ticksToFetch); - return { - row: data, - formatData: await formatData(data) - }; + const { data, isLoading } = useQuery({ + queryKey: ['densityChart', address, client], + queryFn: async () => { + const data = await fetchTicksSurroundingPrice(address, client, INITIAL_TICKS_TO_FETCH); + return { + row: data, + formatData: await formatData(data), + }; + }, }); - const atZoomMax = zoomState.left + ZOOM_INTERVAL >= zoomState.right - ZOOM_INTERVAL - 1; - const atZoomMin = zoomState.left - ZOOM_INTERVAL < 0; - - const handleZoomIn = useCallback(() => { - !atZoomMax && - setZoomState({ - ...zoomState, - left: zoomState.left + ZOOM_INTERVAL, - right: zoomState.right - ZOOM_INTERVAL, - }); - }, [zoomState, atZoomMax]); - - const handleZoomOut = useCallback(() => { - if (atZoomMin) { - setTicksToFetch(ticksToFetch + ZOOM_INTERVAL); - setZoomState({ - ...zoomState, - left: 0, - right: amountTicks, - }); - } else { - setZoomState({ - ...zoomState, - left: zoomState.left - ZOOM_INTERVAL, - right: zoomState.right + ZOOM_INTERVAL, - }); - } - }, [amountTicks, atZoomMin, ticksToFetch, zoomState]); - - const zoomedData = useMemo(() => { - if (data) { - return data.formatData.slice(zoomState.left, zoomState.right); - } - return undefined; - }, [data, zoomState.left, zoomState.right]); + const option = useMemo(() => { + return { + dataZoom: [ + { + type: 'inside', + }, + { + type: 'slider', + left: 5, + right: 4, + bottom: 8, + }, + ], + tooltip: { + trigger: 'axis', + axisPointer: { + type: 'line', + lineStyle: { + color: '#FFFFFF', + opacity: 0.4, + }, + }, + backgroundColor: '#1D2128', + borderColor: '#1D2128', + borderRadius: 8, + textStyle: { + color: '#FDFEFE', + }, + formatter: getRenderTooltip({ + chartData: data?.formatData, + poolData: data?.row, + }), + }, + title: { + show: false, + }, + grid: { + top: 0, + bottom: 32, + left: 1, + right: 1, + containLabel: true, + }, + xAxis: { + type: 'category', + boundaryGap: true, + data: data?.formatData?.map(({ index }) => index).toReversed(), + splitLine: { + show: false, + }, + axisTick: { + show: false, + }, + axisLine: { + show: false, + }, + axisLabel: { + formatter() { + return ''; + }, + }, + }, + yAxis: { + scale: true, + type: 'value', + splitLine: { + show: false, + }, + axisLine: { + show: false, + }, + axisLabel: { + formatter() { + return ''; + }, + }, + }, + series: [ + { + name: 'Liquidity', + type: 'bar', + stack: 'total', + symbol: 'none', + emphasis: { + disabled: false, + }, + itemStyle: { + color: colors.primaryDefault, + borderColor: null, + borderWidth: 2, + }, + data: data?.formatData.map(({ isCurrent, activeLiquidity }) => (isCurrent ? 0 : activeLiquidity)).toReversed(), + }, + { + name: 'Active Tick', + type: 'bar', + stack: 'total', + symbol: 'none', + emphasis: { + disabled: false, + }, + itemStyle: { + color: colors.red, + borderColor: null, + borderWidth: 2, + }, + data: data?.formatData.map(({ isCurrent, activeLiquidity }) => (isCurrent ? activeLiquidity : 0)).toReversed(), + }, + ], + }; + }, [data]); if (!data || isLoading) { return ( @@ -87,45 +149,9 @@ function DensityChart({ address, client }: IProps) { return ( - - - } /> - - { - return ; - }} - > - {zoomedData?.map((entry, index) => { - return ; - })} - - - - - - - - - - - + ); } -export default memo(DensityChart) +export default memo(DensityChart); diff --git a/src/components/Charts/Density/styles.ts b/src/components/Charts/Density/styles.ts index 432d852..4b7eb41 100644 --- a/src/components/Charts/Density/styles.ts +++ b/src/components/Charts/Density/styles.ts @@ -1,53 +1,85 @@ import styled from 'styled-components'; -import { Z_INDEX } from '../../../constants'; export const Wrapper = styled.div` - position: relative; - width: 100%; - height: 400px; flex: 1; - // Fix tooltip "border" - .recharts-tooltip-wrapper { - outline: none; - z-index: ${Z_INDEX.tooltip}; + width: 100%; + max-width: 100%; + position: relative; + + & .chart-tooltip { + display: flex; + flex-direction: column; + gap: 8px; } -`; -export const LoaderWrapper = styled.div` - height: 400px; - width: 100%; - display: flex; - align-items: center; - justify-content: center; -`; + & .chart-tooltip-header { + display: flex; + gap: 4px; + align-items: center; + margin-bottom: 6px; + } -export const ControlsWrapper = styled.div` - position: absolute; - right: 40px; - bottom: 100px; - padding: 4px; - border-radius: 8px; - display: grid; - grid-template-columns: 1fr 1fr; - grid-column-gap: 16px; -`; + & .chart-tooltip-title { + font-size: 14px; + line-height: 10px; + font-weight: 300; + } -export const ActionButton = styled.div<{ disabled?: boolean }>` - display: flex; - align-items: center; - justify-content: center; - border-radius: 50%; + & .chart-tooltip-color { + width: 14px; + height: 14px; + border-radius: 4px; + } + + & .chart-tooltip-label { + color: #afb6c9; + font-size: 14px; + line-height: 10px; + font-weight: 300; + } + + & .chart-tooltip-badge { + display: flex; + align-items: center; + gap: 4px; + height: 20px; + padding: 0 8px; + background-color: #5d93b214; + border-radius: 6px; + } + + & .chart-tooltip-badge-text { + font-size: 12px; + font-weight: 400; + line-height: 8px; + color: #5d93b2; + } + + & .chart-tooltip-separator { + height: 1px; + width: 100%; + background-color: #6d778733; + } - width: 32px; - height: 32px; - padding: 4px; - border: 1px solid rgba(97, 105, 113, 0.2); - background: ${({ theme }) => theme.colors.darkBg}; + & .chart-tooltip-prop-list { + display: flex; + flex-direction: column; + gap: 12px; + } - &:hover { - cursor: pointer; - opacity: 0.4; + & .chart-tooltip-prop { + display: flex; + align-items: center; + justify-content: space-between; } +`; - opacity: ${({ disabled }) => (disabled ? 0.4 : 0.9)}; +export const LoaderWrapper = styled.div` + display: flex; + align-items: center; + justify-content: center; + flex: 1; + width: 100%; + max-width: 100%; + position: relative; `; diff --git a/src/components/Charts/Density/utils.ts b/src/components/Charts/Density/utils.ts new file mode 100644 index 0000000..395d08e --- /dev/null +++ b/src/components/Charts/Density/utils.ts @@ -0,0 +1,94 @@ +import { ChartEntry, PoolTickData } from './types'; + +export type FormatReturnType = undefined | string; + +const genMinAmount = (decimals: number) => { + if (decimals < 1) return 1; + return Number(`0.${''.padEnd(decimals - 1, '0')}1`); +}; + +export const formatNumber = (num?: number, decimals = 4): FormatReturnType => { + let value: FormatReturnType; + const minAmount = genMinAmount(decimals); + if (typeof num === 'number' && !Number.isNaN(num)) { + if (!!num && num < minAmount) { + value = `<${minAmount}`; + } else { + value = new Intl.NumberFormat(void 0, { + style: 'decimal', + maximumFractionDigits: decimals, + minimumFractionDigits: 0, + }).format(num); + } + } + return value; +}; + +interface IGetRenderTooltipParams { + chartData?: ChartEntry[]; + poolData?: PoolTickData; +} + +interface TooltipParams { + axisValue: string; + seriesName: string; + data: number; +} + + +export const getRenderTooltip = + ({ chartData, poolData }: IGetRenderTooltipParams) => + (params: TooltipParams[]) => { + const { axisValue } = params[0]; + const hoverTick = +axisValue; + + const tick = chartData?.find(({ index }) => index === hoverTick); + + const currentPrice = poolData?.token0Price; + const token0 = poolData?.token0; + const token1 = poolData?.token1; + const price0 = tick?.price0; + const price1 = tick?.price1; + const tvlToken0 = tick?.tvlToken0; + const tvlToken1 = tick?.tvlToken1; + + if (!tvlToken0 && !tvlToken1) { + return ''; + } + + const template = ` +
+
+

Tick stats

+
+
+
+

${token0?.symbol} Price:

+

${formatNumber(price0, 10)} ${token1?.symbol}

+
+
+

${token1?.symbol} Price:

+

${formatNumber(price1, 10)} ${token0?.symbol}

+
+
+ ${ + currentPrice && price0 && price1 && currentPrice > price1 + ? ` +
+

${token0?.symbol} Locked:

+

${tvlToken0 ? formatNumber(tvlToken0) : ''} ${token0?.symbol}

+
+ ` + : ` +
+

${token1?.symbol} Locked:

+

${tvlToken1 ? formatNumber(tvlToken1) : ''} ${token1?.symbol}

+
+ ` + } +
+
+ `; + + return template; + }; diff --git a/src/components/Charts/index.stories.tsx b/src/components/Charts/index.stories.tsx index 21e1376..8e59d7c 100644 --- a/src/components/Charts/index.stories.tsx +++ b/src/components/Charts/index.stories.tsx @@ -2,6 +2,8 @@ import React from "react"; import { TerminalChart, DensityChart } from "./index"; import { ChainId } from "@real-wagmi/sdk"; import { GraphQLClient } from "graphql-request"; +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { Flex } from "../Box"; export default { title: "Components/Charts", @@ -14,7 +16,14 @@ export const Terminal: React.FC = () => { }; const client = new GraphQLClient('https://metis.graph.wagmi.com/subgraphs/name/v3'); +const queryClient = new QueryClient(); export const Density: React.FC = () => { - return ; + return ( + + + + + + ) }; \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index 14b3166..f8fb83c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3289,6 +3289,18 @@ "@styled-system/core" "^5.1.2" "@styled-system/css" "^5.1.5" +"@tanstack/query-core@5.59.16": + version "5.59.16" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.59.16.tgz#aa4616e8a9c12afeef4cfbf3ed0f55f404d66e67" + integrity sha512-crHn+G3ltqb5JG0oUv6q+PMz1m1YkjpASrXTU+sYWW9pLk0t2GybUHNRqYPZWhxgjPaVGC4yp92gSFEJgYEsPw== + +"@tanstack/react-query@^5.59.16": + version "5.59.16" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.59.16.tgz#1e701c6e6681965c04aa426df9da54b8edc6db1b" + integrity sha512-MuyWheG47h6ERd4PKQ6V8gDyBu3ThNG22e1fRVwvq6ap3EqsFhyuxCAwhNP/03m/mLg+DAb0upgbPaX6VB+CkQ== + dependencies: + "@tanstack/query-core" "5.59.16" + "@testing-library/dom@^8.3.0": version "8.20.0" resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.0.tgz#914aa862cef0f5e89b98cc48e3445c4c921010f6" @@ -5326,6 +5338,22 @@ duplexify@^3.5.0, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +echarts-for-react@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/echarts-for-react/-/echarts-for-react-3.0.2.tgz#ac5859157048a1066d4553e34b328abb24f2b7c1" + integrity sha512-DRwIiTzx8JfwPOVgGttDytBqdp5VzCSyMRIxubgU/g2n9y3VLUmF2FK7Icmg/sNVkv4+rktmrLN9w22U2yy3fA== + dependencies: + fast-deep-equal "^3.1.3" + size-sensor "^1.0.1" + +echarts@^5.5.1: + version "5.5.1" + resolved "https://registry.yarnpkg.com/echarts/-/echarts-5.5.1.tgz#8dc9c68d0c548934bedcb5f633db07ed1dd2101c" + integrity sha512-Fce8upazaAXUVUVsjgV6mBnGuqgO+JNDlcgF79Dksy4+wgGpQB2lmYoO4TSweFg/mZITdpGHomw/cNBJZj1icA== + dependencies: + tslib "2.3.0" + zrender "5.6.0" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -5677,7 +5705,7 @@ extract-zip@^1.6.6: mkdirp "^0.5.4" yauzl "^2.10.0" -fast-deep-equal@^3.1.1: +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== @@ -8858,6 +8886,11 @@ sisteransi@^1.0.5: resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== +size-sensor@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/size-sensor/-/size-sensor-1.0.2.tgz#b8f8da029683cf2b4e22f12bf8b8f0a1145e8471" + integrity sha512-2NCmWxY7A9pYKGXNBfteo4hy14gWu47rg5692peVMst6lQLPKrVjhY+UTEsPI5ceFRJSl3gVgMYaUi/hKuaiKw== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -9326,6 +9359,11 @@ ts-dedent@^2.0.0, ts-dedent@^2.2.0: resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== +tslib@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" + integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== + tslib@^1.13.0, tslib@^1.8.1: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -10140,3 +10178,10 @@ z-schema@~5.0.2: validator "^13.7.0" optionalDependencies: commander "^10.0.0" + +zrender@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/zrender/-/zrender-5.6.0.tgz#01325b0bb38332dd5e87a8dbee7336cafc0f4a5b" + integrity sha512-uzgraf4njmmHAbEUxMJ8Oxg+P3fT04O+9p7gY+wJRVxo8Ge+KmYv0WJev945EH4wFuc4OY2NLXz46FZrWS9xJg== + dependencies: + tslib "2.3.0"