@parca/profile 0.16.252 → 0.16.254
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/ProfileExplorer/index.d.ts +1 -1
- package/dist/ProfileExplorer/index.js +11 -4
- package/dist/ProfileIcicleGraph/IcicleGraph/index.js +2 -1
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.js +6 -6
- package/dist/ProfileIcicleGraph/IcicleGraphArrow/index.js +2 -1
- package/dist/ProfileIcicleGraph/index.js +26 -6
- package/dist/ProfileMetricsGraph/index.js +11 -5
- package/dist/styles.css +1 -1
- package/package.json +6 -6
- package/src/ProfileExplorer/index.tsx +19 -12
- package/src/ProfileIcicleGraph/IcicleGraph/index.tsx +4 -1
- package/src/ProfileIcicleGraph/IcicleGraphArrow/ColorStackLegend.tsx +26 -17
- package/src/ProfileIcicleGraph/IcicleGraphArrow/index.tsx +8 -5
- package/src/ProfileIcicleGraph/index.tsx +65 -14
- package/src/ProfileMetricsGraph/index.tsx +19 -12
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,14 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
## 0.16.254 (2023-09-14)
|
|
7
|
+
|
|
8
|
+
**Note:** Version bump only for package @parca/profile
|
|
9
|
+
|
|
10
|
+
## [0.16.253](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.252...@parca/profile@0.16.253) (2023-09-11)
|
|
11
|
+
|
|
12
|
+
**Note:** Version bump only for package @parca/profile
|
|
13
|
+
|
|
6
14
|
## 0.16.252 (2023-09-11)
|
|
7
15
|
|
|
8
16
|
**Note:** Version bump only for package @parca/profile
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import { QueryServiceClient } from '@parca/client';
|
|
3
|
-
import type
|
|
3
|
+
import { type NavigateFunction } from '@parca/utilities';
|
|
4
4
|
interface ProfileExplorerProps {
|
|
5
5
|
queryClient: QueryServiceClient;
|
|
6
6
|
queryParams: any;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -15,10 +15,14 @@ import { useEffect, useState } from 'react';
|
|
|
15
15
|
import { Provider } from 'react-redux';
|
|
16
16
|
import { DateTimeRange, KeyDownProvider, useParcaContext } from '@parca/components';
|
|
17
17
|
import { store } from '@parca/store';
|
|
18
|
+
import { capitalizeOnlyFirstLetter } from '@parca/utilities';
|
|
18
19
|
import { ProfileSelectionFromParams, SuffixParams } from '..';
|
|
19
20
|
import { useProfileTypes } from '../ProfileSelector';
|
|
20
21
|
import ProfileExplorerCompare from './ProfileExplorerCompare';
|
|
21
22
|
import ProfileExplorerSingle from './ProfileExplorerSingle';
|
|
23
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
24
|
+
return (_jsx("div", { className: "relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700", role: "alert", children: _jsx("span", { className: "block sm:inline", children: errorMessage }) }));
|
|
25
|
+
};
|
|
22
26
|
const getExpressionAsAString = (expression) => {
|
|
23
27
|
const x = Array.isArray(expression) ? expression.join() : expression;
|
|
24
28
|
return x;
|
|
@@ -45,10 +49,10 @@ const swapQueryParameters = (o) => {
|
|
|
45
49
|
};
|
|
46
50
|
const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
47
51
|
const { loading: profileTypesLoading, data: profileTypesData, error: profileTypesError, } = useProfileTypes(queryClient);
|
|
48
|
-
const { loader, noDataPrompt, onError } = useParcaContext();
|
|
52
|
+
const { loader, noDataPrompt, onError, authenticationErrorMessage } = useParcaContext();
|
|
49
53
|
useEffect(() => {
|
|
50
54
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
51
|
-
onError?.(profileTypesError
|
|
55
|
+
onError?.(profileTypesError);
|
|
52
56
|
}
|
|
53
57
|
}, [profileTypesError, onError]);
|
|
54
58
|
/* eslint-disable @typescript-eslint/naming-convention */
|
|
@@ -83,7 +87,10 @@ const ProfileExplorerApp = ({ queryClient, queryParams, navigateTo, }) => {
|
|
|
83
87
|
return _jsx(_Fragment, { children: noDataPrompt });
|
|
84
88
|
}
|
|
85
89
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
86
|
-
|
|
90
|
+
if (authenticationErrorMessage !== undefined && profileTypesError.code === 'UNAUTHENTICATED') {
|
|
91
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
92
|
+
}
|
|
93
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(profileTypesError.message) });
|
|
87
94
|
}
|
|
88
95
|
const sanitizedRange = sanitizeDateRange(time_selection_a, from_a, to_a);
|
|
89
96
|
time_selection_a = sanitizedRange.time_selection_a;
|
|
@@ -26,6 +26,7 @@ export const IcicleGraph = memo(function IcicleGraph({ graph, total, filtered, w
|
|
|
26
26
|
const coloredGraph = useColoredGraph(graph);
|
|
27
27
|
const currentSearchString = selectQueryParam('search_string') ?? '';
|
|
28
28
|
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
29
|
+
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
29
30
|
useEffect(() => {
|
|
30
31
|
if (ref.current != null) {
|
|
31
32
|
setHeight(ref?.current.getBoundingClientRect().height);
|
|
@@ -40,6 +41,6 @@ export const IcicleGraph = memo(function IcicleGraph({ graph, total, filtered, w
|
|
|
40
41
|
if (coloredGraph.root === undefined || width === undefined) {
|
|
41
42
|
return _jsx(_Fragment, {});
|
|
42
43
|
}
|
|
43
|
-
return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode }), _jsx(GraphTooltip, { unit: sampleUnit, total: total, totalUnfiltered: total + filtered, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) }) }) })] }));
|
|
44
|
+
return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [isColorStackLegendEnabled && (_jsx(ColorStackLegend, { navigateTo: navigateTo, compareMode: compareMode })), _jsx(GraphTooltip, { unit: sampleUnit, total: total, totalUnfiltered: total + filtered, contextElement: svg.current, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function }), _jsx("svg", { className: "font-robotoMono", width: width, height: height, preserveAspectRatio: "xMinYMid", ref: svg, children: _jsx("g", { ref: ref, children: _jsx("g", { transform: 'translate(0, 0)', children: _jsx(IcicleNode, { x: 0, y: 0, totalWidth: width, height: RowHeight, setCurPath: setCurPath, curPath: curPath, data: coloredGraph.root, strings: coloredGraph.stringTable, mappings: coloredGraph.mapping, locations: coloredGraph.locations, functions: coloredGraph.function, total: total, xScale: xScale, path: [], level: 0, isRoot: true, searchString: currentSearchString, compareMode: compareMode }) }) }) })] }));
|
|
44
45
|
});
|
|
45
46
|
export default IcicleGraph;
|
|
@@ -40,10 +40,10 @@ const ColorStackLegend = ({ mappingColors, navigateTo, compareMode = false, }) =
|
|
|
40
40
|
if (colorProfileName === 'default' || compareMode) {
|
|
41
41
|
return _jsx(_Fragment, {});
|
|
42
42
|
}
|
|
43
|
-
return (_jsx("div", { className: "my-
|
|
43
|
+
return (_jsx("div", { className: "my-4 flex w-full flex-wrap justify-start", children: stackColorArray.map(([feature, color]) => {
|
|
44
44
|
const filteringAllowed = feature !== EVERYTHING_ELSE;
|
|
45
45
|
const isHighlighted = currentSearchString === feature;
|
|
46
|
-
return (_jsxs("div", { className: cx('flex items-center justify-between
|
|
46
|
+
return (_jsxs("div", { className: cx('flex-no-wrap mb-1 flex w-1/5 items-center justify-between text-ellipsis p-1', {
|
|
47
47
|
'cursor-pointer': filteringAllowed,
|
|
48
48
|
'bg-gray-200 dark:bg-gray-800': isHighlighted,
|
|
49
49
|
}), onClick: () => {
|
|
@@ -55,10 +55,10 @@ const ColorStackLegend = ({ mappingColors, navigateTo, compareMode = false, }) =
|
|
|
55
55
|
return;
|
|
56
56
|
}
|
|
57
57
|
setSearchString(feature);
|
|
58
|
-
}, children: [_jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "mr-1 inline-block h-4 w-4", style: { backgroundColor: color } }), _jsx("
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
}, children: [_jsxs("div", { className: "flex w-11/12 items-center justify-start", children: [_jsx("div", { className: "flex w-5 items-center", children: _jsx("div", { className: "mr-1 inline-block h-4 w-4", style: { backgroundColor: color } }) }), _jsx("div", { className: "shrink overflow-hidden text-ellipsis whitespace-nowrap text-sm hover:whitespace-normal", children: feature })] }), _jsx("div", { className: "flex w-1/12 justify-end", children: isHighlighted && (_jsx(Icon, { icon: "radix-icons:cross-circled", onClick: e => {
|
|
59
|
+
setSearchString('');
|
|
60
|
+
e.stopPropagation();
|
|
61
|
+
} })) })] }, feature));
|
|
62
62
|
}) }));
|
|
63
63
|
};
|
|
64
64
|
export default ColorStackLegend;
|
|
@@ -49,6 +49,7 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
49
49
|
const ref = useRef(null);
|
|
50
50
|
const currentSearchString = selectQueryParam('search_string') ?? '';
|
|
51
51
|
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
52
|
+
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
52
53
|
const mappings = useMemo(() => {
|
|
53
54
|
// Read the mappings from the dictionary that contains all mapping strings.
|
|
54
55
|
// This is great, as might only have a dozen or so mappings,
|
|
@@ -135,6 +136,6 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ arrow, total, f
|
|
|
135
136
|
if (table.numRows === 0 || width === undefined) {
|
|
136
137
|
return _jsx(_Fragment, {});
|
|
137
138
|
}
|
|
138
|
-
return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode }), dockedMetainfo ? (_jsx(DockedGraphTooltip, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, unit: sampleUnit })) : (_jsx(GraphTooltipArrow, { contextElement: svg.current, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, isFixed: false, total: total, totalUnfiltered: total + filtered, unit: sampleUnit, navigateTo: navigateTo }) })), root] }));
|
|
139
|
+
return (_jsxs("div", { onMouseLeave: () => dispatch(setHoveringNode(undefined)), children: [isColorStackLegendEnabled && (_jsx(ColorStackLegend, { mappingColors: mappingColors, navigateTo: navigateTo, compareMode: compareMode })), dockedMetainfo ? (_jsx(DockedGraphTooltip, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, total: total, totalUnfiltered: total + filtered, unit: sampleUnit })) : (_jsx(GraphTooltipArrow, { contextElement: svg.current, children: _jsx(GraphTooltipArrowContent, { table: table, row: hoveringRow, level: hoveringLevel ?? 0, isFixed: false, total: total, totalUnfiltered: total + filtered, unit: sampleUnit, navigateTo: navigateTo }) })), root] }));
|
|
139
140
|
});
|
|
140
141
|
export default IcicleGraphArrow;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx,
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -15,11 +15,28 @@ import { Fragment, useCallback, useEffect, useMemo } from 'react';
|
|
|
15
15
|
import { Menu, Transition } from '@headlessui/react';
|
|
16
16
|
import { Icon } from '@iconify/react';
|
|
17
17
|
import { Button, Select, useParcaContext, useURLState } from '@parca/components';
|
|
18
|
-
import {
|
|
18
|
+
import { USER_PREFERENCES, useUserPreference } from '@parca/hooks';
|
|
19
|
+
import { capitalizeOnlyFirstLetter, divide, selectQueryParam, } from '@parca/utilities';
|
|
19
20
|
import DiffLegend from '../components/DiffLegend';
|
|
20
21
|
import IcicleGraph from './IcicleGraph';
|
|
21
22
|
import IcicleGraphArrow, { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_NAME, FIELD_LABELS, } from './IcicleGraphArrow';
|
|
22
23
|
const numberFormatter = new Intl.NumberFormat('en-US');
|
|
24
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
25
|
+
return _jsx("div", { className: "flex justify-center p-10", children: errorMessage });
|
|
26
|
+
};
|
|
27
|
+
const ShowHideLegendButton = ({ navigateTo }) => {
|
|
28
|
+
const [colorStackLegend, setStoreColorStackLegend] = useURLState({
|
|
29
|
+
param: 'color_stack_legend',
|
|
30
|
+
navigateTo,
|
|
31
|
+
});
|
|
32
|
+
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
33
|
+
const isColorStackLegendEnabled = colorStackLegend === 'true';
|
|
34
|
+
const [colorProfileName] = useUserPreference(USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key);
|
|
35
|
+
const setColorStackLegend = useCallback((value) => {
|
|
36
|
+
setStoreColorStackLegend(value);
|
|
37
|
+
}, [setStoreColorStackLegend]);
|
|
38
|
+
return (_jsx(_Fragment, { children: colorProfileName === 'default' || compareMode ? null : (_jsxs(Button, { className: "gap-2", variant: "neutral", onClick: () => setColorStackLegend(isColorStackLegendEnabled ? 'false' : 'true'), children: [isColorStackLegendEnabled ? 'Hide legend' : 'Show legend', _jsx(Icon, { icon: isColorStackLegendEnabled ? 'ph:eye-closed' : 'ph:eye', width: 20 })] })) }));
|
|
39
|
+
};
|
|
23
40
|
const GroupAndSortActionButtons = ({ navigateTo }) => {
|
|
24
41
|
const [storeSortBy = FIELD_FUNCTION_NAME, setStoreSortBy] = useURLState({
|
|
25
42
|
param: 'sort_by',
|
|
@@ -50,7 +67,7 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
|
|
|
50
67
|
return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy })] }));
|
|
51
68
|
};
|
|
52
69
|
const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, width, }) {
|
|
53
|
-
const { loader } = useParcaContext();
|
|
70
|
+
const { loader, onError, authenticationErrorMessage } = useParcaContext();
|
|
54
71
|
const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
55
72
|
const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
|
|
56
73
|
param: 'sort_by',
|
|
@@ -78,14 +95,17 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, arrow, to
|
|
|
78
95
|
if (setActionButtons === undefined) {
|
|
79
96
|
return;
|
|
80
97
|
}
|
|
81
|
-
setActionButtons(_jsx("div", { className: "flex w-full justify-end gap-2 pb-2", children: _jsxs("div", { className: "ml-2 flex w-full items-end justify-between gap-2", children: [arrow !== undefined && _jsx(GroupAndSortActionButtons, { navigateTo: navigateTo }), _jsx(
|
|
98
|
+
setActionButtons(_jsx("div", { className: "flex w-full justify-end gap-2 pb-2", children: _jsxs("div", { className: "ml-2 flex w-full items-end justify-between gap-2", children: [arrow !== undefined && _jsx(GroupAndSortActionButtons, { navigateTo: navigateTo }), _jsx(ShowHideLegendButton, { navigateTo: navigateTo }), _jsx(Button, { variant: "neutral", onClick: () => setNewCurPath([]), disabled: curPath.length === 0, children: "Reset View" })] }) }));
|
|
82
99
|
}, [navigateTo, arrow, curPath, setNewCurPath, setActionButtons]);
|
|
83
100
|
if (loading) {
|
|
84
101
|
return _jsx("div", { className: "h-96", children: loader });
|
|
85
102
|
}
|
|
86
103
|
if (error != null) {
|
|
87
|
-
|
|
88
|
-
|
|
104
|
+
onError?.(error);
|
|
105
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
106
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
107
|
+
}
|
|
108
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(error.message) });
|
|
89
109
|
}
|
|
90
110
|
if (graph === undefined && arrow === undefined)
|
|
91
111
|
return _jsx("div", { className: "mx-auto text-center", children: "No data..." });
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
// Copyright 2022 The Parca Authors
|
|
3
3
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
// you may not use this file except in compliance with the License.
|
|
@@ -15,10 +15,13 @@ import { useEffect, useState } from 'react';
|
|
|
15
15
|
import { Duration, Timestamp } from '@parca/client';
|
|
16
16
|
import { useGrpcMetadata, useParcaContext } from '@parca/components';
|
|
17
17
|
import { Query } from '@parca/parser';
|
|
18
|
-
import { getStepDuration } from '@parca/utilities';
|
|
18
|
+
import { capitalizeOnlyFirstLetter, getStepDuration } from '@parca/utilities';
|
|
19
19
|
import MetricsGraph from '../MetricsGraph';
|
|
20
20
|
import { useMetricsGraphDimensions } from '../MetricsGraph/useMetricsGraphDimensions';
|
|
21
21
|
import useDelayedLoader from '../useDelayedLoader';
|
|
22
|
+
const ErrorContent = ({ errorMessage }) => {
|
|
23
|
+
return (_jsx("div", { className: "relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700", role: "alert", children: _jsx("span", { className: "block sm:inline", children: errorMessage }) }));
|
|
24
|
+
};
|
|
22
25
|
export const ProfileMetricsEmptyState = ({ message }) => {
|
|
23
26
|
return (_jsx("div", { className: "flex h-full w-full flex-col items-center justify-center", children: _jsx("p", { children: message }) }));
|
|
24
27
|
};
|
|
@@ -58,11 +61,11 @@ export const useQueryRange = (client, queryExpression, start, end) => {
|
|
|
58
61
|
const ProfileMetricsGraph = ({ queryClient, queryExpression, profile, from, to, setTimeRange, addLabelMatcher, onPointClick, comparing = false, }) => {
|
|
59
62
|
const { isLoading, response, error } = useQueryRange(queryClient, queryExpression, from, to);
|
|
60
63
|
const isLoaderVisible = useDelayedLoader(isLoading);
|
|
61
|
-
const { loader, onError, perf } = useParcaContext();
|
|
64
|
+
const { loader, onError, perf, authenticationErrorMessage } = useParcaContext();
|
|
62
65
|
const { width, height, margin } = useMetricsGraphDimensions(comparing);
|
|
63
66
|
useEffect(() => {
|
|
64
67
|
if (error !== null) {
|
|
65
|
-
onError?.(error
|
|
68
|
+
onError?.(error);
|
|
66
69
|
}
|
|
67
70
|
}, [error, onError]);
|
|
68
71
|
useEffect(() => {
|
|
@@ -77,7 +80,10 @@ const ProfileMetricsGraph = ({ queryClient, queryExpression, profile, from, to,
|
|
|
77
80
|
return _jsx(_Fragment, { children: loader });
|
|
78
81
|
}
|
|
79
82
|
if (error !== null) {
|
|
80
|
-
|
|
83
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
84
|
+
return _jsx(ErrorContent, { errorMessage: authenticationErrorMessage });
|
|
85
|
+
}
|
|
86
|
+
return _jsx(ErrorContent, { errorMessage: capitalizeOnlyFirstLetter(error.message) });
|
|
81
87
|
}
|
|
82
88
|
if (dataAvailable) {
|
|
83
89
|
const handleSampleClick = (timestamp, _value, labels) => {
|
package/dist/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.inset-y-0{bottom:0;top:0}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.bottom-0{bottom:0}.z-50{z-index:50}.z-10{z-index:10}.z-20{z-index:20}.m-auto{margin:auto}.m-2{margin:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.mr-3{margin-right:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mr-6{margin-right:1.5rem}.mr-1{margin-right:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-96{height:24rem}.h-6{height:1.5rem}.h-4{height:1rem}.h-full{height:100%}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-5{height:1.25rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.min-h-48{min-height:12rem}.min-h-\[200px\]{min-height:200px}.w-full{width:100%}.w-auto{width:auto}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-4{width:1rem}.w-40{width:10rem}.w-3{width:.75rem}.w-5{width:1.25rem}.w-7{width:1.75rem}.w-9{width:2.25rem}.w-11{width:2.75rem}.w-\[52px\]{width:52px}.w-\[68px\]{width:68px}.w-\[76px\]{width:76px}.w-\[84px\]{width:84px}.w-\[92px\]{width:92px}.w-\[100px\]{width:100px}.w-\[108px\]{width:108px}.w-\[116px\]{width:116px}.w-8{width:2rem}.w-44{width:11rem}.w-\[460px\]{width:460px}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.min-w-\[400px\]{min-width:400px}.max-w-\[500px\]{max-width:500px}.max-w-\[300px\]{max-width:300px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.flex-grow-0{flex-grow:0}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-x-hidden{overflow-x:hidden}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r{border-right-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.border-r-gray-200{--tw-border-opacity:1;border-right-color:rgb(229 231 235/var(--tw-border-opacity))}.border-l-amber-900{--tw-border-opacity:1;border-left-color:rgb(120 53 15/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity))}.bg-yellow-700{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.bg-opacity-90{--tw-bg-opacity:0.9}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-gray-300{stroke:#d1d5db}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-4{padding-bottom:1rem;padding-top:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-0{padding-bottom:0;padding-top:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-8{padding-left:2rem;padding-right:2rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pb-2{padding-bottom:.5rem}.pr-10{padding-right:2.5rem}.pr-2{padding-right:.5rem}.pl-1{padding-left:.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem}.text-lg,.text-xl{line-height:1.75rem}.text-lg{font-size:1.125rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.leading-5{line-height:1.25rem}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-indigo-600{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.focus\:border-indigo-500:focus{--tw-border-opacity:1;border-color:rgb(99 102 241/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-indigo-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(99 102 241/var(--tw-ring-opacity))}.focus\:ring-indigo-600:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border{border-width:1px}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-r-gray-700{--tw-border-opacity:1;border-right-color:rgb(55 65 81/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-yellow-700{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-opacity-80{--tw-bg-opacity:0.8}[class~=theme-dark] .dark\:stroke-gray-500{stroke:#6b7280}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}[class~=theme-dark] .dark\:ring-white{--tw-ring-opacity:1;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity))}[class~=theme-dark] .dark\:ring-opacity-20{--tw-ring-opacity:0.2}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
|
1
|
+
/*! tailwindcss v3.2.4 | MIT License | https://tailwindcss.com*/*,:after,:before{border:0 solid #e5e7eb;box-sizing:border-box}:after,:before{--tw-content:""}html{-webkit-text-size-adjust:100%;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4}body{line-height:inherit;margin:0}hr{border-top-width:1px;color:inherit;height:0}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-collapse:collapse;border-color:inherit;text-indent:0}button,input,optgroup,select,textarea{color:inherit;font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;margin:0;padding:0}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dd,dl,figure,h1,h2,h3,h4,h5,h6,hr,p,pre{margin:0}fieldset{margin:0}fieldset,legend{padding:0}menu,ol,ul{list-style:none;margin:0;padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{color:#9ca3af;opacity:1}input::placeholder,textarea::placeholder{color:#9ca3af;opacity:1}[role=button],button{cursor:pointer}:disabled{cursor:default}audio,canvas,embed,iframe,img,object,svg,video{display:block;vertical-align:middle}img,video{height:auto;max-width:100%}[hidden]{display:none}*,:after,:before{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:rgba(59,130,246,.5);--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (min-width:640px){.container{max-width:640px}}@media (min-width:768px){.container{max-width:768px}}@media (min-width:1024px){.container{max-width:1024px}}@media (min-width:1280px){.container{max-width:1280px}}@media (min-width:1536px){.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.-inset-2{bottom:-.5rem;left:-.5rem;right:-.5rem;top:-.5rem}.inset-y-0{bottom:0;top:0}.left-\[25px\]{left:25px}.left-0{left:0}.top-\[-46px\]{top:-46px}.right-0{right:0}.bottom-0{bottom:0}.z-50{z-index:50}.z-10{z-index:10}.z-20{z-index:20}.m-auto{margin:auto}.m-2{margin:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.mx-2{margin-left:.5rem;margin-right:.5rem}.my-2{margin-bottom:.5rem;margin-top:.5rem}.my-20{margin-bottom:5rem;margin-top:5rem}.my-6{margin-bottom:1.5rem;margin-top:1.5rem}.my-4{margin-bottom:1rem;margin-top:1rem}.mr-3{margin-right:.75rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.ml-2{margin-left:.5rem}.ml-3{margin-left:.75rem}.mb-2{margin-bottom:.5rem}.mb-4{margin-bottom:1rem}.mr-6{margin-right:1.5rem}.mr-1{margin-right:.25rem}.mb-1{margin-bottom:.25rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-8{margin-top:2rem}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-fit{height:-moz-fit-content;height:fit-content}.h-10{height:2.5rem}.h-96{height:24rem}.h-6{height:1.5rem}.h-4{height:1rem}.h-full{height:100%}.h-1{height:.25rem}.h-\[80vh\]{height:80vh}.h-5{height:1.25rem}.max-h-\[400px\]{max-height:400px}.min-h-52{min-height:13rem}.min-h-48{min-height:12rem}.min-h-\[200px\]{min-height:200px}.w-full{width:100%}.w-auto{width:auto}.w-1\/4{width:25%}.w-3\/4{width:75%}.w-\[500px\]{width:500px}.w-4{width:1rem}.w-40{width:10rem}.w-3{width:.75rem}.w-5{width:1.25rem}.w-7{width:1.75rem}.w-9{width:2.25rem}.w-11{width:2.75rem}.w-\[52px\]{width:52px}.w-\[68px\]{width:68px}.w-\[76px\]{width:76px}.w-\[84px\]{width:84px}.w-\[92px\]{width:92px}.w-\[100px\]{width:100px}.w-\[108px\]{width:108px}.w-\[116px\]{width:116px}.w-8{width:2rem}.w-44{width:11rem}.w-\[460px\]{width:460px}.w-1\/5{width:20%}.w-11\/12{width:91.666667%}.w-1\/12{width:8.333333%}.w-16{width:4rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-\[420px\]{width:420px}.min-w-\[300px\]{min-width:300px}.min-w-\[400px\]{min-width:400px}.max-w-\[500px\]{max-width:500px}.max-w-\[300px\]{max-width:300px}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.shrink-0{flex-shrink:0}.shrink{flex-shrink:1}.flex-grow-0{flex-grow:0}.flex-grow{flex-grow:1}.table-auto{table-layout:auto}.table-fixed{table-layout:fixed}.translate-y-1{--tw-translate-y:0.25rem}.translate-y-0,.translate-y-1{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-0{--tw-translate-y:0px}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.cursor-default{cursor:default}.cursor-not-allowed{cursor:not-allowed}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.content-start{align-content:flex-start}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-4{gap:1rem}.gap-2{gap:.5rem}.gap-1{gap:.25rem}.gap-3{gap:.75rem}.gap-x-2{-moz-column-gap:.5rem;column-gap:.5rem}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse:0;margin-bottom:calc(1.25rem*var(--tw-space-y-reverse));margin-top:calc(1.25rem*(1 - var(--tw-space-y-reverse)))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-x-hidden{overflow-x:hidden}.text-ellipsis{text-overflow:ellipsis}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.rounded-l{border-bottom-left-radius:.25rem;border-top-left-radius:.25rem}.rounded-r{border-bottom-right-radius:.25rem;border-top-right-radius:.25rem}.border{border-width:1px}.border-r{border-right-width:1px}.border-l{border-left-width:1px}.border-t{border-top-width:1px}.border-r-0{border-right-width:0}.border-l-0{border-left-width:0}.border-gray-300{--tw-border-opacity:1;border-color:rgb(209 213 219/var(--tw-border-opacity))}.border-red-400{--tw-border-opacity:1;border-color:rgb(248 113 113/var(--tw-border-opacity))}.border-gray-200{--tw-border-opacity:1;border-color:rgb(229 231 235/var(--tw-border-opacity))}.border-gray-400{--tw-border-opacity:1;border-color:rgb(156 163 175/var(--tw-border-opacity))}.border-r-gray-200{--tw-border-opacity:1;border-right-color:rgb(229 231 235/var(--tw-border-opacity))}.border-l-amber-900{--tw-border-opacity:1;border-left-color:rgb(120 53 15/var(--tw-border-opacity))}.bg-gray-50{--tw-bg-opacity:1;background-color:rgb(249 250 251/var(--tw-bg-opacity))}.bg-gray-200{--tw-bg-opacity:1;background-color:rgb(229 231 235/var(--tw-bg-opacity))}.bg-indigo-600{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.bg-white{--tw-bg-opacity:1;background-color:rgb(255 255 255/var(--tw-bg-opacity))}.bg-red-100{--tw-bg-opacity:1;background-color:rgb(254 226 226/var(--tw-bg-opacity))}.bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}.bg-yellow-200{--tw-bg-opacity:1;background-color:rgb(254 240 138/var(--tw-bg-opacity))}.bg-yellow-700{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-inherit{background-color:inherit}.bg-opacity-90{--tw-bg-opacity:0.9}.fill-transparent{fill:transparent}.fill-current{fill:currentColor}.stroke-gray-300{stroke:#d1d5db}.stroke-white{stroke:#fff}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-10{padding:2.5rem}.p-4{padding:1rem}.p-1{padding:.25rem}.px-2{padding-left:.5rem;padding-right:.5rem}.py-1{padding-bottom:.25rem;padding-top:.25rem}.py-2{padding-bottom:.5rem;padding-top:.5rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-4{padding-bottom:1rem;padding-top:1rem}.px-4{padding-left:1rem;padding-right:1rem}.py-3{padding-bottom:.75rem;padding-top:.75rem}.px-3{padding-left:.75rem;padding-right:.75rem}.py-0{padding-bottom:0;padding-top:0}.px-1{padding-left:.25rem;padding-right:.25rem}.px-8{padding-left:2rem;padding-right:2rem}.pr-0{padding-right:0}.pl-3{padding-left:.75rem}.pr-9{padding-right:2.25rem}.pt-2{padding-top:.5rem}.pb-4{padding-bottom:1rem}.pb-2{padding-bottom:.5rem}.pr-10{padding-right:2.5rem}.pr-2{padding-right:.5rem}.pl-1{padding-left:.25rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.text-base{font-size:1rem;line-height:1.5rem}.text-xl{font-size:1.25rem}.text-lg,.text-xl{line-height:1.75rem}.text-lg{font-size:1.125rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.leading-5{line-height:1.25rem}.text-gray-700{--tw-text-opacity:1;color:rgb(55 65 81/var(--tw-text-opacity))}.text-gray-500{--tw-text-opacity:1;color:rgb(107 114 128/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.text-red-700{--tw-text-opacity:1;color:rgb(185 28 28/var(--tw-text-opacity))}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-indigo-600{--tw-text-opacity:1;color:rgb(79 70 229/var(--tw-text-opacity))}.text-gray-900{--tw-text-opacity:1;color:rgb(17 24 39/var(--tw-text-opacity))}.text-black{--tw-text-opacity:1;color:rgb(0 0 0/var(--tw-text-opacity))}.\!text-indigo-600{--tw-text-opacity:1!important;color:rgb(79 70 229/var(--tw-text-opacity))!important}.opacity-100{opacity:1}.opacity-0{opacity:0}.opacity-90{opacity:.9}.opacity-50{opacity:.5}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\]{--tw-shadow:0 0 10px 2px rgba(0,0,0,.3);--tw-shadow-colored:0 0 10px 2px var(--tw-shadow-color)}.shadow-\[0_0_10px_2px_rgba\(0\2c 0\2c 0\2c 0\.3\)\],.shadow-lg{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px rgba(0,0,0,.1),0 4px 6px -4px rgba(0,0,0,.1);--tw-shadow-colored:0 10px 15px -3px var(--tw-shadow-color),0 4px 6px -4px var(--tw-shadow-color)}.shadow-sm{--tw-shadow:0 1px 2px 0 rgba(0,0,0,.05);--tw-shadow-colored:0 1px 2px 0 var(--tw-shadow-color)}.shadow,.shadow-sm{box-shadow:var(--tw-ring-offset-shadow,0 0 #0000),var(--tw-ring-shadow,0 0 #0000),var(--tw-shadow)}.shadow{--tw-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px -1px rgba(0,0,0,.1);--tw-shadow-colored:0 1px 3px 0 var(--tw-shadow-color),0 1px 2px -1px var(--tw-shadow-color)}.ring-1{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.ring-black{--tw-ring-opacity:1;--tw-ring-color:rgb(0 0 0/var(--tw-ring-opacity))}.ring-opacity-5{--tw-ring-opacity:0.05}.blur{--tw-blur:blur(8px)}.blur,.invert{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.invert{--tw-invert:invert(100%)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition{transition-duration:.15s;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,-webkit-backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter,-webkit-backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1)}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-150{transition-duration:.15s}.ease-in{transition-timing-function:cubic-bezier(.4,0,1,1)}.ease-out{transition-timing-function:cubic-bezier(0,0,.2,1)}.hover\:whitespace-normal:hover{white-space:normal}.focus\:border-indigo-500:focus{--tw-border-opacity:1;border-color:rgb(99 102 241/var(--tw-border-opacity))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-1:focus{--tw-ring-offset-shadow:var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow:var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow,0 0 #0000)}.focus\:ring-indigo-500:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(99 102 241/var(--tw-ring-opacity))}.focus\:ring-indigo-600:focus{--tw-ring-opacity:1;--tw-ring-color:rgb(79 70 229/var(--tw-ring-opacity))}.group:hover .group-hover\:flex{display:flex}[class~=theme-dark] .dark\:border{border-width:1px}[class~=theme-dark] .dark\:border-gray-500{--tw-border-opacity:1;border-color:rgb(107 114 128/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-gray-600{--tw-border-opacity:1;border-color:rgb(75 85 99/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-gray-700{--tw-border-opacity:1;border-color:rgb(55 65 81/var(--tw-border-opacity))}[class~=theme-dark] .dark\:border-r-gray-700{--tw-border-opacity:1;border-right-color:rgb(55 65 81/var(--tw-border-opacity))}[class~=theme-dark] .dark\:bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-700{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-gray-500{--tw-bg-opacity:1;background-color:rgb(107 114 128/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-yellow-700{--tw-bg-opacity:1;background-color:rgb(161 98 7/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-black{--tw-bg-opacity:1;background-color:rgb(0 0 0/var(--tw-bg-opacity))}[class~=theme-dark] .dark\:bg-opacity-80{--tw-bg-opacity:0.8}[class~=theme-dark] .dark\:stroke-gray-500{stroke:#6b7280}[class~=theme-dark] .dark\:stroke-gray-700{stroke:#374151}[class~=theme-dark] .dark\:text-gray-300{--tw-text-opacity:1;color:rgb(209 213 219/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}[class~=theme-dark] .dark\:text-gray-50{--tw-text-opacity:1;color:rgb(249 250 251/var(--tw-text-opacity))}[class~=theme-dark] .dark\:\!text-indigo-400{--tw-text-opacity:1!important;color:rgb(129 140 248/var(--tw-text-opacity))!important}[class~=theme-dark] .dark\:ring-white{--tw-ring-opacity:1;--tw-ring-color:rgb(255 255 255/var(--tw-ring-opacity))}[class~=theme-dark] .dark\:ring-opacity-20{--tw-ring-opacity:0.2}@media (min-width:640px){.sm\:inline{display:inline}.sm\:text-sm{font-size:.875rem;line-height:1.25rem}}
|
package/package.json
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parca/profile",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.254",
|
|
4
4
|
"description": "Profile viewing libraries",
|
|
5
5
|
"dependencies": {
|
|
6
6
|
"@parca/client": "^0.16.86",
|
|
7
|
-
"@parca/components": "^0.16.
|
|
7
|
+
"@parca/components": "^0.16.192",
|
|
8
8
|
"@parca/dynamicsize": "^0.16.54",
|
|
9
|
-
"@parca/hooks": "^0.0.
|
|
9
|
+
"@parca/hooks": "^0.0.23",
|
|
10
10
|
"@parca/parser": "^0.16.55",
|
|
11
|
-
"@parca/store": "^0.16.
|
|
12
|
-
"@parca/utilities": "^0.0.
|
|
11
|
+
"@parca/store": "^0.16.103",
|
|
12
|
+
"@parca/utilities": "^0.0.31",
|
|
13
13
|
"@tanstack/react-query": "^4.0.5",
|
|
14
14
|
"@types/react-beautiful-dnd": "^13.1.3",
|
|
15
15
|
"apache-arrow": "^12.0.0",
|
|
@@ -49,5 +49,5 @@
|
|
|
49
49
|
"access": "public",
|
|
50
50
|
"registry": "https://registry.npmjs.org/"
|
|
51
51
|
},
|
|
52
|
-
"gitHead": "
|
|
52
|
+
"gitHead": "0ca31b9ddf1c2db1ccd5cd3c5e7d7f0e572299fd"
|
|
53
53
|
}
|
|
@@ -18,7 +18,7 @@ import {Provider} from 'react-redux';
|
|
|
18
18
|
import {QueryServiceClient} from '@parca/client';
|
|
19
19
|
import {DateTimeRange, KeyDownProvider, useParcaContext} from '@parca/components';
|
|
20
20
|
import {store} from '@parca/store';
|
|
21
|
-
import type
|
|
21
|
+
import {capitalizeOnlyFirstLetter, type NavigateFunction} from '@parca/utilities';
|
|
22
22
|
|
|
23
23
|
import {ProfileSelection, ProfileSelectionFromParams, SuffixParams} from '..';
|
|
24
24
|
import {QuerySelection, useProfileTypes} from '../ProfileSelector';
|
|
@@ -31,6 +31,17 @@ interface ProfileExplorerProps {
|
|
|
31
31
|
navigateTo: NavigateFunction;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
35
|
+
return (
|
|
36
|
+
<div
|
|
37
|
+
className="relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
|
38
|
+
role="alert"
|
|
39
|
+
>
|
|
40
|
+
<span className="block sm:inline">{errorMessage}</span>
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
};
|
|
44
|
+
|
|
34
45
|
const getExpressionAsAString = (expression: string | []): string => {
|
|
35
46
|
const x = Array.isArray(expression) ? expression.join() : expression;
|
|
36
47
|
return x;
|
|
@@ -81,11 +92,11 @@ const ProfileExplorerApp = ({
|
|
|
81
92
|
error: profileTypesError,
|
|
82
93
|
} = useProfileTypes(queryClient);
|
|
83
94
|
|
|
84
|
-
const {loader, noDataPrompt, onError} = useParcaContext();
|
|
95
|
+
const {loader, noDataPrompt, onError, authenticationErrorMessage} = useParcaContext();
|
|
85
96
|
|
|
86
97
|
useEffect(() => {
|
|
87
98
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
88
|
-
onError?.(profileTypesError
|
|
99
|
+
onError?.(profileTypesError);
|
|
89
100
|
}
|
|
90
101
|
}, [profileTypesError, onError]);
|
|
91
102
|
|
|
@@ -166,15 +177,11 @@ const ProfileExplorerApp = ({
|
|
|
166
177
|
}
|
|
167
178
|
|
|
168
179
|
if (profileTypesError !== undefined && profileTypesError !== null) {
|
|
169
|
-
|
|
170
|
-
<
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
<strong className="font-bold">Error! </strong>
|
|
175
|
-
<span className="block sm:inline">{profileTypesError.message}</span>
|
|
176
|
-
</div>
|
|
177
|
-
);
|
|
180
|
+
if (authenticationErrorMessage !== undefined && profileTypesError.code === 'UNAUTHENTICATED') {
|
|
181
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(profileTypesError.message)} />;
|
|
178
185
|
}
|
|
179
186
|
|
|
180
187
|
const sanitizedRange = sanitizeDateRange(time_selection_a, from_a, to_a);
|
|
@@ -52,6 +52,7 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
52
52
|
const currentSearchString = (selectQueryParam('search_string') as string) ?? '';
|
|
53
53
|
const compareMode: boolean =
|
|
54
54
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
55
|
+
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
55
56
|
|
|
56
57
|
useEffect(() => {
|
|
57
58
|
if (ref.current != null) {
|
|
@@ -72,7 +73,9 @@ export const IcicleGraph = memo(function IcicleGraph({
|
|
|
72
73
|
|
|
73
74
|
return (
|
|
74
75
|
<div onMouseLeave={() => dispatch(setHoveringNode(undefined))}>
|
|
75
|
-
|
|
76
|
+
{isColorStackLegendEnabled && (
|
|
77
|
+
<ColorStackLegend navigateTo={navigateTo} compareMode={compareMode} />
|
|
78
|
+
)}
|
|
76
79
|
<GraphTooltip
|
|
77
80
|
unit={sampleUnit}
|
|
78
81
|
total={total}
|
|
@@ -64,17 +64,20 @@ const ColorStackLegend = ({
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
return (
|
|
67
|
-
<div className="my-
|
|
67
|
+
<div className="my-4 flex w-full flex-wrap justify-start">
|
|
68
68
|
{stackColorArray.map(([feature, color]) => {
|
|
69
69
|
const filteringAllowed = feature !== EVERYTHING_ELSE;
|
|
70
70
|
const isHighlighted = currentSearchString === feature;
|
|
71
71
|
return (
|
|
72
72
|
<div
|
|
73
73
|
key={feature}
|
|
74
|
-
className={cx(
|
|
75
|
-
'
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
className={cx(
|
|
75
|
+
'flex-no-wrap mb-1 flex w-1/5 items-center justify-between text-ellipsis p-1',
|
|
76
|
+
{
|
|
77
|
+
'cursor-pointer': filteringAllowed,
|
|
78
|
+
'bg-gray-200 dark:bg-gray-800': isHighlighted,
|
|
79
|
+
}
|
|
80
|
+
)}
|
|
78
81
|
onClick={() => {
|
|
79
82
|
if (!filteringAllowed) {
|
|
80
83
|
return;
|
|
@@ -86,19 +89,25 @@ const ColorStackLegend = ({
|
|
|
86
89
|
setSearchString(feature);
|
|
87
90
|
}}
|
|
88
91
|
>
|
|
89
|
-
<div className="flex items-center">
|
|
90
|
-
<div className="
|
|
91
|
-
|
|
92
|
+
<div className="flex w-11/12 items-center justify-start">
|
|
93
|
+
<div className="flex w-5 items-center">
|
|
94
|
+
<div className="mr-1 inline-block h-4 w-4" style={{backgroundColor: color}} />
|
|
95
|
+
</div>
|
|
96
|
+
<div className="shrink overflow-hidden text-ellipsis whitespace-nowrap text-sm hover:whitespace-normal">
|
|
97
|
+
{feature}
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
<div className="flex w-1/12 justify-end">
|
|
101
|
+
{isHighlighted && (
|
|
102
|
+
<Icon
|
|
103
|
+
icon="radix-icons:cross-circled"
|
|
104
|
+
onClick={e => {
|
|
105
|
+
setSearchString('');
|
|
106
|
+
e.stopPropagation();
|
|
107
|
+
}}
|
|
108
|
+
/>
|
|
109
|
+
)}
|
|
92
110
|
</div>
|
|
93
|
-
{isHighlighted ? (
|
|
94
|
-
<Icon
|
|
95
|
-
icon="radix-icons:cross-circled"
|
|
96
|
-
onClick={e => {
|
|
97
|
-
setSearchString('');
|
|
98
|
-
e.stopPropagation();
|
|
99
|
-
}}
|
|
100
|
-
/>
|
|
101
|
-
) : null}
|
|
102
111
|
</div>
|
|
103
112
|
);
|
|
104
113
|
})}
|
|
@@ -95,6 +95,7 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({
|
|
|
95
95
|
const currentSearchString = (selectQueryParam('search_string') as string) ?? '';
|
|
96
96
|
const compareMode: boolean =
|
|
97
97
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
98
|
+
const isColorStackLegendEnabled = selectQueryParam('color_stack_legend') === 'true';
|
|
98
99
|
|
|
99
100
|
const mappings = useMemo(() => {
|
|
100
101
|
// Read the mappings from the dictionary that contains all mapping strings.
|
|
@@ -230,11 +231,13 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({
|
|
|
230
231
|
|
|
231
232
|
return (
|
|
232
233
|
<div onMouseLeave={() => dispatch(setHoveringNode(undefined))}>
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
234
|
+
{isColorStackLegendEnabled && (
|
|
235
|
+
<ColorStackLegend
|
|
236
|
+
mappingColors={mappingColors}
|
|
237
|
+
navigateTo={navigateTo}
|
|
238
|
+
compareMode={compareMode}
|
|
239
|
+
/>
|
|
240
|
+
)}
|
|
238
241
|
{dockedMetainfo ? (
|
|
239
242
|
<DockedGraphTooltip
|
|
240
243
|
table={table}
|
|
@@ -18,7 +18,13 @@ import {Icon} from '@iconify/react';
|
|
|
18
18
|
|
|
19
19
|
import {Flamegraph, FlamegraphArrow} from '@parca/client';
|
|
20
20
|
import {Button, Select, useParcaContext, useURLState} from '@parca/components';
|
|
21
|
-
import {
|
|
21
|
+
import {USER_PREFERENCES, useUserPreference} from '@parca/hooks';
|
|
22
|
+
import {
|
|
23
|
+
capitalizeOnlyFirstLetter,
|
|
24
|
+
divide,
|
|
25
|
+
selectQueryParam,
|
|
26
|
+
type NavigateFunction,
|
|
27
|
+
} from '@parca/utilities';
|
|
22
28
|
|
|
23
29
|
import DiffLegend from '../components/DiffLegend';
|
|
24
30
|
import IcicleGraph from './IcicleGraph';
|
|
@@ -48,6 +54,48 @@ interface ProfileIcicleGraphProps {
|
|
|
48
54
|
error?: any;
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
58
|
+
return <div className="flex justify-center p-10">{errorMessage}</div>;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
const ShowHideLegendButton = ({navigateTo}: {navigateTo?: NavigateFunction}): JSX.Element => {
|
|
62
|
+
const [colorStackLegend, setStoreColorStackLegend] = useURLState({
|
|
63
|
+
param: 'color_stack_legend',
|
|
64
|
+
navigateTo,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
const compareMode: boolean =
|
|
68
|
+
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
69
|
+
|
|
70
|
+
const isColorStackLegendEnabled = colorStackLegend === 'true';
|
|
71
|
+
|
|
72
|
+
const [colorProfileName] = useUserPreference<string>(
|
|
73
|
+
USER_PREFERENCES.FLAMEGRAPH_COLOR_PROFILE.key
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
const setColorStackLegend = useCallback(
|
|
77
|
+
(value: string): void => {
|
|
78
|
+
setStoreColorStackLegend(value);
|
|
79
|
+
},
|
|
80
|
+
[setStoreColorStackLegend]
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<>
|
|
85
|
+
{colorProfileName === 'default' || compareMode ? null : (
|
|
86
|
+
<Button
|
|
87
|
+
className="gap-2"
|
|
88
|
+
variant="neutral"
|
|
89
|
+
onClick={() => setColorStackLegend(isColorStackLegendEnabled ? 'false' : 'true')}
|
|
90
|
+
>
|
|
91
|
+
{isColorStackLegendEnabled ? 'Hide legend' : 'Show legend'}
|
|
92
|
+
<Icon icon={isColorStackLegendEnabled ? 'ph:eye-closed' : 'ph:eye'} width={20} />
|
|
93
|
+
</Button>
|
|
94
|
+
)}
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
};
|
|
98
|
+
|
|
51
99
|
const GroupAndSortActionButtons = ({navigateTo}: {navigateTo?: NavigateFunction}): JSX.Element => {
|
|
52
100
|
const [storeSortBy = FIELD_FUNCTION_NAME, setStoreSortBy] = useURLState({
|
|
53
101
|
param: 'sort_by',
|
|
@@ -113,7 +161,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
113
161
|
error,
|
|
114
162
|
width,
|
|
115
163
|
}: ProfileIcicleGraphProps): JSX.Element {
|
|
116
|
-
const {loader} = useParcaContext();
|
|
164
|
+
const {loader, onError, authenticationErrorMessage} = useParcaContext();
|
|
117
165
|
const compareMode: boolean =
|
|
118
166
|
selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
|
|
119
167
|
|
|
@@ -160,16 +208,14 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
160
208
|
<div className="flex w-full justify-end gap-2 pb-2">
|
|
161
209
|
<div className="ml-2 flex w-full items-end justify-between gap-2">
|
|
162
210
|
{arrow !== undefined && <GroupAndSortActionButtons navigateTo={navigateTo} />}
|
|
163
|
-
<
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
</Button>
|
|
172
|
-
</div>
|
|
211
|
+
<ShowHideLegendButton navigateTo={navigateTo} />
|
|
212
|
+
<Button
|
|
213
|
+
variant="neutral"
|
|
214
|
+
onClick={() => setNewCurPath([])}
|
|
215
|
+
disabled={curPath.length === 0}
|
|
216
|
+
>
|
|
217
|
+
Reset View
|
|
218
|
+
</Button>
|
|
173
219
|
</div>
|
|
174
220
|
</div>
|
|
175
221
|
);
|
|
@@ -180,8 +226,13 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
|
|
|
180
226
|
}
|
|
181
227
|
|
|
182
228
|
if (error != null) {
|
|
183
|
-
|
|
184
|
-
|
|
229
|
+
onError?.(error);
|
|
230
|
+
|
|
231
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
232
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(error.message)} />;
|
|
185
236
|
}
|
|
186
237
|
|
|
187
238
|
if (graph === undefined && arrow === undefined)
|
|
@@ -18,7 +18,7 @@ import {RpcError} from '@protobuf-ts/runtime-rpc';
|
|
|
18
18
|
import {Duration, Label, QueryRangeResponse, QueryServiceClient, Timestamp} from '@parca/client';
|
|
19
19
|
import {DateTimeRange, useGrpcMetadata, useParcaContext} from '@parca/components';
|
|
20
20
|
import {Query} from '@parca/parser';
|
|
21
|
-
import {getStepDuration} from '@parca/utilities';
|
|
21
|
+
import {capitalizeOnlyFirstLetter, getStepDuration} from '@parca/utilities';
|
|
22
22
|
|
|
23
23
|
import {MergedProfileSelection, ProfileSelection} from '..';
|
|
24
24
|
import MetricsGraph from '../MetricsGraph';
|
|
@@ -29,6 +29,17 @@ interface ProfileMetricsEmptyStateProps {
|
|
|
29
29
|
message: string;
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
+
const ErrorContent = ({errorMessage}: {errorMessage: string}): JSX.Element => {
|
|
33
|
+
return (
|
|
34
|
+
<div
|
|
35
|
+
className="relative rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700"
|
|
36
|
+
role="alert"
|
|
37
|
+
>
|
|
38
|
+
<span className="block sm:inline">{errorMessage}</span>
|
|
39
|
+
</div>
|
|
40
|
+
);
|
|
41
|
+
};
|
|
42
|
+
|
|
32
43
|
export const ProfileMetricsEmptyState = ({message}: ProfileMetricsEmptyStateProps): JSX.Element => {
|
|
33
44
|
return (
|
|
34
45
|
<div className="flex h-full w-full flex-col items-center justify-center">
|
|
@@ -114,12 +125,12 @@ const ProfileMetricsGraph = ({
|
|
|
114
125
|
}: ProfileMetricsGraphProps): JSX.Element => {
|
|
115
126
|
const {isLoading, response, error} = useQueryRange(queryClient, queryExpression, from, to);
|
|
116
127
|
const isLoaderVisible = useDelayedLoader(isLoading);
|
|
117
|
-
const {loader, onError, perf} = useParcaContext();
|
|
128
|
+
const {loader, onError, perf, authenticationErrorMessage} = useParcaContext();
|
|
118
129
|
const {width, height, margin} = useMetricsGraphDimensions(comparing);
|
|
119
130
|
|
|
120
131
|
useEffect(() => {
|
|
121
132
|
if (error !== null) {
|
|
122
|
-
onError?.(error
|
|
133
|
+
onError?.(error);
|
|
123
134
|
}
|
|
124
135
|
}, [error, onError]);
|
|
125
136
|
|
|
@@ -139,15 +150,11 @@ const ProfileMetricsGraph = ({
|
|
|
139
150
|
}
|
|
140
151
|
|
|
141
152
|
if (error !== null) {
|
|
142
|
-
|
|
143
|
-
<
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
<strong className="font-bold">Error! </strong>
|
|
148
|
-
<span className="block sm:inline">{error.message}</span>
|
|
149
|
-
</div>
|
|
150
|
-
);
|
|
153
|
+
if (authenticationErrorMessage !== undefined && error.code === 'UNAUTHENTICATED') {
|
|
154
|
+
return <ErrorContent errorMessage={authenticationErrorMessage} />;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
return <ErrorContent errorMessage={capitalizeOnlyFirstLetter(error.message)} />;
|
|
151
158
|
}
|
|
152
159
|
|
|
153
160
|
if (dataAvailable) {
|