diff --git a/frontend/package.json b/frontend/package.json index 711aa01a..187160a0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -15,6 +15,7 @@ "@emotion/react": "^11.4.0", "@emotion/styled": "^11.3.0", "@nivo/bar": "^0.73.1", + "@nivo/core": "^0.73.0", "@stripe/stripe-js": "^1.16.0", "axios": "^0.21.1", "focus-visible": "^5.2.0", diff --git a/frontend/pages/_app.js b/frontend/pages/_app.js index b4e2894c..f265fa60 100644 --- a/frontend/pages/_app.js +++ b/frontend/pages/_app.js @@ -6,6 +6,7 @@ import "highlight.js/styles/github.css"; import "focus-visible/dist/focus-visible"; import dynamic from "next/dynamic"; import { QueryClient, QueryClientProvider } from "react-query"; +import { ReactQueryDevtools } from "react-query/devtools"; const HeadSEO = dynamic(() => import("../src/components/HeadSEO"), { ssr: false, @@ -69,6 +70,7 @@ export default function CachingApp({ Component, pageProps }) { {pageProps.metaTags && } + {getLayout()} diff --git a/frontend/pages/nft.js b/frontend/pages/nft.js index 94da0bd9..3e7251c9 100644 --- a/frontend/pages/nft.js +++ b/frontend/pages/nft.js @@ -6,12 +6,13 @@ import React, { useState, } from "react"; import { getLayout } from "../src/layouts/AppLayout"; -import { Spinner, Flex, Heading, Stack } from "@chakra-ui/react"; +import { Spinner, Flex, Heading, Stack, Text, Spacer } from "@chakra-ui/react"; import Scrollable from "../src/components/Scrollable"; import useNFTs from "../src/core/hooks/useNFTs"; import RangeSelector from "../src/components/RangeSelector"; import StatsCard from "../src/components/StatsCard"; import useWindowSize from "../src/core/hooks/useWindowSize"; +import NFTChart from "../src/components/NFTChart"; const HOUR_KEY = "Hourly"; const DAY_KEY = "Daily"; @@ -25,7 +26,7 @@ const Analytics = () => { const windowSize = useWindowSize(); useEffect(() => { if (typeof window !== "undefined") { - document.title = `Analytics: Page under construction`; + document.title = `NFT Analytics`; } }, []); @@ -33,11 +34,15 @@ const Analytics = () => { ntx: false, values: false, mints: false, + NFTOwners: false, + minters: false, }); const nTxRef_ = useRef(); const valueRef_ = useRef(); const mintsRef_ = useRef(); + const uniqueNFTOwnersRef_ = useRef(); + const mintersRef_ = useRef(); const nTxRef = useCallback( (node) => { @@ -67,13 +72,40 @@ const Analytics = () => { [nodesReady] ); + const uniqueNFTOwnersRef = useCallback( + (node) => { + if (node !== null && !nodesReady.NFTOwners) { + setNodeReady({ ...nodesReady, NFTOwners: true }); + uniqueNFTOwnersRef_.current = node; + } + }, + [nodesReady] + ); + + const mintersRef = useCallback( + (node) => { + if (node !== null && !nodesReady.minters) { + setNodeReady({ ...nodesReady, minters: true }); + mintersRef_.current = node; + } + }, + [nodesReady] + ); + const [timeRange, setTimeRange] = useState(HOUR_KEY); const { nftCache } = useNFTs(); useLayoutEffect(() => { - const items = [nTxRef_, valueRef_, mintsRef_]; + const items = [ + nTxRef_, + valueRef_, + mintsRef_, + uniqueNFTOwnersRef_, + mintersRef_, + ]; console.log("useeffect fired"); - if (nTxRef_.current) { + if (items.some((item) => !!item.current)) { + console.log("brder fun"); var firstItemInCurrentRow = items[0]; items.forEach((item) => { if (item.current) { @@ -99,7 +131,12 @@ const Analytics = () => { } }, [nodesReady, windowSize]); + const keys = ["NFTs", "Other"]; + if (nftCache.isLoading) return ; + + const plotMinW = "500px"; + return ( { alignItems="center" minH="100vh" > - - NFT market analysis - - setTimeRange(e)} - /> + + + NFT market analysis + + + setTimeRange(e)} + /> + { boxShadow="md" borderRadius="lg" bgColor="gray.100" - // divider={} > nTxRef(node)} - // borderTopLeftRadius="inherit" - labelKey="transactions" + labelKey="nft_transfers" + totalKey="num_transactions" timeRange={timeMap[timeRange]} netLabel="Ethereum mainnet" label="Number of transactions" /> valueRef(node)} - labelKey="values" + labelKey="nft_transfer_value" + totalKey="total_value" timeRange={timeMap[timeRange]} netLabel="Ethereum mainnet" label="Value of transactions" /> mintsRef(node)} - // borderTopRightRadius="inherit" - // borderRightWidth="0" - labelKey="mints" + labelKey="nft_mints" timeRange={timeMap[timeRange]} netLabel="Ethereum mainnet" label="Minted NFTs" /> + uniqueNFTOwnersRef(node)} + labelKey="nft_owners" + timeRange={timeMap[timeRange]} + netLabel="Ethereum mainnet" + label="NFTs owners" + /> + + mintersRef(node)} + labelKey="nft_minters" + timeRange={timeMap[timeRange]} + netLabel="Ethereum mainnet" + label="NFTs minters" + /> + + + + NFT owners dynamic + + + + + + NFT values compared to total + + + + + + NFT Minting activity + + + + + + Unique minters number + + + + + + Number of NFT owners accounts + + + + + + NFT transactions vs all Ethereum + + + + + + NFT transfers vs all Ethereum + + + + ); diff --git a/frontend/src/components/NFTChart.js b/frontend/src/components/NFTChart.js new file mode 100644 index 00000000..cb23b05a --- /dev/null +++ b/frontend/src/components/NFTChart.js @@ -0,0 +1,176 @@ +import React, { useCallback } from "react"; +import { Spinner } from "@chakra-ui/react"; +import useNFTs from "../core/hooks/useNFTs"; +import { ResponsiveBarCanvas } from "@nivo/bar"; +import moment from "moment"; + +const HOUR_KEY = "Hourly"; +const DAY_KEY = "Daily"; +const WEEK_KEY = "Weekly"; +let timeMap = {}; +timeMap[HOUR_KEY] = "hour"; +timeMap[DAY_KEY] = "day"; +timeMap[WEEK_KEY] = "week"; + +const NFTChart = ({ timeRange, keyPosition, keyTotal }) => { + const { nftCache } = useNFTs(); + + const getHourlyData = useCallback( + (keyPosition, keyTotal) => { + const retval = []; + nftCache?.data?.forEach((block, idx) => { + let diff = + keyTotal && Number(block[keyTotal]) - Number(block[keyPosition]); + + let date = moment(block.crawled_at).format(`HH`); + //group by days if not hour key + if (idx < 23) { + retval.push({ + date: date, + NFTs: Number(block[keyPosition]), + Other: keyTotal && diff, + }); + } + }); + + return retval; + }, + [nftCache.data] + ); + + const getDailyData = useCallback( + (keyPosition, keyTotal) => { + const retval = []; + nftCache?.data?.forEach((block, idx) => { + if (idx < 7 * 24) { + let diff = + keyTotal && Number(block[keyTotal]) - Number(block[keyPosition]); + + let date = moment(block.crawled_at).format(`l`); + let existingIdx = retval.findIndex( + (element) => element.date === date + ); + if (existingIdx !== -1) { + const prevValue = retval[existingIdx]; + const newValue = { + date: prevValue.date, + NFTs: prevValue.NFTs + Number(block[keyPosition]), + Other: prevValue.Other + Number(block[keyPosition]), + }; + retval[existingIdx] = { ...newValue }; + } else { + retval.push({ + date: date, + + NFTs: Number(block[keyPosition]), + Other: keyTotal && diff, + }); + } + } + }); + + return retval; + }, + [nftCache.data] + ); + + const getWeeklyData = useCallback( + (keyPosition, keyTotal) => { + const retval = []; + nftCache?.data?.forEach((block, idx) => { + if (idx < 28 * 24) { + let diff = + keyTotal && Number(block[keyTotal]) - Number(block[keyPosition]); + + let date = moment(block.crawled_at).format(`l`); + let existingIdx = retval.findIndex( + (element) => element.date === date + ); + if (existingIdx !== -1) { + const prevValue = retval[existingIdx]; + const newValue = { + date: prevValue.date, + NFTs: prevValue.NFTs + Number(block[keyPosition]), + Other: prevValue.Other + Number(block[keyPosition]), + }; + retval[existingIdx] = { ...newValue }; + } else { + retval.push({ + date: date, + NFTs: Number(block[keyPosition]), + Other: keyTotal && diff, + }); + } + } + }); + + return retval; + }, + [nftCache.data] + ); + + const plotData = + timeRange === HOUR_KEY + ? getHourlyData(keyPosition, keyTotal) + : timeRange === DAY_KEY + ? getDailyData(keyPosition, keyTotal) + : getWeeklyData(keyPosition, keyTotal); + + plotData.forEach((item, index) => { + plotData[index].NFTs = plotData[index].NFTs / 1e18; + plotData[index].Other = plotData[index].Other / 1e18; + }); + if (nftCache.isLoading) return ; + return ( + labelLookup[d.id]} + // tooltipLabel={(d) => labelLookup[d.id]} + legends={[ + { + anchor: "bottom-right", + direction: "column", + translateX: 100, + itemWidth: 80, + itemHeight: 20, + itemTextColor: "#999999", + symbolSize: 12, + symbolShape: "circle", + effects: [ + { + on: "hover", + style: { + itemTextColor: "#000000", + }, + }, + ], + }, + ]} + /> + ); +}; + +export default NFTChart; diff --git a/frontend/src/components/RangeSelector.js b/frontend/src/components/RangeSelector.js index cf4ef35a..72eceb58 100644 --- a/frontend/src/components/RangeSelector.js +++ b/frontend/src/components/RangeSelector.js @@ -20,7 +20,7 @@ const RangeSelector_ = ({ }, [range, onChange]); return ( - + {ranges.map((item, idx) => { const isActive = item === range ? true : false; return ( @@ -37,6 +37,7 @@ const RangeSelector_ = ({ bgColor: isActive ? "secondary.900" : "secondary.50", }} cursor="pointer" + py="2px" > {item} diff --git a/frontend/src/components/StatsCard.js b/frontend/src/components/StatsCard.js index 2e941268..31ce9c8c 100644 --- a/frontend/src/components/StatsCard.js +++ b/frontend/src/components/StatsCard.js @@ -4,11 +4,6 @@ import { TriangleDownIcon, TriangleUpIcon } from "@chakra-ui/icons"; import useNFTs from "../core/hooks/useNFTs"; import { fromWei } from "web3-utils"; -const TIME_PERIOD = { - current: 0, - previous: 1, -}; - const isNumberNonzeroAndFinite = (str) => { return !(isNaN(Number(str)) || Number(str) === 0); }; @@ -39,6 +34,7 @@ const nFormatter = (num, digits) => { }; const getChange = (a, b) => { + console.log(`change:`, a, b); if (isNumberNonzeroAndFinite(a) && isNumberNonzeroAndFinite(b)) { let retval = (Math.abs(Number(a) - Number(b)) * 100) / Number(b); retval = @@ -53,7 +49,7 @@ const getDiff = (a, b) => { if (isNaN(a) || isNaN(b)) { return "-"; } else { - return Number(a) - Number(b); + return Number(Number(a) - Number(b)).toFixed(2); } }; @@ -67,26 +63,61 @@ const StatsCard_ = ({ label, netLabel, labelKey, + totalKey, timeRange, innerRef, }) => { + console.log("stats card"); const { nftCache } = useNFTs(); const [nftData, setData] = useState(); useEffect(() => { - if (nftCache.data[TIME_PERIOD.current][labelKey][timeRange]) { - const cacheData = nftCache.data[TIME_PERIOD.current][labelKey][timeRange]; - const prevCacheData = - nftCache.data[TIME_PERIOD.previous][labelKey][timeRange]; - const valueChange = getChange(cacheData.amount, prevCacheData.amount); - const share = isNaN(cacheData.percentage) - ? "-" - : Number(cacheData.percentage).toFixed(2); - const shareChange = getDiff( - cacheData.percentage, - prevCacheData.percentage + if (nftCache.data) { + const resolution = + timeRange === "hour" ? 1 : timeRange === "day" ? 24 : 24 * 7; + + let currentPeriod = 0, + previousPeriod = 0, + currentTotalPeriod = 0, + previousTotalPeriod = 0; + for (let i = 0; i < resolution; i++) { + currentPeriod += Number(nftCache.data[i][labelKey]); + previousPeriod += Number(nftCache.data[resolution + i][labelKey]); + if (totalKey) { + currentTotalPeriod += Number(nftCache.data[i][totalKey]); + previousTotalPeriod += Number( + nftCache.data[resolution + i][totalKey] + ); + } + } + console.log( + "card,", + totalKey, + labelKey, + currentPeriod, + currentTotalPeriod ); + // percentage = + // const cacheData = nftCache.data[TIME_PERIOD.current][labelKey][timeRange]; + // const prevCacheData = + // nftCache.data[TIME_PERIOD.previous][labelKey][timeRange]; + const valueChange = getChange(currentPeriod, previousPeriod); + totalKey && + console.log( + "getting change in share", + currentPeriod, + currentTotalPeriod + ); + + const share = !totalKey + ? "-" + : getChange(currentPeriod, currentTotalPeriod); + const shareChange = getDiff( + share, + getChange(previousPeriod, previousTotalPeriod) + ); + totalKey && console.log("share", share); setData({ dimension: labelKey === "values" ? "Eth" : "#", @@ -96,12 +127,13 @@ const StatsCard_ = ({ shareChange, share, value: - labelKey === "values" - ? getEthValue(cacheData.amount) - : nFormatter(cacheData.amount, 2), + labelKey === "total_value" + ? getEthValue(currentPeriod) + : nFormatter(currentPeriod, 2), }); } - }, [nftCache?.data, nftCache.isLoading, labelKey, timeRange]); + }, [nftCache?.data, nftCache.isLoading, labelKey, totalKey, timeRange]); + console.log("nftData", nftData); if (nftCache.isLoading || !nftData) return ""; return ( diff --git a/frontend/src/core/utils/mockupRequests.js b/frontend/src/core/utils/mockupRequests.js index 5e7a8a1d..0a727af0 100644 --- a/frontend/src/core/utils/mockupRequests.js +++ b/frontend/src/core/utils/mockupRequests.js @@ -19,6 +19,9 @@ export const makenum = (length) => { for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } + if (result[0] === "0") { + result = "1" + result.slice(1, result.length); + } return result; }; @@ -27,6 +30,28 @@ const randDate = () => { new Date(+new Date() - Math.floor(Math.random() * 10000000000)) ).format("MM/DD/YYYY"); }; + +const generateMockNFTData = (days) => { + const retArr = []; + console.log("calculating array..."); + for (let i = 0; i < days * 24; i++) { + let total_value = makenum(23); + let nft_transfer_value = makenum(22); + retArr.push({ + num_transactions: makenum(5), + total_value: total_value.toString(), + nft_transfers: makenum(4), + nft_transfer_value: nft_transfer_value.toString(), + nft_mints: makenum(4), + nft_owners: makenum(4), + nft_minters: makenum(4), + crawled_at: moment.utc().subtract(i, "hours"), + }); + } + return retArr; +}; + +const mockNFTData = generateMockNFTData(100); export let MockSubscriptions = [ { label: "Bobs wallet", @@ -74,132 +99,7 @@ const enableMockupRequests = (axiosInstance) => { //assume all currency units are in wei mock.onGet(`${MOCK_API}/nft`).reply(200, { - data: [ - { - crawled_at: "2021-09-06T06:10:10.889073+00:00", - blocks: { - hour: { - start: 13170228, - end: 13271506, - }, - day: { - start: 13164032, - end: 14270506, - }, - week: { - start: 13154612, - end: 14270508, - }, - }, - transactions: { - hour: { - total: "50017", - amount: "1076", - percentage: "6.323468771476769", - }, - day: { - total: "1534628", - amount: "68423", - percentage: "4.149088511829428", - }, - week: { - total: "3036720", - amount: "252081", - percentage: "2.3611565469979405", - }, - }, - values: { - hour: { - total: "32108237248132871265869", - amount: "902575483711416563753", - percentage: "3.222693614745530439610725634", - }, - day: { - total: "1248742881687945808996123", - amount: "36532034623835761073277", - percentage: "2.967167722185197815518956241", - }, - week: { - total: "4496907645654832424013847", - amount: "171796514135927551452190", - percentage: "4.053142988352582169869986652", - }, - }, - mints: { - hour: { - amount: 1884, - }, - day: { - amount: 45131, - }, - week: { - amount: 1281978, - }, - }, - }, - { - crawled_at: "2021-09-06T06:10:10.889073+00:00", - blocks: { - hour: { - start: 13170228, - end: 13170506, - }, - day: { - start: 13164032, - end: 13170506, - }, - week: { - start: 13154612, - end: 13170508, - }, - }, - transactions: { - hour: { - total: "48017", - amount: "2076", - percentage: "4.323468771476769", - }, - day: { - total: "1134628", - amount: "58423", - percentage: "5.149088511829428", - }, - week: { - total: "2836720", - amount: "152081", - percentage: "5.3611565469979405", - }, - }, - values: { - hour: { - total: "36108237248132871265869", - amount: "802575483711416563753", - percentage: "2.222693614745530439610725634", - }, - day: { - total: "1348742881687945808996123", - amount: "26532034623835761073277", - percentage: "1.967167722185197815518956241", - }, - week: { - total: "3496907645654832424013847", - amount: "71796514135927551452190", - percentage: "2.053142988352582169869986652", - }, - }, - mints: { - hour: { - amount: 2884, - }, - day: { - amount: 95131, - }, - week: { - amount: 281978, - }, - }, - }, - ], + data: [...mockNFTData], }); // mock.onGet(`${MOCK_API}/subscription_types/`).reply(200, { @@ -245,7 +145,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -257,7 +157,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -269,7 +169,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -281,7 +181,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -293,7 +193,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -305,7 +205,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -317,7 +217,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -329,7 +229,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -341,7 +241,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, @@ -353,7 +253,7 @@ const enableMockupRequests = (axiosInstance) => { // gas: 2265656, // gasPrice: 1000000000, // hash: "0x5f0b6e212e55c7120f36fe6f88d46eb001c848064fd099116b42805bb3564ae6", - // value: 0, + // values: 0, // input: // "0x606061026b61014039602061026b60c03960c05160a01c1561002057600080fd5b61014051600055610160516001556001546101805181818301101561004457600080fd5b80820190509050600255600254421061005c57600080fd5b61025356600436101561000d576101ec565b600035601c52600051631998aeef8114156100855760015442101561003157600080fd5b600254421061003f57600080fd5b600454341161004d57600080fd5b600660035460e05260c052604060c020805460045481818301101561007157600080fd5b808201905090508155503360035534600455005b341561009057600080fd5b633ccfd60b8114156100db5760063360e05260c052604060c0205461014052600060063360e05260c052604060c02055600060006000600061014051336000f16100d957600080fd5b005b63fe67a54b811415610124576002544210156100f657600080fd5b6005541561010357600080fd5b600160055560006000600060006004546000546000f161012257600080fd5b005b6338af3eed81141561013c5760005460005260206000f35b634f245ef78114156101545760015460005260206000f35b632a24f46c81141561016c5760025460005260206000f35b6391f901578114156101845760035460005260206000f35b63d57bde7981141561019c5760045460005260206000f35b6312fa6feb8114156101b45760055460005260206000f35b6326b387bb8114156101ea5760043560a01c156101d057600080fd5b600660043560e05260c052604060c0205460005260206000f35b505b60006000fd5b61006161025303610061600039610061610253036000f30000000000000000000000002e337e0fb68f5e51ce9295e80bcd02273d7420c40000000000000000000000000000000000000000000000000000000060d2b04a00000000000000000000000000000000000000000000000000000000616b46ca", // }, diff --git a/frontend/yarn.lock b/frontend/yarn.lock index 2ad192e4..381d638a 100644 --- a/frontend/yarn.lock +++ b/frontend/yarn.lock @@ -1299,6 +1299,24 @@ lodash "^4.17.21" react-motion "^0.5.2" +"@nivo/core@^0.73.0": + version "0.73.0" + resolved "https://registry.yarnpkg.com/@nivo/core/-/core-0.73.0.tgz#58fac20c8cd7eac12bfdc96619554764ca225cdf" + integrity sha512-NFKSk5NQgC2NB3olG8hltN4b4Ri0rB0vt3q1yGmQj+RdGRS4f82Dtwt5Ratxu6QeZD8lt0DhqN9Q7TJ+j/kt0g== + dependencies: + "@nivo/recompose" "0.73.0" + "@react-spring/web" "9.2.4" + d3-color "^2.0.0" + d3-format "^1.4.4" + d3-hierarchy "^1.1.8" + d3-interpolate "^2.0.1" + d3-scale "^3.2.3" + d3-scale-chromatic "^2.0.0" + d3-shape "^1.3.5" + d3-time-format "^3.0.0" + lodash "^4.17.21" + resize-observer-polyfill "^1.5.1" + "@nivo/legends@0.73.0": version "0.73.0" resolved "https://registry.yarnpkg.com/@nivo/legends/-/legends-0.73.0.tgz#ef344038c4ff03249ffffebaf14412d012004fda" @@ -2596,7 +2614,12 @@ d3-format@^1.4.4: resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== -"d3-interpolate@1 - 2", "d3-interpolate@1.2.0 - 2": +d3-hierarchy@^1.1.8: + version "1.1.9" + resolved "https://registry.yarnpkg.com/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz#2f6bee24caaea43f8dc37545fa01628559647a83" + integrity sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ== + +"d3-interpolate@1 - 2", "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== @@ -2627,7 +2650,7 @@ d3-scale@^3.2.3: d3-time "^2.1.1" d3-time-format "2 - 3" -d3-shape@^1.2.2: +d3-shape@^1.2.2, d3-shape@^1.3.5: version "1.3.7" resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7" integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==