@workflow/web-shared 5.0.0-beta.2 → 5.0.0-beta.20
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/dist/components/error-boundary.js +1 -1
- package/dist/components/event-list-view.d.ts +16 -1
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +196 -85
- package/dist/components/hook-actions.js +1 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +5 -1
- package/dist/components/new-trace-viewer/components/copy-button.d.ts +9 -0
- package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/copy-button.js +27 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts +10 -0
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/event-list.js +46 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts +18 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +54 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts +25 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +101 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts +20 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
- package/dist/components/new-trace-viewer/components/span-markers.d.ts +46 -0
- package/dist/components/new-trace-viewer/components/span-markers.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/span-markers.js +85 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts +15 -0
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/split-pane.js +105 -0
- package/dist/components/new-trace-viewer/components/timeline.d.ts +36 -0
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/timeline.js +254 -0
- package/dist/components/new-trace-viewer/components/timeline.module.css +46 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts +2 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +19 -0
- package/dist/components/new-trace-viewer/components/use-row-window.d.ts +34 -0
- package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/components/use-row-window.js +107 -0
- package/dist/components/new-trace-viewer/context.d.ts +15 -0
- package/dist/components/new-trace-viewer/context.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/context.js +47 -0
- package/dist/components/new-trace-viewer/icons.d.ts +6 -0
- package/dist/components/new-trace-viewer/icons.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/icons.js +15 -0
- package/dist/components/new-trace-viewer/search.d.ts +19 -0
- package/dist/components/new-trace-viewer/search.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/search.js +134 -0
- package/dist/components/new-trace-viewer/trace-viewer.d.ts +11 -0
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/trace-viewer.js +462 -0
- package/dist/components/new-trace-viewer/types.d.ts +3 -0
- package/dist/components/new-trace-viewer/types.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/types.js +2 -0
- package/dist/components/new-trace-viewer/utils.d.ts +61 -0
- package/dist/components/new-trace-viewer/utils.d.ts.map +1 -0
- package/dist/components/new-trace-viewer/utils.js +345 -0
- package/dist/components/run-trace-view.js +1 -1
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +129 -102
- package/dist/components/sidebar/attributes-block.d.ts +28 -0
- package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
- package/dist/components/sidebar/attributes-block.js +81 -0
- package/dist/components/sidebar/conversation-view.js +1 -1
- package/dist/components/sidebar/copyable-data-block.d.ts +1 -0
- package/dist/components/sidebar/copyable-data-block.d.ts.map +1 -1
- package/dist/components/sidebar/copyable-data-block.js +16 -15
- package/dist/components/sidebar/detail-card.d.ts +5 -6
- package/dist/components/sidebar/detail-card.d.ts.map +1 -1
- package/dist/components/sidebar/detail-card.js +32 -16
- package/dist/components/sidebar/entity-detail-panel.d.ts +1 -3
- package/dist/components/sidebar/entity-detail-panel.d.ts.map +1 -1
- package/dist/components/sidebar/entity-detail-panel.js +17 -35
- package/dist/components/sidebar/events-list.d.ts +3 -1
- package/dist/components/sidebar/events-list.d.ts.map +1 -1
- package/dist/components/sidebar/events-list.js +36 -22
- package/dist/components/sidebar/resolve-hook-modal.js +1 -1
- package/dist/components/sidebar/sidebar-data-context.d.ts +29 -0
- package/dist/components/sidebar/sidebar-data-context.d.ts.map +1 -0
- package/dist/components/sidebar/sidebar-data-context.js +19 -0
- package/dist/components/sidebar/span-detail-merge.d.ts +16 -0
- package/dist/components/sidebar/span-detail-merge.d.ts.map +1 -0
- package/dist/components/sidebar/span-detail-merge.js +53 -0
- package/dist/components/stream-viewer.d.ts +1 -1
- package/dist/components/stream-viewer.d.ts.map +1 -1
- package/dist/components/stream-viewer.js +3 -27
- package/dist/components/trace-viewer/components/map.js +1 -1
- package/dist/components/trace-viewer/components/markers.js +1 -1
- package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
- package/dist/components/trace-viewer/components/node.js +2 -1
- package/dist/components/trace-viewer/components/search-input.js +1 -1
- package/dist/components/trace-viewer/components/search.js +1 -1
- package/dist/components/trace-viewer/components/span-content.js +1 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js +1 -1
- package/dist/components/trace-viewer/components/span-segments.js +1 -1
- package/dist/components/trace-viewer/components/span-strategies.js +1 -1
- package/dist/components/trace-viewer/components/ui.js +1 -1
- package/dist/components/trace-viewer/components/zoom-button.js +1 -1
- package/dist/components/trace-viewer/components/zoom-icons.js +1 -1
- package/dist/components/trace-viewer/context.js +1 -1
- package/dist/components/trace-viewer/index.js +1 -1
- package/dist/components/trace-viewer/trace-viewer.js +1 -1
- package/dist/components/trace-viewer/trace-viewer.module.css +4 -4
- package/dist/components/trace-viewer/types.js +1 -1
- package/dist/components/trace-viewer/util/constants.js +1 -1
- package/dist/components/trace-viewer/util/scrollbar-width.js +1 -1
- package/dist/components/trace-viewer/util/timing.d.ts +3 -3
- package/dist/components/trace-viewer/util/timing.d.ts.map +1 -1
- package/dist/components/trace-viewer/util/timing.js +8 -11
- package/dist/components/trace-viewer/util/tree.js +1 -1
- package/dist/components/trace-viewer/util/use-immediate-style.js +1 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js +1 -1
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js +1 -1
- package/dist/components/trace-viewer/worker.js +1 -1
- package/dist/components/trace-viewer-new.d.ts +14 -0
- package/dist/components/trace-viewer-new.d.ts.map +1 -0
- package/dist/components/trace-viewer-new.js +21 -0
- package/dist/components/ui/alert.js +1 -1
- package/dist/components/ui/button.d.ts +10 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/button.js +46 -0
- package/dist/components/ui/card.js +1 -1
- package/dist/components/ui/context-card.d.ts +47 -0
- package/dist/components/ui/context-card.d.ts.map +1 -0
- package/dist/components/ui/context-card.js +471 -0
- package/dist/components/ui/data-inspector.d.ts +22 -0
- package/dist/components/ui/data-inspector.d.ts.map +1 -1
- package/dist/components/ui/data-inspector.js +103 -13
- package/dist/components/ui/decrypt-button.js +1 -1
- package/dist/components/ui/error-card.js +1 -1
- package/dist/components/ui/error-stack-block.d.ts +17 -10
- package/dist/components/ui/error-stack-block.d.ts.map +1 -1
- package/dist/components/ui/error-stack-block.js +49 -30
- package/dist/components/ui/icon-button.d.ts +19 -0
- package/dist/components/ui/icon-button.d.ts.map +1 -0
- package/dist/components/ui/icon-button.js +29 -0
- package/dist/components/ui/inspector-theme.d.ts +9 -10
- package/dist/components/ui/inspector-theme.d.ts.map +1 -1
- package/dist/components/ui/inspector-theme.js +39 -72
- package/dist/components/ui/kbd.d.ts +6 -0
- package/dist/components/ui/kbd.d.ts.map +1 -0
- package/dist/components/ui/kbd.js +6 -0
- package/dist/components/ui/load-more-button.js +1 -1
- package/dist/components/ui/menu-dropdown.js +1 -1
- package/dist/components/ui/skeleton.js +1 -1
- package/dist/components/ui/spinner.js +1 -1
- package/dist/components/ui/timestamp-tooltip.d.ts +34 -1
- package/dist/components/ui/timestamp-tooltip.d.ts.map +1 -1
- package/dist/components/ui/timestamp-tooltip.js +80 -132
- package/dist/components/ui/tooltip.d.ts +10 -0
- package/dist/components/ui/tooltip.d.ts.map +1 -0
- package/dist/components/ui/tooltip.js +12 -0
- package/dist/components/workflow-trace-view.d.ts +1 -3
- package/dist/components/workflow-trace-view.d.ts.map +1 -1
- package/dist/components/workflow-trace-view.js +11 -13
- package/dist/components/workflow-traces/event-colors.d.ts +1 -0
- package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
- package/dist/components/workflow-traces/event-colors.js +12 -1
- package/dist/components/workflow-traces/trace-colors.js +1 -1
- package/dist/components/workflow-traces/trace-span-construction.d.ts +2 -2
- package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +19 -5
- package/dist/components/workflow-traces/trace-time-utils.js +1 -1
- package/dist/hooks/use-dark-mode.js +1 -1
- package/dist/hooks/use-intersection-observer.d.ts +17 -0
- package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
- package/dist/hooks/use-intersection-observer.js +29 -0
- package/dist/hooks/use-load-more-on-scroll.d.ts +21 -0
- package/dist/hooks/use-load-more-on-scroll.d.ts.map +1 -0
- package/dist/hooks/use-load-more-on-scroll.js +28 -0
- package/dist/hooks/use-reduced-motion.d.ts +10 -0
- package/dist/hooks/use-reduced-motion.d.ts.map +1 -0
- package/dist/hooks/use-reduced-motion.js +29 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/lib/event-analysis.js +1 -1
- package/dist/lib/event-materialization.js +1 -1
- package/dist/lib/exact-event-search-id.d.ts +25 -0
- package/dist/lib/exact-event-search-id.d.ts.map +1 -0
- package/dist/lib/exact-event-search-id.js +39 -0
- package/dist/lib/hydration.d.ts +6 -0
- package/dist/lib/hydration.d.ts.map +1 -1
- package/dist/lib/hydration.js +154 -2
- package/dist/lib/stream-display.d.ts +18 -0
- package/dist/lib/stream-display.d.ts.map +1 -0
- package/dist/lib/stream-display.js +30 -0
- package/dist/lib/toast.js +1 -1
- package/dist/lib/trace-builder.d.ts +15 -0
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +29 -3
- package/dist/lib/utils.d.ts +20 -9
- package/dist/lib/utils.d.ts.map +1 -1
- package/dist/lib/utils.js +74 -31
- package/dist/lib/zstd-browser-decoder.d.ts +7 -0
- package/dist/lib/zstd-browser-decoder.d.ts.map +1 -0
- package/dist/lib/zstd-browser-decoder.js +41 -0
- package/dist/styles.css +484 -1
- package/package.json +10 -5
- package/src/components/event-list-view.tsx +279 -104
- package/src/components/index.ts +7 -0
- package/src/components/new-trace-viewer/components/copy-button.tsx +68 -0
- package/src/components/new-trace-viewer/components/event-list.tsx +136 -0
- package/src/components/new-trace-viewer/components/middle-truncate/copy-selection.ts +114 -0
- package/src/components/new-trace-viewer/components/middle-truncate/middle-truncate.tsx +157 -0
- package/src/components/new-trace-viewer/components/middle-truncate/truncate.ts +132 -0
- package/src/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.ts +167 -0
- package/src/components/new-trace-viewer/components/span-markers.tsx +173 -0
- package/src/components/new-trace-viewer/components/split-pane.tsx +198 -0
- package/src/components/new-trace-viewer/components/timeline.module.css +46 -0
- package/src/components/new-trace-viewer/components/timeline.tsx +744 -0
- package/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +94 -0
- package/src/components/new-trace-viewer/components/use-row-window.ts +140 -0
- package/src/components/new-trace-viewer/context.tsx +90 -0
- package/src/components/new-trace-viewer/icons.tsx +79 -0
- package/src/components/new-trace-viewer/search.ts +178 -0
- package/src/components/new-trace-viewer/trace-viewer.tsx +843 -0
- package/src/components/new-trace-viewer/types.ts +2 -0
- package/src/components/new-trace-viewer/utils.test.ts +182 -0
- package/src/components/new-trace-viewer/utils.ts +519 -0
- package/src/components/sidebar/attribute-panel.tsx +194 -240
- package/src/components/sidebar/attributes-block.tsx +173 -0
- package/src/components/sidebar/copyable-data-block.tsx +49 -27
- package/src/components/sidebar/detail-card.tsx +119 -59
- package/src/components/sidebar/entity-detail-panel.tsx +55 -111
- package/src/components/sidebar/events-list.tsx +85 -96
- package/src/components/sidebar/sidebar-data-context.tsx +62 -0
- package/src/components/sidebar/span-detail-merge.ts +65 -0
- package/src/components/stream-viewer.tsx +18 -40
- package/src/components/trace-viewer/components/node.tsx +3 -2
- package/src/components/trace-viewer/trace-viewer.module.css +4 -4
- package/src/components/trace-viewer/util/timing.ts +7 -11
- package/src/components/trace-viewer-new.tsx +55 -0
- package/src/components/ui/button.tsx +68 -0
- package/src/components/ui/context-card.tsx +784 -0
- package/src/components/ui/data-inspector.tsx +244 -22
- package/src/components/ui/error-stack-block.tsx +84 -55
- package/src/components/ui/icon-button.tsx +53 -0
- package/src/components/ui/inspector-theme.ts +39 -81
- package/src/components/ui/kbd.tsx +21 -0
- package/src/components/ui/timestamp-tooltip.tsx +132 -194
- package/src/components/ui/tooltip.tsx +47 -0
- package/src/components/workflow-trace-view.tsx +19 -15
- package/src/components/workflow-traces/event-colors.ts +12 -0
- package/src/components/workflow-traces/trace-span-construction.ts +24 -5
- package/src/hooks/use-intersection-observer.ts +57 -0
- package/src/hooks/use-load-more-on-scroll.ts +49 -0
- package/src/hooks/use-reduced-motion.ts +34 -0
- package/src/index.ts +9 -0
- package/src/lib/exact-event-search-id.ts +67 -0
- package/src/lib/hydration.ts +166 -1
- package/src/lib/stream-display.ts +48 -0
- package/src/lib/trace-builder.ts +34 -2
- package/src/lib/utils.ts +83 -31
- package/src/lib/zstd-browser-decoder.ts +42 -0
- package/src/styles.css +484 -1
- package/dist/components/error-boundary.js.map +0 -1
- package/dist/components/event-list-view.js.map +0 -1
- package/dist/components/hook-actions.js.map +0 -1
- package/dist/components/index.js.map +0 -1
- package/dist/components/run-trace-view.js.map +0 -1
- package/dist/components/sidebar/attribute-panel.js.map +0 -1
- package/dist/components/sidebar/conversation-view.js.map +0 -1
- package/dist/components/sidebar/copyable-data-block.js.map +0 -1
- package/dist/components/sidebar/detail-card.js.map +0 -1
- package/dist/components/sidebar/entity-detail-panel.js.map +0 -1
- package/dist/components/sidebar/events-list.js.map +0 -1
- package/dist/components/sidebar/resolve-hook-modal.js.map +0 -1
- package/dist/components/stream-viewer.js.map +0 -1
- package/dist/components/trace-viewer/components/map.js.map +0 -1
- package/dist/components/trace-viewer/components/markers.js.map +0 -1
- package/dist/components/trace-viewer/components/node.js.map +0 -1
- package/dist/components/trace-viewer/components/search-input.js.map +0 -1
- package/dist/components/trace-viewer/components/search.js.map +0 -1
- package/dist/components/trace-viewer/components/span-content.js.map +0 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js.map +0 -1
- package/dist/components/trace-viewer/components/span-segments.js.map +0 -1
- package/dist/components/trace-viewer/components/span-strategies.js.map +0 -1
- package/dist/components/trace-viewer/components/ui.js.map +0 -1
- package/dist/components/trace-viewer/components/zoom-button.js.map +0 -1
- package/dist/components/trace-viewer/components/zoom-icons.js.map +0 -1
- package/dist/components/trace-viewer/context.js.map +0 -1
- package/dist/components/trace-viewer/index.js.map +0 -1
- package/dist/components/trace-viewer/trace-viewer.js.map +0 -1
- package/dist/components/trace-viewer/types.js.map +0 -1
- package/dist/components/trace-viewer/util/constants.js.map +0 -1
- package/dist/components/trace-viewer/util/scrollbar-width.js.map +0 -1
- package/dist/components/trace-viewer/util/timing.js.map +0 -1
- package/dist/components/trace-viewer/util/tree.js.map +0 -1
- package/dist/components/trace-viewer/util/use-immediate-style.js.map +0 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js.map +0 -1
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js.map +0 -1
- package/dist/components/trace-viewer/worker.js.map +0 -1
- package/dist/components/ui/alert.js.map +0 -1
- package/dist/components/ui/card.js.map +0 -1
- package/dist/components/ui/data-inspector.js.map +0 -1
- package/dist/components/ui/decrypt-button.js.map +0 -1
- package/dist/components/ui/error-card.js.map +0 -1
- package/dist/components/ui/error-stack-block.js.map +0 -1
- package/dist/components/ui/inspector-theme.js.map +0 -1
- package/dist/components/ui/load-more-button.js.map +0 -1
- package/dist/components/ui/menu-dropdown.js.map +0 -1
- package/dist/components/ui/skeleton.js.map +0 -1
- package/dist/components/ui/spinner.js.map +0 -1
- package/dist/components/ui/timestamp-tooltip.js.map +0 -1
- package/dist/components/workflow-trace-view.js.map +0 -1
- package/dist/components/workflow-traces/event-colors.js.map +0 -1
- package/dist/components/workflow-traces/trace-colors.js.map +0 -1
- package/dist/components/workflow-traces/trace-span-construction.js.map +0 -1
- package/dist/components/workflow-traces/trace-time-utils.js.map +0 -1
- package/dist/hooks/use-dark-mode.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/lib/event-analysis.js.map +0 -1
- package/dist/lib/event-materialization.js.map +0 -1
- package/dist/lib/hydration.js.map +0 -1
- package/dist/lib/toast.js.map +0 -1
- package/dist/lib/trace-builder.js.map +0 -1
- package/dist/lib/utils.js.map +0 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ArrowLeft, ArrowRight } from 'lucide-react';
|
|
4
|
+
import { Fragment, memo, useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
5
|
+
import { cn } from '../../../lib/utils';
|
|
6
|
+
import { formatDuration, formatDurationPrecise, getHighResInMs, } from '../../trace-viewer/util/timing';
|
|
7
|
+
import { isSpanDimmedBySearch } from '../search';
|
|
8
|
+
import { computeOffscreenMarkers, computeSpanGaps, computeSpanMarkers, computeSpanSegments, getResourceColor, getSpanDurationMs, } from '../utils';
|
|
9
|
+
import { cullCollidingMarkers, MarkerLayer, OffscreenMarkerIndicator, projectMarkers, } from './span-markers';
|
|
10
|
+
import styles from './timeline.module.css';
|
|
11
|
+
import { ROW_HEIGHT_PX, useRowWindow } from './use-row-window';
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Constants
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
const TINY_BAR_BOX_SIZE_PX = 24;
|
|
16
|
+
const TINY_BAR_WIDTH_PX = 4;
|
|
17
|
+
export const TIMELINE_PADDING_PX = 16;
|
|
18
|
+
const SEGMENT_CLASSES = {
|
|
19
|
+
queued: 'bg-gray-400 border border-gray-500',
|
|
20
|
+
pending: 'bg-gray-200 border border-gray-500',
|
|
21
|
+
retrying: 'bg-gray-400 border border-gray-500',
|
|
22
|
+
waiting: 'bg-gray-200 border border-gray-500',
|
|
23
|
+
running: 'bg-blue-200 border border-blue-500',
|
|
24
|
+
completed: 'bg-blue-200 border border-blue-500',
|
|
25
|
+
failed: 'bg-red-200 border border-red-500',
|
|
26
|
+
succeeded: 'bg-green-200 border border-green-500',
|
|
27
|
+
sleeping: 'bg-gray-400 border border-gray-500',
|
|
28
|
+
received: 'bg-blue-200 border border-blue-500',
|
|
29
|
+
};
|
|
30
|
+
const TIMELINE_INSET_STYLE = {
|
|
31
|
+
left: TIMELINE_PADDING_PX,
|
|
32
|
+
right: TIMELINE_PADDING_PX,
|
|
33
|
+
};
|
|
34
|
+
const STRIPED_SEGMENT_STATUSES = new Set([
|
|
35
|
+
'pending',
|
|
36
|
+
'running',
|
|
37
|
+
'received',
|
|
38
|
+
]);
|
|
39
|
+
function AnimatedStripes({ status }) {
|
|
40
|
+
return (_jsx("div", { "aria-hidden": true, className: status === 'pending' ? styles.pendingStripes : styles.runningStripes }));
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Compute the bar's geometry inside the timeline viewport. Percentages are
|
|
44
|
+
* always in [0, 100] so we never emit CSS values that exceed browser layout
|
|
45
|
+
* limits at extreme zoom.
|
|
46
|
+
*/
|
|
47
|
+
function computeBarGeometry(startMs, endMs, viewStart, viewEnd, containerWidth) {
|
|
48
|
+
const viewDuration = viewEnd - viewStart;
|
|
49
|
+
const visibleStartMs = Math.max(startMs, viewStart);
|
|
50
|
+
const visibleEndMs = Math.min(endMs, viewEnd);
|
|
51
|
+
const visibleDurationMs = Math.max(0, visibleEndMs - visibleStartMs);
|
|
52
|
+
const widthFrac = viewDuration > 0 ? visibleDurationMs / viewDuration : 0;
|
|
53
|
+
const visiblePixelWidth = widthFrac * containerWidth;
|
|
54
|
+
const isTiny = containerWidth > 0 && visiblePixelWidth < TINY_BAR_BOX_SIZE_PX;
|
|
55
|
+
const extendsOffLeft = startMs < viewStart;
|
|
56
|
+
const extendsOffRight = endMs > viewEnd;
|
|
57
|
+
const mode = isTiny && (extendsOffLeft || extendsOffRight)
|
|
58
|
+
? { kind: 'arrow', direction: extendsOffRight ? 'right' : 'left' }
|
|
59
|
+
: isTiny
|
|
60
|
+
? { kind: 'tiny' }
|
|
61
|
+
: { kind: 'full' };
|
|
62
|
+
return {
|
|
63
|
+
mode,
|
|
64
|
+
leftPct: viewDuration > 0
|
|
65
|
+
? ((visibleStartMs - viewStart) / viewDuration) * 100
|
|
66
|
+
: 0,
|
|
67
|
+
widthPct: widthFrac * 100,
|
|
68
|
+
visibleStartMs,
|
|
69
|
+
visibleEndMs,
|
|
70
|
+
visiblePixelWidth,
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function getBarPositionStyle(geometry) {
|
|
74
|
+
switch (geometry.mode.kind) {
|
|
75
|
+
case 'arrow':
|
|
76
|
+
return {
|
|
77
|
+
left: geometry.mode.direction === 'right'
|
|
78
|
+
? `calc(100% - ${TINY_BAR_BOX_SIZE_PX}px)`
|
|
79
|
+
: '0px',
|
|
80
|
+
width: `${TINY_BAR_BOX_SIZE_PX}px`,
|
|
81
|
+
};
|
|
82
|
+
case 'tiny':
|
|
83
|
+
return {
|
|
84
|
+
left: `min(${geometry.leftPct}%, calc(100% - ${TINY_BAR_WIDTH_PX}px))`,
|
|
85
|
+
width: `${TINY_BAR_WIDTH_PX}px`,
|
|
86
|
+
};
|
|
87
|
+
case 'full':
|
|
88
|
+
return {
|
|
89
|
+
left: `${geometry.leftPct}%`,
|
|
90
|
+
width: `max(${geometry.widthPct}%, 4px)`,
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Project status segments onto the visible portion of a bar. Segments fully
|
|
96
|
+
* outside the visible window are dropped; segments crossing the edge are
|
|
97
|
+
* clipped to [0%, 100%] of the visible bar.
|
|
98
|
+
*/
|
|
99
|
+
function projectSegments(segments, spanStartMs, spanDurationMs, geometry) {
|
|
100
|
+
const visibleDurationMs = geometry.visibleEndMs - geometry.visibleStartMs;
|
|
101
|
+
if (visibleDurationMs <= 0)
|
|
102
|
+
return [];
|
|
103
|
+
return segments.flatMap((seg) => {
|
|
104
|
+
const segStartMs = spanStartMs + seg.startFraction * spanDurationMs;
|
|
105
|
+
const segEndMs = spanStartMs + seg.endFraction * spanDurationMs;
|
|
106
|
+
const startMs = Math.max(segStartMs, geometry.visibleStartMs);
|
|
107
|
+
const endMs = Math.min(segEndMs, geometry.visibleEndMs);
|
|
108
|
+
if (endMs <= startMs)
|
|
109
|
+
return [];
|
|
110
|
+
const widthFrac = (endMs - startMs) / visibleDurationMs;
|
|
111
|
+
return [
|
|
112
|
+
{
|
|
113
|
+
status: seg.status,
|
|
114
|
+
leftPct: ((startMs - geometry.visibleStartMs) / visibleDurationMs) * 100,
|
|
115
|
+
widthPct: widthFrac * 100,
|
|
116
|
+
pixelWidth: widthFrac * geometry.visiblePixelWidth,
|
|
117
|
+
fullDurationMs: (seg.endFraction - seg.startFraction) * spanDurationMs,
|
|
118
|
+
},
|
|
119
|
+
];
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Small render helpers
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
function DurationLabel({ label, className, }) {
|
|
126
|
+
return (_jsx("span", { className: cn('pointer-events-none absolute inset-0 flex items-center justify-start overflow-hidden px-1 text-[10px] font-mono font-medium leading-none whitespace-nowrap text-left text-gray-1000 tabular-nums opacity-0 group-hover/timeline-row:opacity-100', className), children: label }));
|
|
127
|
+
}
|
|
128
|
+
function BoundaryArrow({ direction, }) {
|
|
129
|
+
const Icon = direction === 'right' ? ArrowRight : ArrowLeft;
|
|
130
|
+
return (_jsx("div", { className: "flex h-6 w-6 items-center justify-center rounded-[0.25rem]", children: _jsx(Icon, { className: "size-3 text-gray-900" }) }));
|
|
131
|
+
}
|
|
132
|
+
function PlainBar({ bg, border, label, }) {
|
|
133
|
+
return (_jsx("div", { className: "relative h-6 w-full min-w-1 rounded-[0.25rem] border", style: { background: bg, borderColor: border }, children: label ? _jsx(DurationLabel, { label: label }) : null }));
|
|
134
|
+
}
|
|
135
|
+
function LeadInConnector({ leftPct, widthPct, label, }) {
|
|
136
|
+
return (_jsxs("div", { className: "absolute top-1/2 h-6 -translate-y-1/2", style: {
|
|
137
|
+
left: `calc(${leftPct}% + 0.5px)`,
|
|
138
|
+
width: `calc(${widthPct}% - 1px)`,
|
|
139
|
+
}, children: [_jsx("div", { className: "absolute left-0 top-1/2 h-4 w-px -translate-y-1/2 bg-gray-500" }), _jsx("div", { className: "absolute inset-x-0 top-1/2 h-px -translate-y-1/2 bg-gray-500" }), label ? _jsx(DurationLabel, { label: label }) : null] }));
|
|
140
|
+
}
|
|
141
|
+
function SegmentBar({ segments, showLabels = true, }) {
|
|
142
|
+
return (_jsx("div", { className: "relative h-6 w-full", children: segments.map((seg, i) => {
|
|
143
|
+
if (seg.status === 'queued') {
|
|
144
|
+
const leadInLabel = formatDurationPrecise(seg.fullDurationMs);
|
|
145
|
+
const showLeadInLabel = showLabels &&
|
|
146
|
+
seg.pixelWidth >= Math.max(40, leadInLabel.length * 6 + 12);
|
|
147
|
+
const isFullWidthQueued = segments.length === 1;
|
|
148
|
+
return (_jsxs(Fragment, { children: [_jsx(LeadInConnector, { leftPct: seg.leftPct, widthPct: seg.widthPct, label: showLeadInLabel ? leadInLabel : null }), isFullWidthQueued ? (_jsx("div", { className: "absolute top-1/2 h-4 w-px -translate-y-1/2 bg-gray-500", style: {
|
|
149
|
+
left: `calc(${seg.leftPct + seg.widthPct}% - 1.5px)`,
|
|
150
|
+
} })) : null] }, i));
|
|
151
|
+
}
|
|
152
|
+
const label = formatDurationPrecise(seg.fullDurationMs);
|
|
153
|
+
// Only render the label when there's enough room for it without clipping.
|
|
154
|
+
const showLabel = showLabels && seg.pixelWidth >= Math.max(40, label.length * 6 + 12);
|
|
155
|
+
return (_jsxs("div", { className: cn('absolute h-full overflow-hidden rounded-[0.25rem]', SEGMENT_CLASSES[seg.status]), style: {
|
|
156
|
+
// 1px gap between adjacent segments, distributed equally.
|
|
157
|
+
left: `calc(${seg.leftPct}% + 0.5px)`,
|
|
158
|
+
width: `calc(${seg.widthPct}% - 1px)`,
|
|
159
|
+
minWidth: 1,
|
|
160
|
+
}, children: [STRIPED_SEGMENT_STATUSES.has(seg.status) ? (_jsx(AnimatedStripes, { status: seg.status })) : null, showLabel ? _jsx(DurationLabel, { label: label }) : null] }, i));
|
|
161
|
+
}) }));
|
|
162
|
+
}
|
|
163
|
+
// ---------------------------------------------------------------------------
|
|
164
|
+
// TimelineBar
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
const TimelineBar = memo(function TimelineBar({ span, viewStart, viewDuration, containerWidth, isSelected, isDimmed, onSelect, onRevealTime, }) {
|
|
167
|
+
const startMs = getHighResInMs(span.startTime);
|
|
168
|
+
const endMs = getHighResInMs(span.endTime);
|
|
169
|
+
const totalDurationMs = getSpanDurationMs(span);
|
|
170
|
+
const geometry = useMemo(() => computeBarGeometry(startMs, endMs, viewStart, viewStart + viewDuration, containerWidth), [startMs, endMs, viewStart, viewDuration, containerWidth]);
|
|
171
|
+
const baseSegments = useMemo(() => computeSpanSegments(span), [span]);
|
|
172
|
+
const segments = useMemo(() => geometry.mode.kind === 'full'
|
|
173
|
+
? projectSegments(baseSegments, startMs, totalDurationMs, geometry)
|
|
174
|
+
: [], [geometry, baseSegments, startMs, totalDurationMs]);
|
|
175
|
+
const baseMarkers = useMemo(() => computeSpanMarkers(span), [span]);
|
|
176
|
+
const markers = useMemo(() => geometry.mode.kind === 'full'
|
|
177
|
+
? cullCollidingMarkers(projectMarkers(baseMarkers, geometry.visibleStartMs, geometry.visibleEndMs), geometry.visiblePixelWidth)
|
|
178
|
+
: [], [geometry, baseMarkers]);
|
|
179
|
+
// Markers that fall outside the visible window (scrolled off while zoomed in)
|
|
180
|
+
// — surfaced as edge indicators so they aren't silently lost.
|
|
181
|
+
const offscreen = useMemo(() => geometry.mode.kind === 'full'
|
|
182
|
+
? computeOffscreenMarkers(baseMarkers, geometry.visibleStartMs, geometry.visibleEndMs)
|
|
183
|
+
: { left: null, right: null }, [geometry, baseMarkers]);
|
|
184
|
+
// Markers (visible or off-screen) move the duration label into the overlay,
|
|
185
|
+
// so the in-bar segment label is suppressed.
|
|
186
|
+
const hasMarkers = markers.length > 0 || offscreen.left !== null || offscreen.right !== null;
|
|
187
|
+
const workflowStatus = span.attributes.data
|
|
188
|
+
?.status;
|
|
189
|
+
const isErrored = span.status.code === 2 || workflowStatus === 'failed';
|
|
190
|
+
const colors = getResourceColor(span.resource);
|
|
191
|
+
const fallbackBg = isErrored
|
|
192
|
+
? (colors.errorBg ?? 'var(--ds-red-200)')
|
|
193
|
+
: colors.bg;
|
|
194
|
+
const fallbackBorder = isErrored
|
|
195
|
+
? (colors.errorBorder ?? 'var(--ds-red-500)')
|
|
196
|
+
: colors.border;
|
|
197
|
+
const totalLabel = formatDurationPrecise(totalDurationMs);
|
|
198
|
+
const showTotalLabel = geometry.visiblePixelWidth >= Math.max(40, totalLabel.length * 6 + 12);
|
|
199
|
+
const handleClick = useCallback(() => {
|
|
200
|
+
onSelect(span.spanId);
|
|
201
|
+
}, [onSelect, span.spanId]);
|
|
202
|
+
return (_jsx("div", { role: "treeitem", "aria-selected": isSelected, "aria-expanded": isSelected, "aria-level": 1, className: cn('group/timeline-row h-10 relative flex items-center hover:bg-gray-100 aria-selected:bg-gray-100 aria-selected:hover:bg-gray-200 transition-opacity', isDimmed && 'opacity-35'), onClick: handleClick, children: _jsxs("div", { className: "absolute inset-y-0", style: TIMELINE_INSET_STYLE, children: [_jsx("div", { className: "absolute top-1/2 h-6 -translate-y-1/2 overflow-hidden rounded-[0.25rem]", style: getBarPositionStyle(geometry), children: geometry.mode.kind === 'arrow' ? (_jsx(BoundaryArrow, { direction: geometry.mode.direction })) : geometry.mode.kind === 'tiny' ? (_jsx("div", { className: "h-6 rounded-[0.25rem] border", style: { background: fallbackBg, borderColor: fallbackBorder } })) : segments.length > 0 ? (_jsx(SegmentBar, { segments: segments, showLabels: !hasMarkers })) : (_jsx(PlainBar, { bg: fallbackBg, border: fallbackBorder, label: showTotalLabel ? totalLabel : null })) }), hasMarkers ? (_jsxs("div", { className: "pointer-events-none absolute top-1/2 h-6 -translate-y-1/2", style: getBarPositionStyle(geometry), children: [markers.length > 0 ? _jsx(MarkerLayer, { markers: markers }) : null, offscreen.left ? (_jsx(OffscreenMarkerIndicator, { direction: "left", count: offscreen.left.count, targetMs: offscreen.left.nearestMs, onReveal: onRevealTime })) : null, offscreen.right ? (_jsx(OffscreenMarkerIndicator, { direction: "right", count: offscreen.right.count, targetMs: offscreen.right.nearestMs, onReveal: onRevealTime })) : null, showTotalLabel ? (_jsx(DurationLabel, { label: totalLabel,
|
|
203
|
+
// Shift clear of the left edge indicator so it isn't covered.
|
|
204
|
+
className: offscreen.left ? 'pl-10' : undefined })) : null] })) : null] }) }));
|
|
205
|
+
});
|
|
206
|
+
export { TimelineBar };
|
|
207
|
+
// ---------------------------------------------------------------------------
|
|
208
|
+
// DeltaIndicator (Alt-key gap overlay)
|
|
209
|
+
// ---------------------------------------------------------------------------
|
|
210
|
+
const DELTA_CAP_HEIGHT_PX = 8;
|
|
211
|
+
// Vertical offset to sit the indicator inside the gap between row N and N+1,
|
|
212
|
+
// aligned with where the bar starts in the next row (rows center a 24px bar
|
|
213
|
+
// inside 40px, so bars start ~8px from the top of the row).
|
|
214
|
+
const DELTA_ROW_OFFSET_PX = 8;
|
|
215
|
+
const DeltaIndicator = memo(function DeltaIndicator({ leftFrac, rightFrac, label, rowIndex, }) {
|
|
216
|
+
const centerY = DELTA_ROW_OFFSET_PX + (rowIndex + 1) * ROW_HEIGHT_PX;
|
|
217
|
+
return (_jsxs("div", { className: "absolute pointer-events-none", style: {
|
|
218
|
+
left: `${leftFrac * 100}%`,
|
|
219
|
+
width: `${(rightFrac - leftFrac) * 100}%`,
|
|
220
|
+
top: centerY - DELTA_CAP_HEIGHT_PX / 2,
|
|
221
|
+
height: DELTA_CAP_HEIGHT_PX,
|
|
222
|
+
}, children: [_jsx("div", { className: "absolute left-0 top-0 w-px h-full bg-amber-800" }), _jsx("div", { className: "absolute left-0 right-0 top-1/2 h-px bg-amber-800" }), _jsx("div", { className: "absolute right-0 top-0 w-px h-full bg-amber-800" }), _jsx("span", { className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 text-label-12 leading-none whitespace-nowrap rounded-xs px-1 py-0.5 text-gray-100 bg-amber-800", children: label })] }));
|
|
223
|
+
});
|
|
224
|
+
// ---------------------------------------------------------------------------
|
|
225
|
+
// TimelineHeader
|
|
226
|
+
// ---------------------------------------------------------------------------
|
|
227
|
+
export function TimelineHeader({ markers, hoverInfo, }) {
|
|
228
|
+
return (_jsx("div", { className: "relative bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-end px-4 pb-1", children: _jsxs("div", { className: "relative h-full flex-1", children: [markers.map((m) => (_jsx("span", { className: "absolute bottom-1 font-mono text-xs font-normal leading-4 text-gray-900 whitespace-nowrap", style: { left: `${m.position * 100}%` }, children: m.label }, String(m.value)))), hoverInfo && (_jsx("span", { className: "absolute top-1 pointer-events-none z-10 font-mono text-[11px] leading-4 text-gray-1000 whitespace-nowrap bg-background-100 border border-gray-alpha-400 rounded px-1 -translate-x-1/2", style: { left: `${hoverInfo.fraction * 100}%` }, children: hoverInfo.label }))] }) }));
|
|
229
|
+
}
|
|
230
|
+
// ---------------------------------------------------------------------------
|
|
231
|
+
// Timeline
|
|
232
|
+
// ---------------------------------------------------------------------------
|
|
233
|
+
export function Timeline({ spans, viewStart, viewEnd, markers, selectedId, searchResult, onSelect, onRevealTime, hoverFraction, altHeld = false, }) {
|
|
234
|
+
const containerRef = useRef(null);
|
|
235
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
236
|
+
const viewDuration = viewEnd - viewStart;
|
|
237
|
+
const timelineWidth = Math.max(0, containerWidth - TIMELINE_PADDING_PX * 2);
|
|
238
|
+
const { start, end } = useRowWindow(containerRef, spans.length, ROW_HEIGHT_PX);
|
|
239
|
+
useEffect(() => {
|
|
240
|
+
const el = containerRef.current;
|
|
241
|
+
if (!el)
|
|
242
|
+
return;
|
|
243
|
+
const ro = new ResizeObserver(([entry]) => {
|
|
244
|
+
setContainerWidth(entry.contentRect.width);
|
|
245
|
+
});
|
|
246
|
+
ro.observe(el);
|
|
247
|
+
return () => ro.disconnect();
|
|
248
|
+
}, []);
|
|
249
|
+
const gaps = useMemo(() => computeSpanGaps(spans, viewStart, viewEnd), [spans, viewStart, viewEnd]);
|
|
250
|
+
return (_jsxs("div", { ref: containerRef, className: "relative h-full overflow-hidden", style: { minHeight: spans.length * ROW_HEIGHT_PX }, children: [_jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: markers.map((marker) =>
|
|
251
|
+
// Skip the "0s" origin marker since the left edge already implies it.
|
|
252
|
+
Math.abs(marker.value) > 0.000001 ? (_jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-300", style: { left: `${marker.position * 100}%` } }, String(marker.value))) : null) }), hoverFraction != null && (_jsx("div", { className: "absolute inset-y-0 pointer-events-none z-10", style: TIMELINE_INSET_STYLE, children: _jsx("div", { className: "absolute top-0 bottom-0 w-px bg-gray-alpha-500", style: { left: `${hoverFraction * 100}%` } }) })), _jsx("div", { style: { transform: `translateY(${start * ROW_HEIGHT_PX}px)` }, children: spans.slice(start, end).map((span) => (_jsx(TimelineBar, { span: span, viewStart: viewStart, viewDuration: viewDuration, containerWidth: timelineWidth, isSelected: selectedId === span.spanId, isDimmed: isSpanDimmedBySearch(span.spanId, searchResult), onSelect: onSelect, onRevealTime: onRevealTime }, span.spanId))) }), altHeld && (_jsx("div", { "aria-hidden": true, className: "absolute inset-y-0 pointer-events-none", style: TIMELINE_INSET_STYLE, children: gaps.map((gap) => (_jsx(DeltaIndicator, { leftFrac: gap.leftFrac, rightFrac: gap.rightFrac, label: formatDuration(gap.gapMs, true), rowIndex: gap.rowIndex }, gap.rowIndex))) }))] }));
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9uZXctdHJhY2Utdmlld2VyL2NvbXBvbmVudHMvdGltZWxpbmUudHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVksQ0FBQzs7QUFFYixPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVyRCxPQUFPLEVBQ0wsUUFBUSxFQUNSLElBQUksRUFDSixXQUFXLEVBQ1gsU0FBUyxFQUNULE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxHQUNULE1BQU0sT0FBTyxDQUFDO0FBQ2YsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hDLE9BQU8sRUFDTCxjQUFjLEVBQ2QscUJBQXFCLEVBQ3JCLGNBQWMsR0FDZixNQUFNLGdDQUFnQyxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxvQkFBb0IsRUFBeUIsTUFBTSxXQUFXLENBQUM7QUFReEUsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQixnQkFBZ0IsRUFDaEIsaUJBQWlCLEdBQ2xCLE1BQU0sVUFBVSxDQUFDO0FBQ2xCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsV0FBVyxFQUNYLHdCQUF3QixFQUN4QixjQUFjLEdBQ2YsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLE1BQU0sTUFBTSx1QkFBdUIsQ0FBQztBQUMzQyxPQUFPLEVBQUUsYUFBYSxFQUFFLFlBQVksRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBRS9ELDhFQUE4RTtBQUM5RSxZQUFZO0FBQ1osOEVBQThFO0FBRTlFLE1BQU0sb0JBQW9CLEdBQUcsRUFBRSxDQUFDO0FBQ2hDLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxDQUFDO0FBQzVCLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLEVBQUUsQ0FBQztBQUV0QyxNQUFN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QUFDIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBjbGllbnQnO1xuXG5pbXBvcnQgeyBBcnJvd0xlZnQsIEFycm93UmlnaHQgfSBmcm9tICdsdWNpZGUtcmVhY3QnO1xuaW1wb3J0IHR5cGUgeyBDU1NQcm9wZXJ0aWVzLCBSZWFjdE5vZGUgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQge1xuICBGcmFnbWVudCxcbiAgbWVtbyxcbiAgdXNlQ2FsbGJhY2ssXG4gIHVzZUVmZmVjdCxcbiAgdXNlTWVtbyxcbiAgdXNlUmVmLFxuICB1c2VTdGF0ZSxcbn0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuLi8uLi8uLi9saWIvdXRpbHMnO1xuaW1wb3J0IHtcbiAgZm9ybWF0RHVyYXRpb24sXG4gIGZvcm1hdER1cmF0aW9uUHJlY2lzZSxcbiAgZ2V0SGlnaFJlc0luTXMsXG59IGZyb20gJy4uLy4uL3RyYWNlLXZpZXdlci91dGlsL3RpbWluZyc7XG5pbXBvcnQgeyBpc1NwYW5EaW1tZWRCeVNlYXJjaCwgdHlwZSBTcGFuU2VhcmNoUmVzdWx0IH0gZnJvbSAnLi4vc2VhcmNoJztcbmltcG9ydCB0eXBlIHsgU3BhbiB9IGZyb20gJy4uL3R5cGVzJztcbmltcG9ydCB0eXBlIHtcbiAgT2Zmc2NyZWVuTWFya2VycyxcbiAgU2VnbWVudCxcbiAgU2VnbWVudFN0YXR1cyxcbiAgVGltZU1hcmtlcixcbn0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtcbiAgY29tcHV0ZU9mZnNjcmVlbk1hcmtlcnMsXG4gIGNvbXB1dGVTcGFuR2FwcyxcbiAgY29tcHV0ZVNwYW5NYXJrZXJzLFxuICBjb21wdXRlU3BhblNlZ21lbnRzLFxuICBnZXRSZXNvdXJjZUNvbG9yLFxuICBnZXRTcGFuRHVyYXRpb25Ncyxcbn0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHtcbiAgY3VsbENvbGxpZGluZ01hcmtlcnMsXG4gIE1hcmtlckxheWVyLFxuICBPZmZzY3JlZW5NYXJrZXJJbmRpY2F0b3IsXG4gIHByb2plY3RNYXJrZXJzLFxufSBmcm9tICcuL3NwYW4tbWFya2Vycyc7XG5pbXBvcnQgc3R5bGVzIGZyb20gJy4vdGltZWxpbmUubW9kdWxlLmNzcyc7XG5pbXBvcnQgeyBST1dfSEVJR0hUX1BYLCB1c2VSb3dXaW5kb3cgfSBmcm9tICcuL3VzZS1yb3ctd2luZG93JztcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBDb25zdGFudHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5jb25zdCBUSU5ZX0JBUl9CT1hfU0laRV9QWCA9IDI0O1xuY29uc3QgVElOWV9CQVJfV0lEVEhfUFggPSA0O1xuZXhwb3J0IGNvbnN0IFRJTUVMSU5FX1BBRERJTkdfUFggPSAxNjtcblxuY29uc3QgU0VHTUVOVF9DTEFTU0VTOiBSZWNvcmQ8U2VnbWVudFN0YXR1cywgc3RyaW5nPiA9IHtcbiAgcXVldWVkOiAnYmctZ3JheS00MDAgYm9yZGVyIGJvcmRlci1ncmF5LTUwMCcsXG4gIHBlbmRpbmc6ICdiZy1ncmF5LTIwMCBib3JkZXIgYm9yZGVyLWdyYXktNTAwJyxcbiAgcmV0cnlpbmc6ICdiZy1ncmF5LTQwMCBib3JkZXIgYm9yZGVyLWdyYXktNTAwJyxcbiAgd2FpdGluZzogJ2JnLWdyYXktMjAwIGJvcmRlciBib3JkZXItZ3JheS01MDAnLFxuICBydW5uaW5nOiAnYmctYmx1ZS0yMDAgYm9yZGVyIGJvcmRlci1ibHVlLTUwMCcsXG4gIGNvbXBsZXRlZDogJ2JnLWJsdWUtMjAwIGJvcmRlciBib3JkZXItYmx1ZS01MDAnLFxuICBmYWlsZWQ6ICdiZy1yZWQtMjAwIGJvcmRlciBib3JkZXItcmVkLTUwMCcsXG4gIHN1Y2NlZWRlZDogJ2JnLWdyZWVuLTIwMCBib3JkZXIgYm9yZGVyLWdyZWVuLTUwMCcsXG4gIHNsZWVwaW5nOiAnYmctZ3JheS00MDAgYm9yZGVyIGJvcmRlci1ncmF5LTUwMCcsXG4gIHJlY2VpdmVkOiAnYmctYmx1ZS0yMDAgYm9yZGVyIGJvcmRlci1ibHVlLTUwMCcsXG59O1xuXG5jb25zdCBUSU1FTElORV9JTlNFVF9TVFlMRTogQ1NTUHJvcGVydGllcyA9IHtcbiAgbGVmdDogVElNRUxJTkVfUEFERElOR19QWCxcbiAgcmlnaHQ6IFRJTUVMSU5FX1BBRERJTkdfUFgsXG59O1xuXG5jb25zdCBTVFJJUEVEX1NFR01FTlRfU1RBVFVTRVM6IFJlYWRvbmx5U2V0PFNlZ21lbnRTdGF0dXM+ID0gbmV3IFNldChbXG4gICdwZW5kaW5nJyxcbiAgJ3J1bm5pbmcnLFxuICAncmVjZWl2ZWQnLFxuXSk7XG5cbmZ1bmN0aW9uIEFuaW1hdGVkU3RyaXBlcyh7IHN0YXR1cyB9OiB7IHN0YXR1czogU2VnbWVudFN0YXR1cyB9KTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBhcmlhLWhpZGRlblxuICAgICAgY2xhc3NOYW1lPXtcbiAgICAgICAgc3RhdHVzID09PSAncGVuZGluZycgPyBzdHlsZXMucGVuZGluZ1N0cmlwZXMgOiBzdHlsZXMucnVubmluZ1N0cmlwZXNcbiAgICAgIH1cbiAgICAvPlxuICApO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEJhciBnZW9tZXRyeVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbnR5cGUgQmFyTW9kZSA9XG4gIHwgeyBraW5kOiAnYXJyb3cnOyBkaXJlY3Rpb246ICdsZWZ0JyB8ICdyaWdodCcgfVxuICB8IHsga2luZDogJ3RpbnknIH1cbiAgfCB7IGtpbmQ6ICdmdWxsJyB9O1xuXG5pbnRlcmZhY2UgQmFyR2VvbWV0cnkge1xuICBtb2RlOiBCYXJNb2RlO1xuICBsZWZ0UGN0OiBudW1iZXI7XG4gIHdpZHRoUGN0OiBudW1iZXI7XG4gIHZpc2libGVTdGFydE1zOiBudW1iZXI7XG4gIHZpc2libGVFbmRNczogbnVtYmVyO1xuICB2aXNpYmxlUGl4ZWxXaWR0aDogbnVtYmVyO1xufVxuXG4vKipcbiAqIENvbXB1dGUgdGhlIGJhcidzIGdlb21ldHJ5IGluc2lkZSB0aGUgdGltZWxpbmUgdmlld3BvcnQuIFBlcmNlbnRhZ2VzIGFyZVxuICogYWx3YXlzIGluIFswLCAxMDBdIHNvIHdlIG5ldmVyIGVtaXQgQ1NTIHZhbHVlcyB0aGF0IGV4Y2VlZCBicm93c2VyIGxheW91dFxuICogbGltaXRzIGF0IGV4dHJlbWUgem9vbS5cbiAqL1xuZnVuY3Rpb24gY29tcHV0ZUJhckdlb21ldHJ5KFxuICBzdGFydE1zOiBudW1iZXIsXG4gIGVuZE1zOiBudW1iZXIsXG4gIHZpZXdTdGFydDogbnVtYmVyLFxuICB2aWV3RW5kOiBudW1iZXIsXG4gIGNvbnRhaW5lcldpZHRoOiBudW1iZXJcbik6IEJhckdlb21ldHJ5IHtcbiAgY29uc3Qgdmlld0R1cmF0aW9uID0gdmlld0VuZCAtIHZpZXdTdGFydDtcbiAgY29uc3QgdmlzaWJsZVN0YXJ0TXMgPSBNYXRoLm1heChzdGFydE1zLCB2aWV3U3RhcnQpO1xuICBjb25zdCB2aXNpYmxlRW5kTXMgPSBNYXRoLm1pbihlbmRNcywgdmlld0VuZCk7XG4gIGNvbnN0IHZpc2libGVEdXJhdGlvbk1zID0gTWF0aC5tYXgoMCwgdmlzaWJsZUVuZE1zIC0gdmlzaWJsZVN0YXJ0TXMpO1xuICBjb25zdCB3aWR0aEZyYWMgPSB2aWV3RHVyYXRpb24gPiAwID8gdmlzaWJsZUR1cmF0aW9uTXMgLyB2aWV3RHVyYXRpb24gOiAwO1xuICBjb25zdCB2aXNpYmxlUGl4ZWxXaWR0aCA9IHdpZHRoRnJhYyAqIGNvbnRhaW5lcldpZHRoO1xuXG4gIGNvbnN0IGlzVGlueSA9IGNvbnRhaW5lcldpZHRoID4gMCAmJiB2aXNpYmxlUGl4ZWxXaWR0aCA8IFRJTllfQkFSX0JPWF9TSVpFX1BYO1xuICBjb25zdCBleHRlbmRzT2ZmTGVmdCA9IHN0YXJ0TXMgPCB2aWV3U3RhcnQ7XG4gIGNvbnN0IGV4dGVuZHNPZmZSaWdodCA9IGVuZE1zID4gdmlld0VuZDtcblxuICBjb25zdCBtb2RlOiBCYXJNb2RlID1cbiAgICBpc1RpbnkgJiYgKGV4dGVuZHNPZmZMZWZ0IHx8IGV4dGVuZHNPZmZSaWdodClcbiAgICAgID8geyBraW5kOiAnYXJyb3cnLCBkaXJlY3Rpb246IGV4dGVuZHNPZmZSaWdodCA/ICdyaWdodCcgOiAnbGVmdCcgfVxuICAgICAgOiBpc1RpbnlcbiAgICAgICAgPyB7IGtpbmQ6ICd0aW55JyB9XG4gICAgICAgIDogeyBraW5kOiAnZnVsbCcgfTtcblxuICByZXR1cm4ge1xuICAgIG1vZGUsXG4gICAgbGVmdFBjdDpcbiAgICAgIHZpZXdEdXJhdGlvbiA+IDBcbiAgICAgICAgPyAoKHZpc2libGVTdGFydE1zIC0gdmlld1N0YXJ0KSAvIHZpZXdEdXJhdGlvbikgKiAxMDBcbiAgICAgICAgOiAwLFxuICAgIHdpZHRoUGN0OiB3aWR0aEZyYWMgKiAxMDAsXG4gICAgdmlzaWJsZVN0YXJ0TXMsXG4gICAgdmlzaWJsZUVuZE1zLFxuICAgIHZpc2libGVQaXhlbFdpZHRoLFxuICB9O1xufVxuXG5mdW5jdGlvbiBnZXRCYXJQb3NpdGlvblN0eWxlKGdlb21ldHJ5OiBCYXJHZW9tZXRyeSk6IHtcbiAgbGVmdDogc3RyaW5nO1xuICB3aWR0aDogc3RyaW5nO1xufSB7XG4gIHN3aXRjaCAoZ2VvbWV0cnkubW9kZS5raW5kKSB7XG4gICAgY2FzZSAnYXJyb3cnOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbGVmdDpcbiAgICAgICAgICBnZW9tZXRyeS5tb2RlLmRpcmVjdGlvbiA9PT0gJ3JpZ2h0J1xuICAgICAgICAgICAgPyBgY2FsYygxMDAlIC0gJHtUSU5ZX0JBUl9CT1hfU0laRV9QWH1weClgXG4gICAgICAgICAgICA6ICcwcHgnLFxuICAgICAgICB3aWR0aDogYCR7VElOWV9CQVJfQk9YX1NJWkVfUFh9cHhgLFxuICAgICAgfTtcbiAgICBjYXNlICd0aW55JzpcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGxlZnQ6IGBtaW4oJHtnZW9tZXRyeS5sZWZ0UGN0fSUsIGNhbGMoMTAwJSAtICR7VElOWV9CQVJfV0lEVEhfUFh9cHgpKWAsXG4gICAgICAgIHdpZHRoOiBgJHtUSU5ZX0JBUl9XSURUSF9QWH1weGAsXG4gICAgICB9O1xuICAgIGNhc2UgJ2Z1bGwnOlxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbGVmdDogYCR7Z2VvbWV0cnkubGVmdFBjdH0lYCxcbiAgICAgICAgd2lkdGg6IGBtYXgoJHtnZW9tZXRyeS53aWR0aFBjdH0lLCA0cHgpYCxcbiAgICAgIH07XG4gIH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTZWdtZW50IHByb2plY3Rpb25cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5pbnRlcmZhY2UgVmlzaWJsZVNlZ21lbnQge1xuICBzdGF0dXM6IFNlZ21lbnRTdGF0dXM7XG4gIGxlZnRQY3Q6IG51bWJlcjtcbiAgd2lkdGhQY3Q6IG51bWJlcjtcbiAgcGl4ZWxXaWR0aDogbnVtYmVyO1xuICBmdWxsRHVyYXRpb25NczogbnVtYmVyO1xufVxuXG4vKipcbiAqIFByb2plY3Qgc3RhdHVzIHNlZ21lbnRzIG9udG8gdGhlIHZpc2libGUgcG9ydGlvbiBvZiBhIGJhci4gU2VnbWVudHMgZnVsbHlcbiAqIG91dHNpZGUgdGhlIHZpc2libGUgd2luZG93IGFyZSBkcm9wcGVkOyBzZWdtZW50cyBjcm9zc2luZyB0aGUgZWRnZSBhcmVcbiAqIGNsaXBwZWQgdG8gWzAlLCAxMDAlXSBvZiB0aGUgdmlzaWJsZSBiYXIuXG4gKi9cbmZ1bmN0aW9uIHByb2plY3RTZWdtZW50cyhcbiAgc2VnbWVudHM6IFNlZ21lbnRbXSxcbiAgc3BhblN0YXJ0TXM6IG51bWJlcixcbiAgc3BhbkR1cmF0aW9uTXM6IG51bWJlcixcbiAgZ2VvbWV0cnk6IEJhckdlb21ldHJ5XG4pOiBWaXNpYmxlU2VnbWVudFtdIHtcbiAgY29uc3QgdmlzaWJsZUR1cmF0aW9uTXMgPSBnZW9tZXRyeS52aXNpYmxlRW5kTXMgLSBnZW9tZXRyeS52aXNpYmxlU3RhcnRNcztcbiAgaWYgKHZpc2libGVEdXJhdGlvbk1zIDw9IDApIHJldHVybiBbXTtcblxuICByZXR1cm4gc2VnbWVudHMuZmxhdE1hcCgoc2VnKSA9PiB7XG4gICAgY29uc3Qgc2VnU3RhcnRNcyA9IHNwYW5TdGFydE1zICsgc2VnLnN0YXJ0RnJhY3Rpb24gKiBzcGFuRHVyYXRpb25NcztcbiAgICBjb25zdCBzZWdFbmRNcyA9IHNwYW5TdGFydE1zICsgc2VnLmVuZEZyYWN0aW9uICogc3BhbkR1cmF0aW9uTXM7XG4gICAgY29uc3Qgc3RhcnRNcyA9IE1hdGgubWF4KHNlZ1N0YXJ0TXMsIGdlb21ldHJ5LnZpc2libGVTdGFydE1zKTtcbiAgICBjb25zdCBlbmRNcyA9IE1hdGgubWluKHNlZ0VuZE1zLCBnZW9tZXRyeS52aXNpYmxlRW5kTXMpO1xuICAgIGlmIChlbmRNcyA8PSBzdGFydE1zKSByZXR1cm4gW107XG5cbiAgICBjb25zdCB3aWR0aEZyYWMgPSAoZW5kTXMgLSBzdGFydE1zKSAvIHZpc2libGVEdXJhdGlvbk1zO1xuICAgIHJldHVybiBbXG4gICAgICB7XG4gICAgICAgIHN0YXR1czogc2VnLnN0YXR1cyxcbiAgICAgICAgbGVmdFBjdDpcbiAgICAgICAgICAoKHN0YXJ0TXMgLSBnZW9tZXRyeS52aXNpYmxlU3RhcnRNcykgLyB2aXNpYmxlRHVyYXRpb25NcykgKiAxMDAsXG4gICAgICAgIHdpZHRoUGN0OiB3aWR0aEZyYWMgKiAxMDAsXG4gICAgICAgIHBpeGVsV2lkdGg6IHdpZHRoRnJhYyAqIGdlb21ldHJ5LnZpc2libGVQaXhlbFdpZHRoLFxuICAgICAgICBmdWxsRHVyYXRpb25NczogKHNlZy5lbmRGcmFjdGlvbiAtIHNlZy5zdGFydEZyYWN0aW9uKSAqIHNwYW5EdXJhdGlvbk1zLFxuICAgICAgfSxcbiAgICBdO1xuICB9KTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTbWFsbCByZW5kZXIgaGVscGVyc1xuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmZ1bmN0aW9uIER1cmF0aW9uTGFiZWwoe1xuICBsYWJlbCxcbiAgY2xhc3NOYW1lLFxufToge1xuICBsYWJlbDogc3RyaW5nO1xuICBjbGFzc05hbWU/OiBzdHJpbmc7XG59KTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIChcbiAgICA8c3BhblxuICAgICAgY2xhc3NOYW1lPXtjbihcbiAgICAgICAgJ3BvaW50ZXItZXZlbnRzLW5vbmUgYWJzb2x1dGUgaW5zZXQtMCBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LXN0YXJ0IG92ZXJmbG93LWhpZGRlbiBweC0xIHRleHQtWzEwcHhdIGZvbnQtbW9ubyBmb250LW1lZGl1bSBsZWFkaW5nLW5vbmUgd2hpdGVzcGFjZS1ub3dyYXAgdGV4dC1sZWZ0IHRleHQtZ3JheS0xMDAwIHRhYnVsYXItbnVtcyBvcGFjaXR5LTAgZ3JvdXAtaG92ZXIvdGltZWxpbmUtcm93Om9wYWNpdHktMTAwJyxcbiAgICAgICAgY2xhc3NOYW1lXG4gICAgICApfVxuICAgID5cbiAgICAgIHtsYWJlbH1cbiAgICA8L3NwYW4+XG4gICk7XG59XG5cbmZ1bmN0aW9uIEJvdW5kYXJ5QXJyb3coe1xuICBkaXJlY3Rpb24sXG59OiB7XG4gIGRpcmVjdGlvbjogJ2xlZnQnIHwgJ3JpZ2h0Jztcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCBJY29uID0gZGlyZWN0aW9uID09PSAncmlnaHQnID8gQXJyb3dSaWdodCA6IEFycm93TGVmdDtcbiAgcmV0dXJuIChcbiAgICA8ZGl2IGNsYXNzTmFtZT1cImZsZXggaC02IHctNiBpdGVtcy1jZW50ZXIganVzdGlmeS1jZW50ZXIgcm91bmRlZC1bMC4yNXJlbV1cIj5cbiAgICAgIDxJY29uIGNsYXNzTmFtZT1cInNpemUtMyB0ZXh0LWdyYXktOTAwXCIgLz5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuZnVuY3Rpb24gUGxhaW5CYXIoe1xuICBiZyxcbiAgYm9yZGVyLFxuICBsYWJlbCxcbn06IHtcbiAgYmc6IHN0cmluZztcbiAgYm9yZGVyOiBzdHJpbmc7XG4gIGxhYmVsOiBzdHJpbmcgfCBudWxsO1xufSk6IFJlYWN0Tm9kZSB7XG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgY2xhc3NOYW1lPVwicmVsYXRpdmUgaC02IHctZnVsbCBtaW4tdy0xIHJvdW5kZWQtWzAuMjVyZW1dIGJvcmRlclwiXG4gICAgICBzdHlsZT17eyBiYWNrZ3JvdW5kOiBiZywgYm9yZGVyQ29sb3I6IGJvcmRlciB9fVxuICAgID5cbiAgICAgIHtsYWJlbCA/IDxEdXJhdGlvbkxhYmVsIGxhYmVsPXtsYWJlbH0gLz4gOiBudWxsfVxuICAgIDwvZGl2PlxuICApO1xufVxuXG5mdW5jdGlvbiBMZWFkSW5Db25uZWN0b3Ioe1xuICBsZWZ0UGN0LFxuICB3aWR0aFBjdCxcbiAgbGFiZWwsXG59OiB7XG4gIGxlZnRQY3Q6IG51bWJlcjtcbiAgd2lkdGhQY3Q6IG51bWJlcjtcbiAgbGFiZWw6IHN0cmluZyB8IG51bGw7XG59KTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSB0b3AtMS8yIGgtNiAtdHJhbnNsYXRlLXktMS8yXCJcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIGxlZnQ6IGBjYWxjKCR7bGVmdFBjdH0lICsgMC41cHgpYCxcbiAgICAgICAgd2lkdGg6IGBjYWxjKCR7d2lkdGhQY3R9JSAtIDFweClgLFxuICAgICAgfX1cbiAgICA+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFic29sdXRlIGxlZnQtMCB0b3AtMS8yIGgtNCB3LXB4IC10cmFuc2xhdGUteS0xLzIgYmctZ3JheS01MDBcIiAvPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhYnNvbHV0ZSBpbnNldC14LTAgdG9wLTEvMiBoLXB4IC10cmFuc2xhdGUteS0xLzIgYmctZ3JheS01MDBcIiAvPlxuICAgICAge2xhYmVsID8gPER1cmF0aW9uTGFiZWwgbGFiZWw9e2xhYmVsfSAvPiA6IG51bGx9XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbmZ1bmN0aW9uIFNlZ21lbnRCYXIoe1xuICBzZWdtZW50cyxcbiAgc2hvd0xhYmVscyA9IHRydWUsXG59OiB7XG4gIHNlZ21lbnRzOiBWaXNpYmxlU2VnbWVudFtdO1xuICAvKipcbiAgICogV2hlbiBmYWxzZSwgc2VnbWVudCBkdXJhdGlvbiBsYWJlbHMgYXJlIHN1cHByZXNzZWQuIFVzZWQgd2hlbiBhIHNlcGFyYXRlXG4gICAqIHRvcCBsYXllciAoZS5nLiB0aGUgcmVzdW1wdGlvbi1tYXJrZXIgZHVyYXRpb24gb3ZlcmxheSkgcmVuZGVycyB0aGUgbGFiZWxcbiAgICogYWJvdmUgdGhlIG1hcmtlcnMgaW5zdGVhZCwgc28gd2UgZG9uJ3QgZHJhdyBpdCB0d2ljZS5cbiAgICovXG4gIHNob3dMYWJlbHM/OiBib29sZWFuO1xufSk6IFJlYWN0Tm9kZSB7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJyZWxhdGl2ZSBoLTYgdy1mdWxsXCI+XG4gICAgICB7c2VnbWVudHMubWFwKChzZWcsIGkpID0+IHtcbiAgICAgICAgaWYgKHNlZy5zdGF0dXMgPT09ICdxdWV1ZWQnKSB7XG4gICAgICAgICAgY29uc3QgbGVhZEluTGFiZWwgPSBmb3JtYXREdXJhdGlvblByZWNpc2Uoc2VnLmZ1bGxEdXJhdGlvbk1zKTtcbiAgICAgICAgICBjb25zdCBzaG93TGVhZEluTGFiZWwgPVxuICAgICAgICAgICAgc2hvd0xhYmVscyAmJlxuICAgICAgICAgICAgc2VnLnBpeGVsV2lkdGggPj0gTWF0aC5tYXgoNDAsIGxlYWRJbkxhYmVsLmxlbmd0aCAqIDYgKyAxMik7XG4gICAgICAgICAgY29uc3QgaXNGdWxsV2lkdGhRdWV1ZWQgPSBzZWdtZW50cy5sZW5ndGggPT09IDE7XG4gICAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICAgIDxGcmFnbWVudCBrZXk9e2l9PlxuICAgICAgICAgICAgICA8TGVhZEluQ29ubmVjdG9yXG4gICAgICAgICAgICAgICAgbGVmdFBjdD17c2VnLmxlZnRQY3R9XG4gICAgICAgICAgICAgICAgd2lkdGhQY3Q9e3NlZy53aWR0aFBjdH1cbiAgICAgICAgICAgICAgICBsYWJlbD17c2hvd0xlYWRJbkxhYmVsID8gbGVhZEluTGFiZWwgOiBudWxsfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICB7aXNGdWxsV2lkdGhRdWV1ZWQgPyAoXG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPVwiYWJzb2x1dGUgdG9wLTEvMiBoLTQgdy1weCAtdHJhbnNsYXRlLXktMS8yIGJnLWdyYXktNTAwXCJcbiAgICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IGBjYWxjKCR7c2VnLmxlZnRQY3QgKyBzZWcud2lkdGhQY3R9JSAtIDEuNXB4KWAsXG4gICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgICAgPC9GcmFnbWVudD5cbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgbGFiZWwgPSBmb3JtYXREdXJhdGlvblByZWNpc2Uoc2VnLmZ1bGxEdXJhdGlvbk1zKTtcbiAgICAgICAgLy8gT25seSByZW5kZXIgdGhlIGxhYmVsIHdoZW4gdGhlcmUncyBlbm91Z2ggcm9vbSBmb3IgaXQgd2l0aG91dCBjbGlwcGluZy5cbiAgICAgICAgY29uc3Qgc2hvd0xhYmVsID1cbiAgICAgICAgICBzaG93TGFiZWxzICYmIHNlZy5waXhlbFdpZHRoID49IE1hdGgubWF4KDQwLCBsYWJlbC5sZW5ndGggKiA2ICsgMTIpO1xuXG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAga2V5PXtpfVxuICAgICAgICAgICAgY2xhc3NOYW1lPXtjbihcbiAgICAgICAgICAgICAgJ2Fic29sdXRlIGgtZnVsbCBvdmVyZmxvdy1oaWRkZW4gcm91bmRlZC1bMC4yNXJlbV0nLFxuICAgICAgICAgICAgICBTRUdNRU5UX0NMQVNTRVNbc2VnLnN0YXR1c11cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAvLyAxcHggZ2FwIGJldHdlZW4gYWRqYWNlbnQgc2VnbWVudHMsIGRpc3RyaWJ1dGVkIGVxdWFsbHkuXG4gICAgICAgICAgICAgIGxlZnQ6IGBjYWxjKCR7c2VnLmxlZnRQY3R9JSArIDAuNXB4KWAsXG4gICAgICAgICAgICAgIHdpZHRoOiBgY2FsYygke3NlZy53aWR0aFBjdH0lIC0gMXB4KWAsXG4gICAgICAgICAgICAgIG1pbldpZHRoOiAxLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7U1RSSVBFRF9TRUdNRU5UX1NUQVRVU0VTLmhhcyhzZWcuc3RhdHVzKSA/IChcbiAgICAgICAgICAgICAgPEFuaW1hdGVkU3RyaXBlcyBzdGF0dXM9e3NlZy5zdGF0dXN9IC8+XG4gICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIHtzaG93TGFiZWwgPyA8RHVyYXRpb25MYWJlbCBsYWJlbD17bGFiZWx9IC8+IDogbnVsbH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgKTtcbiAgICAgIH0pfVxuICAgIDwvZGl2PlxuICApO1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFRpbWVsaW5lQmFyXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgVGltZWxpbmVCYXIgPSBtZW1vKGZ1bmN0aW9uIFRpbWVsaW5lQmFyKHtcbiAgc3BhbixcbiAgdmlld1N0YXJ0LFxuICB2aWV3RHVyYXRpb24sXG4gIGNvbnRhaW5lcldpZHRoLFxuICBpc1NlbGVjdGVkLFxuICBpc0RpbW1lZCxcbiAgb25TZWxlY3QsXG4gIG9uUmV2ZWFsVGltZSxcbn06IHtcbiAgc3BhbjogU3BhbjtcbiAgdmlld1N0YXJ0OiBudW1iZXI7XG4gIHZpZXdEdXJhdGlvbjogbnVtYmVyO1xuICBjb250YWluZXJXaWR0aDogbnVtYmVyO1xuICBpc1NlbGVjdGVkOiBib29sZWFuO1xuICBpc0RpbW1lZD86IGJvb2xlYW47XG4gIG9uU2VsZWN0OiAoc3BhbklkOiBzdHJpbmcpID0+IHZvaWQ7XG4gIG9uUmV2ZWFsVGltZT86ICh0aW1lTXM6IG51bWJlcikgPT4gdm9pZDtcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCBzdGFydE1zID0gZ2V0SGlnaFJlc0luTXMoc3Bhbi5zdGFydFRpbWUpO1xuICBjb25zdCBlbmRNcyA9IGdldEhpZ2hSZXNJbk1zKHNwYW4uZW5kVGltZSk7XG4gIGNvbnN0IHRvdGFsRHVyYXRpb25NcyA9IGdldFNwYW5EdXJhdGlvbk1zKHNwYW4pO1xuXG4gIGNvbnN0IGdlb21ldHJ5ID0gdXNlTWVtbyhcbiAgICAoKSA9PlxuICAgICAgY29tcHV0ZUJhckdlb21ldHJ5KFxuICAgICAgICBzdGFydE1zLFxuICAgICAgICBlbmRNcyxcbiAgICAgICAgdmlld1N0YXJ0LFxuICAgICAgICB2aWV3U3RhcnQgKyB2aWV3RHVyYXRpb24sXG4gICAgICAgIGNvbnRhaW5lcldpZHRoXG4gICAgICApLFxuICAgIFtzdGFydE1zLCBlbmRNcywgdmlld1N0YXJ0LCB2aWV3RHVyYXRpb24sIGNvbnRhaW5lcldpZHRoXVxuICApO1xuXG4gIGNvbnN0IGJhc2VTZWdtZW50cyA9IHVzZU1lbW8oKCkgPT4gY29tcHV0ZVNwYW5TZWdtZW50cyhzcGFuKSwgW3NwYW5dKTtcbiAgY29uc3Qgc2VnbWVudHMgPSB1c2VNZW1vKFxuICAgICgpID0+XG4gICAgICBnZW9tZXRyeS5tb2RlLmtpbmQgPT09ICdmdWxsJ1xuICAgICAgICA/IHByb2plY3RTZWdtZW50cyhiYXNlU2VnbWVudHMsIHN0YXJ0TXMsIHRvdGFsRHVyYXRpb25NcywgZ2VvbWV0cnkpXG4gICAgICAgIDogW10sXG4gICAgW2dlb21ldHJ5LCBiYXNlU2VnbWVudHMsIHN0YXJ0TXMsIHRvdGFsRHVyYXRpb25Nc11cbiAgKTtcblxuICBjb25zdCBiYXNlTWFya2VycyA9IHVzZU1lbW8oKCkgPT4gY29tcHV0ZVNwYW5NYXJrZXJzKHNwYW4pLCBbc3Bhbl0pO1xuICBjb25zdCBtYXJrZXJzID0gdXNlTWVtbyhcbiAgICAoKSA9PlxuICAgICAgZ2VvbWV0cnkubW9kZS5raW5kID09PSAnZnVsbCdcbiAgICAgICAgPyBjdWxsQ29sbGlkaW5nTWFya2VycyhcbiAgICAgICAgICAgIHByb2plY3RNYXJrZXJzKFxuICAgICAgICAgICAgICBiYXNlTWFya2VycyxcbiAgICAgICAgICAgICAgZ2VvbWV0cnkudmlzaWJsZVN0YXJ0TXMsXG4gICAgICAgICAgICAgIGdlb21ldHJ5LnZpc2libGVFbmRNc1xuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIGdlb21ldHJ5LnZpc2libGVQaXhlbFdpZHRoXG4gICAgICAgICAgKVxuICAgICAgICA6IFtdLFxuICAgIFtnZW9tZXRyeSwgYmFzZU1hcmtlcnNdXG4gICk7XG5cbiAgLy8gTWFya2VycyB0aGF0IGZhbGwgb3V0c2lkZSB0aGUgdmlzaWJsZSB3aW5kb3cgKHNjcm9sbGVkIG9mZiB3aGlsZSB6b29tZWQgaW4pXG4gIC8vIOKAlCBzdXJmYWNlZCBhcyBlZGdlIGluZGljYXRvcnMgc28gdGhleSBhcmVuJ3Qgc2lsZW50bHkgbG9zdC5cbiAgY29uc3Qgb2Zmc2NyZWVuID0gdXNlTWVtbzxPZmZzY3JlZW5NYXJrZXJzPihcbiAgICAoKSA9PlxuICAgICAgZ2VvbWV0cnkubW9kZS5raW5kID09PSAnZnVsbCdcbiAgICAgICAgPyBjb21wdXRlT2Zmc2NyZWVuTWFya2VycyhcbiAgICAgICAgICAgIGJhc2VNYXJrZXJzLFxuICAgICAgICAgICAgZ2VvbWV0cnkudmlzaWJsZVN0YXJ0TXMsXG4gICAgICAgICAgICBnZW9tZXRyeS52aXNpYmxlRW5kTXNcbiAgICAgICAgICApXG4gICAgICAgIDogeyBsZWZ0OiBudWxsLCByaWdodDogbnVsbCB9LFxuICAgIFtnZW9tZXRyeSwgYmFzZU1hcmtlcnNdXG4gICk7XG5cbiAgLy8gTWFya2VycyAodmlzaWJsZSBvciBvZmYtc2NyZWVuKSBtb3ZlIHRoZSBkdXJhdGlvbiBsYWJlbCBpbnRvIHRoZSBvdmVybGF5LFxuICAvLyBzbyB0aGUgaW4tYmFyIHNlZ21lbnQgbGFiZWwgaXMgc3VwcHJlc3NlZC5cbiAgY29uc3QgaGFzTWFya2VycyA9XG4gICAgbWFya2Vycy5sZW5ndGggPiAwIHx8IG9mZnNjcmVlbi5sZWZ0ICE9PSBudWxsIHx8IG9mZnNjcmVlbi5yaWdodCAhPT0gbnVsbDtcblxuICBjb25zdCB3b3JrZmxvd1N0YXR1cyA9IChzcGFuLmF0dHJpYnV0ZXMuZGF0YSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilcbiAgICA/LnN0YXR1cyBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIGNvbnN0IGlzRXJyb3JlZCA9IHNwYW4uc3RhdHVzLmNvZGUgPT09IDIgfHwgd29ya2Zsb3dTdGF0dXMgPT09ICdmYWlsZWQnO1xuICBjb25zdCBjb2xvcnMgPSBnZXRSZXNvdXJjZUNvbG9yKHNwYW4ucmVzb3VyY2UpO1xuICBjb25zdCBmYWxsYmFja0JnID0gaXNFcnJvcmVkXG4gICAgPyAoY29sb3JzLmVycm9yQmcgPz8gJ3ZhcigtLWRzLXJlZC0yMDApJylcbiAgICA6IGNvbG9ycy5iZztcbiAgY29uc3QgZmFsbGJhY2tCb3JkZXIgPSBpc0Vycm9yZWRcbiAgICA/IChjb2xvcnMuZXJyb3JCb3JkZXIgPz8gJ3ZhcigtLWRzLXJlZC01MDApJylcbiAgICA6IGNvbG9ycy5ib3JkZXI7XG5cbiAgY29uc3QgdG90YWxMYWJlbCA9IGZvcm1hdER1cmF0aW9uUHJlY2lzZSh0b3RhbER1cmF0aW9uTXMpO1xuICBjb25zdCBzaG93VG90YWxMYWJlbCA9XG4gICAgZ2VvbWV0cnkudmlzaWJsZVBpeGVsV2lkdGggPj0gTWF0aC5tYXgoNDAsIHRvdGFsTGFiZWwubGVuZ3RoICogNiArIDEyKTtcblxuICBjb25zdCBoYW5kbGVDbGljayA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBvblNlbGVjdChzcGFuLnNwYW5JZCk7XG4gIH0sIFtvblNlbGVjdCwgc3Bhbi5zcGFuSWRdKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHJvbGU9XCJ0cmVlaXRlbVwiXG4gICAgICBhcmlhLXNlbGVjdGVkPXtpc1NlbGVjdGVkfVxuICAgICAgYXJpYS1leHBhbmRlZD17aXNTZWxlY3RlZH1cbiAgICAgIGFyaWEtbGV2ZWw9ezF9XG4gICAgICBjbGFzc05hbWU9e2NuKFxuICAgICAgICAnZ3JvdXAvdGltZWxpbmUtcm93IGgtMTAgcmVsYXRpdmUgZmxleCBpdGVtcy1jZW50ZXIgaG92ZXI6YmctZ3JheS0xMDAgYXJpYS1zZWxlY3RlZDpiZy1ncmF5LTEwMCBhcmlhLXNlbGVjdGVkOmhvdmVyOmJnLWdyYXktMjAwIHRyYW5zaXRpb24tb3BhY2l0eScsXG4gICAgICAgIGlzRGltbWVkICYmICdvcGFjaXR5LTM1J1xuICAgICAgKX1cbiAgICAgIG9uQ2xpY2s9e2hhbmRsZUNsaWNrfVxuICAgID5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWJzb2x1dGUgaW5zZXQteS0wXCIgc3R5bGU9e1RJTUVMSU5FX0lOU0VUX1NUWUxFfT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIHRvcC0xLzIgaC02IC10cmFuc2xhdGUteS0xLzIgb3ZlcmZsb3ctaGlkZGVuIHJvdW5kZWQtWzAuMjVyZW1dXCJcbiAgICAgICAgICBzdHlsZT17Z2V0QmFyUG9zaXRpb25TdHlsZShnZW9tZXRyeSl9XG4gICAgICAgID5cbiAgICAgICAgICB7Z2VvbWV0cnkubW9kZS5raW5kID09PSAnYXJyb3cnID8gKFxuICAgICAgICAgICAgPEJvdW5kYXJ5QXJyb3cgZGlyZWN0aW9uPXtnZW9tZXRyeS5tb2RlLmRpcmVjdGlvbn0gLz5cbiAgICAgICAgICApIDogZ2VvbWV0cnkubW9kZS5raW5kID09PSAndGlueScgPyAoXG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT1cImgtNiByb3VuZGVkLVswLjI1cmVtXSBib3JkZXJcIlxuICAgICAgICAgICAgICBzdHlsZT17eyBiYWNrZ3JvdW5kOiBmYWxsYmFja0JnLCBib3JkZXJDb2xvcjogZmFsbGJhY2tCb3JkZXIgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSA6IHNlZ21lbnRzLmxlbmd0aCA+IDAgPyAoXG4gICAgICAgICAgICA8U2VnbWVudEJhciBzZWdtZW50cz17c2VnbWVudHN9IHNob3dMYWJlbHM9eyFoYXNNYXJrZXJzfSAvPlxuICAgICAgICAgICkgOiAoXG4gICAgICAgICAgICA8UGxhaW5CYXJcbiAgICAgICAgICAgICAgYmc9e2ZhbGxiYWNrQmd9XG4gICAgICAgICAgICAgIGJvcmRlcj17ZmFsbGJhY2tCb3JkZXJ9XG4gICAgICAgICAgICAgIGxhYmVsPXtzaG93VG90YWxMYWJlbCA/IHRvdGFsTGFiZWwgOiBudWxsfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApfVxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgey8qIE92ZXJsYXkgKG5vdCBjbGlwcGVkKTogdGlja3MsIG9mZi1zY3JlZW4gaW5kaWNhdG9ycywgdGhlbiB0aGUgZHVyYXRpb24gbGFiZWwgb24gdG9wLiAqL31cbiAgICAgICAge2hhc01hcmtlcnMgPyAoXG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwicG9pbnRlci1ldmVudHMtbm9uZSBhYnNvbHV0ZSB0b3AtMS8yIGgtNiAtdHJhbnNsYXRlLXktMS8yXCJcbiAgICAgICAgICAgIHN0eWxlPXtnZXRCYXJQb3NpdGlvblN0eWxlKGdlb21ldHJ5KX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICB7bWFya2Vycy5sZW5ndGggPiAwID8gPE1hcmtlckxheWVyIG1hcmtlcnM9e21hcmtlcnN9IC8+IDogbnVsbH1cbiAgICAgICAgICAgIHtvZmZzY3JlZW4ubGVmdCA/IChcbiAgICAgICAgICAgICAgPE9mZnNjcmVlbk1hcmtlckluZGljYXRvclxuICAgICAgICAgICAgICAgIGRpcmVjdGlvbj1cImxlZnRcIlxuICAgICAgICAgICAgICAgIGNvdW50PXtvZmZzY3JlZW4ubGVmdC5jb3VudH1cbiAgICAgICAgICAgICAgICB0YXJnZXRNcz17b2Zmc2NyZWVuLmxlZnQubmVhcmVzdE1zfVxuICAgICAgICAgICAgICAgIG9uUmV2ZWFsPXtvblJldmVhbFRpbWV9XG4gICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIHtvZmZzY3JlZW4ucmlnaHQgPyAoXG4gICAgICAgICAgICAgIDxPZmZzY3JlZW5NYXJrZXJJbmRpY2F0b3JcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb249XCJyaWdodFwiXG4gICAgICAgICAgICAgICAgY291bnQ9e29mZnNjcmVlbi5yaWdodC5jb3VudH1cbiAgICAgICAgICAgICAgICB0YXJnZXRNcz17b2Zmc2NyZWVuLnJpZ2h0Lm5lYXJlc3RNc31cbiAgICAgICAgICAgICAgICBvblJldmVhbD17b25SZXZlYWxUaW1lfVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKSA6IG51bGx9XG4gICAgICAgICAgICB7c2hvd1RvdGFsTGFiZWwgPyAoXG4gICAgICAgICAgICAgIDxEdXJhdGlvbkxhYmVsXG4gICAgICAgICAgICAgICAgbGFiZWw9e3RvdGFsTGFiZWx9XG4gICAgICAgICAgICAgICAgLy8gU2hpZnQgY2xlYXIgb2YgdGhlIGxlZnQgZWRnZSBpbmRpY2F0b3Igc28gaXQgaXNuJ3QgY292ZXJlZC5cbiAgICAgICAgICAgICAgICBjbGFzc05hbWU9e29mZnNjcmVlbi5sZWZ0ID8gJ3BsLTEwJyA6IHVuZGVmaW5lZH1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICkgOiBudWxsfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICApIDogbnVsbH1cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICApO1xufSk7XG5cbmV4cG9ydCB7IFRpbWVsaW5lQmFyIH07XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gRGVsdGFJbmRpY2F0b3IgKEFsdC1rZXkgZ2FwIG92ZXJsYXkpXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgREVMVEFfQ0FQX0hFSUdIVF9QWCA9IDg7XG4vLyBWZXJ0aWNhbCBvZmZzZXQgdG8gc2l0IHRoZSBpbmRpY2F0b3IgaW5zaWRlIHRoZSBnYXAgYmV0d2VlbiByb3cgTiBhbmQgTisxLFxuLy8gYWxpZ25lZCB3aXRoIHdoZXJlIHRoZSBiYXIgc3RhcnRzIGluIHRoZSBuZXh0IHJvdyAocm93cyBjZW50ZXIgYSAyNHB4IGJhclxuLy8gaW5zaWRlIDQwcHgsIHNvIGJhcnMgc3RhcnQgfjhweCBmcm9tIHRoZSB0b3Agb2YgdGhlIHJvdykuXG5jb25zdCBERUxUQV9ST1dfT0ZGU0VUX1BYID0gODtcblxuY29uc3QgRGVsdGFJbmRpY2F0b3IgPSBtZW1vKGZ1bmN0aW9uIERlbHRhSW5kaWNhdG9yKHtcbiAgbGVmdEZyYWMsXG4gIHJpZ2h0RnJhYyxcbiAgbGFiZWwsXG4gIHJvd0luZGV4LFxufToge1xuICBsZWZ0RnJhYzogbnVtYmVyO1xuICByaWdodEZyYWM6IG51bWJlcjtcbiAgbGFiZWw6IHN0cmluZztcbiAgcm93SW5kZXg6IG51bWJlcjtcbn0pIHtcbiAgY29uc3QgY2VudGVyWSA9IERFTFRBX1JPV19PRkZTRVRfUFggKyAocm93SW5kZXggKyAxKSAqIFJPV19IRUlHSFRfUFg7XG5cbiAgcmV0dXJuIChcbiAgICA8ZGl2XG4gICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSBwb2ludGVyLWV2ZW50cy1ub25lXCJcbiAgICAgIHN0eWxlPXt7XG4gICAgICAgIGxlZnQ6IGAke2xlZnRGcmFjICogMTAwfSVgLFxuICAgICAgICB3aWR0aDogYCR7KHJpZ2h0RnJhYyAtIGxlZnRGcmFjKSAqIDEwMH0lYCxcbiAgICAgICAgdG9wOiBjZW50ZXJZIC0gREVMVEFfQ0FQX0hFSUdIVF9QWCAvIDIsXG4gICAgICAgIGhlaWdodDogREVMVEFfQ0FQX0hFSUdIVF9QWCxcbiAgICAgIH19XG4gICAgPlxuICAgICAgPGRpdiBjbGFzc05hbWU9XCJhYnNvbHV0ZSBsZWZ0LTAgdG9wLTAgdy1weCBoLWZ1bGwgYmctYW1iZXItODAwXCIgLz5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYWJzb2x1dGUgbGVmdC0wIHJpZ2h0LTAgdG9wLTEvMiBoLXB4IGJnLWFtYmVyLTgwMFwiIC8+XG4gICAgICA8ZGl2IGNsYXNzTmFtZT1cImFic29sdXRlIHJpZ2h0LTAgdG9wLTAgdy1weCBoLWZ1bGwgYmctYW1iZXItODAwXCIgLz5cbiAgICAgIDxzcGFuIGNsYXNzTmFtZT1cImFic29sdXRlIGxlZnQtMS8yIHRvcC0xLzIgLXRyYW5zbGF0ZS14LTEvMiAtdHJhbnNsYXRlLXktMS8yIHRleHQtbGFiZWwtMTIgbGVhZGluZy1ub25lIHdoaXRlc3BhY2Utbm93cmFwIHJvdW5kZWQteHMgcHgtMSBweS0wLjUgdGV4dC1ncmF5LTEwMCBiZy1hbWJlci04MDBcIj5cbiAgICAgICAge2xhYmVsfVxuICAgICAgPC9zcGFuPlxuICAgIDwvZGl2PlxuICApO1xufSk7XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gVGltZWxpbmVIZWFkZXJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5leHBvcnQgZnVuY3Rpb24gVGltZWxpbmVIZWFkZXIoe1xuICBtYXJrZXJzLFxuICBob3ZlckluZm8sXG59OiB7XG4gIG1hcmtlcnM6IFRpbWVNYXJrZXJbXTtcbiAgaG92ZXJJbmZvPzogeyBmcmFjdGlvbjogbnVtYmVyOyBsYWJlbDogc3RyaW5nIH0gfCBudWxsO1xufSk6IFJlYWN0Tm9kZSB7XG4gIHJldHVybiAoXG4gICAgPGRpdiBjbGFzc05hbWU9XCJyZWxhdGl2ZSBiZy1iYWNrZ3JvdW5kLTEwMCBib3JkZXItYiBib3JkZXItZ3JheS1hbHBoYS00MDAgaC0xMCBtaW4taC0xMCBmbGV4IGl0ZW1zLWVuZCBweC00IHBiLTFcIj5cbiAgICAgIDxkaXYgY2xhc3NOYW1lPVwicmVsYXRpdmUgaC1mdWxsIGZsZXgtMVwiPlxuICAgICAgICB7bWFya2Vycy5tYXAoKG0pID0+IChcbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAga2V5PXtTdHJpbmcobS52YWx1ZSl9XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSBib3R0b20tMSBmb250LW1vbm8gdGV4dC14cyBmb250LW5vcm1hbCBsZWFkaW5nLTQgdGV4dC1ncmF5LTkwMCB3aGl0ZXNwYWNlLW5vd3JhcFwiXG4gICAgICAgICAgICBzdHlsZT17eyBsZWZ0OiBgJHttLnBvc2l0aW9uICogMTAwfSVgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAge20ubGFiZWx9XG4gICAgICAgICAgPC9zcGFuPlxuICAgICAgICApKX1cbiAgICAgICAge2hvdmVySW5mbyAmJiAoXG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIHRvcC0xIHBvaW50ZXItZXZlbnRzLW5vbmUgei0xMCBmb250LW1vbm8gdGV4dC1bMTFweF0gbGVhZGluZy00IHRleHQtZ3JheS0xMDAwIHdoaXRlc3BhY2Utbm93cmFwIGJnLWJhY2tncm91bmQtMTAwIGJvcmRlciBib3JkZXItZ3JheS1hbHBoYS00MDAgcm91bmRlZCBweC0xIC10cmFuc2xhdGUteC0xLzJcIlxuICAgICAgICAgICAgc3R5bGU9e3sgbGVmdDogYCR7aG92ZXJJbmZvLmZyYWN0aW9uICogMTAwfSVgIH19XG4gICAgICAgICAgPlxuICAgICAgICAgICAge2hvdmVySW5mby5sYWJlbH1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICl9XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgKTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUaW1lbGluZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmV4cG9ydCBmdW5jdGlvbiBUaW1lbGluZSh7XG4gIHNwYW5zLFxuICB2aWV3U3RhcnQsXG4gIHZpZXdFbmQsXG4gIG1hcmtlcnMsXG4gIHNlbGVjdGVkSWQsXG4gIHNlYXJjaFJlc3VsdCxcbiAgb25TZWxlY3QsXG4gIG9uUmV2ZWFsVGltZSxcbiAgaG92ZXJGcmFjdGlvbixcbiAgYWx0SGVsZCA9IGZhbHNlLFxufToge1xuICBzcGFuczogU3BhbltdO1xuICB2aWV3U3RhcnQ6IG51bWJlcjtcbiAgdmlld0VuZDogbnVtYmVyO1xuICBtYXJrZXJzOiBUaW1lTWFya2VyW107XG4gIHNlbGVjdGVkSWQ6IHN0cmluZyB8IG51bGw7XG4gIHNlYXJjaFJlc3VsdDogU3BhblNlYXJjaFJlc3VsdDtcbiAgb25TZWxlY3Q6IChzcGFuSWQ6IHN0cmluZykgPT4gdm9pZDtcbiAgb25SZXZlYWxUaW1lPzogKHRpbWVNczogbnVtYmVyKSA9PiB2b2lkO1xuICBob3ZlckZyYWN0aW9uPzogbnVtYmVyIHwgbnVsbDtcbiAgYWx0SGVsZD86IGJvb2xlYW47XG59KTogUmVhY3ROb2RlIHtcbiAgY29uc3QgY29udGFpbmVyUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgW2NvbnRhaW5lcldpZHRoLCBzZXRDb250YWluZXJXaWR0aF0gPSB1c2VTdGF0ZSgwKTtcbiAgY29uc3Qgdmlld0R1cmF0aW9uID0gdmlld0VuZCAtIHZpZXdTdGFydDtcbiAgY29uc3QgdGltZWxpbmVXaWR0aCA9IE1hdGgubWF4KDAsIGNvbnRhaW5lcldpZHRoIC0gVElNRUxJTkVfUEFERElOR19QWCAqIDIpO1xuICBjb25zdCB7IHN0YXJ0LCBlbmQgfSA9IHVzZVJvd1dpbmRvdyhcbiAgICBjb250YWluZXJSZWYsXG4gICAgc3BhbnMubGVuZ3RoLFxuICAgIFJPV19IRUlHSFRfUFhcbiAgKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IGVsID0gY29udGFpbmVyUmVmLmN1cnJlbnQ7XG4gICAgaWYgKCFlbCkgcmV0dXJuO1xuICAgIGNvbnN0IHJvID0gbmV3IFJlc2l6ZU9ic2VydmVyKChbZW50cnldKSA9PiB7XG4gICAgICBzZXRDb250YWluZXJXaWR0aChlbnRyeS5jb250ZW50UmVjdC53aWR0aCk7XG4gICAgfSk7XG4gICAgcm8ub2JzZXJ2ZShlbCk7XG4gICAgcmV0dXJuICgpID0+IHJvLmRpc2Nvbm5lY3QoKTtcbiAgfSwgW10pO1xuXG4gIGNvbnN0IGdhcHMgPSB1c2VNZW1vKFxuICAgICgpID0+IGNvbXB1dGVTcGFuR2FwcyhzcGFucywgdmlld1N0YXJ0LCB2aWV3RW5kKSxcbiAgICBbc3BhbnMsIHZpZXdTdGFydCwgdmlld0VuZF1cbiAgKTtcblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIHJlZj17Y29udGFpbmVyUmVmfVxuICAgICAgY2xhc3NOYW1lPVwicmVsYXRpdmUgaC1mdWxsIG92ZXJmbG93LWhpZGRlblwiXG4gICAgICBzdHlsZT17eyBtaW5IZWlnaHQ6IHNwYW5zLmxlbmd0aCAqIFJPV19IRUlHSFRfUFggfX1cbiAgICA+XG4gICAgICA8ZGl2XG4gICAgICAgIGFyaWEtaGlkZGVuXG4gICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIGluc2V0LXktMCBwb2ludGVyLWV2ZW50cy1ub25lXCJcbiAgICAgICAgc3R5bGU9e1RJTUVMSU5FX0lOU0VUX1NUWUxFfVxuICAgICAgPlxuICAgICAgICB7bWFya2Vycy5tYXAoKG1hcmtlcikgPT5cbiAgICAgICAgICAvLyBTa2lwIHRoZSBcIjBzXCIgb3JpZ2luIG1hcmtlciBzaW5jZSB0aGUgbGVmdCBlZGdlIGFscmVhZHkgaW1wbGllcyBpdC5cbiAgICAgICAgICBNYXRoLmFicyhtYXJrZXIudmFsdWUpID4gMC4wMDAwMDEgPyAoXG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGtleT17U3RyaW5nKG1hcmtlci52YWx1ZSl9XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIHRvcC0wIGJvdHRvbS0wIHctcHggYmctZ3JheS1hbHBoYS0zMDBcIlxuICAgICAgICAgICAgICBzdHlsZT17eyBsZWZ0OiBgJHttYXJrZXIucG9zaXRpb24gKiAxMDB9JWAgfX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKSA6IG51bGxcbiAgICAgICAgKX1cbiAgICAgIDwvZGl2PlxuICAgICAge2hvdmVyRnJhY3Rpb24gIT0gbnVsbCAmJiAoXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSBpbnNldC15LTAgcG9pbnRlci1ldmVudHMtbm9uZSB6LTEwXCJcbiAgICAgICAgICBzdHlsZT17VElNRUxJTkVfSU5TRVRfU1RZTEV9XG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzc05hbWU9XCJhYnNvbHV0ZSB0b3AtMCBib3R0b20tMCB3LXB4IGJnLWdyYXktYWxwaGEtNTAwXCJcbiAgICAgICAgICAgIHN0eWxlPXt7IGxlZnQ6IGAke2hvdmVyRnJhY3Rpb24gKiAxMDB9JWAgfX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICl9XG4gICAgICA8ZGl2IHN0eWxlPXt7IHRyYW5zZm9ybTogYHRyYW5zbGF0ZVkoJHtzdGFydCAqIFJPV19IRUlHSFRfUFh9cHgpYCB9fT5cbiAgICAgICAge3NwYW5zLnNsaWNlKHN0YXJ0LCBlbmQpLm1hcCgoc3BhbikgPT4gKFxuICAgICAgICAgIDxUaW1lbGluZUJhclxuICAgICAgICAgICAga2V5PXtzcGFuLnNwYW5JZH1cbiAgICAgICAgICAgIHNwYW49e3NwYW59XG4gICAgICAgICAgICB2aWV3U3RhcnQ9e3ZpZXdTdGFydH1cbiAgICAgICAgICAgIHZpZXdEdXJhdGlvbj17dmlld0R1cmF0aW9ufVxuICAgICAgICAgICAgY29udGFpbmVyV2lkdGg9e3RpbWVsaW5lV2lkdGh9XG4gICAgICAgICAgICBpc1NlbGVjdGVkPXtzZWxlY3RlZElkID09PSBzcGFuLnNwYW5JZH1cbiAgICAgICAgICAgIGlzRGltbWVkPXtpc1NwYW5EaW1tZWRCeVNlYXJjaChzcGFuLnNwYW5JZCwgc2VhcmNoUmVzdWx0KX1cbiAgICAgICAgICAgIG9uU2VsZWN0PXtvblNlbGVjdH1cbiAgICAgICAgICAgIG9uUmV2ZWFsVGltZT17b25SZXZlYWxUaW1lfVxuICAgICAgICAgIC8+XG4gICAgICAgICkpfVxuICAgICAgPC9kaXY+XG4gICAgICB7YWx0SGVsZCAmJiAoXG4gICAgICAgIDxkaXZcbiAgICAgICAgICBhcmlhLWhpZGRlblxuICAgICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIGluc2V0LXktMCBwb2ludGVyLWV2ZW50cy1ub25lXCJcbiAgICAgICAgICBzdHlsZT17VElNRUxJTkVfSU5TRVRfU1RZTEV9XG4gICAgICAgID5cbiAgICAgICAgICB7Z2Fwcy5tYXAoKGdhcCkgPT4gKFxuICAgICAgICAgICAgPERlbHRhSW5kaWNhdG9yXG4gICAgICAgICAgICAgIGtleT17Z2FwLnJvd0luZGV4fVxuICAgICAgICAgICAgICBsZWZ0RnJhYz17Z2FwLmxlZnRGcmFjfVxuICAgICAgICAgICAgICByaWdodEZyYWM9e2dhcC5yaWdodEZyYWN9XG4gICAgICAgICAgICAgIGxhYmVsPXtmb3JtYXREdXJhdGlvbihnYXAuZ2FwTXMsIHRydWUpfVxuICAgICAgICAgICAgICByb3dJbmRleD17Z2FwLnJvd0luZGV4fVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICApKX1cbiAgICAgICAgPC9kaXY+XG4gICAgICApfVxuICAgIDwvZGl2PlxuICApO1xufVxuIl19
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
.runningStripes,
|
|
2
|
+
.pendingStripes {
|
|
3
|
+
position: absolute;
|
|
4
|
+
inset: 0;
|
|
5
|
+
pointer-events: none;
|
|
6
|
+
border-radius: 0.25rem;
|
|
7
|
+
opacity: 0.5;
|
|
8
|
+
background-size: 11.314px 11.314px;
|
|
9
|
+
animation: running-stripes 0.6s linear infinite;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.runningStripes {
|
|
13
|
+
background-image: repeating-linear-gradient(
|
|
14
|
+
45deg,
|
|
15
|
+
var(--ds-blue-500) 0,
|
|
16
|
+
var(--ds-blue-500) 1.5px,
|
|
17
|
+
transparent 1.5px,
|
|
18
|
+
transparent 8px
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.pendingStripes {
|
|
23
|
+
background-image: repeating-linear-gradient(
|
|
24
|
+
45deg,
|
|
25
|
+
var(--ds-gray-500) 0,
|
|
26
|
+
var(--ds-gray-500) 1.5px,
|
|
27
|
+
transparent 1.5px,
|
|
28
|
+
transparent 8px
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@keyframes running-stripes {
|
|
33
|
+
from {
|
|
34
|
+
background-position: 0 0;
|
|
35
|
+
}
|
|
36
|
+
to {
|
|
37
|
+
background-position: 11.314px 0;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@media (prefers-reduced-motion: reduce) {
|
|
42
|
+
.runningStripes,
|
|
43
|
+
.pendingStripes {
|
|
44
|
+
animation: none;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace-viewer-skeleton.d.ts","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx"],"names":[],"mappings":"AAuBA,wBAAgB,mBAAmB,4CAsElC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Skeleton } from '../../ui/skeleton';
|
|
3
|
+
const COL_TEMPLATE = '340px 1px minmax(50px, 1fr)';
|
|
4
|
+
const ROWS = [
|
|
5
|
+
{ id: 'r0', name: 62, off: 0, bar: 72 },
|
|
6
|
+
{ id: 'r1', name: 78, off: 6, bar: 48 },
|
|
7
|
+
{ id: 'r2', name: 50, off: 10, bar: 55 },
|
|
8
|
+
{ id: 'r3', name: 84, off: 18, bar: 30 },
|
|
9
|
+
{ id: 'r4', name: 45, off: 18, bar: 42 },
|
|
10
|
+
{ id: 'r5', name: 66, off: 34, bar: 38 },
|
|
11
|
+
{ id: 'r6', name: 55, off: 41, bar: 25 },
|
|
12
|
+
{ id: 'r7', name: 40, off: 50, bar: 30 },
|
|
13
|
+
];
|
|
14
|
+
const HEADER_MARKERS = ['m0', 'm1', 'm2', 'm3'];
|
|
15
|
+
const HeaderDivider = () => (_jsx("div", { className: "flex justify-center", children: _jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }) }));
|
|
16
|
+
export function TraceViewerSkeleton() {
|
|
17
|
+
return (_jsxs("output", { "aria-busy": "true", "aria-label": "Loading trace", className: "flex flex-col w-full h-full min-h-0 bg-background-100", children: [_jsx("span", { className: "sr-only", children: "Loading trace\u2026" }), _jsxs("div", { className: "shrink-0 grid", style: { gridTemplateColumns: COL_TEMPLATE }, children: [_jsxs("div", { className: "h-10 min-h-10 flex items-center border-b border-gray-alpha-400 pl-4 pr-2 gap-1.5", children: [_jsx(Skeleton, { className: "w-3.5 h-3.5 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3.5 w-40" })] }), _jsx(HeaderDivider, {}), _jsx("div", { className: "h-10 min-h-10 flex items-end border-b border-gray-alpha-400 px-4 pb-1 gap-2", children: _jsx("div", { className: "relative flex-1 flex items-end justify-between", children: HEADER_MARKERS.map((id) => (_jsx(Skeleton, { className: "h-3.5 w-9" }, id))) }) })] }), _jsxs("div", { className: "grid flex-1 min-h-0 overflow-hidden", style: { gridTemplateColumns: COL_TEMPLATE }, children: [_jsx("div", { className: "block overflow-visible", children: _jsx("ul", { className: "block divide-y divide-gray-alpha-400 border-b border-gray-alpha-400", children: ROWS.map((row) => (_jsxs("li", { className: "h-10 flex items-center pl-4 pr-2", children: [_jsxs("div", { className: "flex min-w-0 flex-1 items-center gap-2", children: [_jsx(Skeleton, { className: "w-4 h-4 shrink-0 rounded-sm" }), _jsx(Skeleton, { className: "h-3.5", style: { width: `${row.name}%` } })] }), _jsx(Skeleton, { className: "ml-2 h-3.5 w-10 shrink-0" })] }, row.id))) }) }), _jsx("span", { "aria-hidden": true, className: "h-full w-px bg-gray-alpha-400" }), _jsx("div", { className: "relative min-h-0", children: ROWS.map((row) => (_jsx("div", { className: "relative h-10", children: _jsx("div", { className: "absolute inset-x-4 inset-y-0", children: _jsx(Skeleton, { className: "absolute top-1/2 -translate-y-1/2 h-6 rounded-[0.25rem]", style: { left: `${row.off}%`, width: `${row.bar}%` } }) }) }, row.id))) })] })] }));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2Utdmlld2VyLXNrZWxldG9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvbmV3LXRyYWNlLXZpZXdlci9jb21wb25lbnRzL3RyYWNlLXZpZXdlci1za2VsZXRvbi50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUU3QyxNQUFNLFlBQVksR0FBRyw2QkFBNkIsQ0FBQztBQUVuRCxNQUFNLElBQUksR0FBNkQ7SUFDckUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFO0lBQ3ZDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRTtJQUN2QyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUU7SUFDeEMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFO0lBQ3hDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRTtJQUN4QyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUU7SUFDeEMsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxFQUFFO0lBQ3hDLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsRUFBRTtDQUN6QyxDQUFDO0FBRUYsTUFBTSxjQUFjLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztBQUVoRCxNQUFNLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUMxQixjQUFLLFNBQVMsRUFBQyxxQkFBcUIsWUFDbEMsb0NBQWtCLFNBQVMsRUFBQywrQkFBK0IsR0FBRyxHQUMxRCxDQUNQLENBQUM7QUFFRixNQUFNLFVBQVUsbUJBQW1CO0lBQ2pDLE9BQU8sQ0FDTCwrQkFDWSxNQUFNLGdCQUNMLGVBQWUsRUFDMUIsU0FBUyxFQUFDLHVEQUF1RCxhQUVqRSxlQUFNLFNBQVMsRUFBQyxTQUFTLG9DQUFzQixFQUcvQyxlQUNFLFNBQVMsRUFBQyxlQUFlLEVBQ3pCLEtBQUssRUFBRSxFQUFFLG1CQUFtQixFQUFFLFlBQVksRUFBRSxhQUU1QyxlQUFLLFNBQVMsRUFBQyxrRkFBa0YsYUFDL0YsS0FBQyxRQUFRLElBQUMsU0FBUyxFQUFDLGlDQUFpQyxHQUFHLEVBQ3hELEtBQUMsUUFBUSxJQUFDLFNBQVMsRUFBQyxZQUFZLEdBQUcsSUFDL0IsRUFDTixLQUFDLGFBQWEsS0FBRyxFQUNqQixjQUFLLFNBQVMsRUFBQyw2RUFBNkUsWUFDMUYsY0FBSyxTQUFTLEVBQUMsZ0RBQWdELFlBQzVELGNBQWMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQzFCLEtBQUMsUUFBUSxJQUFVLFNBQVMsRUFBQyxXQUFXLElBQXpCLEVBQUUsQ0FBMEIsQ0FDNUMsQ0FBQyxHQUNFLEdBQ0YsSUFDRixFQUdOLGVBQ0UsU0FBUyxFQUFDLHFDQUFxQyxFQUMvQyxLQUFLLEVBQUUsRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsYUFHNUMsY0FBSyxTQUFTLEVBQUMsd0JBQXdCLFlBQ3JDLGFBQUksU0FBUyxFQUFDLHFFQUFxRSxZQUNoRixJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUNqQixjQUFpQixTQUFTLEVBQUMsa0NBQWtDLGFBQzNELGVBQUssU0FBUyxFQUFDLHdDQUF3QyxhQUNyRCxLQUFDLFFBQVEsSUFBQyxTQUFTLEVBQUMsNkJBQTZCLEdBQUcsRUFDcEQsS0FBQyxRQUFRLElBQ1AsU0FBUyxFQUFDLE9BQU8sRUFDakIsS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLEdBQUcsR0FBRyxDQUFDLElBQUksR0FBRyxFQUFFLEdBQ2hDLElBQ0UsRUFDTixLQUFDLFFBQVEsSUFBQyxTQUFTLEVBQUMsMEJBQTBCLEdBQUcsS0FSMUMsR0FBRyxDQUFDLEVBQUUsQ0FTVixDQUNOLENBQUMsR0FDQyxHQUNELEVBR04sb0NBQWtCLFNBQVMsRUFBQywrQkFBK0IsR0FBRyxFQUc5RCxjQUFLLFNBQVMsRUFBQyxrQkFBa0IsWUFDOUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FDakIsY0FBa0IsU0FBUyxFQUFDLGVBQWUsWUFDekMsY0FBSyxTQUFTLEVBQUMsOEJBQThCLFlBQzNDLEtBQUMsUUFBUSxJQUNQLFNBQVMsRUFBQyx5REFBeUQsRUFDbkUsS0FBSyxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLEtBQUssRUFBRSxHQUFHLEdBQUcsQ0FBQyxHQUFHLEdBQUcsRUFBRSxHQUNwRCxHQUNFLElBTkUsR0FBRyxDQUFDLEVBQUUsQ0FPVixDQUNQLENBQUMsR0FDRSxJQUNGLElBQ0MsQ0FDVixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNrZWxldG9uIH0gZnJvbSAnLi4vLi4vdWkvc2tlbGV0b24nO1xuXG5jb25zdCBDT0xfVEVNUExBVEUgPSAnMzQwcHggMXB4IG1pbm1heCg1MHB4LCAxZnIpJztcblxuY29uc3QgUk9XUzogeyBpZDogc3RyaW5nOyBuYW1lOiBudW1iZXI7IG9mZjogbnVtYmVyOyBiYXI6IG51bWJlciB9W10gPSBbXG4gIHsgaWQ6ICdyMCcsIG5hbWU6IDYyLCBvZmY6IDAsIGJhcjogNzIgfSxcbiAgeyBpZDogJ3IxJywgbmFtZTogNzgsIG9mZjogNiwgYmFyOiA0OCB9LFxuICB7IGlkOiAncjInLCBuYW1lOiA1MCwgb2ZmOiAxMCwgYmFyOiA1NSB9LFxuICB7IGlkOiAncjMnLCBuYW1lOiA4NCwgb2ZmOiAxOCwgYmFyOiAzMCB9LFxuICB7IGlkOiAncjQnLCBuYW1lOiA0NSwgb2ZmOiAxOCwgYmFyOiA0MiB9LFxuICB7IGlkOiAncjUnLCBuYW1lOiA2Niwgb2ZmOiAzNCwgYmFyOiAzOCB9LFxuICB7IGlkOiAncjYnLCBuYW1lOiA1NSwgb2ZmOiA0MSwgYmFyOiAyNSB9LFxuICB7IGlkOiAncjcnLCBuYW1lOiA0MCwgb2ZmOiA1MCwgYmFyOiAzMCB9LFxuXTtcblxuY29uc3QgSEVBREVSX01BUktFUlMgPSBbJ20wJywgJ20xJywgJ20yJywgJ20zJ107XG5cbmNvbnN0IEhlYWRlckRpdmlkZXIgPSAoKSA9PiAoXG4gIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBqdXN0aWZ5LWNlbnRlclwiPlxuICAgIDxzcGFuIGFyaWEtaGlkZGVuIGNsYXNzTmFtZT1cImgtZnVsbCB3LXB4IGJnLWdyYXktYWxwaGEtNDAwXCIgLz5cbiAgPC9kaXY+XG4pO1xuXG5leHBvcnQgZnVuY3Rpb24gVHJhY2VWaWV3ZXJTa2VsZXRvbigpIHtcbiAgcmV0dXJuIChcbiAgICA8b3V0cHV0XG4gICAgICBhcmlhLWJ1c3k9XCJ0cnVlXCJcbiAgICAgIGFyaWEtbGFiZWw9XCJMb2FkaW5nIHRyYWNlXCJcbiAgICAgIGNsYXNzTmFtZT1cImZsZXggZmxleC1jb2wgdy1mdWxsIGgtZnVsbCBtaW4taC0wIGJnLWJhY2tncm91bmQtMTAwXCJcbiAgICA+XG4gICAgICA8c3BhbiBjbGFzc05hbWU9XCJzci1vbmx5XCI+TG9hZGluZyB0cmFjZeKApjwvc3Bhbj5cblxuICAgICAgey8qIEhlYWRlciByb3c6IHNlYXJjaCBoZWFkZXIgfCBkaXZpZGVyIHwgdGltZWxpbmUgaGVhZGVyICovfVxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9XCJzaHJpbmstMCBncmlkXCJcbiAgICAgICAgc3R5bGU9e3sgZ3JpZFRlbXBsYXRlQ29sdW1uczogQ09MX1RFTVBMQVRFIH19XG4gICAgICA+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiaC0xMCBtaW4taC0xMCBmbGV4IGl0ZW1zLWNlbnRlciBib3JkZXItYiBib3JkZXItZ3JheS1hbHBoYS00MDAgcGwtNCBwci0yIGdhcC0xLjVcIj5cbiAgICAgICAgICA8U2tlbGV0b24gY2xhc3NOYW1lPVwidy0zLjUgaC0zLjUgc2hyaW5rLTAgcm91bmRlZC1zbVwiIC8+XG4gICAgICAgICAgPFNrZWxldG9uIGNsYXNzTmFtZT1cImgtMy41IHctNDBcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPEhlYWRlckRpdmlkZXIgLz5cbiAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJoLTEwIG1pbi1oLTEwIGZsZXggaXRlbXMtZW5kIGJvcmRlci1iIGJvcmRlci1ncmF5LWFscGhhLTQwMCBweC00IHBiLTEgZ2FwLTJcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInJlbGF0aXZlIGZsZXgtMSBmbGV4IGl0ZW1zLWVuZCBqdXN0aWZ5LWJldHdlZW5cIj5cbiAgICAgICAgICAgIHtIRUFERVJfTUFSS0VSUy5tYXAoKGlkKSA9PiAoXG4gICAgICAgICAgICAgIDxTa2VsZXRvbiBrZXk9e2lkfSBjbGFzc05hbWU9XCJoLTMuNSB3LTlcIiAvPlxuICAgICAgICAgICAgKSl9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIHsvKiBDb250ZW50IHJvdzogZXZlbnQgbGlzdCB8IGd1dHRlciB8IHRpbWVsaW5lICovfVxuICAgICAgPGRpdlxuICAgICAgICBjbGFzc05hbWU9XCJncmlkIGZsZXgtMSBtaW4taC0wIG92ZXJmbG93LWhpZGRlblwiXG4gICAgICAgIHN0eWxlPXt7IGdyaWRUZW1wbGF0ZUNvbHVtbnM6IENPTF9URU1QTEFURSB9fVxuICAgICAgPlxuICAgICAgICB7LyogU2lkZWJhciBldmVudCByb3dzICovfVxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImJsb2NrIG92ZXJmbG93LXZpc2libGVcIj5cbiAgICAgICAgICA8dWwgY2xhc3NOYW1lPVwiYmxvY2sgZGl2aWRlLXkgZGl2aWRlLWdyYXktYWxwaGEtNDAwIGJvcmRlci1iIGJvcmRlci1ncmF5LWFscGhhLTQwMFwiPlxuICAgICAgICAgICAge1JPV1MubWFwKChyb3cpID0+IChcbiAgICAgICAgICAgICAgPGxpIGtleT17cm93LmlkfSBjbGFzc05hbWU9XCJoLTEwIGZsZXggaXRlbXMtY2VudGVyIHBsLTQgcHItMlwiPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiZmxleCBtaW4tdy0wIGZsZXgtMSBpdGVtcy1jZW50ZXIgZ2FwLTJcIj5cbiAgICAgICAgICAgICAgICAgIDxTa2VsZXRvbiBjbGFzc05hbWU9XCJ3LTQgaC00IHNocmluay0wIHJvdW5kZWQtc21cIiAvPlxuICAgICAgICAgICAgICAgICAgPFNrZWxldG9uXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImgtMy41XCJcbiAgICAgICAgICAgICAgICAgICAgc3R5bGU9e3sgd2lkdGg6IGAke3Jvdy5uYW1lfSVgIH19XG4gICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDxTa2VsZXRvbiBjbGFzc05hbWU9XCJtbC0yIGgtMy41IHctMTAgc2hyaW5rLTBcIiAvPlxuICAgICAgICAgICAgICA8L2xpPlxuICAgICAgICAgICAgKSl9XG4gICAgICAgICAgPC91bD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgey8qIEd1dHRlciAqL31cbiAgICAgICAgPHNwYW4gYXJpYS1oaWRkZW4gY2xhc3NOYW1lPVwiaC1mdWxsIHctcHggYmctZ3JheS1hbHBoYS00MDBcIiAvPlxuXG4gICAgICAgIHsvKiBUaW1lbGluZSBiYXJzICovfVxuICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInJlbGF0aXZlIG1pbi1oLTBcIj5cbiAgICAgICAgICB7Uk9XUy5tYXAoKHJvdykgPT4gKFxuICAgICAgICAgICAgPGRpdiBrZXk9e3Jvdy5pZH0gY2xhc3NOYW1lPVwicmVsYXRpdmUgaC0xMFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cImFic29sdXRlIGluc2V0LXgtNCBpbnNldC15LTBcIj5cbiAgICAgICAgICAgICAgICA8U2tlbGV0b25cbiAgICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImFic29sdXRlIHRvcC0xLzIgLXRyYW5zbGF0ZS15LTEvMiBoLTYgcm91bmRlZC1bMC4yNXJlbV1cIlxuICAgICAgICAgICAgICAgICAgc3R5bGU9e3sgbGVmdDogYCR7cm93Lm9mZn0lYCwgd2lkdGg6IGAke3Jvdy5iYXJ9JWAgfX1cbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICkpfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvb3V0cHV0PlxuICApO1xufVxuIl19
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type RefObject } from 'react';
|
|
2
|
+
export interface RowWindow {
|
|
3
|
+
/** First visible row index (inclusive), already padded by overscan. */
|
|
4
|
+
start: number;
|
|
5
|
+
/** Last visible row index (exclusive), already padded by overscan. */
|
|
6
|
+
end: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Fixed-height windowing over a shared scroll container.
|
|
10
|
+
*
|
|
11
|
+
* The events list and timeline both render one `rowHeight`-tall row per span
|
|
12
|
+
* and scroll together inside the same `SplitPane`. Each caller passes a ref to
|
|
13
|
+
* its own root; the hook walks up to the shared scrollable ancestor, so the
|
|
14
|
+
* scroll container doesn't have to be threaded through props. Same scroll
|
|
15
|
+
* position + same row height means both panes window to the same range.
|
|
16
|
+
*/
|
|
17
|
+
export declare function useRowWindow(ref: RefObject<HTMLElement | null>, rowCount: number, rowHeight: number, overscan?: number): RowWindow;
|
|
18
|
+
/** Row height (px) shared by the events list and timeline rows (`h-10`). */
|
|
19
|
+
export declare const ROW_HEIGHT_PX = 40;
|
|
20
|
+
/**
|
|
21
|
+
* Scroll a windowed row into view by index.
|
|
22
|
+
*
|
|
23
|
+
* The list is virtualized (fixed `rowHeight` rows), so an off-screen row has no
|
|
24
|
+
* DOM node to `scrollIntoView` — its target offset is computed from its index
|
|
25
|
+
* instead. Walks up from `listEl` to the shared scrollable ancestor (the same
|
|
26
|
+
* one `useRowWindow` measures against), only scrolls when the row sits outside
|
|
27
|
+
* the visible area, leaves a one-row `margin` of breathing room past it, and
|
|
28
|
+
* clamps the result to `[0, scrollHeight - clientHeight]`.
|
|
29
|
+
*/
|
|
30
|
+
export declare function scrollRowIntoView(listEl: HTMLElement | null, index: number, rowHeight: number, opts?: {
|
|
31
|
+
margin?: number;
|
|
32
|
+
behavior?: ScrollBehavior;
|
|
33
|
+
}): void;
|
|
34
|
+
//# sourceMappingURL=use-row-window.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-row-window.d.ts","sourceRoot":"","sources":["../../../../src/components/new-trace-viewer/components/use-row-window.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAC;AAK5D,MAAM,WAAW,SAAS;IACxB,uEAAuE;IACvE,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC;CACb;AAaD;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,SAAK,GACZ,SAAS,CAkDX;AAED,4EAA4E;AAC5E,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,WAAW,GAAG,IAAI,EAC1B,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,MAAM,EACjB,IAAI,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,cAAc,CAAA;CAAE,GACpD,IAAI,CA8BN"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
/** Rows rendered on the first paint, before the container has been measured. */
|
|
4
|
+
const INITIAL_VISIBLE_ROWS = 60;
|
|
5
|
+
/** Nearest scrollable ancestor of `el` (the shared `SplitPane` container). */
|
|
6
|
+
function getScrollParent(el) {
|
|
7
|
+
let node = el?.parentElement ?? null;
|
|
8
|
+
while (node) {
|
|
9
|
+
const overflowY = getComputedStyle(node).overflowY;
|
|
10
|
+
if (overflowY === 'auto' || overflowY === 'scroll')
|
|
11
|
+
return node;
|
|
12
|
+
node = node.parentElement;
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Fixed-height windowing over a shared scroll container.
|
|
18
|
+
*
|
|
19
|
+
* The events list and timeline both render one `rowHeight`-tall row per span
|
|
20
|
+
* and scroll together inside the same `SplitPane`. Each caller passes a ref to
|
|
21
|
+
* its own root; the hook walks up to the shared scrollable ancestor, so the
|
|
22
|
+
* scroll container doesn't have to be threaded through props. Same scroll
|
|
23
|
+
* position + same row height means both panes window to the same range.
|
|
24
|
+
*/
|
|
25
|
+
export function useRowWindow(ref, rowCount, rowHeight, overscan = 12) {
|
|
26
|
+
// Bound the pre-measurement window so the first paint of a large trace
|
|
27
|
+
// doesn't render every row before the effect narrows it down.
|
|
28
|
+
const [range, setRange] = useState(() => ({
|
|
29
|
+
start: 0,
|
|
30
|
+
end: Math.min(rowCount, INITIAL_VISIBLE_ROWS),
|
|
31
|
+
}));
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
const self = ref.current;
|
|
34
|
+
const el = getScrollParent(self);
|
|
35
|
+
if (!self || !el)
|
|
36
|
+
return;
|
|
37
|
+
let raf = 0;
|
|
38
|
+
const measure = () => {
|
|
39
|
+
raf = 0;
|
|
40
|
+
// Offset of the list's top within the scroll container's content, so the
|
|
41
|
+
// window stays correct even if the list isn't flush with the top.
|
|
42
|
+
const offset = self.getBoundingClientRect().top -
|
|
43
|
+
el.getBoundingClientRect().top +
|
|
44
|
+
el.scrollTop;
|
|
45
|
+
const top = el.scrollTop - offset;
|
|
46
|
+
const start = Math.max(0, Math.floor(top / rowHeight) - overscan);
|
|
47
|
+
const end = Math.min(rowCount, Math.ceil((top + el.clientHeight) / rowHeight) + overscan);
|
|
48
|
+
setRange((prev) => prev.start === start && prev.end === end ? prev : { start, end });
|
|
49
|
+
};
|
|
50
|
+
const onScroll = () => {
|
|
51
|
+
if (!raf)
|
|
52
|
+
raf = requestAnimationFrame(measure);
|
|
53
|
+
};
|
|
54
|
+
measure();
|
|
55
|
+
el.addEventListener('scroll', onScroll, { passive: true });
|
|
56
|
+
const ro = new ResizeObserver(measure);
|
|
57
|
+
ro.observe(el);
|
|
58
|
+
return () => {
|
|
59
|
+
el.removeEventListener('scroll', onScroll);
|
|
60
|
+
ro.disconnect();
|
|
61
|
+
if (raf)
|
|
62
|
+
cancelAnimationFrame(raf);
|
|
63
|
+
};
|
|
64
|
+
}, [ref, rowCount, rowHeight, overscan]);
|
|
65
|
+
return range;
|
|
66
|
+
}
|
|
67
|
+
/** Row height (px) shared by the events list and timeline rows (`h-10`). */
|
|
68
|
+
export const ROW_HEIGHT_PX = 40;
|
|
69
|
+
/**
|
|
70
|
+
* Scroll a windowed row into view by index.
|
|
71
|
+
*
|
|
72
|
+
* The list is virtualized (fixed `rowHeight` rows), so an off-screen row has no
|
|
73
|
+
* DOM node to `scrollIntoView` — its target offset is computed from its index
|
|
74
|
+
* instead. Walks up from `listEl` to the shared scrollable ancestor (the same
|
|
75
|
+
* one `useRowWindow` measures against), only scrolls when the row sits outside
|
|
76
|
+
* the visible area, leaves a one-row `margin` of breathing room past it, and
|
|
77
|
+
* clamps the result to `[0, scrollHeight - clientHeight]`.
|
|
78
|
+
*/
|
|
79
|
+
export function scrollRowIntoView(listEl, index, rowHeight, opts) {
|
|
80
|
+
const scroller = listEl ? getScrollParent(listEl) : null;
|
|
81
|
+
if (!listEl || !scroller)
|
|
82
|
+
return;
|
|
83
|
+
const margin = opts?.margin ?? rowHeight;
|
|
84
|
+
// Offset of the list's top within the scroll container's content.
|
|
85
|
+
const listOffset = listEl.getBoundingClientRect().top -
|
|
86
|
+
scroller.getBoundingClientRect().top +
|
|
87
|
+
scroller.scrollTop;
|
|
88
|
+
const rowTop = listOffset + index * rowHeight;
|
|
89
|
+
const rowBottom = rowTop + rowHeight;
|
|
90
|
+
const viewTop = scroller.scrollTop;
|
|
91
|
+
const viewBottom = viewTop + scroller.clientHeight;
|
|
92
|
+
let top = null;
|
|
93
|
+
if (rowTop < viewTop) {
|
|
94
|
+
top = rowTop - margin;
|
|
95
|
+
}
|
|
96
|
+
else if (rowBottom > viewBottom) {
|
|
97
|
+
top = rowBottom + margin - scroller.clientHeight;
|
|
98
|
+
}
|
|
99
|
+
if (top === null)
|
|
100
|
+
return;
|
|
101
|
+
const max = scroller.scrollHeight - scroller.clientHeight;
|
|
102
|
+
scroller.scrollTo({
|
|
103
|
+
top: Math.max(0, Math.min(top, max)),
|
|
104
|
+
behavior: opts?.behavior,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXNlLXJvdy13aW5kb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9uZXctdHJhY2Utdmlld2VyL2NvbXBvbmVudHMvdXNlLXJvdy13aW5kb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDO0FBRWIsT0FBTyxFQUFrQixTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sT0FBTyxDQUFDO0FBRTVELGdGQUFnRjtBQUNoRixNQUFNLG9CQUFvQixHQUFHLEVBQUUsQ0FBQztBQVNoQyw4RUFBOEU7QUFDOUUsU0FBUyxlQUFlLENBQUMsRUFBc0I7SUFDN0MsSUFBSSxJQUFJLEdBQUcsRUFBRSxFQUFFLGFBQWEsSUFBSSxJQUFJLENBQUM7SUFDckMsT0FBTyxJQUFJLEVBQUUsQ0FBQztRQUNaLE1BQU0sU0FBUyxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsQ0FBQztRQUNuRCxJQUFJLFNBQVMsS0FBSyxNQUFNLElBQUksU0FBUyxLQUFLLFFBQVE7WUFBRSxPQUFPLElBQUksQ0FBQztRQUNoRSxJQUFJLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLFVBQVUsWUFBWSxDQUMxQixHQUFrQyxFQUNsQyxRQUFnQixFQUNoQixTQUFpQixFQUNqQixRQUFRLEdBQUcsRUFBRTtJQUViLHVFQUF1RTtJQUN2RSw4REFBOEQ7SUFDOUQsTUFBTSxDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsR0FBRyxRQUFRLENBQVksR0FBRyxFQUFFLENBQUMsQ0FBQztRQUNuRCxLQUFLLEVBQUUsQ0FBQztRQUNSLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxvQkFBb0IsQ0FBQztLQUM5QyxDQUFDLENBQUMsQ0FBQztJQUVKLFNBQVMsQ0FBQyxH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QUFxQixFQUFFLENBQUMsR0FBRztRQUNsQyxRQUFRLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxHQUFHO1FBQ3BDLFFBQVEsQ0FBQyxTQUFTLENBQUM7SUFFckIsTUFBTSxNQUFNLEdBQUcsVUFBVSxHQUFHLEtBQUssR0FBRyxTQUFTLENBQUM7SUFDOUMsTUFBTSxTQUFTLEdBQUcsTUFBTSxHQUFHLFNBQVMsQ0FBQztJQUNyQyxNQUFNLE9BQU8sR0FBRyxRQUFRLENBQUMsU0FBUyxDQUFDO0lBQ25DLE1BQU0sVUFBVSxHQUFHLE9BQU8sR0FBRyxRQUFRLENBQUMsWUFBWSxDQUFDO0lBRW5ELElBQUksR0FBRyxHQUFrQixJQUFJLENBQUM7SUFDOUIsSUFBSSxNQUFNLEdBQUcsT0FBTyxFQUFFLENBQUM7UUFDckIsR0FBRyxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUM7SUFDeEIsQ0FBQztTQUFNLElBQUksU0FBUyxHQUFHLFVBQVUsRUFBRSxDQUFDO1FBQ2xDLEdBQUcsR0FBRyxTQUFTLEdBQUcsTUFBTSxHQUFHLFFBQVEsQ0FBQyxZQUFZLENBQUM7SUFDbkQsQ0FBQztJQUNELElBQUksR0FBRyxLQUFLLElBQUk7UUFBRSxPQUFPO0lBRXpCLE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxZQUFZLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQztJQUMxRCxRQUFRLENBQUMsUUFBUSxDQUFDO1FBQ2hCLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNwQyxRQUFRLEVBQUUsSUFBSSxFQUFFLFFBQVE7S0FDekIsQ0FBQyxDQUFDO0FBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIid1c2UgY2xpZW50JztcblxuaW1wb3J0IHsgdHlwZSBSZWZPYmplY3QsIHVzZUVmZmVjdCwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCc7XG5cbi8qKiBSb3dzIHJlbmRlcmVkIG9uIHRoZSBmaXJzdCBwYWludCwgYmVmb3JlIHRoZSBjb250YWluZXIgaGFzIGJlZW4gbWVhc3VyZWQuICovXG5jb25zdCBJTklUSUFMX1ZJU0lCTEVfUk9XUyA9IDYwO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJvd1dpbmRvdyB7XG4gIC8qKiBGaXJzdCB2aXNpYmxlIHJvdyBpbmRleCAoaW5jbHVzaXZlKSwgYWxyZWFkeSBwYWRkZWQgYnkgb3ZlcnNjYW4uICovXG4gIHN0YXJ0OiBudW1iZXI7XG4gIC8qKiBMYXN0IHZpc2libGUgcm93IGluZGV4IChleGNsdXNpdmUpLCBhbHJlYWR5IHBhZGRlZCBieSBvdmVyc2Nhbi4gKi9cbiAgZW5kOiBudW1iZXI7XG59XG5cbi8qKiBOZWFyZXN0IHNjcm9sbGFibGUgYW5jZXN0b3Igb2YgYGVsYCAodGhlIHNoYXJlZCBgU3BsaXRQYW5lYCBjb250YWluZXIpLiAqL1xuZnVuY3Rpb24gZ2V0U2Nyb2xsUGFyZW50KGVsOiBIVE1MRWxlbWVudCB8IG51bGwpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICBsZXQgbm9kZSA9IGVsPy5wYXJlbnRFbGVtZW50ID8/IG51bGw7XG4gIHdoaWxlIChub2RlKSB7XG4gICAgY29uc3Qgb3ZlcmZsb3dZID0gZ2V0Q29tcHV0ZWRTdHlsZShub2RlKS5vdmVyZmxvd1k7XG4gICAgaWYgKG92ZXJmbG93WSA9PT0gJ2F1dG8nIHx8IG92ZXJmbG93WSA9PT0gJ3Njcm9sbCcpIHJldHVybiBub2RlO1xuICAgIG5vZGUgPSBub2RlLnBhcmVudEVsZW1lbnQ7XG4gIH1cbiAgcmV0dXJuIG51bGw7XG59XG5cbi8qKlxuICogRml4ZWQtaGVpZ2h0IHdpbmRvd2luZyBvdmVyIGEgc2hhcmVkIHNjcm9sbCBjb250YWluZXIuXG4gKlxuICogVGhlIGV2ZW50cyBsaXN0IGFuZCB0aW1lbGluZSBib3RoIHJlbmRlciBvbmUgYHJvd0hlaWdodGAtdGFsbCByb3cgcGVyIHNwYW5cbiAqIGFuZCBzY3JvbGwgdG9nZXRoZXIgaW5zaWRlIHRoZSBzYW1lIGBTcGxpdFBhbmVgLiBFYWNoIGNhbGxlciBwYXNzZXMgYSByZWYgdG9cbiAqIGl0cyBvd24gcm9vdDsgdGhlIGhvb2sgd2Fsa3MgdXAgdG8gdGhlIHNoYXJlZCBzY3JvbGxhYmxlIGFuY2VzdG9yLCBzbyB0aGVcbiAqIHNjcm9sbCBjb250YWluZXIgZG9lc24ndCBoYXZlIHRvIGJlIHRocmVhZGVkIHRocm91Z2ggcHJvcHMuIFNhbWUgc2Nyb2xsXG4gKiBwb3NpdGlvbiArIHNhbWUgcm93IGhlaWdodCBtZWFucyBib3RoIHBhbmVzIHdpbmRvdyB0byB0aGUgc2FtZSByYW5nZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVJvd1dpbmRvdyhcbiAgcmVmOiBSZWZPYmplY3Q8SFRNTEVsZW1lbnQgfCBudWxsPixcbiAgcm93Q291bnQ6IG51bWJlcixcbiAgcm93SGVpZ2h0OiBudW1iZXIsXG4gIG92ZXJzY2FuID0gMTJcbik6IFJvd1dpbmRvdyB7XG4gIC8vIEJvdW5kIHRoZSBwcmUtbWVhc3VyZW1lbnQgd2luZG93IHNvIHRoZSBmaXJzdCBwYWludCBvZiBhIGxhcmdlIHRyYWNlXG4gIC8vIGRvZXNuJ3QgcmVuZGVyIGV2ZXJ5IHJvdyBiZWZvcmUgdGhlIGVmZmVjdCBuYXJyb3dzIGl0IGRvd24uXG4gIGNvbnN0IFtyYW5nZSwgc2V0UmFuZ2VdID0gdXNlU3RhdGU8Um93V2luZG93PigoKSA9PiAoe1xuICAgIHN0YXJ0OiAwLFxuICAgIGVuZDogTWF0aC5taW4ocm93Q291bnQsIElOSVRJQUxfVklTSUJMRV9ST1dTKSxcbiAgfSkpO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgc2VsZiA9IHJlZi5jdXJyZW50O1xuICAgIGNvbnN0IGVsID0gZ2V0U2Nyb2xsUGFyZW50KHNlbGYpO1xuICAgIGlmICghc2VsZiB8fCAhZWwpIHJldHVybjtcblxuICAgIGxldCByYWYgPSAwO1xuICAgIGNvbnN0IG1lYXN1cmUgPSAoKSA9PiB7XG4gICAgICByYWYgPSAwO1xuICAgICAgLy8gT2Zmc2V0IG9mIHRoZSBsaXN0J3MgdG9wIHdpdGhpbiB0aGUgc2Nyb2xsIGNvbnRhaW5lcidzIGNvbnRlbnQsIHNvIHRoZVxuICAgICAgLy8gd2luZG93IHN0YXlzIGNvcnJlY3QgZXZlbiBpZiB0aGUgbGlzdCBpc24ndCBmbHVzaCB3aXRoIHRoZSB0b3AuXG4gICAgICBjb25zdCBvZmZzZXQgPVxuICAgICAgICBzZWxmLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtXG4gICAgICAgIGVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCArXG4gICAgICAgIGVsLnNjcm9sbFRvcDtcbiAgICAgIGNvbnN0IHRvcCA9IGVsLnNjcm9sbFRvcCAtIG9mZnNldDtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gTWF0aC5tYXgoMCwgTWF0aC5mbG9vcih0b3AgLyByb3dIZWlnaHQpIC0gb3ZlcnNjYW4pO1xuICAgICAgY29uc3QgZW5kID0gTWF0aC5taW4oXG4gICAgICAgIHJvd0NvdW50LFxuICAgICAgICBNYXRoLmNlaWwoKHRvcCArIGVsLmNsaWVudEhlaWdodCkgLyByb3dIZWlnaHQpICsgb3ZlcnNjYW5cbiAgICAgICk7XG4gICAgICBzZXRSYW5nZSgocHJldikgPT5cbiAgICAgICAgcHJldi5zdGFydCA9PT0gc3RhcnQgJiYgcHJldi5lbmQgPT09IGVuZCA/IHByZXYgOiB7IHN0YXJ0LCBlbmQgfVxuICAgICAgKTtcbiAgICB9O1xuXG4gICAgY29uc3Qgb25TY3JvbGwgPSAoKSA9PiB7XG4gICAgICBpZiAoIXJhZikgcmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKG1lYXN1cmUpO1xuICAgIH07XG5cbiAgICBtZWFzdXJlKCk7XG4gICAgZWwuYWRkRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwsIHsgcGFzc2l2ZTogdHJ1ZSB9KTtcbiAgICBjb25zdCBybyA9IG5ldyBSZXNpemVPYnNlcnZlcihtZWFzdXJlKTtcbiAgICByby5vYnNlcnZlKGVsKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBlbC5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCk7XG4gICAgICByby5kaXNjb25uZWN0KCk7XG4gICAgICBpZiAocmFmKSBjYW5jZWxBbmltYXRpb25GcmFtZShyYWYpO1xuICAgIH07XG4gIH0sIFtyZWYsIHJvd0NvdW50LCByb3dIZWlnaHQsIG92ZXJzY2FuXSk7XG5cbiAgcmV0dXJuIHJhbmdlO1xufVxuXG4vKiogUm93IGhlaWdodCAocHgpIHNoYXJlZCBieSB0aGUgZXZlbnRzIGxpc3QgYW5kIHRpbWVsaW5lIHJvd3MgKGBoLTEwYCkuICovXG5leHBvcnQgY29uc3QgUk9XX0hFSUdIVF9QWCA9IDQwO1xuXG4vKipcbiAqIFNjcm9sbCBhIHdpbmRvd2VkIHJvdyBpbnRvIHZpZXcgYnkgaW5kZXguXG4gKlxuICogVGhlIGxpc3QgaXMgdmlydHVhbGl6ZWQgKGZpeGVkIGByb3dIZWlnaHRgIHJvd3MpLCBzbyBhbiBvZmYtc2NyZWVuIHJvdyBoYXMgbm9cbiAqIERPTSBub2RlIHRvIGBzY3JvbGxJbnRvVmlld2Ag4oCUIGl0cyB0YXJnZXQgb2Zmc2V0IGlzIGNvbXB1dGVkIGZyb20gaXRzIGluZGV4XG4gKiBpbnN0ZWFkLiBXYWxrcyB1cCBmcm9tIGBsaXN0RWxgIHRvIHRoZSBzaGFyZWQgc2Nyb2xsYWJsZSBhbmNlc3RvciAodGhlIHNhbWVcbiAqIG9uZSBgdXNlUm93V2luZG93YCBtZWFzdXJlcyBhZ2FpbnN0KSwgb25seSBzY3JvbGxzIHdoZW4gdGhlIHJvdyBzaXRzIG91dHNpZGVcbiAqIHRoZSB2aXNpYmxlIGFyZWEsIGxlYXZlcyBhIG9uZS1yb3cgYG1hcmdpbmAgb2YgYnJlYXRoaW5nIHJvb20gcGFzdCBpdCwgYW5kXG4gKiBjbGFtcHMgdGhlIHJlc3VsdCB0byBgWzAsIHNjcm9sbEhlaWdodCAtIGNsaWVudEhlaWdodF1gLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2Nyb2xsUm93SW50b1ZpZXcoXG4gIGxpc3RFbDogSFRNTEVsZW1lbnQgfCBudWxsLFxuICBpbmRleDogbnVtYmVyLFxuICByb3dIZWlnaHQ6IG51bWJlcixcbiAgb3B0cz86IHsgbWFyZ2luPzogbnVtYmVyOyBiZWhhdmlvcj86IFNjcm9sbEJlaGF2aW9yIH1cbik6IHZvaWQge1xuICBjb25zdCBzY3JvbGxlciA9IGxpc3RFbCA/IGdldFNjcm9sbFBhcmVudChsaXN0RWwpIDogbnVsbDtcbiAgaWYgKCFsaXN0RWwgfHwgIXNjcm9sbGVyKSByZXR1cm47XG5cbiAgY29uc3QgbWFyZ2luID0gb3B0cz8ubWFyZ2luID8/IHJvd0hlaWdodDtcblxuICAvLyBPZmZzZXQgb2YgdGhlIGxpc3QncyB0b3Agd2l0aGluIHRoZSBzY3JvbGwgY29udGFpbmVyJ3MgY29udGVudC5cbiAgY29uc3QgbGlzdE9mZnNldCA9XG4gICAgbGlzdEVsLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAtXG4gICAgc2Nyb2xsZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wICtcbiAgICBzY3JvbGxlci5zY3JvbGxUb3A7XG5cbiAgY29uc3Qgcm93VG9wID0gbGlzdE9mZnNldCArIGluZGV4ICogcm93SGVpZ2h0O1xuICBjb25zdCByb3dCb3R0b20gPSByb3dUb3AgKyByb3dIZWlnaHQ7XG4gIGNvbnN0IHZpZXdUb3AgPSBzY3JvbGxlci5zY3JvbGxUb3A7XG4gIGNvbnN0IHZpZXdCb3R0b20gPSB2aWV3VG9wICsgc2Nyb2xsZXIuY2xpZW50SGVpZ2h0O1xuXG4gIGxldCB0b3A6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICBpZiAocm93VG9wIDwgdmlld1RvcCkge1xuICAgIHRvcCA9IHJvd1RvcCAtIG1hcmdpbjtcbiAgfSBlbHNlIGlmIChyb3dCb3R0b20gPiB2aWV3Qm90dG9tKSB7XG4gICAgdG9wID0gcm93Qm90dG9tICsgbWFyZ2luIC0gc2Nyb2xsZXIuY2xpZW50SGVpZ2h0O1xuICB9XG4gIGlmICh0b3AgPT09IG51bGwpIHJldHVybjtcblxuICBjb25zdCBtYXggPSBzY3JvbGxlci5zY3JvbGxIZWlnaHQgLSBzY3JvbGxlci5jbGllbnRIZWlnaHQ7XG4gIHNjcm9sbGVyLnNjcm9sbFRvKHtcbiAgICB0b3A6IE1hdGgubWF4KDAsIE1hdGgubWluKHRvcCwgbWF4KSksXG4gICAgYmVoYXZpb3I6IG9wdHM/LmJlaGF2aW9yLFxuICB9KTtcbn1cbiJdfQ==
|