@parca/profile 0.16.239 → 0.16.241

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 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.241](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.240...@parca/profile@0.16.241) (2023-08-31)
7
+
8
+ **Note:** Version bump only for package @parca/profile
9
+
10
+ ## [0.16.240](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.239...@parca/profile@0.16.240) (2023-08-31)
11
+
12
+ **Note:** Version bump only for package @parca/profile
13
+
6
14
  ## [0.16.239](https://github.com/parca-dev/parca/compare/@parca/profile@0.16.238...@parca/profile@0.16.239) (2023-08-30)
7
15
 
8
16
  **Note:** Version bump only for package @parca/profile
@@ -19,7 +19,7 @@ import { QueryRequest_ReportType } from '@parca/client';
19
19
  import { Button, useParcaContext, useURLState } from '@parca/components';
20
20
  import { divide, getLastItem, valueFormatter } from '@parca/utilities';
21
21
  import { FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_FILE_NAME, FIELD_FUNCTION_START_LINE, FIELD_LOCATION_ADDRESS, FIELD_LOCATION_LINE, FIELD_MAPPING_BUILD_ID, FIELD_MAPPING_FILE, } from '../ProfileIcicleGraph/IcicleGraphArrow';
22
- import { nodeLabel } from '../ProfileIcicleGraph/IcicleGraphArrow/utils';
22
+ import { arrowToString, nodeLabel } from '../ProfileIcicleGraph/IcicleGraphArrow/utils';
23
23
  import { useProfileViewContext } from '../ProfileView/ProfileViewContext';
24
24
  import { useQuery } from '../useQuery';
25
25
  import { hexifyAddress, truncateString, truncateStringReverse } from '../utils';
@@ -63,11 +63,11 @@ const TooltipMetaInfo = ({ table,
63
63
  // total,
64
64
  // totalUnfiltered,
65
65
  onCopy, row, navigateTo, }) => {
66
- const mappingFile = table.getChild(FIELD_MAPPING_FILE)?.get(row) ?? '';
67
- const mappingBuildID = table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row) ?? '';
66
+ const mappingFile = arrowToString(table.getChild(FIELD_MAPPING_FILE)?.get(row)) ?? '';
67
+ const mappingBuildID = arrowToString(table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row)) ?? '';
68
68
  const locationAddress = table.getChild(FIELD_LOCATION_ADDRESS)?.get(row) ?? 0n;
69
69
  const locationLine = table.getChild(FIELD_LOCATION_LINE)?.get(row) ?? 0n;
70
- const functionFilename = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row) ?? '';
70
+ const functionFilename = arrowToString(table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row)) ?? '';
71
71
  const functionStartLine = table.getChild(FIELD_FUNCTION_START_LINE)?.get(row) ?? 0n;
72
72
  const lineNumber = locationLine !== 0n ? locationLine : functionStartLine !== 0n ? functionStartLine : undefined;
73
73
  const pprofLabelPrefix = 'pprof_labels.';
@@ -18,7 +18,7 @@ import { selectBinaries, useAppSelector } from '@parca/store';
18
18
  import { isSearchMatch, scaleLinear } from '@parca/utilities';
19
19
  import { FIELD_CHILDREN, FIELD_CUMULATIVE, FIELD_DIFF, FIELD_FUNCTION_NAME, FIELD_MAPPING_FILE, } from './index';
20
20
  import useNodeColor from './useNodeColor';
21
- import { nodeLabel } from './utils';
21
+ import { arrowToString, nodeLabel } from './utils';
22
22
  export const RowHeight = 26;
23
23
  export const IcicleGraphNodes = React.memo(function IcicleGraphNodesNoMemo({ table, childRows, mappingColors, x, y, xScale, total, totalWidth, level, path, setCurPath, setHoveringRow, setHoveringLevel, curPath, sortBy, searchString, darkMode, compareMode, }) {
24
24
  const cumulatives = table.getChild(FIELD_CUMULATIVE);
@@ -56,8 +56,8 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
56
56
  const cumulativeColumn = table.getChild(FIELD_CUMULATIVE);
57
57
  const diffColumn = table.getChild(FIELD_DIFF);
58
58
  // get the actual values from the columns
59
- const mappingFile = mappingColumn?.get(row);
60
- const functionName = functionNameColumn?.get(row);
59
+ const mappingFile = arrowToString(mappingColumn?.get(row));
60
+ const functionName = arrowToString(functionNameColumn?.get(row));
61
61
  const cumulative = cumulativeColumn?.get(row);
62
62
  const diff = diffColumn?.get(row);
63
63
  const childRows = Array.from(table.getChild(FIELD_CHILDREN)?.get(row) ?? []);
@@ -66,8 +66,8 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({ table, row, map
66
66
  case FIELD_FUNCTION_NAME:
67
67
  childRows.sort((a, b) => {
68
68
  // TODO: Support fallthrough to comparing addresses or something
69
- const afn = functionNameColumn?.get(a);
70
- const bfn = functionNameColumn?.get(b);
69
+ const afn = arrowToString(functionNameColumn?.get(a));
70
+ const bfn = arrowToString(functionNameColumn?.get(b));
71
71
  if (afn !== null && bfn !== null) {
72
72
  return afn.localeCompare(bfn);
73
73
  }
@@ -19,7 +19,7 @@ import GraphTooltipArrow from '../../GraphTooltipArrow';
19
19
  import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
20
20
  import ColorStackLegend from './ColorStackLegend';
21
21
  import { IcicleNode, RowHeight } from './IcicleGraphNodes';
22
- import { extractFeature } from './utils';
22
+ import { arrowToString, extractFeature } from './utils';
23
23
  export const FIELD_LABELS_ONLY = 'labels_only';
24
24
  export const FIELD_MAPPING_FILE = 'mapping_file';
25
25
  export const FIELD_MAPPING_BUILD_ID = 'mapping_build_id';
@@ -56,7 +56,8 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ table, total, f
56
56
  const len = mapping.dictionary.length;
57
57
  const entries = [];
58
58
  for (let i = 0; i < len; i++) {
59
- entries.push(getLastItem(mapping.dictionary.get(i)) ?? '');
59
+ const fn = arrowToString(mapping.dictionary.get(i));
60
+ entries.push(getLastItem(fn) ?? '');
60
61
  }
61
62
  return entries;
62
63
  })
@@ -73,7 +74,7 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({ table, total, f
73
74
  }
74
75
  const len = fn.dictionary.length;
75
76
  for (let i = 0; i < len; i++) {
76
- const fn = functionNamesDict?.get(i);
77
+ const fn = arrowToString(functionNamesDict?.get(i));
77
78
  if (fn?.startsWith('runtime') === true) {
78
79
  mappings.push('runtime');
79
80
  break;
@@ -2,3 +2,4 @@ import { Table } from 'apache-arrow';
2
2
  import { type Feature } from '@parca/store';
3
3
  export declare function nodeLabel(table: Table<any>, row: number, level: number, showBinaryName: boolean): string;
4
4
  export declare const extractFeature: (mapping: string) => Feature;
5
+ export declare const arrowToString: (buffer: any) => string | null;
@@ -15,7 +15,7 @@ import { getLastItem } from '@parca/utilities';
15
15
  import { hexifyAddress } from '../../utils';
16
16
  import { FIELD_FUNCTION_NAME, FIELD_LABELS_ONLY, FIELD_LOCATION_ADDRESS, FIELD_MAPPING_FILE, } from './index';
17
17
  export function nodeLabel(table, row, level, showBinaryName) {
18
- const functionName = table.getChild(FIELD_FUNCTION_NAME)?.get(row);
18
+ const functionName = arrowToString(table.getChild(FIELD_FUNCTION_NAME)?.get(row));
19
19
  const labelsOnly = table.getChild(FIELD_LABELS_ONLY)?.get(row);
20
20
  const pprofLabelPrefix = 'pprof_labels.';
21
21
  const labelColumnNames = table.schema.fields.filter(field => field.name.startsWith(pprofLabelPrefix));
@@ -53,3 +53,12 @@ export const extractFeature = (mapping) => {
53
53
  }
54
54
  return { name: EVERYTHING_ELSE, type: FEATURE_TYPES.Misc };
55
55
  };
56
+ export const arrowToString = (buffer) => {
57
+ if (buffer == null || typeof buffer === 'string') {
58
+ return buffer;
59
+ }
60
+ if (ArrayBuffer.isView(buffer)) {
61
+ return String.fromCharCode.apply(null, buffer);
62
+ }
63
+ return '';
64
+ };
@@ -14,7 +14,7 @@ import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-run
14
14
  import { Fragment, useCallback, useEffect, useMemo } from 'react';
15
15
  import { Menu, Transition } from '@headlessui/react';
16
16
  import { Icon } from '@iconify/react';
17
- import { Button, Select, useURLState } from '@parca/components';
17
+ import { Button, Select, useParcaContext, useURLState } from '@parca/components';
18
18
  import { useContainerDimensions } from '@parca/hooks';
19
19
  import { divide, selectQueryParam } from '@parca/utilities';
20
20
  import DiffLegend from '../components/DiffLegend';
@@ -51,6 +51,7 @@ const GroupAndSortActionButtons = ({ navigateTo }) => {
51
51
  return (_jsxs(_Fragment, { children: [_jsx(GroupByDropdown, { groupBy: groupBy, toggleGroupBy: toggleGroupBy }), _jsx(SortBySelect, { compareMode: compareMode, sortBy: storeSortBy, setSortBy: setStoreSortBy })] }));
52
52
  };
53
53
  const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, total, filtered, curPath, setNewCurPath, sampleUnit, navigateTo, loading, setActionButtons, error, }) {
54
+ const { loader } = useParcaContext();
54
55
  const compareMode = selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
55
56
  const { ref, dimensions } = useContainerDimensions();
56
57
  const [storeSortBy = FIELD_FUNCTION_NAME] = useURLState({
@@ -82,12 +83,15 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({ graph, table, to
82
83
  }
83
84
  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: [table !== undefined && _jsx(GroupAndSortActionButtons, { navigateTo: navigateTo }), _jsx("div", { children: _jsx(Button, { color: "neutral", onClick: () => setNewCurPath([]), disabled: curPath.length === 0, variant: "neutral", children: "Reset View" }) })] }) }));
84
85
  }, [navigateTo, table, curPath, setNewCurPath, setActionButtons]);
86
+ if (loading) {
87
+ return _jsx("div", { className: "h-96", children: loader });
88
+ }
85
89
  if (error != null) {
86
90
  console.error('Error: ', error);
87
91
  return _jsxs("div", { className: "flex justify-center p-10", children: ["An error occurred: ", error.message] });
88
92
  }
89
93
  if (graph === undefined && table === undefined)
90
- return _jsx("div", { className: "mx-auto text-center", children: "no data..." });
94
+ return _jsx("div", { className: "mx-auto text-center", children: "No data..." });
91
95
  if (total === 0n && !loading)
92
96
  return _jsx("div", { className: "mx-auto text-center", children: "Profile has no samples" });
93
97
  if (isTrimmed) {
@@ -22,6 +22,7 @@ export const Table = React.memo(function Table({ data, sampleUnit: unit, navigat
22
22
  const router = parseParams(window?.location.search);
23
23
  const [rawDashboardItems] = useURLState({ param: 'dashboard_items' });
24
24
  const [rawcompareMode] = useURLState({ param: 'compare_a' });
25
+ const [filterByFunctionInput] = useURLState({ param: 'filter_by_function' });
25
26
  const compareMode = rawcompareMode === undefined ? false : rawcompareMode === 'true';
26
27
  const dashboardItems = useMemo(() => {
27
28
  if (rawDashboardItems !== undefined) {
@@ -100,10 +101,10 @@ export const Table = React.memo(function Table({ data, sampleUnit: unit, navigat
100
101
  if (navigateTo != null) {
101
102
  navigateTo('/', {
102
103
  ...router,
103
- ...{ search_string: '' },
104
+ ...{ search_string: filterByFunctionInput ?? '' },
104
105
  }, { replace: true });
105
106
  }
106
- }, [navigateTo, router]);
107
+ }, [navigateTo, router, filterByFunctionInput]);
107
108
  useEffect(() => {
108
109
  if (setActionButtons === undefined) {
109
110
  return;
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}.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}.z-50{z-index:50}.z-10{z-index:10}.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-6{height:1.5rem}.h-4{height:1rem}.h-full{height:100%}.h-1{height:.25rem}.h-96{height:24rem}.h-\[80vh\]{height:80vh}.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-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-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-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-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}.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}.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;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-medium{font-weight:500}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.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\: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}.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}.z-50{z-index:50}.z-10{z-index:10}.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}.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-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-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-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-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}.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}.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;line-height:1.75rem}.font-semibold{font-weight:600}.font-bold{font-weight:700}.font-medium{font-weight:500}.capitalize{text-transform:capitalize}.leading-6{line-height:1.5rem}.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\: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.239",
3
+ "version": "0.16.241",
4
4
  "description": "Profile viewing libraries",
5
5
  "dependencies": {
6
6
  "@parca/client": "^0.16.86",
7
- "@parca/components": "^0.16.186",
7
+ "@parca/components": "^0.16.187",
8
8
  "@parca/dynamicsize": "^0.16.54",
9
9
  "@parca/hooks": "^0.0.21",
10
10
  "@parca/parser": "^0.16.55",
11
- "@parca/store": "^0.16.99",
12
- "@parca/utilities": "^0.0.28",
11
+ "@parca/store": "^0.16.100",
12
+ "@parca/utilities": "^0.0.29",
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": "5405ab0efe17d1d327b9bb1f8bd316ade745f68a"
52
+ "gitHead": "39455561ec0a34a25d5eeb32c933da2dbbf2a604"
53
53
  }
@@ -33,7 +33,7 @@ import {
33
33
  FIELD_MAPPING_BUILD_ID,
34
34
  FIELD_MAPPING_FILE,
35
35
  } from '../ProfileIcicleGraph/IcicleGraphArrow';
36
- import {nodeLabel} from '../ProfileIcicleGraph/IcicleGraphArrow/utils';
36
+ import {arrowToString, nodeLabel} from '../ProfileIcicleGraph/IcicleGraphArrow/utils';
37
37
  import {ProfileSource} from '../ProfileSource';
38
38
  import {useProfileViewContext} from '../ProfileView/ProfileViewContext';
39
39
  import {useQuery} from '../useQuery';
@@ -190,11 +190,13 @@ const TooltipMetaInfo = ({
190
190
  onCopy: () => void;
191
191
  navigateTo: NavigateFunction;
192
192
  }): React.JSX.Element => {
193
- const mappingFile: string = table.getChild(FIELD_MAPPING_FILE)?.get(row) ?? '';
194
- const mappingBuildID: string = table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row) ?? '';
193
+ const mappingFile: string = arrowToString(table.getChild(FIELD_MAPPING_FILE)?.get(row)) ?? '';
194
+ const mappingBuildID: string =
195
+ arrowToString(table.getChild(FIELD_MAPPING_BUILD_ID)?.get(row)) ?? '';
195
196
  const locationAddress: bigint = table.getChild(FIELD_LOCATION_ADDRESS)?.get(row) ?? 0n;
196
197
  const locationLine: bigint = table.getChild(FIELD_LOCATION_LINE)?.get(row) ?? 0n;
197
- const functionFilename: string = table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row) ?? '';
198
+ const functionFilename: string =
199
+ arrowToString(table.getChild(FIELD_FUNCTION_FILE_NAME)?.get(row)) ?? '';
198
200
  const functionStartLine: bigint = table.getChild(FIELD_FUNCTION_START_LINE)?.get(row) ?? 0n;
199
201
  const lineNumber =
200
202
  locationLine !== 0n ? locationLine : functionStartLine !== 0n ? functionStartLine : undefined;
@@ -28,7 +28,7 @@ import {
28
28
  FIELD_MAPPING_FILE,
29
29
  } from './index';
30
30
  import useNodeColor from './useNodeColor';
31
- import {nodeLabel} from './utils';
31
+ import {arrowToString, nodeLabel} from './utils';
32
32
 
33
33
  export const RowHeight = 26;
34
34
 
@@ -188,8 +188,8 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({
188
188
  const cumulativeColumn = table.getChild(FIELD_CUMULATIVE);
189
189
  const diffColumn = table.getChild(FIELD_DIFF);
190
190
  // get the actual values from the columns
191
- const mappingFile: string | null = mappingColumn?.get(row);
192
- const functionName: string | null = functionNameColumn?.get(row);
191
+ const mappingFile: string | null = arrowToString(mappingColumn?.get(row));
192
+ const functionName: string | null = arrowToString(functionNameColumn?.get(row));
193
193
  const cumulative: bigint = cumulativeColumn?.get(row);
194
194
  const diff: bigint | null = diffColumn?.get(row);
195
195
  const childRows: number[] = Array.from(table.getChild(FIELD_CHILDREN)?.get(row) ?? []);
@@ -199,8 +199,8 @@ export const IcicleNode = React.memo(function IcicleNodeNoMemo({
199
199
  case FIELD_FUNCTION_NAME:
200
200
  childRows.sort((a, b) => {
201
201
  // TODO: Support fallthrough to comparing addresses or something
202
- const afn: string | null = functionNameColumn?.get(a);
203
- const bfn: string | null = functionNameColumn?.get(b);
202
+ const afn: string | null = arrowToString(functionNameColumn?.get(a));
203
+ const bfn: string | null = arrowToString(functionNameColumn?.get(b));
204
204
  if (afn !== null && bfn !== null) {
205
205
  return afn.localeCompare(bfn);
206
206
  }
@@ -35,7 +35,7 @@ import GraphTooltipArrow from '../../GraphTooltipArrow';
35
35
  import GraphTooltipArrowContent from '../../GraphTooltipArrow/Content';
36
36
  import ColorStackLegend from './ColorStackLegend';
37
37
  import {IcicleNode, RowHeight, mappingColors} from './IcicleGraphNodes';
38
- import {extractFeature} from './utils';
38
+ import {arrowToString, extractFeature} from './utils';
39
39
 
40
40
  export const FIELD_LABELS_ONLY = 'labels_only';
41
41
  export const FIELD_MAPPING_FILE = 'mapping_file';
@@ -103,7 +103,8 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({
103
103
  const len = mapping.dictionary.length;
104
104
  const entries: string[] = [];
105
105
  for (let i = 0; i < len; i++) {
106
- entries.push(getLastItem(mapping.dictionary.get(i)) ?? '');
106
+ const fn = arrowToString(mapping.dictionary.get(i));
107
+ entries.push(getLastItem(fn) ?? '');
107
108
  }
108
109
  return entries;
109
110
  })
@@ -122,7 +123,7 @@ export const IcicleGraphArrow = memo(function IcicleGraphArrow({
122
123
  }
123
124
  const len = fn.dictionary.length;
124
125
  for (let i = 0; i < len; i++) {
125
- const fn: string | null = functionNamesDict?.get(i);
126
+ const fn: string | null = arrowToString(functionNamesDict?.get(i));
126
127
  if (fn?.startsWith('runtime') === true) {
127
128
  mappings.push('runtime');
128
129
  break;
@@ -31,7 +31,7 @@ export function nodeLabel(
31
31
  level: number,
32
32
  showBinaryName: boolean
33
33
  ): string {
34
- const functionName: string | null = table.getChild(FIELD_FUNCTION_NAME)?.get(row);
34
+ const functionName: string | null = arrowToString(table.getChild(FIELD_FUNCTION_NAME)?.get(row));
35
35
  const labelsOnly: boolean | null = table.getChild(FIELD_LABELS_ONLY)?.get(row);
36
36
  const pprofLabelPrefix = 'pprof_labels.';
37
37
  const labelColumnNames = table.schema.fields.filter(field =>
@@ -76,3 +76,13 @@ export const extractFeature = (mapping: string): Feature => {
76
76
 
77
77
  return {name: EVERYTHING_ELSE, type: FEATURE_TYPES.Misc};
78
78
  };
79
+
80
+ export const arrowToString = (buffer: any): string | null => {
81
+ if (buffer == null || typeof buffer === 'string') {
82
+ return buffer;
83
+ }
84
+ if (ArrayBuffer.isView(buffer)) {
85
+ return String.fromCharCode.apply(null, buffer as unknown as number[]);
86
+ }
87
+ return '';
88
+ };
@@ -18,7 +18,7 @@ import {Icon} from '@iconify/react';
18
18
  import {Table} from 'apache-arrow';
19
19
 
20
20
  import {Flamegraph} from '@parca/client';
21
- import {Button, Select, useURLState} from '@parca/components';
21
+ import {Button, Select, useParcaContext, useURLState} from '@parca/components';
22
22
  import {useContainerDimensions} from '@parca/hooks';
23
23
  import {divide, selectQueryParam, type NavigateFunction} from '@parca/utilities';
24
24
 
@@ -114,6 +114,7 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
114
114
  setActionButtons,
115
115
  error,
116
116
  }: ProfileIcicleGraphProps): JSX.Element {
117
+ const {loader} = useParcaContext();
117
118
  const compareMode: boolean =
118
119
  selectQueryParam('compare_a') === 'true' && selectQueryParam('compare_b') === 'true';
119
120
  const {ref, dimensions} = useContainerDimensions();
@@ -177,13 +178,17 @@ const ProfileIcicleGraph = function ProfileIcicleGraphNonMemo({
177
178
  );
178
179
  }, [navigateTo, table, curPath, setNewCurPath, setActionButtons]);
179
180
 
181
+ if (loading) {
182
+ return <div className="h-96">{loader}</div>;
183
+ }
184
+
180
185
  if (error != null) {
181
186
  console.error('Error: ', error);
182
187
  return <div className="flex justify-center p-10">An error occurred: {error.message}</div>;
183
188
  }
184
189
 
185
190
  if (graph === undefined && table === undefined)
186
- return <div className="mx-auto text-center">no data...</div>;
191
+ return <div className="mx-auto text-center">No data...</div>;
187
192
 
188
193
  if (total === 0n && !loading)
189
194
  return <div className="mx-auto text-center">Profile has no samples</div>;
@@ -57,6 +57,7 @@ export const Table = React.memo(function Table({
57
57
  const router = parseParams(window?.location.search);
58
58
  const [rawDashboardItems] = useURLState({param: 'dashboard_items'});
59
59
  const [rawcompareMode] = useURLState({param: 'compare_a'});
60
+ const [filterByFunctionInput] = useURLState({param: 'filter_by_function'});
60
61
 
61
62
  const compareMode: boolean = rawcompareMode === undefined ? false : rawcompareMode === 'true';
62
63
 
@@ -158,12 +159,12 @@ export const Table = React.memo(function Table({
158
159
  '/',
159
160
  {
160
161
  ...router,
161
- ...{search_string: ''},
162
+ ...{search_string: filterByFunctionInput ?? ''},
162
163
  },
163
164
  {replace: true}
164
165
  );
165
166
  }
166
- }, [navigateTo, router]);
167
+ }, [navigateTo, router, filterByFunctionInput]);
167
168
 
168
169
  useEffect(() => {
169
170
  if (setActionButtons === undefined) {