mirror of
https://github.com/niespodd/browser-fingerprinting.git
synced 2021-11-01 22:44:07 +03:00
add resource timing api & co
This commit is contained in:
1
docs/assets/index.e17f1f40.js
Normal file
1
docs/assets/index.e17f1f40.js
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -11,8 +11,8 @@
|
||||
break-inside: avoid;
|
||||
}
|
||||
</style>
|
||||
<script type="module" crossorigin src="assets/index.f5baa570.js"></script>
|
||||
<link rel="modulepreload" href="assets/vendor.dfdf208d.js">
|
||||
<script type="module" crossorigin src="assets/index.e17f1f40.js"></script>
|
||||
<link rel="modulepreload" href="assets/vendor.0d07671f.js">
|
||||
<link rel="stylesheet" href="assets/index.f44316bf.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -6,10 +6,14 @@
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chakra-ui/icons": "^1.0.13",
|
||||
"@chakra-ui/react": "^1.6.3",
|
||||
"@emotion/react": "11",
|
||||
"@emotion/styled": "11",
|
||||
"@react-three/fiber": "^6.2.3",
|
||||
"@visx/group": "^1.7.0",
|
||||
"@visx/shape": "^1.12.0",
|
||||
"@visx/text": "^1.10.0",
|
||||
"chart.js": "^3.3.2",
|
||||
"copy-to-clipboard": "^3.3.1",
|
||||
"framer-motion": "4",
|
||||
|
||||
@@ -15,6 +15,7 @@ import DeviceSensors from "./testers/DeviceSensors";
|
||||
import base64 from "./utils/base64";
|
||||
import MediaDevices from "./testers/MediaDevices";
|
||||
import EncryptedMediaExtensions from "./testers/EncryptedMediaExtensions";
|
||||
import ResourceTiming from "./testers/ResourceTiming";
|
||||
|
||||
const AppPersisted = () => {
|
||||
const dispatch = useDispatch();
|
||||
@@ -65,7 +66,8 @@ const App = () => {
|
||||
|
||||
<Container maxW="container.xl">
|
||||
<Box w="100%" sx={{ columnCount: window.outerWidth > 500 ? 2 : 1, columnGap: "24px" }}>
|
||||
<EncryptedMediaExtensions />
|
||||
{/*<EncryptedMediaExtensions />*/}
|
||||
<ResourceTiming />
|
||||
<BasicInformation />
|
||||
<MediaDevices />
|
||||
|
||||
|
||||
@@ -27,13 +27,13 @@ const probeStackLimit = async () => {
|
||||
let accessor = 'window.parent';
|
||||
let p = 0;
|
||||
while (true) {
|
||||
p += 50;
|
||||
p += 500;
|
||||
try {
|
||||
eval(accessor);
|
||||
} catch (err) {
|
||||
break;
|
||||
}
|
||||
for (let i=0; i<50; i++) {
|
||||
for (let i=0; i<500; i++) {
|
||||
accessor += '.parent';
|
||||
}
|
||||
await new Promise((resolve) => setTimeout(resolve, 50)); // helps to prevent early freeze/crash
|
||||
@@ -41,20 +41,39 @@ const probeStackLimit = async () => {
|
||||
return p;
|
||||
}
|
||||
|
||||
const getConnectionInformation = async () => {
|
||||
const connection = await (navigator.connection || navigator.mozConnection || navigator.webkitConnection);
|
||||
if (!connection) return {};
|
||||
return {
|
||||
effectiveType: connection.effectiveType,
|
||||
saveData: connection.saveData,
|
||||
rtt: connection.rtt,
|
||||
downlink: connection.downlink,
|
||||
}
|
||||
}
|
||||
|
||||
const BasicInformation = ({ fn, value }) => {
|
||||
fn(async () => {
|
||||
const devtools = devToolsOpened();
|
||||
const stackLimit = await probeStackLimit();
|
||||
const connection = await getConnectionInformation();
|
||||
return {
|
||||
"deviceMemory": navigator.deviceMemory,
|
||||
"hardwareConcurrency": navigator.hardwareConcurrency,
|
||||
"window.innerHeight": window.innerHeight,
|
||||
"window.innerWidth": window.innerWidth,
|
||||
"window.outerHeight": window.outerHeight,
|
||||
"window.outerWidth": window.outerWidth,
|
||||
"devTools.isOpen": devtools.isOpen,
|
||||
"devTools.orientation": devtools.orientation,
|
||||
"stackLimit": stackLimit,
|
||||
navigator: {
|
||||
deviceMemory: navigator.deviceMemory,
|
||||
hardwareConcurrency: navigator.hardwareConcurrency,
|
||||
},
|
||||
performance: {
|
||||
"jsHeapSizeLimit": performance.memory.jsHeapSizeLimit,
|
||||
},
|
||||
stackLimit: stackLimit,
|
||||
window: {
|
||||
innerHeight: window.innerHeight,
|
||||
innerWidth: window.innerWidth,
|
||||
outerHeight: window.outerHeight,
|
||||
outerWidth: window.outerWidth,
|
||||
},
|
||||
devtools,
|
||||
connection,
|
||||
};
|
||||
});
|
||||
|
||||
@@ -68,7 +87,15 @@ const BasicInformation = ({ fn, value }) => {
|
||||
<Text fontSize="sm" mb={2}>
|
||||
Available hardware details:
|
||||
</Text>
|
||||
<DictToTable dict={value} limitKeys={["deviceMemory", "hardwareConcurrency", "stackLimit"]} />
|
||||
<DictToTable dict={value} limitKeys={["navigator", "stackLimit", "performance"]} />
|
||||
</Box>
|
||||
</GridItem>
|
||||
<GridItem>
|
||||
<Box mb={4}>
|
||||
<Text fontSize="sm" mb={2}>
|
||||
Window dimensions:
|
||||
</Text>
|
||||
<DictToTable dict={value} limitKeys={["window"]} />
|
||||
</Box>
|
||||
<Box>
|
||||
<Text>
|
||||
@@ -76,20 +103,12 @@ const BasicInformation = ({ fn, value }) => {
|
||||
</Text>
|
||||
</Box>
|
||||
</GridItem>
|
||||
<GridItem>
|
||||
<Text fontSize="sm" mb={2}>
|
||||
Window dimensions:
|
||||
</Text>
|
||||
<DictToTable dict={value} limitKeys={[
|
||||
"window.innerWidth",
|
||||
"window.innerHeight",
|
||||
"window.outerHeight",
|
||||
"window.outerWidth",
|
||||
]} />
|
||||
|
||||
</GridItem>
|
||||
</SimpleGrid>
|
||||
|
||||
<Text fontSize="sm" mb={2} mt={2}>
|
||||
Connection information:
|
||||
</Text>
|
||||
<DictToTable dict={value.connection} limitKeys={["downlink", "rtt", "effectiveType", "saveData"]} />
|
||||
<Divider my={4} />
|
||||
<Text fontSize="xs">
|
||||
DevTools information are based on window sizing (borrowed from <Link color="teal.500" href="https://github.com/sindresorhus/devtools-detect/blob/main/index.js">sindresorhus/devtools-detect</Link>)
|
||||
|
||||
@@ -5,13 +5,17 @@ import {DictToTable} from "./utils";
|
||||
|
||||
const DocumentStatus = ({ fn, value }) => {
|
||||
fn(() => ({
|
||||
hasFocus: document.hasFocus(),
|
||||
compatMode: document.compatMode,
|
||||
documentURI: document.documentURI,
|
||||
designMode: document.designMode,
|
||||
document: {
|
||||
hasFocus: document.hasFocus(),
|
||||
compatMode: document.compatMode,
|
||||
documentURI: document.documentURI,
|
||||
designMode: document.designMode,
|
||||
}
|
||||
}));
|
||||
return (
|
||||
<DictToTable dict={value} />
|
||||
<DictToTable dict={value} limitKeys={[
|
||||
"document"
|
||||
]} />
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
123
tester/src/testers/ResourceTiming.jsx
Normal file
123
tester/src/testers/ResourceTiming.jsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import tester from "./tester";
|
||||
import React from "react";
|
||||
import {Text, Code, Alert, Divider, Heading} from "@chakra-ui/react";
|
||||
import {DictToTable} from "./utils";
|
||||
import {Bar} from '@visx/shape';
|
||||
import {Group} from "@visx/group";
|
||||
import {Text as VText} from '@visx/text';
|
||||
|
||||
const TIMING_COLOR = {
|
||||
"resource": "#4834d4",
|
||||
"paint": "#eb4d4b",
|
||||
"mark": "#22a6b3",
|
||||
"navigation": "#6ab04c",
|
||||
}
|
||||
|
||||
const TimelineVisualisation = ({ data }) => {
|
||||
const timelineWrapper = React.useRef(undefined);
|
||||
const [svgDimensions, setSvgDimensions] = React.useState(undefined);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!timelineWrapper.current) return;
|
||||
const { clientWidth } = timelineWrapper.current;
|
||||
setSvgDimensions({ width: clientWidth, height: (10 * data.length) });
|
||||
}, [timelineWrapper]);
|
||||
|
||||
const normalizedData = React.useMemo(() => {
|
||||
if (!svgDimensions) return [];
|
||||
const { width } = svgDimensions;
|
||||
const minW = Math.min(...data.map((d) => d.startTime));
|
||||
const maxW = Math.max(...data.map((d) => d.startTime + d.duration));
|
||||
const W = maxW - minW;
|
||||
|
||||
return data.map((e) => {
|
||||
return {
|
||||
x: ((e.startTime - minW)/W) * width,
|
||||
width: !!e.duration ? ((e.duration / W) * width) : W,
|
||||
fill: TIMING_COLOR[e.entryType],
|
||||
name: e.name,
|
||||
};
|
||||
});
|
||||
}, [svgDimensions, data]);
|
||||
|
||||
return (
|
||||
<div ref={timelineWrapper} style={{ marginTop: '8px' }}>
|
||||
{svgDimensions && normalizedData && (
|
||||
<svg {...svgDimensions}>
|
||||
<Group>
|
||||
{normalizedData.map((e, idx) => (
|
||||
<>
|
||||
<Bar y={idx * 10} height={8} {...e} key={idx} />
|
||||
<VText {...e} x={e.x + e.width + 6} fill="gray" y={idx * 10 + 6.5} height={12} fontSize={6} width={undefined}>{e.name}</VText>
|
||||
</>
|
||||
))}
|
||||
</Group>
|
||||
</svg>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ResourceTiming = ({ fn, value }) => {
|
||||
fn(async () => {
|
||||
await new Promise((resolve) => setTimeout(resolve, 1000));
|
||||
const performanceEntries = window.performance.getEntries();
|
||||
const navigationTiming = performanceEntries.find((k) => k instanceof PerformanceNavigationTiming);
|
||||
return {
|
||||
navigationType: navigationTiming.type,
|
||||
encodedBodySize: navigationTiming.encodedBodySize,
|
||||
entriesCount: performanceEntries.length,
|
||||
domainLookupTime: navigationTiming.domainLookupEnd - navigationTiming.domainLookupStart,
|
||||
}
|
||||
});
|
||||
|
||||
const [timeline, setTimelineData] = React.useState([]);
|
||||
React.useEffect(() => {
|
||||
setTimeout(() => setTimelineData(window.performance.getEntries()), 3000);
|
||||
}, []);
|
||||
|
||||
if (!value) return null;
|
||||
|
||||
return (
|
||||
<>
|
||||
<Text my={4}>
|
||||
You entered this page by <Code>{value.navigationType}</Code> action. Encoded body size of this page is <Code>{value.encodedBodySize}B</Code> (this can vary by encoding supported by your browser).
|
||||
</Text>
|
||||
|
||||
{value.domainLookupTime < 1 && (
|
||||
<Alert status="info" mb={4}>
|
||||
<Text fontSize="sm" >
|
||||
You have very likely <strong>already visited</strong> this page because domain lookup time was under 1ms.
|
||||
</Text>
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<DictToTable dict={value} limitKeys={["entriesCount", "domainLookupTime", "encodedBodySize", "navigationType"]} />
|
||||
|
||||
{timeline.length > 0 && (
|
||||
<>
|
||||
<Divider my={4} />
|
||||
<Heading size="sm">
|
||||
Loading timeline
|
||||
</Heading>
|
||||
<Text fontSize="sm" mb={2}>
|
||||
This is visualisation of resource loading. It is not included in the fingerprint hash.
|
||||
</Text>
|
||||
|
||||
<TimelineVisualisation data={timeline} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default tester(ResourceTiming, {
|
||||
key: 'resourceTiming',
|
||||
title: "Resource Timing API",
|
||||
explainer: (
|
||||
<>
|
||||
Performance APIs can be useful to detect that proxy is in use by validating request timings. Data comes from <Code>window.performance</Code> scope.
|
||||
</>
|
||||
)
|
||||
});
|
||||
|
||||
@@ -1,12 +1,58 @@
|
||||
import React from "react";
|
||||
import {HStack, Box, Tag, Table, Thead, Tbody, Tr, Td, Th, Text} from "@chakra-ui/react";
|
||||
import {HStack, Box, Tag, Table, Thead, Tbody, Tr, Td, Th, Text, List, ListItem} from "@chakra-ui/react";
|
||||
import { PhoneIcon, AddIcon, WarningIcon } from '@chakra-ui/icons';
|
||||
|
||||
const getObjectValueFromPath = function(o, s) {
|
||||
s = s.replace(".*", "");
|
||||
s = s.replace(/\[(\w+)\]/g, '.$1'); // convert indexes to properties
|
||||
s = s.replace(/^\./, ''); // strip a leading dot
|
||||
var a = s.split('.');
|
||||
for (var i = 0, n = a.length; i < n; ++i) {
|
||||
var k = a[i];
|
||||
if (k in o) {
|
||||
o = o[k];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (typeof o == "object") {
|
||||
return Object.entries(o);
|
||||
}
|
||||
return o;
|
||||
}
|
||||
|
||||
const render = (v) => {
|
||||
if (v instanceof Array) {
|
||||
if (v[0] instanceof Array) {
|
||||
// list of kv (from Object.entries)
|
||||
return [true, (
|
||||
<List>
|
||||
{v.map(([key, value], idx) => (
|
||||
<ListItem key={idx}>
|
||||
{key} = {value}
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
)];
|
||||
} else {
|
||||
// list of values
|
||||
return [true, (
|
||||
<List>
|
||||
{v.map((entry, idx) => (
|
||||
<ListItem key={idx}>
|
||||
{entry.toString()}
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
)];
|
||||
}
|
||||
}
|
||||
|
||||
switch (typeof v) {
|
||||
case "boolean":
|
||||
return v ? "✔️" : "❌";
|
||||
return [false, v ? "✔️" : "❌"];
|
||||
default:
|
||||
return v;
|
||||
return [false, v];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,34 +69,49 @@ export const YesNoList = ({ list = [] }) => (
|
||||
</Box>
|
||||
);
|
||||
|
||||
export const DictToTable = ({ dict = {}, limitKeys = [] }) => (
|
||||
<Box border="1px" borderColor="gray.100" borderRadius="md">
|
||||
<Table size="sm" shadow="sm">
|
||||
<Thead>
|
||||
<Tr>
|
||||
<Th>
|
||||
Key
|
||||
</Th>
|
||||
<Th>
|
||||
Value
|
||||
</Th>
|
||||
</Tr>
|
||||
</Thead>
|
||||
<Tbody>
|
||||
{Object.entries(dict).map(([k, v], idx) => (limitKeys.length === 0 || limitKeys.indexOf(k) >= 0) ? (
|
||||
<Tr key={idx}>
|
||||
<Td>
|
||||
<Text color="gray.700">{k}</Text>
|
||||
</Td>
|
||||
<Td>
|
||||
<Text isTruncated>
|
||||
{render(v)}
|
||||
</Text>
|
||||
</Td>
|
||||
</Tr>
|
||||
) : null)}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
const DictToTableRow = ({ dict, k }) => {
|
||||
const [isList, rendered] = render(getObjectValueFromPath(dict, k));
|
||||
if (isList) {
|
||||
return (
|
||||
<Tr>
|
||||
<Td colSpan={2}>
|
||||
<Text fontSize="xs" fontWeight="500">{k}</Text>
|
||||
<Text isTruncated ml={2}>
|
||||
{rendered}
|
||||
</Text>
|
||||
</Td>
|
||||
</Tr>
|
||||
)
|
||||
} else {
|
||||
return (
|
||||
<Tr>
|
||||
<Td>
|
||||
{k}
|
||||
</Td>
|
||||
<Td>
|
||||
{rendered}
|
||||
</Td>
|
||||
</Tr>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export const DictToTable = ({ dict = {}, limitKeys = [] }) => {
|
||||
const dictKeys = React.useMemo(() =>
|
||||
limitKeys ? Object.keys(dict).filter((k) => limitKeys.indexOf(k) >= 0) : Object.keys(dict),
|
||||
[dict, limitKeys]
|
||||
);
|
||||
if (!dict) return null;
|
||||
return (
|
||||
<Box border="1px" borderColor="gray.100" borderRadius="md">
|
||||
<Table size="sm" shadow="sm">
|
||||
<Tbody>
|
||||
{dictKeys.map((k, idx) => (
|
||||
<DictToTableRow dict={dict} k={k} idx={idx} />
|
||||
))}
|
||||
</Tbody>
|
||||
</Table>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
242
tester/yarn.lock
242
tester/yarn.lock
@@ -378,6 +378,14 @@
|
||||
dependencies:
|
||||
"@chakra-ui/utils" "1.8.0"
|
||||
|
||||
"@chakra-ui/icons@^1.0.13":
|
||||
version "1.0.13"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/icons/-/icons-1.0.13.tgz#d8eb04479b048d8023ae90d76205cd4a0bf7dd79"
|
||||
integrity sha512-twDpFz2uPVboMTEI4QA2y3EJND3G4+/9AVs730fgnnfhTw4EOJt0Lhfm4Spq1qi1LgHF16x4/Lao1E2imB5lWw==
|
||||
dependencies:
|
||||
"@chakra-ui/icon" "1.1.9"
|
||||
"@types/react" "^17.0.0"
|
||||
|
||||
"@chakra-ui/image@1.0.15":
|
||||
version "1.0.15"
|
||||
resolved "https://registry.yarnpkg.com/@chakra-ui/image/-/image-1.0.15.tgz#57aaf7e22d2793b9278481aab56b27063a922e5b"
|
||||
@@ -914,6 +922,49 @@
|
||||
utility-types "^3.10.0"
|
||||
zustand "^3.5.1"
|
||||
|
||||
"@types/classnames@^2.2.9":
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.3.1.tgz#3c2467aa0f1a93f1f021e3b9bcf938bd5dfdc0dd"
|
||||
integrity sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A==
|
||||
dependencies:
|
||||
classnames "*"
|
||||
|
||||
"@types/d3-color@^1":
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.1.tgz#0d9746c84dfef28807b2989eed4f37b2575e1f33"
|
||||
integrity sha512-xkPLi+gbgUU9ED6QX4g6jqYL2KCB0/3AlM+ncMGqn49OgH0gFMY/ITGqPF8HwEiLzJaC+2L0I+gNwBgABv1Pvg==
|
||||
|
||||
"@types/d3-interpolate@^1.3.1":
|
||||
version "1.4.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.2.tgz#88902a205f682773a517612299a44699285eed7b"
|
||||
integrity sha512-ylycts6llFf8yAEs1tXzx2loxxzDZHseuhPokrqKprTQSTcD3JbJI1omZP1rphsELZO3Q+of3ff0ZS7+O6yVzg==
|
||||
dependencies:
|
||||
"@types/d3-color" "^1"
|
||||
|
||||
"@types/d3-path@^1", "@types/d3-path@^1.0.8":
|
||||
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.2.1":
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-3.3.0.tgz#7ab91db0186bac0f24834ceb33f970e829f2fba1"
|
||||
integrity sha512-rJj4nh/71Rw5bZgTF5cA5rW60WT3x8RbivEsScgQ66sqFnYZRmuyKSayyo7JiP+c9KJJiQhY9JXBmY16FZa3+g==
|
||||
dependencies:
|
||||
"@types/d3-time" "*"
|
||||
|
||||
"@types/d3-shape@^1.3.1":
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-1.3.5.tgz#c0164c1be1429473016f855871d487f806c4e968"
|
||||
integrity sha512-aPEax03owTAKynoK8ZkmkZEDZvvT4Y5pWgii4Jp4oQt0gH45j6siDl9gNDVC5kl64XHN2goN9jbYoHK88tFAcA==
|
||||
dependencies:
|
||||
"@types/d3-path" "^1"
|
||||
|
||||
"@types/d3-time@*", "@types/d3-time@^2.0.0":
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-2.1.0.tgz#95708e5c92b199959806fd2116eeb3dfa0e9661c"
|
||||
integrity sha512-qVCiT93utxN0cawScyQuNx8H82vBvZXSClZfgOu3l3dRRlRO6FjKEZlaPgXG9XUFjIAOsA4kAJY101vobHeJLQ==
|
||||
|
||||
"@types/estree@*":
|
||||
version "0.0.48"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.48.tgz#18dc8091b285df90db2f25aa7d906cfc394b7f74"
|
||||
@@ -934,7 +985,7 @@
|
||||
dependencies:
|
||||
"@types/lodash" "*"
|
||||
|
||||
"@types/lodash@*":
|
||||
"@types/lodash@*", "@types/lodash@^4.14.146", "@types/lodash@^4.14.160":
|
||||
version "4.14.170"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.170.tgz#0d67711d4bf7f4ca5147e9091b847479b87925d6"
|
||||
integrity sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q==
|
||||
@@ -973,6 +1024,15 @@
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/react@^17.0.0":
|
||||
version "17.0.11"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.11.tgz#67fcd0ddbf5a0b083a0f94e926c7d63f3b836451"
|
||||
integrity sha512-yFRQbD+whVonItSk7ZzP/L+gPTJVBkL/7shLEF+i9GC/1cV3JmUxEQz6+9ylhUpWSDuqo1N9qEvqS6vTj4USUA==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
"@types/scheduler" "*"
|
||||
csstype "^3.0.2"
|
||||
|
||||
"@types/scheduler@*":
|
||||
version "0.16.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
|
||||
@@ -988,6 +1048,68 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/warning/-/warning-3.0.0.tgz#0d2501268ad8f9962b740d387c4654f5f8e23e52"
|
||||
integrity sha1-DSUBJorY+ZYrdA04fEZU9fjiPlI=
|
||||
|
||||
"@visx/curve@1.7.0":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/curve/-/curve-1.7.0.tgz#b8c8ae902de469ae43014c78ed9bfda8aed8137c"
|
||||
integrity sha512-n0/SHM4YXjke+aEinhHFZPLMxWu3jbqtvqzfGJyibX8OmbDjavk9P+MHfGokUcw0xHy6Ch3YTuwbYuvVw5ny9A==
|
||||
dependencies:
|
||||
"@types/d3-shape" "^1.3.1"
|
||||
d3-shape "^1.0.6"
|
||||
|
||||
"@visx/group@1.7.0", "@visx/group@^1.7.0":
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/group/-/group-1.7.0.tgz#e0ef2efbe00ef05326215d65b3d8a2b114df4f35"
|
||||
integrity sha512-rzSXtV0+MHUyK+rwhVSV4qaHdzGi3Me3PRFXJSIAKVfoJIZczOkudUOLy34WvSrRlVyoFvGL7k9U5g8wHyY3nw==
|
||||
dependencies:
|
||||
"@types/classnames" "^2.2.9"
|
||||
"@types/react" "*"
|
||||
classnames "^2.2.5"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
"@visx/scale@1.11.1":
|
||||
version "1.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@visx/scale/-/scale-1.11.1.tgz#8dab1dd95b066d00edcf897c5e0bae04d2fbb4ba"
|
||||
integrity sha512-VXQ/VXmDh0IjHHNVFzUNKPa9GBVSITOrMZ5RECYRIBJ6zdbs8QuowTwmtsyLaINvY2N9O+xKVokfIohnTkCMKw==
|
||||
dependencies:
|
||||
"@types/d3-interpolate" "^1.3.1"
|
||||
"@types/d3-scale" "^3.2.1"
|
||||
"@types/d3-time" "^2.0.0"
|
||||
d3-interpolate "^1.4.0"
|
||||
d3-scale "^3.2.3"
|
||||
d3-time "^2.1.1"
|
||||
|
||||
"@visx/shape@^1.12.0":
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/shape/-/shape-1.12.0.tgz#c62c6d366f2afd79286155b751985202c04e642a"
|
||||
integrity sha512-BiY5nXrpg/CdY2Vd/oIaEsQoYjL7Nb+7IGsRCT5DVNelulgnwU1P13SqdVvs4FUtp/WYy97djQuIrR/6zCHdyw==
|
||||
dependencies:
|
||||
"@types/classnames" "^2.2.9"
|
||||
"@types/d3-path" "^1.0.8"
|
||||
"@types/d3-shape" "^1.3.1"
|
||||
"@types/lodash" "^4.14.146"
|
||||
"@types/react" "*"
|
||||
"@visx/curve" "1.7.0"
|
||||
"@visx/group" "1.7.0"
|
||||
"@visx/scale" "1.11.1"
|
||||
classnames "^2.2.5"
|
||||
d3-path "^1.0.5"
|
||||
d3-shape "^1.2.0"
|
||||
lodash "^4.17.15"
|
||||
prop-types "^15.5.10"
|
||||
|
||||
"@visx/text@^1.10.0":
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@visx/text/-/text-1.10.0.tgz#d9b9fb3d195f6843312025dc672b958529d2d4f6"
|
||||
integrity sha512-2y56LxbbSHAlu8XP0cARB9JlhPx0HlQyIC4iKUzj36+iJaBiw9wUwLb9RbT/rY715V+6VzU7WCNCxoa4lDr9Sg==
|
||||
dependencies:
|
||||
"@types/classnames" "^2.2.9"
|
||||
"@types/lodash" "^4.14.160"
|
||||
"@types/react" "*"
|
||||
classnames "^2.2.5"
|
||||
lodash "^4.17.20"
|
||||
prop-types "^15.7.2"
|
||||
reduce-css-calc "^1.3.0"
|
||||
|
||||
"@vitejs/plugin-react-refresh@^1.3.1":
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/@vitejs/plugin-react-refresh/-/plugin-react-refresh-1.3.3.tgz#d5afb3e0463f368a8afadfdd7305fe5c5fe78a6a"
|
||||
@@ -1034,6 +1156,16 @@ babel-plugin-macros@^2.6.1:
|
||||
cosmiconfig "^6.0.0"
|
||||
resolve "^1.12.0"
|
||||
|
||||
balanced-match@^0.4.2:
|
||||
version "0.4.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838"
|
||||
integrity sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=
|
||||
|
||||
balanced-match@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||
|
||||
binary-extensions@^2.0.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d"
|
||||
@@ -1096,6 +1228,11 @@ chart.js@^3.3.2:
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.1"
|
||||
|
||||
classnames@*, classnames@^2.2.5:
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
|
||||
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
|
||||
|
||||
color-convert@^1.9.0:
|
||||
version "1.9.3"
|
||||
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
|
||||
@@ -1155,6 +1292,79 @@ csstype@^3.0.2, csstype@^3.0.6:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
|
||||
integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
|
||||
|
||||
d3-array@2, 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:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.4.1.tgz#c52002bf8846ada4424d55d97982fef26eb3bc8a"
|
||||
integrity sha512-p2sTHSLCJI2QKunbGb7ocOh7DgTAn8IrLx21QRc/BSnodXM4sv6aLQlnfpvehFMLZEfBc6g9pH9SWQccFYfJ9Q==
|
||||
|
||||
"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":
|
||||
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-interpolate@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.4.0.tgz#526e79e2d80daa383f9e0c1c1c7dcc0f0583e987"
|
||||
integrity sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==
|
||||
dependencies:
|
||||
d3-color "1"
|
||||
|
||||
d3-path@1, d3-path@^1.0.5:
|
||||
version "1.0.9"
|
||||
resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-1.0.9.tgz#48c050bb1fe8c262493a8caf5524e3e9591701cf"
|
||||
integrity sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg==
|
||||
|
||||
d3-scale@^3.2.3:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-3.3.0.tgz#28c600b29f47e5b9cd2df9749c206727966203f3"
|
||||
integrity sha512-1JGp44NQCt5d1g+Yy+GeOnZP7xHo0ii8zsQp6PGzd+C1/dl0KGsp9A7Mxwp+1D1o4unbTTxVdU/ZOIEBoeZPbQ==
|
||||
dependencies:
|
||||
d3-array "^2.3.0"
|
||||
d3-format "1 - 2"
|
||||
d3-interpolate "1.2.0 - 2"
|
||||
d3-time "^2.1.1"
|
||||
d3-time-format "2 - 3"
|
||||
|
||||
d3-shape@^1.0.6, d3-shape@^1.2.0:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-1.3.7.tgz#df63801be07bc986bc54f63789b4fe502992b5d7"
|
||||
integrity sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==
|
||||
dependencies:
|
||||
d3-path "1"
|
||||
|
||||
"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", d3-time@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682"
|
||||
integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==
|
||||
dependencies:
|
||||
d3-array "2"
|
||||
|
||||
debounce@^1.2.0:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
|
||||
@@ -1322,6 +1532,11 @@ import-fresh@^3.1.0:
|
||||
parent-module "^1.0.0"
|
||||
resolve-from "^4.0.0"
|
||||
|
||||
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==
|
||||
|
||||
invariant@^2.2.4:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6"
|
||||
@@ -1402,7 +1617,7 @@ lodash.mergewith@4.6.2:
|
||||
resolved "https://registry.yarnpkg.com/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz#617121f89ac55f59047c7aec1ccd6654c6590f55"
|
||||
integrity sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==
|
||||
|
||||
lodash@^4.17.19:
|
||||
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@@ -1414,6 +1629,11 @@ loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
math-expression-evaluator@^1.2.14:
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/math-expression-evaluator/-/math-expression-evaluator-1.3.7.tgz#1b62225db86af06f7ea1fd9576a34af605a5b253"
|
||||
integrity sha512-nrbaifCl42w37hYd6oRLvoymFK42tWB+WQTMFtksDGQMi5GvlJwnz/CsS30FFAISFLtX+A0csJ0xLiuuyyec7w==
|
||||
|
||||
minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
@@ -1500,7 +1720,7 @@ postcss@^8.2.10:
|
||||
nanoid "^3.1.23"
|
||||
source-map-js "^0.6.2"
|
||||
|
||||
prop-types@^15.6.2, prop-types@^15.7.2:
|
||||
prop-types@^15.5.10, 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==
|
||||
@@ -1652,6 +1872,22 @@ readdirp@~3.5.0:
|
||||
dependencies:
|
||||
picomatch "^2.2.1"
|
||||
|
||||
reduce-css-calc@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz#747c914e049614a4c9cfbba629871ad1d2927716"
|
||||
integrity sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=
|
||||
dependencies:
|
||||
balanced-match "^0.4.2"
|
||||
math-expression-evaluator "^1.2.14"
|
||||
reduce-function-call "^1.0.1"
|
||||
|
||||
reduce-function-call@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/reduce-function-call/-/reduce-function-call-1.0.3.tgz#60350f7fb252c0a67eb10fd4694d16909971300f"
|
||||
integrity sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==
|
||||
dependencies:
|
||||
balanced-match "^1.0.0"
|
||||
|
||||
reduce-reducers@^0.4.3:
|
||||
version "0.4.3"
|
||||
resolved "https://registry.yarnpkg.com/reduce-reducers/-/reduce-reducers-0.4.3.tgz#8e052618801cd8fc2714b4915adaa8937eb6d66c"
|
||||
|
||||
Reference in New Issue
Block a user