@workflow/web-shared 5.0.0-beta.15 → 5.0.0-beta.17

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.
Files changed (51) hide show
  1. package/dist/components/event-list-view.d.ts +1 -1
  2. package/dist/components/event-list-view.d.ts.map +1 -1
  3. package/dist/components/event-list-view.js +20 -3
  4. package/dist/components/new-trace-viewer/components/timeline.d.ts +1 -1
  5. package/dist/components/new-trace-viewer/components/timeline.d.ts.map +1 -1
  6. package/dist/components/new-trace-viewer/components/timeline.js +40 -4
  7. package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +1 -1
  8. package/dist/components/new-trace-viewer/trace-viewer.js +8 -9
  9. package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
  10. package/dist/components/sidebar/attribute-panel.js +26 -32
  11. package/dist/components/sidebar/attributes-block.d.ts +28 -0
  12. package/dist/components/sidebar/attributes-block.d.ts.map +1 -0
  13. package/dist/components/sidebar/attributes-block.js +83 -0
  14. package/dist/components/sidebar/entity-detail-panel.js +2 -2
  15. package/dist/components/sidebar/events-list.d.ts.map +1 -1
  16. package/dist/components/sidebar/events-list.js +8 -1
  17. package/dist/components/trace-viewer/components/node.d.ts.map +1 -1
  18. package/dist/components/trace-viewer/components/node.js +2 -1
  19. package/dist/components/ui/context-card.d.ts +47 -0
  20. package/dist/components/ui/context-card.d.ts.map +1 -0
  21. package/dist/components/ui/context-card.js +471 -0
  22. package/dist/components/ui/timestamp-tooltip.d.ts +34 -1
  23. package/dist/components/ui/timestamp-tooltip.d.ts.map +1 -1
  24. package/dist/components/ui/timestamp-tooltip.js +80 -132
  25. package/dist/components/workflow-trace-view.d.ts.map +1 -1
  26. package/dist/components/workflow-trace-view.js +8 -10
  27. package/dist/components/workflow-traces/event-colors.d.ts +1 -0
  28. package/dist/components/workflow-traces/event-colors.d.ts.map +1 -1
  29. package/dist/components/workflow-traces/event-colors.js +12 -1
  30. package/dist/components/workflow-traces/trace-span-construction.d.ts.map +1 -1
  31. package/dist/components/workflow-traces/trace-span-construction.js +2 -1
  32. package/dist/lib/trace-builder.d.ts +15 -0
  33. package/dist/lib/trace-builder.d.ts.map +1 -1
  34. package/dist/lib/trace-builder.js +27 -2
  35. package/dist/styles.css +9 -0
  36. package/package.json +7 -5
  37. package/src/components/event-list-view.tsx +25 -2
  38. package/src/components/new-trace-viewer/components/timeline.tsx +82 -2
  39. package/src/components/new-trace-viewer/trace-viewer.tsx +17 -14
  40. package/src/components/sidebar/attribute-panel.tsx +117 -119
  41. package/src/components/sidebar/attributes-block.tsx +182 -0
  42. package/src/components/sidebar/entity-detail-panel.tsx +1 -1
  43. package/src/components/sidebar/events-list.tsx +8 -0
  44. package/src/components/trace-viewer/components/node.tsx +3 -2
  45. package/src/components/ui/context-card.tsx +784 -0
  46. package/src/components/ui/timestamp-tooltip.tsx +132 -194
  47. package/src/components/workflow-trace-view.tsx +18 -10
  48. package/src/components/workflow-traces/event-colors.ts +12 -0
  49. package/src/components/workflow-traces/trace-span-construction.ts +1 -0
  50. package/src/lib/trace-builder.ts +32 -1
  51. package/src/styles.css +9 -0
@@ -0,0 +1,471 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { Root as SlotRoot, Slottable } from '@radix-ui/react-slot';
4
+ import { createContext, useContext, useEffect, useId, useMemo, useRef, useState, } from 'react';
5
+ import { createPortal } from 'react-dom';
6
+ import useMeasure from 'react-use-measure';
7
+ import { useReducedMotion } from '../../hooks/use-reduced-motion';
8
+ import { cn } from '../../lib/utils';
9
+ const INACTIVE_TIMEOUT_MS = 250;
10
+ const ENTER_DELAY_MS = 0;
11
+ const OPEN_DELAY_MS = 150;
12
+ const MAX_TRANSITION_DISTANCE_PX = 150;
13
+ const MAX_OVERLAP_FOR_TRANSITION_PERCENT = 100;
14
+ const PERSIST_TIMEOUT_MS = 1000;
15
+ const ContextCardContext = createContext({
16
+ rootOrigin: { x: 0, y: 0 },
17
+ rootBounds: { width: 0, height: 0 },
18
+ portalRef: null,
19
+ activeId: null,
20
+ setActiveId: () => void 0,
21
+ hoveredId: null,
22
+ setHoveredId: () => void 0,
23
+ updateActiveContextCard: () => void 0,
24
+ skipTransition: false,
25
+ rootVisible: false,
26
+ distanceFromLast: 0,
27
+ lastOrigin: null,
28
+ isProvided: false,
29
+ });
30
+ ContextCardContext.displayName = 'ContextCardContext';
31
+ /**
32
+ * Returns whether the current subtree is wrapped in a {@link ContextCardProvider}.
33
+ */
34
+ export function useHasContextCardProvider() {
35
+ return useContext(ContextCardContext).isProvided;
36
+ }
37
+ function usePrevious(value) {
38
+ const ref = useRef(null);
39
+ useEffect(() => {
40
+ ref.current = value;
41
+ });
42
+ return ref.current;
43
+ }
44
+ function isRefObject(value) {
45
+ return value !== null && value !== undefined && 'current' in value;
46
+ }
47
+ /**
48
+ * Provides shared state and a portal container for {@link ContextCardTrigger}
49
+ * components. Must wrap any tree containing triggers; manages positioning,
50
+ * visibility transitions, and the animated arrow tip across all cards.
51
+ */
52
+ export function ContextCardProvider({ children, portalTarget, }) {
53
+ const [isMounted, setIsMounted] = useState(false);
54
+ useEffect(() => setIsMounted(true), []);
55
+ const resolvedPortalTarget = isRefObject(portalTarget)
56
+ ? portalTarget.current
57
+ : portalTarget;
58
+ const [ref, bounds] = useMeasure();
59
+ const portalRef = useRef(null);
60
+ const [activeContextCard, setActiveContextCard] = useState(null);
61
+ const [visible, setVisible] = useState(false);
62
+ const [hoveredId, setHoveredId] = useState(null);
63
+ const activeId = useRef(null);
64
+ function setActiveId(id) {
65
+ activeId.current = id;
66
+ setVisible(id !== null);
67
+ }
68
+ const updateActiveContextCard = (update) => {
69
+ if (update?.id !== activeId.current && update !== null)
70
+ return;
71
+ setActiveContextCard(update);
72
+ };
73
+ const BORDER_WIDTH = 1;
74
+ const activeBounds = useMemo(() => {
75
+ if (!activeContextCard)
76
+ return {
77
+ width: 0,
78
+ height: 0,
79
+ x: 0,
80
+ y: 0,
81
+ side: 'top',
82
+ arrowOffset: { x: 0, y: 0 },
83
+ };
84
+ return {
85
+ width: activeContextCard.contentSize.width + BORDER_WIDTH * 2,
86
+ height: activeContextCard.contentSize.height + BORDER_WIDTH * 2,
87
+ x: activeContextCard.origin.x,
88
+ y: activeContextCard.origin.y,
89
+ side: activeContextCard.side,
90
+ arrowOffset: activeContextCard.arrowOffset,
91
+ };
92
+ }, [activeContextCard]);
93
+ const lastBounds = usePrevious(activeBounds);
94
+ const lastId = usePrevious(activeId.current);
95
+ const percentOverlapFromLast = useMemo(() => {
96
+ if (!lastBounds)
97
+ return 0;
98
+ const overlapLeft = Math.max(activeBounds.x, lastBounds.x);
99
+ const overlapRight = Math.min(activeBounds.x + activeBounds.width, lastBounds.x + lastBounds.width);
100
+ const overlapTop = Math.max(activeBounds.y, lastBounds.y);
101
+ const overlapBottom = Math.min(activeBounds.y + activeBounds.height, lastBounds.y + lastBounds.height);
102
+ if (overlapLeft < overlapRight && overlapTop < overlapBottom) {
103
+ const overlapArea = (overlapRight - overlapLeft) * (overlapBottom - overlapTop);
104
+ const activeBoundsArea = activeBounds.width * activeBounds.height;
105
+ if (activeBoundsArea === 0)
106
+ return 0;
107
+ return (overlapArea / activeBoundsArea) * 100;
108
+ }
109
+ return 0;
110
+ }, [activeBounds, lastBounds]);
111
+ const distanceFromLast = useMemo(() => Math.sqrt(((lastBounds?.x ?? 0) - activeBounds.x) ** 2 +
112
+ ((lastBounds?.y ?? 0) - activeBounds.y) ** 2), [activeBounds.x, activeBounds.y, lastBounds?.x, lastBounds?.y]);
113
+ const lastOrigin = useMemo(() => {
114
+ if (!lastBounds)
115
+ return null;
116
+ return {
117
+ x: lastBounds.x - activeBounds.x,
118
+ y: lastBounds.y - activeBounds.y,
119
+ };
120
+ }, [activeBounds, lastBounds]);
121
+ const [isScrolling, setIsScrolling] = useState(false);
122
+ const skipTransition = useMemo(() => distanceFromLast > MAX_TRANSITION_DISTANCE_PX ||
123
+ percentOverlapFromLast > MAX_OVERLAP_FOR_TRANSITION_PERCENT ||
124
+ lastId === null ||
125
+ isScrolling, [distanceFromLast, isScrolling, lastId, percentOverlapFromLast]);
126
+ useEffect(() => {
127
+ let isScrollingTimeout = null;
128
+ const onScroll = () => {
129
+ if (isScrollingTimeout)
130
+ window.clearTimeout(isScrollingTimeout);
131
+ isScrollingTimeout = setTimeout(() => {
132
+ setIsScrolling(false);
133
+ }, 66);
134
+ if (!isScrolling) {
135
+ setIsScrolling(true);
136
+ }
137
+ };
138
+ document.addEventListener('scroll', onScroll, true);
139
+ return () => {
140
+ document.removeEventListener('scroll', onScroll, true);
141
+ };
142
+ }, [isScrolling]);
143
+ const contextValue = useMemo(() => ({
144
+ updateActiveContextCard,
145
+ rootOrigin: { ...activeBounds },
146
+ rootBounds: bounds,
147
+ portalRef,
148
+ setActiveId,
149
+ activeId,
150
+ setHoveredId,
151
+ hoveredId,
152
+ skipTransition,
153
+ rootVisible: visible,
154
+ distanceFromLast,
155
+ lastOrigin,
156
+ isProvided: true,
157
+ }), [
158
+ activeBounds,
159
+ bounds,
160
+ hoveredId,
161
+ skipTransition,
162
+ visible,
163
+ distanceFromLast,
164
+ lastOrigin,
165
+ ]);
166
+ return (_jsxs(ContextCardContext.Provider, { value: contextValue, children: [children, isMounted
167
+ ? createPortal(_jsx("div", { className: "w-full h-full inset-0 fixed pointer-events-none z-[100000]", ref: ref, children: _jsx("div", { className: "min-w-max transition-all duration-150 ease-[easing-function:cubic-bezier(0.3,_0.57,_0.07,_0.95)] will-change-[transform,width,height] motion-reduce:!transition-none", style: {
168
+ opacity: visible ? 1 : 0,
169
+ }, children: _jsxs("div", { className: cn('absolute bg-background-100 bg-clip-padding rounded-[6px] overflow-visible pointer-events-none z-[1000000] shadow-[var(--ds-shadow-tooltip),0_0_0_1px_var(--ds-background-100)] w-fit [--context-card-tip-stroke:#DBDBDB] dark-theme:[--context-card-tip-stroke:#252525]', skipTransition
170
+ ? '!transition-none'
171
+ : 'transition-[transform,width,height] duration-250 ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none'), "data-skip-transition": skipTransition, style: {
172
+ transform: `translate(${activeBounds.x}px,${activeBounds.y}px)`,
173
+ width: activeBounds.width,
174
+ height: activeBounds.height,
175
+ }, children: [_jsx("div", { className: cn('w-[14px] h-[7px] absolute grid place-content-center z-[999999999] origin-center', {
176
+ 'top-full -translate-x-1/2 rotate-0': activeBounds.side === 'top',
177
+ 'right-full -translate-y-1/2 rotate-90 -mr-[3.5px]': activeBounds.side === 'right',
178
+ 'bottom-full -translate-x-1/2 rotate-180': activeBounds.side === 'bottom',
179
+ 'left-full -translate-y-1/2 rotate-[270deg] -ml-[3.5px]': activeBounds.side === 'left',
180
+ }, skipTransition
181
+ ? '!transition-none'
182
+ : 'transition-[transform,width,height] duration-250 ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none'), style: {
183
+ ...(activeBounds.side === 'top' ||
184
+ activeBounds.side === 'bottom'
185
+ ? {
186
+ left: `calc(50% + ${activeBounds.arrowOffset.x}px)`,
187
+ }
188
+ : {
189
+ top: `calc(50% + ${activeBounds.arrowOffset.y}px)`,
190
+ }),
191
+ }, "data-skip-transition": skipTransition, "data-side": activeBounds.side, children: _jsxs("svg", { width: "14", height: "7", viewBox: "0 0 14 7", fill: "none", xmlns: "http://www.w3.org/2000/svg", "aria-hidden": "true", children: [_jsx("g", { clipPath: "url(#context-card-tip-clip)", children: _jsx("path", { d: "M15 -0.5V0.5H12.9834L12.8184 0.508789C12.4377 0.550822 12.0853 0.738056 11.8359 1.03418L8.53027 4.95996C7.73114 5.90893 6.26886 5.90892 5.46973 4.95996L2.16406 1.03418C1.87905 0.695733 1.45907 0.5 1.0166 0.5H-1V-0.5H15Z", fill: "var(--ds-background-100)", style: {
192
+ fill: 'var(--ds-background-100)',
193
+ fillOpacity: 1,
194
+ stroke: 'var(--context-card-tip-stroke)',
195
+ strokeOpacity: 1,
196
+ } }) }), _jsx("defs", { children: _jsx("clipPath", { id: "context-card-tip-clip", children: _jsx("rect", { width: "14", height: "7", fill: "white", style: { fill: 'white', fillOpacity: 1 } }) }) })] }) }), _jsx("div", { ref: portalRef })] }) }) }), resolvedPortalTarget ?? document.body)
197
+ : null] }));
198
+ }
199
+ /**
200
+ * Displays a floating context card on hover with viewport-aware collision
201
+ * detection and animated position transitions between triggers in the same
202
+ * {@link ContextCardProvider}. Persists briefly after mouse leave.
203
+ */
204
+ export function ContextCardTrigger({ content, children, side = 'right', align = 'center', sideOffset = 16, alignOffset = 0, ignoreCardPointerEvents = false, noPadding, asChild, className, hide, inactiveTimeoutMs = INACTIVE_TIMEOUT_MS, }) {
205
+ const triggerRef = useRef(null);
206
+ const contentRef = useRef(null);
207
+ const [contentMeasureRef, contentMeasureBounds] = useMeasure();
208
+ const { portalRef, updateActiveContextCard, activeId, setActiveId, hoveredId, setHoveredId, skipTransition, rootVisible, } = useContext(ContextCardContext);
209
+ const id = useId();
210
+ useEffect(() => {
211
+ return () => {
212
+ // Only clear the shared active card if this trigger was the active one;
213
+ // otherwise an unmounting inactive trigger would hide another trigger's card.
214
+ if (activeId.current === id) {
215
+ setActiveId(null);
216
+ }
217
+ };
218
+ }, []);
219
+ const reduceMotion = useReducedMotion();
220
+ const [localHover, setLocalHover] = useState(false);
221
+ const [persisting, setPersisting] = useState(false);
222
+ const [visible, setVisible] = useState(false);
223
+ const activeTimeout = useRef(null);
224
+ const persistingTimeout = useRef(null);
225
+ const openTimeout = useRef(null);
226
+ useEffect(() => {
227
+ if (localHover &&
228
+ contentMeasureBounds.width > 0 &&
229
+ contentMeasureBounds.height > 0) {
230
+ if (openTimeout.current)
231
+ clearTimeout(openTimeout.current);
232
+ openTimeout.current = setTimeout(() => {
233
+ setActiveId(id);
234
+ updateBounds();
235
+ }, rootVisible ? 0 : OPEN_DELAY_MS);
236
+ }
237
+ return () => {
238
+ if (openTimeout.current)
239
+ clearTimeout(openTimeout.current);
240
+ };
241
+ }, [localHover, contentMeasureBounds]);
242
+ const enterTimeout = useRef(null);
243
+ useEffect(() => {
244
+ if (enterTimeout.current)
245
+ clearTimeout(enterTimeout.current);
246
+ if (hoveredId !== id) {
247
+ // Exits are instant
248
+ setVisible(false);
249
+ }
250
+ else {
251
+ // Enters can be delayed unless we wish to script the transition
252
+ enterTimeout.current = setTimeout(() => {
253
+ setVisible(true);
254
+ }, reduceMotion || skipTransition ? 0 : ENTER_DELAY_MS);
255
+ }
256
+ }, [hoveredId, id, reduceMotion, skipTransition]);
257
+ function updateBounds() {
258
+ if (!contentRef.current)
259
+ return;
260
+ const bounds = computeBounds();
261
+ updateActiveContextCard({ id, ...bounds });
262
+ }
263
+ function computeBounds(sideOverride) {
264
+ if (!triggerRef.current)
265
+ throw new Error('Trigger not found');
266
+ if (!contentRef.current)
267
+ throw new Error('Content not found');
268
+ const appliedSide = sideOverride ?? side;
269
+ const triggerRect = triggerRef.current.getBoundingClientRect();
270
+ const contentRect = contentRef.current.getBoundingClientRect();
271
+ contentRef.current.style.width = 'max-content';
272
+ contentRef.current.style.position = 'absolute';
273
+ const contentSize = {
274
+ width: Math.max(contentRect.width, contentRef.current.offsetWidth),
275
+ height: contentRect.height,
276
+ };
277
+ let origin;
278
+ const arrowWidth = 14;
279
+ const halfArrowWidth = arrowWidth / 2;
280
+ const halfTriggerWidth = triggerRect.width / 2;
281
+ const halfTriggerHeight = triggerRect.height / 2;
282
+ const halfContentWidth = contentSize.width / 2;
283
+ const halfContentHeight = contentSize.height / 2;
284
+ const top = triggerRect.top;
285
+ const left = triggerRect.left;
286
+ let alignX = left + halfTriggerWidth - halfContentWidth + alignOffset;
287
+ if (align === 'start')
288
+ alignX = left + alignOffset;
289
+ if (align === 'end')
290
+ alignX = left + triggerRect.width - contentRect.width + alignOffset;
291
+ let alignY = top + halfTriggerHeight - halfContentHeight + alignOffset;
292
+ if (align === 'start')
293
+ alignY = top + alignOffset;
294
+ if (align === 'end')
295
+ alignY = top + triggerRect.height - contentRect.height + alignOffset;
296
+ switch (appliedSide) {
297
+ case 'top':
298
+ origin = {
299
+ x: alignX,
300
+ y: top - contentRect.height - sideOffset,
301
+ };
302
+ break;
303
+ case 'right':
304
+ origin = {
305
+ x: left + triggerRect.width + sideOffset,
306
+ y: alignY,
307
+ };
308
+ break;
309
+ case 'bottom':
310
+ origin = {
311
+ x: alignX,
312
+ y: top + triggerRect.height + sideOffset,
313
+ };
314
+ break;
315
+ case 'left':
316
+ origin = {
317
+ x: left - contentRect.width - sideOffset,
318
+ y: alignY,
319
+ };
320
+ break;
321
+ default: {
322
+ const _exhaustive = appliedSide;
323
+ throw new Error(`Unknown side: ${String(_exhaustive)}`);
324
+ }
325
+ }
326
+ const viewportWidth = document.documentElement.clientWidth;
327
+ const viewportHeight = document.documentElement.clientHeight;
328
+ const isOffscreenLeft = origin.x < 0;
329
+ const isOffscreenRight = origin.x + contentRect.width > viewportWidth;
330
+ const isOffscreenTop = origin.y < 0;
331
+ const isOffscreenBottom = origin.y + contentRect.height > viewportHeight;
332
+ if (!sideOverride) {
333
+ const spaceAbove = top;
334
+ const spaceBelow = viewportHeight - (top + triggerRect.height);
335
+ const spaceLeft = left;
336
+ const spaceRight = viewportWidth - (left + triggerRect.width);
337
+ if (side === 'top' && isOffscreenTop && spaceBelow > spaceAbove) {
338
+ return computeBounds('bottom');
339
+ }
340
+ if (side === 'bottom' && isOffscreenBottom && spaceAbove > spaceBelow) {
341
+ return computeBounds('top');
342
+ }
343
+ if (side === 'right' && isOffscreenRight && spaceLeft > spaceRight) {
344
+ return computeBounds('left');
345
+ }
346
+ if (side === 'left' && isOffscreenLeft && spaceRight > spaceLeft) {
347
+ return computeBounds('right');
348
+ }
349
+ if ((side === 'top' || side === 'bottom') &&
350
+ isOffscreenLeft &&
351
+ spaceRight > contentRect.width) {
352
+ return computeBounds('right');
353
+ }
354
+ if ((side === 'top' || side === 'bottom') &&
355
+ isOffscreenRight &&
356
+ spaceLeft > contentRect.width) {
357
+ return computeBounds('left');
358
+ }
359
+ if ((side === 'left' || side === 'right') &&
360
+ isOffscreenTop &&
361
+ spaceBelow > contentRect.height) {
362
+ return computeBounds('bottom');
363
+ }
364
+ if ((side === 'left' || side === 'right') &&
365
+ isOffscreenBottom &&
366
+ spaceAbove > contentRect.height) {
367
+ return computeBounds('top');
368
+ }
369
+ }
370
+ const viewportPadding = 8;
371
+ if (appliedSide === 'left' || appliedSide === 'right') {
372
+ origin.y = Math.max(viewportPadding, Math.min(origin.y, viewportHeight - contentSize.height - viewportPadding));
373
+ }
374
+ else {
375
+ origin.x = Math.max(viewportPadding, Math.min(origin.x, viewportWidth - contentSize.width - viewportPadding));
376
+ }
377
+ // Always constrain Y position within viewport bounds
378
+ origin.y = Math.max(viewportPadding, Math.min(origin.y, viewportHeight - contentSize.height - viewportPadding));
379
+ const triggerCenterX = left + halfTriggerWidth;
380
+ const triggerCenterY = top + halfTriggerHeight;
381
+ const cardCenterX = origin.x + contentSize.width / 2;
382
+ const cardCenterY = origin.y + contentSize.height / 2;
383
+ let arrowOffsetX = triggerCenterX - cardCenterX;
384
+ let arrowOffsetY = triggerCenterY - cardCenterY;
385
+ // Clamp arrow offset to ensure it stays within card boundaries.
386
+ // Arrow should be at least halfArrowWidth (7px) from the card edges.
387
+ const maxArrowOffsetX = halfContentWidth - halfArrowWidth;
388
+ const maxArrowOffsetY = halfContentHeight - halfArrowWidth;
389
+ if (appliedSide === 'top' || appliedSide === 'bottom') {
390
+ arrowOffsetX = Math.max(-maxArrowOffsetX, Math.min(arrowOffsetX, maxArrowOffsetX));
391
+ }
392
+ if (appliedSide === 'left' || appliedSide === 'right') {
393
+ arrowOffsetY = Math.max(-maxArrowOffsetY, Math.min(arrowOffsetY, maxArrowOffsetY));
394
+ }
395
+ const arrowOffset = {
396
+ x: arrowOffsetX,
397
+ y: arrowOffsetY,
398
+ };
399
+ return { origin, contentSize, side: appliedSide, arrowOffset };
400
+ }
401
+ useEffect(() => {
402
+ document.addEventListener('scroll', updateBounds, true);
403
+ window.addEventListener('resize', updateBounds);
404
+ return () => {
405
+ document.removeEventListener('scroll', updateBounds, true);
406
+ window.removeEventListener('resize', updateBounds);
407
+ };
408
+ }, []);
409
+ function resetDestructiveTimeouts() {
410
+ if (activeTimeout.current)
411
+ clearTimeout(activeTimeout.current);
412
+ if (persistingTimeout.current)
413
+ clearTimeout(persistingTimeout.current);
414
+ if (openTimeout.current)
415
+ clearTimeout(openTimeout.current);
416
+ }
417
+ function attemptDeactivate() {
418
+ if (activeTimeout.current)
419
+ clearTimeout(activeTimeout.current);
420
+ activeTimeout.current = setTimeout(() => {
421
+ if (activeId.current !== id)
422
+ return;
423
+ setActiveId(null);
424
+ }, inactiveTimeoutMs);
425
+ }
426
+ function attemptPersist() {
427
+ setPersisting(true);
428
+ if (persistingTimeout.current)
429
+ clearTimeout(persistingTimeout.current);
430
+ persistingTimeout.current = setTimeout(() => {
431
+ setPersisting(false);
432
+ }, PERSIST_TIMEOUT_MS);
433
+ }
434
+ function onMouseEnter() {
435
+ resetDestructiveTimeouts();
436
+ setHoveredId(id);
437
+ setLocalHover(true);
438
+ }
439
+ function onMouseLeave() {
440
+ setLocalHover(false);
441
+ attemptDeactivate();
442
+ attemptPersist();
443
+ }
444
+ useEffect(() => {
445
+ // close instantly
446
+ if (hide) {
447
+ setLocalHover(false);
448
+ setActiveId(null);
449
+ }
450
+ }, [hide, setActiveId]);
451
+ function handleClick(e) {
452
+ // Close if clicking a link. We assume we want the card to disappear if navigating.
453
+ if (e.target instanceof HTMLElement && e.target.closest('a[href]')) {
454
+ onMouseLeave();
455
+ }
456
+ }
457
+ const Comp = asChild ? SlotRoot : 'div';
458
+ return (_jsxs(Comp, { className: cn('inline-flex cursor-pointer flex-[0_1_auto] overflow-hidden', className), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, onClick: handleClick, ref: triggerRef, children: [_jsx(Slottable, { children: children }), portalRef?.current && (localHover || persisting)
459
+ ? createPortal(_jsx("div", { className: cn('absolute top-0 p-3 left-0 max-w-max transition-[transform,width,height] duration-250 ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none', skipTransition && '!transition-none'), ref: contentRef, style: {
460
+ ...(noPadding ? { padding: 0 } : {}),
461
+ pointerEvents: rootVisible && visible && !ignoreCardPointerEvents
462
+ ? 'all'
463
+ : 'none',
464
+ }, children: _jsx("div", { className: cn('min-w-max transition-all duration-150 ease-[easing-function:cubic-bezier(0.3,_0.57,_0.07,_0.95)] will-change-[transform,width,height] motion-reduce:!transition-none', skipTransition
465
+ ? '!transition-none'
466
+ : 'transition-[transform,width,height] duration-250 ease-[easing-function:cubic-bezier(0.29,0.31,0.05,0.96)] will-change-[transform,width,height] motion-reduce:!transition-none'), ref: contentMeasureRef, style: {
467
+ opacity: Number(visible),
468
+ }, children: content }) }, id), portalRef.current)
469
+ : null] }));
470
+ }
471
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC1jYXJkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdWkvY29udGV4dC1jYXJkLnRzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZLENBQUM7O0FBRWIsT0FBTyxFQUFFLElBQUksSUFBSSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFbkUsT0FBTyxFQUNMLGFBQWEsRUFDYixVQUFVLEVBQ1YsU0FBUyxFQUNULEtBQUssRUFDTCxPQUFPLEVBQ1AsTUFBTSxFQUNOLFFBQVEsR0FDVCxNQUFNLE9BQU8sQ0FBQztBQUNmLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDekMsT0FBTyxVQUFVLE1BQU0sbUJBQW1CLENBQUM7QUFDM0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBRXJDLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDO0FBQ2hDLE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN6QixNQUFNLGFBQWEsR0FBRyxHQUFHLENBQUM7QUFDMUIsTUFBTSwwQkFBMEIsR0FBRyxHQUFHLENBQUM7QUFDdkMsTUFBTSxrQ0FBa0MsR0FBRyxHQUFHLENBQUM7QUFDL0MsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLENBQUM7QUFrQ2hDLE1BQU0sa0JBQWtCLEdBQUcsYUFBYSxDQUF5QjtJQUMvRCxVQUFVLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUU7SUFDMUIsVUFBVSxFQUFFLEVBQUUsS0FBSyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFO0lBQ25DLFNBQVMsRUFBRSxJQUFtRDtJQUM5RCxRQUFRLEVBQUUsSUFBa0Q7SUFDNUQsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFD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Qy9DLENBQUMsQ0FBQyxZQUFZLENBQ1YsY0FDRSxTQUFTLEVBQUUsRUFBRSxDQUNYLG1OQUFtTixFQUNuTixjQUFjLElBQUksa0JBQWtCLENBQ3JDLEVBRUQsR0FBRyxFQUFFLFVBQVUsRUFDZixLQUFLLEVBQUU7d0JBQ0wsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQzt3QkFDcEMsYUFBYSxFQUNYLFdBQVcsSUFBSSxPQUFPLElBQUksQ0FBQyx1QkFBdUI7NEJBQ2hELENBQUMsQ0FBQyxLQUFLOzRCQUNQLENBQUMsQ0FBQyxNQUFNO3FCQUNiLFlBRUQsY0FDRSxTQUFTLEVBQUUsRUFBRSxDQUNYLHNLQUFzSyxFQUN0SyxjQUFjOzRCQUNaLENBQUMsQ0FBQyxrQkFBa0I7NEJBQ3BCLENBQUMsQ0FBQywrS0FBK0ssQ0FDcEwsRUFDRCxHQUFHLEVBQUUsaUJBQWlCLEVBQ3RCLEtBQUssRUFBRTs0QkFDTCxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQzt5QkFDekIsWUFFQSxPQUFPLEdBQ0osSUF2QkQsRUFBRSxDQXdCSCxFQUNOLFNBQVMsQ0FBQyxPQUFPLENBQ2xCO2dCQUNILENBQUMsQ0FBQyxJQUFJLElBQ0gsQ0FDUixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIid1c2UgY2xpZW50JztcblxuaW1wb3J0IHsgUm9vdCBhcyBTbG90Um9vdCwgU2xvdHRhYmxlIH0gZnJvbSAnQHJhZGl4LXVpL3JlYWN0LXNsb3QnO1xuaW1wb3J0IHR5cGUgeyBKU1gsIE11dGFibGVSZWZPYmplY3QsIFJlYWN0Tm9kZSwgUmVmT2JqZWN0IH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHtcbiAgY3JlYXRlQ29udGV4dCxcbiAgdXNlQ29udGV4dCxcbiAgdXNlRWZmZWN0LFxuICB1c2VJZCxcbiAgdXNlTWVtbyxcbiAgdXNlUmVmLFxuICB1c2VTdGF0ZSxcbn0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgY3JlYXRlUG9ydGFsIH0gZnJvbSAncmVhY3QtZG9tJztcbmltcG9ydCB1c2VNZWFzdXJlIGZyb20gJ3JlYWN0LXVzZS1tZWFzdXJlJztcbmltcG9ydCB7IHVzZVJlZHVjZWRNb3Rpb24gfSBmcm9tICcuLi8uLi9ob29rcy91c2UtcmVkdWNlZC1tb3Rpb24nO1xuaW1wb3J0IHsgY24gfSBmcm9tICcuLi8uLi9saWIvdXRpbHMnO1xuXG5jb25zdCBJTkFDVElWRV9USU1FT1VUX01TID0gMjUwO1xuY29uc3QgRU5URVJfREVMQVlfTVMgPSAwO1xuY29uc3QgT1BFTl9ERUxBWV9NUyA9IDE1MDtcbmNvbnN0IE1BWF9UUkFOU0lUSU9OX0RJU1RBTkNFX1BYID0gMTUwO1xuY29uc3QgTUFYX09WRVJMQVBfRk9SX1RSQU5TSVRJT05fUEVSQ0VOVCA9IDEwMDtcbmNvbnN0IFBFUlNJU1RfVElNRU9VVF9NUyA9IDEwMDA7XG5cbmludGVyZmFjZSBQb2ludCB7XG4gIHg6IG51bWJlcjtcbiAgeTogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgQ29udGV4dENhcmREYXRhIHtcbiAgaWQ6IHN0cmluZztcbiAgb3JpZ2luOiBQb2ludDtcbiAgY29udGVudFNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcbiAgc2lkZTogU2lkZTtcbiAgYXJyb3dPZmZzZXQ6IFBvaW50O1xufVxuXG50eXBlIE51bGxTdHJpbmcgPSBzdHJpbmcgfCBudWxsO1xuXG5pbnRlcmZhY2UgQ29udGV4dENhcmRDb250ZXh0VHlwZSB7XG4gIHJvb3RPcmlnaW46IFBvaW50O1xuICByb290Qm91bmRzOiB7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH07XG4gIHBvcnRhbFJlZjogUmVmT2JqZWN0PEhUTUxEaXZFbGVtZW50IHwgbnVsbD47XG4gIGFjdGl2ZUlkOiBSZWZPYmplY3Q8TnVsbFN0cmluZyB8IG51bGw+O1xuICBzZXRBY3RpdmVJZDogKGlkOiBOdWxsU3RyaW5nKSA9PiB2b2lkO1xuICBob3ZlcmVkSWQ6IE51bGxTdHJpbmc7XG4gIHNldEhvdmVyZWRJZDogKGlkOiBOdWxsU3RyaW5nKSA9PiB2b2lkO1xuICB1cGRhdGVBY3RpdmVDb250ZXh0Q2FyZDogKHVwZGF0ZTogQ29udGV4dENhcmREYXRhIHwgbnVsbCkgPT4gdm9pZDtcbiAgc2tpcFRyYW5zaXRpb246IGJvb2xlYW47XG4gIHJvb3RWaXNpYmxlOiBib29sZWFuO1xuICBkaXN0YW5jZUZyb21MYXN0OiBudW1iZXI7XG4gIGxhc3RPcmlnaW46IFBvaW50IHwgbnVsbDtcbiAgLyoqIFdoZXRoZXIgYSByZWFsIHtAbGluayBDb250ZXh0Q2FyZFByb3ZpZGVyfSBpcyBtb3VudGVkIGFib3ZlIHRoaXMgY29uc3VtZXIuICovXG4gIGlzUHJvdmlkZWQ6IGJvb2xlYW47XG59XG5cbmNvbnN0IENvbnRleHRDYXJkQ29udGV4dCA9IGNyZWF0ZUNvbnRleHQ8Q29udGV4dENhcmRDb250ZXh0VHlwZT4oe1xuICByb290T3JpZ2luOiB7IHg6IDAsIHk6IDAgfSxcbiAgcm9vdEJvdW5kczogeyB3aWR0aDogMCwgaGVpZ2h0OiAwIH0sXG4gIHBvcnRhbFJlZjogbnVsbCBhcyB1bmtub3duIGFzIFJlZk9iamVjdDxIVE1MRGl2RWxlbWVudCB8IG51bGw+LFxuICBhY3RpdmVJZDogbnVsbCBhcyB1bmtub3duIGFzIE11dGFibGVSZWZPYmplY3Q8c3RyaW5nIHwgbnVsbD4sXG4gIHNldEFjdGl2ZUlkOiAoKSA9PiB2b2lkIDAsXG4gIGhvdmVyZWRJZDogbnVsbCxcbiAgc2V0SG92ZXJlZElkOiAoKSA9PiB2b2lkIDAsXG4gIHVwZGF0ZUFjdGl2ZUNvbnRleHRDYXJkOiAoKSA9PiB2b2lkIDAsXG4gIHNraXBUcmFuc2l0aW9uOiBmYWxzZSxcbiAgcm9vdFZpc2libGU6IGZhbHNlLFxuICBkaXN0YW5jZUZyb21MYXN0OiAwLFxuICBsYXN0T3JpZ2luOiBudWxsLFxuICBpc1Byb3ZpZGVkOiBmYWxzZSxcbn0pO1xuQ29udGV4dENhcmRDb250ZXh0LmRpc3BsYXlOYW1lID0gJ0NvbnRleHRDYXJkQ29udGV4dCc7XG5cbi8qKlxuICogUmV0dXJucyB3aGV0aGVyIHRoZSBjdXJyZW50IHN1YnRyZWUgaXMgd3JhcHBlZCBpbiBhIHtAbGluayBDb250ZXh0Q2FyZFByb3ZpZGVyfS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUhhc0NvbnRleHRDYXJkUHJvdmlkZXIoKTogYm9vbGVhbiB7XG4gIHJldHVybiB1c2VDb250ZXh0KENvbnRleHRDYXJkQ29udGV4dCkuaXNQcm92aWRlZDtcbn1cblxuZnVuY3Rpb24gdXNlUHJldmlvdXM8VD4odmFsdWU6IFQpOiBUIHwgbnVsbCB7XG4gIGNvbnN0IHJlZiA9IHVzZVJlZjxUIHwgbnVsbD4obnVsbCk7XG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgcmVmLmN1cnJlbnQgPSB2YWx1ZTtcbiAgfSk7XG4gIHJldHVybiByZWYuY3VycmVudDtcbn1cblxuZnVuY3Rpb24gaXNSZWZPYmplY3QoXG4gIHZhbHVlOiBIVE1MRWxlbWVudCB8IFJlZk9iamVjdDxIVE1MRWxlbWVudCB8IG51bGw+IHwgbnVsbCB8IHVuZGVmaW5lZFxuKTogdmFsdWUgaXMgUmVmT2JqZWN0PEhUTUxFbGVtZW50IHwgbnVsbD4ge1xuICByZXR1cm4gdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgIT09IHVuZGVmaW5lZCAmJiAnY3VycmVudCcgaW4gdmFsdWU7XG59XG5cbi8qKlxuICogUHJvdmlkZXMgc2hhcmVkIHN0YXRlIGFuZCBhIHBvcnRhbCBjb250YWluZXIgZm9yIHtAbGluayBDb250ZXh0Q2FyZFRyaWdnZXJ9XG4gKiBjb21wb25lbnRzLiBNdXN0IHdyYXAgYW55IHRyZWUgY29udGFpbmluZyB0cmlnZ2VyczsgbWFuYWdlcyBwb3NpdGlvbmluZyxcbiAqIHZpc2liaWxpdHkgdHJhbnNpdGlvbnMsIGFuZCB0aGUgYW5pbWF0ZWQgYXJyb3cgdGlwIGFjcm9zcyBhbGwgY2FyZHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBDb250ZXh0Q2FyZFByb3ZpZGVyKHtcbiAgY2hpbGRyZW4sXG4gIHBvcnRhbFRhcmdldCxcbn06IHtcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbiAgLyoqIEN1c3RvbSBjb250YWluZXIgZm9yIHRoZSBwb3J0YWwuIEFjY2VwdHMgZWl0aGVyIGFuIGVsZW1lbnQgb3IgYSByZWYuICovXG4gIHBvcnRhbFRhcmdldD86IEhUTUxFbGVtZW50IHwgUmVmT2JqZWN0PEhUTUxFbGVtZW50IHwgbnVsbD4gfCBudWxsO1xufSk6IFJlYWN0Tm9kZSB7XG4gIGNvbnN0IFtpc01vdW50ZWQsIHNldElzTW91bnRlZF0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIHVzZUVmZmVjdCgoKSA9PiBzZXRJc01vdW50ZWQodHJ1ZSksIFtdKTtcbiAgY29uc3QgcmVzb2x2ZWRQb3J0YWxUYXJnZXQgPSBpc1JlZk9iamVjdChwb3J0YWxUYXJnZXQpXG4gICAgPyBwb3J0YWxUYXJnZXQuY3VycmVudFxuICAgIDogcG9ydGFsVGFyZ2V0O1xuICBjb25zdCBbcmVmLCBib3VuZHNdID0gdXNlTWVhc3VyZSgpO1xuICBjb25zdCBwb3J0YWxSZWYgPSB1c2VSZWY8SFRNTERpdkVsZW1lbnQgfCBudWxsPihudWxsKTtcbiAgY29uc3QgW2FjdGl2ZUNvbnRleHRDYXJkLCBzZXRBY3RpdmVDb250ZXh0Q2FyZF0gPVxuICAgIHVzZVN0YXRlPENvbnRleHRDYXJkRGF0YSB8IG51bGw+KG51bGwpO1xuICBjb25zdCBbdmlzaWJsZSwgc2V0VmlzaWJsZV0gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFtob3ZlcmVkSWQsIHNldEhvdmVyZWRJZF0gPSB1c2VTdGF0ZTxOdWxsU3RyaW5nPihudWxsKTtcbiAgY29uc3QgYWN0aXZlSWQgPSB1c2VSZWY8TnVsbFN0cmluZz4obnVsbCk7XG5cbiAgZnVuY3Rpb24gc2V0QWN0aXZlSWQoaWQ6IE51bGxTdHJpbmcpOiB2b2lkIHtcbiAgICBhY3RpdmVJZC5jdXJyZW50ID0gaWQ7XG4gICAgc2V0VmlzaWJsZShpZCAhPT0gbnVsbCk7XG4gIH1cbiAgY29uc3QgdXBkYXRlQWN0aXZlQ29udGV4dENhcmQgPSAodXBkYXRlOiBDb250ZXh0Q2FyZERhdGEgfCBudWxsKTogdm9pZCA9PiB7XG4gICAgaWYgKHVwZGF0ZT8uaWQgIT09IGFjdGl2ZUlkLmN1cnJlbnQgJiYgdXBkYXRlICE9PSBudWxsKSByZXR1cm47XG4gICAgc2V0QWN0aXZlQ29udGV4dENhcmQodXBkYXRlKTtcbiAgfTtcblxuICBjb25zdCBCT1JERVJfV0lEVEggPSAxO1xuXG4gIGNvbnN0IGFjdGl2ZUJvdW5kcyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICghYWN0aXZlQ29udGV4dENhcmQpXG4gICAgICByZXR1cm4ge1xuICAgICAgICB3aWR0aDogMCxcbiAgICAgICAgaGVpZ2h0OiAwLFxuICAgICAgICB4OiAwLFxuICAgICAgICB5OiAwLFxuICAgICAgICBzaWRlOiAndG9wJyBhcyBTaWRlLFxuICAgICAgICBhcnJvd09mZnNldDogeyB4OiAwLCB5OiAwIH0sXG4gICAgICB9O1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aDogYWN0aXZlQ29udGV4dENhcmQuY29udGVudFNpemUud2lkdGggKyBCT1JERVJfV0lEVEggKiAyLFxuICAgICAgaGVpZ2h0OiBhY3RpdmVDb250ZXh0Q2FyZC5jb250ZW50U2l6ZS5oZWlnaHQgKyBCT1JERVJfV0lEVEggKiAyLFxuICAgICAgeDogYWN0aXZlQ29udGV4dENhcmQub3JpZ2luLngsXG4gICAgICB5OiBhY3RpdmVDb250ZXh0Q2FyZC5vcmlnaW4ueSxcbiAgICAgIHNpZGU6IGFjdGl2ZUNvbnRleHRDYXJkLnNpZGUsXG4gICAgICBhcnJvd09mZnNldDogYWN0aXZlQ29udGV4dENhcmQuYXJyb3dPZmZzZXQsXG4gICAgfTtcbiAgfSwgW2FjdGl2ZUNvbnRleHRDYXJkXSk7XG5cbiAgY29uc3QgbGFzdEJvdW5kcyA9IHVzZVByZXZpb3VzKGFjdGl2ZUJvdW5kcyk7XG4gIGNvbnN0IGxhc3RJZCA9IHVzZVByZXZpb3VzKGFjdGl2ZUlkLmN1cnJlbnQpO1xuXG4gIGNvbnN0IHBlcmNlbnRPdmVybGFwRnJvbUxhc3QgPSB1c2VNZW1vKCgpID0+IHtcbiAgICBpZiAoIWxhc3RCb3VuZHMpIHJldHVybiAwO1xuXG4gICAgY29uc3Qgb3ZlcmxhcExlZnQgPSBNYXRoLm1heChhY3RpdmVCb3VuZHMueCwgbGFzdEJvdW5kcy54KTtcbiAgICBjb25zdCBvdmVybGFwUmlnaHQgPSBNYXRoLm1pbihcbiAgICAgIGFjdGl2ZUJvdW5kcy54ICsgYWN0aXZlQm91bmRzLndpZHRoLFxuICAgICAgbGFzdEJvdW5kcy54ICsgbGFzdEJvdW5kcy53aWR0aFxuICAgICk7XG4gICAgY29uc3Qgb3ZlcmxhcFRvcCA9IE1hdGgubWF4KGFjdGl2ZUJvdW5kcy55LCBsYXN0Qm91bmRzLnkpO1xuICAgIGNvbnN0IG92ZXJsYXBCb3R0b20gPSBNYXRoLm1pbihcbiAgICAgIGFjdGl2ZUJvdW5kcy55ICsgYWN0aXZlQm91bmRzLmhlaWdodCxcbiAgICAgIGxhc3RCb3VuZHMueSArIGxhc3RCb3VuZHMuaGVpZ2h0XG4gICAgKTtcblxuICAgIGlmIChvdmVybGFwTGVmdCA8IG92ZXJsYXBSaWdodCAmJiBvdmVybGFwVG9wIDwgb3ZlcmxhcEJvdHRvbSkge1xuICAgICAgY29uc3Qgb3ZlcmxhcEFyZWEgPVxuICAgICAgICAob3ZlcmxhcFJpZ2h0IC0gb3ZlcmxhcExlZnQpICogKG92ZXJsYXBCb3R0b20gLSBvdmVybGFwVG9wKTtcblxuICAgICAgY29uc3QgYWN0aXZlQm91bmRzQXJlYSA9IGFjdGl2ZUJvdW5kcy53aWR0aCAqIGFjdGl2ZUJvdW5kcy5oZWlnaHQ7XG5cbiAgICAgIGlmIChhY3RpdmVCb3VuZHNBcmVhID09PSAwKSByZXR1cm4gMDtcblxuICAgICAgcmV0dXJuIChvdmVybGFwQXJlYSAvIGFjdGl2ZUJvdW5kc0FyZWEpICogMTAwO1xuICAgIH1cblxuICAgIHJldHVybiAwO1xuICB9LCBbYWN0aXZlQm91bmRzLCBsYXN0Qm91bmRzXSk7XG5cbiAgY29uc3QgZGlzdGFuY2VGcm9tTGFzdCA9IHVzZU1lbW8oXG4gICAgKCkgPT5cbiAgICAgIE1hdGguc3FydChcbiAgICAgICAgKChsYXN0Qm91bmRzPy54ID8/IDApIC0gYWN0aXZlQm91bmRzLngpICoqIDIgK1xuICAgICAgICAgICgobGFzdEJvdW5kcz8ueSA/PyAwKSAtIGFjdGl2ZUJvdW5kcy55KSAqKiAyXG4gICAgICApLFxuICAgIFthY3RpdmVCb3VuZHMueCwgYWN0aXZlQm91bmRzLnksIGxhc3RCb3VuZHM/LngsIGxhc3RCb3VuZHM/LnldXG4gICk7XG5cbiAgY29uc3QgbGFzdE9yaWdpbiA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmICghbGFzdEJvdW5kcykgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IGxhc3RCb3VuZHMueCAtIGFjdGl2ZUJvdW5kcy54LFxuICAgICAgeTogbGFzdEJvdW5kcy55IC0gYWN0aXZlQm91bmRzLnksXG4gICAgfTtcbiAgfSwgW2FjdGl2ZUJvdW5kcywgbGFzdEJvdW5kc10pO1xuXG4gIGNvbnN0IFtpc1Njcm9sbGluZywgc2V0SXNTY3JvbGxpbmddID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBza2lwVHJhbnNpdGlvbiA9IHVzZU1lbW8oXG4gICAgKCkgPT5cbiAgICAgIGRpc3RhbmNlRnJvbUxhc3QgPiBNQVhfVFJBTlNJVElPTl9ESVNUQU5DRV9QWCB8fFxuICAgICAgcGVyY2VudE92ZXJsYXBGcm9tTGFzdCA+IE1BWF9PVkVSTEFQX0ZPUl9UUkFOU0lUSU9OX1BFUkNFTlQgfHxcbiAgICAgIGxhc3RJZCA9PT0gbnVsbCB8fFxuICAgICAgaXNTY3JvbGxpbmcsXG4gICAgW2Rpc3RhbmNlRnJvbUxhc3QsIGlzU2Nyb2xsaW5nLCBsYXN0SWQsIHBlcmNlbnRPdmVybGFwRnJvbUxhc3RdXG4gICk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgaXNTY3JvbGxpbmdUaW1lb3V0OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuXG4gICAgY29uc3Qgb25TY3JvbGwgPSAoKTogdm9pZCA9PiB7XG4gICAgICBpZiAoaXNTY3JvbGxpbmdUaW1lb3V0KSB3aW5kb3cuY2xlYXJUaW1lb3V0KGlzU2Nyb2xsaW5nVGltZW91dCk7XG5cbiAgICAgIGlzU2Nyb2xsaW5nVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBzZXRJc1Njcm9sbGluZyhmYWxzZSk7XG4gICAgICB9LCA2Nik7XG5cbiAgICAgIGlmICghaXNTY3JvbGxpbmcpIHtcbiAgICAgICAgc2V0SXNTY3JvbGxpbmcodHJ1ZSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIG9uU2Nyb2xsLCB0cnVlKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCwgdHJ1ZSk7XG4gICAgfTtcbiAgfSwgW2lzU2Nyb2xsaW5nXSk7XG5cbiAgY29uc3QgY29udGV4dFZhbHVlID0gdXNlTWVtbyhcbiAgICAoKSA9PiAoe1xuICAgICAgdXBkYXRlQWN0aXZlQ29udGV4dENhcmQsXG4gICAgICByb290T3JpZ2luOiB7IC4uLmFjdGl2ZUJvdW5kcyB9LFxuICAgICAgcm9vdEJvdW5kczogYm91bmRzLFxuICAgICAgcG9ydGFsUmVmLFxuICAgICAgc2V0QWN0aXZlSWQsXG4gICAgICBhY3RpdmVJZCxcbiAgICAgIHNldEhvdmVyZWRJZCxcbiAgICAgIGhvdmVyZWRJZCxcbiAgICAgIHNraXBUcmFuc2l0aW9uLFxuICAgICAgcm9vdFZpc2libGU6IHZpc2libGUsXG4gICAgICBkaXN0YW5jZUZyb21MYXN0LFxuICAgICAgbGFzdE9yaWdpbixcbiAgICAgIGlzUHJvdmlkZWQ6IHRydWUsXG4gICAgfSksXG4gICAgW1xuICAgICAgYWN0aXZlQm91bmRzLFxuICAgICAgYm91bmRzLFxuICAgICAgaG92ZXJlZElkLFxuICAgICAgc2tpcFRyYW5zaXRpb24sXG4gICAgICB2aXNpYmxlLFxuICAgICAgZGlzdGFuY2VGcm9tTGFzdCxcbiAgICAgIGxhc3RPcmlnaW4sXG4gICAgXVxuICApO1xuXG4gIHJldHVybiAoXG4gICAgPENvbnRleHRDYXJkQ29udGV4dC5Qcm92aWRlciB2YWx1ZT17Y29udGV4dFZhbHVlfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICAgIHtpc01vdW50ZWRcbiAgICAgICAgPyBjcmVhdGVQb3J0YWwoXG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT1cInctZnVsbCBoLWZ1bGwgaW5zZXQtMCBmaXhlZCBwb2ludGVyLWV2ZW50cy1ub25lIHotWzEwMDAwMF1cIlxuICAgICAgICAgICAgICByZWY9e3JlZn1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cIm1pbi13LW1heCB0cmFuc2l0aW9uLWFsbCBkdXJhdGlvbi0xNTAgZWFzZS1bZWFzaW5nLWZ1bmN0aW9uOmN1YmljLWJlemllcigwLjMsXzAuNTcsXzAuMDcsXzAuOTUpXSB3aWxsLWNoYW5nZS1bdHJhbnNmb3JtLHdpZHRoLGhlaWdodF0gbW90aW9uLXJlZHVjZTohdHJhbnNpdGlvbi1ub25lXCJcbiAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgb3BhY2l0eTogdmlzaWJsZSA/IDEgOiAwLFxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9e2NuKFxuICAgICAgICAgICAgICAgICAgICAnYWJzb2x1dGUgYmctYmFja2dyb3VuZC0xMDAgYmctY2xpcC1wYWRkaW5nIHJvdW5kZWQtWzZweF0gb3ZlcmZsb3ctdmlzaWJsZSBwb2ludGVyLWV2ZW50cy1ub25lIHotWzEwMDAwMDBdIHNoYWRvdy1bdmFyKC0tZHMtc2hhZG93LXRvb2x0aXApLDBfMF8wXzFweF92YXIoLS1kcy1iYWNrZ3JvdW5kLTEwMCldIHctZml0IFstLWNvbnRleHQtY2FyZC10aXAtc3Ryb2tlOiNEQkRCREJdIGRhcmstdGhlbWU6Wy0tY29udGV4dC1jYXJkLXRpcC1zdHJva2U6IzI1MjUyNV0nLFxuICAgICAgICAgICAgICAgICAgICBza2lwVHJhbnNpdGlvblxuICAgICAgICAgICAgICAgICAgICAgID8gJyF0cmFuc2l0aW9uLW5vbmUnXG4gICAgICAgICAgICAgICAgICAgICAgOiAndHJhbnNpdGlvbi1bdHJhbnNmb3JtLHdpZHRoLGhlaWdodF0gZHVyYXRpb24tMjUwIGVhc2UtW2Vhc2luZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC4yOSwwLjMxLDAuMDUsMC45NildIHdpbGwtY2hhbmdlLVt0cmFuc2Zvcm0sd2lkdGgsaGVpZ2h0XSBtb3Rpb24tcmVkdWNlOiF0cmFuc2l0aW9uLW5vbmUnXG4gICAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICAgICAgZGF0YS1za2lwLXRyYW5zaXRpb249e3NraXBUcmFuc2l0aW9ufVxuICAgICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNmb3JtOiBgdHJhbnNsYXRlKCR7YWN0aXZlQm91bmRzLnh9cHgsJHthY3RpdmVCb3VuZHMueX1weClgLFxuICAgICAgICAgICAgICAgICAgICB3aWR0aDogYWN0aXZlQm91bmRzLndpZHRoLFxuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IGFjdGl2ZUJvdW5kcy5oZWlnaHQsXG4gICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lPXtjbihcbiAgICAgICAgICAgICAgICAgICAgICAndy1bMTRweF0gaC1bN3B4XSBhYnNvbHV0ZSBncmlkIHBsYWNlLWNvbnRlbnQtY2VudGVyIHotWzk5OTk5OTk5OV0gb3JpZ2luLWNlbnRlcicsXG4gICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgJ3RvcC1mdWxsIC10cmFuc2xhdGUteC0xLzIgcm90YXRlLTAnOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVCb3VuZHMuc2lkZSA9PT0gJ3RvcCcsXG4gICAgICAgICAgICAgICAgICAgICAgICAncmlnaHQtZnVsbCAtdHJhbnNsYXRlLXktMS8yIHJvdGF0ZS05MCAtbXItWzMuNXB4XSc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUJvdW5kcy5zaWRlID09PSAncmlnaHQnLFxuICAgICAgICAgICAgICAgICAgICAgICAgJ2JvdHRvbS1mdWxsIC10cmFuc2xhdGUteC0xLzIgcm90YXRlLTE4MCc6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUJvdW5kcy5zaWRlID09PSAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICdsZWZ0LWZ1bGwgLXRyYW5zbGF0ZS15LTEvMiByb3RhdGUtWzI3MGRlZ10gLW1sLVszLjVweF0nOlxuICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVCb3VuZHMuc2lkZSA9PT0gJ2xlZnQnLFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgc2tpcFRyYW5zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgID8gJyF0cmFuc2l0aW9uLW5vbmUnXG4gICAgICAgICAgICAgICAgICAgICAgICA6ICd0cmFuc2l0aW9uLVt0cmFuc2Zvcm0sd2lkdGgsaGVpZ2h0XSBkdXJhdGlvbi0yNTAgZWFzZS1bZWFzaW5nLWZ1bmN0aW9uOmN1YmljLWJlemllcigwLjI5LDAuMzEsMC4wNSwwLjk2KV0gd2lsbC1jaGFuZ2UtW3RyYW5zZm9ybSx3aWR0aCxoZWlnaHRdIG1vdGlvbi1yZWR1Y2U6IXRyYW5zaXRpb24tbm9uZSdcbiAgICAgICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICAgICAgICAuLi4oYWN0aXZlQm91bmRzLnNpZGUgPT09ICd0b3AnIHx8XG4gICAgICAgICAgICAgICAgICAgICAgYWN0aXZlQm91bmRzLnNpZGUgPT09ICdib3R0b20nXG4gICAgICAgICAgICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBgY2FsYyg1MCUgKyAke2FjdGl2ZUJvdW5kcy5hcnJvd09mZnNldC54fXB4KWAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDoge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvcDogYGNhbGMoNTAlICsgJHthY3RpdmVCb3VuZHMuYXJyb3dPZmZzZXQueX1weClgLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgICAgICAgZGF0YS1za2lwLXRyYW5zaXRpb249e3NraXBUcmFuc2l0aW9ufVxuICAgICAgICAgICAgICAgICAgICBkYXRhLXNpZGU9e2FjdGl2ZUJvdW5kcy5zaWRlfVxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8c3ZnXG4gICAgICAgICAgICAgICAgICAgICAgd2lkdGg9XCIxNFwiXG4gICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0PVwiN1wiXG4gICAgICAgICAgICAgICAgICAgICAgdmlld0JveD1cIjAgMCAxNCA3XCJcbiAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwibm9uZVwiXG4gICAgICAgICAgICAgICAgICAgICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiXG4gICAgICAgICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxnIGNsaXBQYXRoPVwidXJsKCNjb250ZXh0LWNhcmQtdGlwLWNsaXApXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cGF0aFxuICAgICAgICAgICAgICAgICAgICAgICAgICBkPVwiTTE1IC0wLjVWMC41SDEyLjk4MzRMMTIuODE4NCAwLjUwODc4OUMxMi40Mzc3IDAuNTUwODIyIDEyLjA4NTMgMC43MzgwNTYgMTEuODM1OSAxLjAzNDE4TDguNTMwMjcgNC45NTk5NkM3LjczMTE0IDUuOTA4OTMgNi4yNjg4NiA1LjkwODkyIDUuNDY5NzMgNC45NTk5NkwyLjE2NDA2IDEuMDM0MThDMS44NzkwNSAwLjY5NTczMyAxLjQ1OTA3IDAuNSAxLjAxNjYgMC41SC0xVi0wLjVIMTVaXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbD1cInZhcigtLWRzLWJhY2tncm91bmQtMTAwKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbDogJ3ZhcigtLWRzLWJhY2tncm91bmQtMTAwKScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsbE9wYWNpdHk6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Ryb2tlOiAndmFyKC0tY29udGV4dC1jYXJkLXRpcC1zdHJva2UpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHJva2VPcGFjaXR5OiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2c+XG4gICAgICAgICAgICAgICAgICAgICAgPGRlZnM+XG4gICAgICAgICAgICAgICAgICAgICAgICA8Y2xpcFBhdGggaWQ9XCJjb250ZXh0LWNhcmQtdGlwLWNsaXBcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHJlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aWR0aD1cIjE0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBoZWlnaHQ9XCI3XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxsPVwid2hpdGVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0eWxlPXt7IGZpbGw6ICd3aGl0ZScsIGZpbGxPcGFjaXR5OiAxIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2NsaXBQYXRoPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGVmcz5cbiAgICAgICAgICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgcmVmPXtwb3J0YWxSZWZ9IC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+LFxuICAgICAgICAgICAgcmVzb2x2ZWRQb3J0YWxUYXJnZXQgPz8gZG9jdW1lbnQuYm9keVxuICAgICAgICAgIClcbiAgICAgICAgOiBudWxsfVxuICAgIDwvQ29udGV4dENhcmRDb250ZXh0LlByb3ZpZGVyPlxuICApO1xufVxuXG5leHBvcnQgdHlwZSBTaWRlID0gJ3RvcCcgfCAnYm90dG9tJyB8ICdsZWZ0JyB8ICdyaWdodCc7XG5leHBvcnQgdHlwZSBBbGlnbiA9ICdzdGFydCcgfCAnY2VudGVyJyB8ICdlbmQnO1xuXG4vKiogUHJvcHMgZm9yIHRoZSB7QGxpbmsgQ29udGV4dENhcmRUcmlnZ2VyfSBjb21wb25lbnQuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbnRleHRDYXJkVHJpZ2dlclByb3BzXG4gIGV4dGVuZHMgT21pdDxSZWFjdC5IVE1MQXR0cmlidXRlczxIVE1MRGl2RWxlbWVudD4sICdjb250ZW50Jz4ge1xuICAvKiogVGhlIGNvbnRlbnQgcmVuZGVyZWQgaW5zaWRlIHRoZSBjb250ZXh0IGNhcmQgcG9wdXAuICovXG4gIGNvbnRlbnQ6IFJlYWN0Tm9kZTtcbiAgLyoqIFdoaWNoIHNpZGUgb2YgdGhlIHRyaWdnZXIgdG8gZGlzcGxheSB0aGUgY2FyZC4gRGVmYXVsdHMgdG8gYFwicmlnaHRcImAuICovXG4gIHNpZGU/OiBTaWRlO1xuICAvKiogQWxpZ25tZW50IG9mIHRoZSBjYXJkIHJlbGF0aXZlIHRvIHRoZSB0cmlnZ2VyLiBEZWZhdWx0cyB0byBgXCJjZW50ZXJcImAuICovXG4gIGFsaWduPzogQWxpZ247XG4gIC8qKiBEaXN0YW5jZSBpbiBwaXhlbHMgYmV0d2VlbiB0aGUgdHJpZ2dlciBhbmQgdGhlIGNhcmQuIERlZmF1bHRzIHRvIGAxNmAuICovXG4gIHNpZGVPZmZzZXQ/OiBudW1iZXI7XG4gIC8qKiBPZmZzZXQgaW4gcGl4ZWxzIGFsb25nIHRoZSBhbGlnbm1lbnQgYXhpcy4gRGVmYXVsdHMgdG8gYDBgLiAqL1xuICBhbGlnbk9mZnNldD86IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgdG8gZGlzYWJsZSBwb2ludGVyIGV2ZW50cyBvbiB0aGUgY2FyZCBjb250ZW50LiAqL1xuICBpZ25vcmVDYXJkUG9pbnRlckV2ZW50cz86IGJvb2xlYW47XG4gIC8qKiBXaGV0aGVyIHRvIHJlbW92ZSBkZWZhdWx0IHBhZGRpbmcgZnJvbSB0aGUgY2FyZCBjb250ZW50LiAqL1xuICBub1BhZGRpbmc/OiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgdHJpZ2dlciB1c2VzIHRoZSBTbG90IHBhdHRlcm4gdG8gbWVyZ2UgcHJvcHMgb250byBpdHMgY2hpbGQuICovXG4gIGFzQ2hpbGQ/OiBib29sZWFuO1xuICAvKiogQ2FuIGJlIHVzZWQgdG8gaGlkZSB0aGUgY2FyZCB3aGVuIG5lZWRlZC4gKi9cbiAgaGlkZT86IGJvb2xlYW47XG4gIC8qKiBUaW1lIGluIG1pbGxpc2Vjb25kcyBiZWZvcmUgdGhlIGNhcmQgaXMgZGlzbWlzc2VkIGFmdGVyIG1vdXNlIGxlYXZlcy4gKi9cbiAgaW5hY3RpdmVUaW1lb3V0TXM/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRGlzcGxheXMgYSBmbG9hdGluZyBjb250ZXh0IGNhcmQgb24gaG92ZXIgd2l0aCB2aWV3cG9ydC1hd2FyZSBjb2xsaXNpb25cbiAqIGRldGVjdGlvbiBhbmQgYW5pbWF0ZWQgcG9zaXRpb24gdHJhbnNpdGlvbnMgYmV0d2VlbiB0cmlnZ2VycyBpbiB0aGUgc2FtZVxuICoge0BsaW5rIENvbnRleHRDYXJkUHJvdmlkZXJ9LiBQZXJzaXN0cyBicmllZmx5IGFmdGVyIG1vdXNlIGxlYXZlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gQ29udGV4dENhcmRUcmlnZ2VyKHtcbiAgY29udGVudCxcbiAgY2hpbGRyZW4sXG4gIHNpZGUgPSAncmlnaHQnLFxuICBhbGlnbiA9ICdjZW50ZXInLFxuICBzaWRlT2Zmc2V0ID0gMTYsXG4gIGFsaWduT2Zmc2V0ID0gMCxcbiAgaWdub3JlQ2FyZFBvaW50ZXJFdmVudHMgPSBmYWxzZSxcbiAgbm9QYWRkaW5nLFxuICBhc0NoaWxkLFxuICBjbGFzc05hbWUsXG4gIGhpZGUsXG4gIGluYWN0aXZlVGltZW91dE1zID0gSU5BQ1RJVkVfVElNRU9VVF9NUyxcbn06IENvbnRleHRDYXJkVHJpZ2dlclByb3BzKTogSlNYLkVsZW1lbnQge1xuICBjb25zdCB0cmlnZ2VyUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgY29udGVudFJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG4gIGNvbnN0IFtjb250ZW50TWVhc3VyZVJlZiwgY29udGVudE1lYXN1cmVCb3VuZHNdID0gdXNlTWVhc3VyZSgpO1xuICBjb25zdCB7XG4gICAgcG9ydGFsUmVmLFxuICAgIHVwZGF0ZUFjdGl2ZUNvbnRleHRDYXJkLFxuICAgIGFjdGl2ZUlkLFxuICAgIHNldEFjdGl2ZUlkLFxuICAgIGhvdmVyZWRJZCxcbiAgICBzZXRIb3ZlcmVkSWQsXG4gICAgc2tpcFRyYW5zaXRpb24sXG4gICAgcm9vdFZpc2libGUsXG4gIH0gPSB1c2VDb250ZXh0KENvbnRleHRDYXJkQ29udGV4dCk7XG4gIGNvbnN0IGlkID0gdXNlSWQoKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAvLyBPbmx5IGNsZWFyIHRoZSBzaGFyZWQgYWN0aXZlIGNhcmQgaWYgdGhpcyB0cmlnZ2VyIHdhcyB0aGUgYWN0aXZlIG9uZTtcbiAgICAgIC8vIG90aGVyd2lzZSBhbiB1bm1vdW50aW5nIGluYWN0aXZlIHRyaWdnZXIgd291bGQgaGlkZSBhbm90aGVyIHRyaWdnZXIncyBjYXJkLlxuICAgICAgaWYgKGFjdGl2ZUlkLmN1cnJlbnQgPT09IGlkKSB7XG4gICAgICAgIHNldEFjdGl2ZUlkKG51bGwpO1xuICAgICAgfVxuICAgIH07XG4gIH0sIFtdKTtcblxuICBjb25zdCByZWR1Y2VNb3Rpb24gPSB1c2VSZWR1Y2VkTW90aW9uKCk7XG5cbiAgY29uc3QgW2xvY2FsSG92ZXIsIHNldExvY2FsSG92ZXJdID0gdXNlU3RhdGUoZmFsc2UpO1xuICBjb25zdCBbcGVyc2lzdGluZywgc2V0UGVyc2lzdGluZ10gPSB1c2VTdGF0ZShmYWxzZSk7XG4gIGNvbnN0IFt2aXNpYmxlLCBzZXRWaXNpYmxlXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICBjb25zdCBhY3RpdmVUaW1lb3V0ID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHBlcnNpc3RpbmdUaW1lb3V0ID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IG9wZW5UaW1lb3V0ID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoXG4gICAgICBsb2NhbEhvdmVyICYmXG4gICAgICBjb250ZW50TWVhc3VyZUJvdW5kcy53aWR0aCA+IDAgJiZcbiAgICAgIGNvbnRlbnRNZWFzdXJlQm91bmRzLmhlaWdodCA+IDBcbiAgICApIHtcbiAgICAgIGlmIChvcGVuVGltZW91dC5jdXJyZW50KSBjbGVhclRpbWVvdXQob3BlblRpbWVvdXQuY3VycmVudCk7XG4gICAgICBvcGVuVGltZW91dC5jdXJyZW50ID0gc2V0VGltZW91dChcbiAgICAgICAgKCkgPT4ge1xuICAgICAgICAgIHNldEFjdGl2ZUlkKGlkKTtcbiAgICAgICAgICB1cGRhdGVCb3VuZHMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgcm9vdFZpc2libGUgPyAwIDogT1BFTl9ERUxBWV9NU1xuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGlmIChvcGVuVGltZW91dC5jdXJyZW50KSBjbGVhclRpbWVvdXQob3BlblRpbWVvdXQuY3VycmVudCk7XG4gICAgfTtcbiAgfSwgW2xvY2FsSG92ZXIsIGNvbnRlbnRNZWFzdXJlQm91bmRzXSk7XG5cbiAgY29uc3QgZW50ZXJUaW1lb3V0ID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoZW50ZXJUaW1lb3V0LmN1cnJlbnQpIGNsZWFyVGltZW91dChlbnRlclRpbWVvdXQuY3VycmVudCk7XG4gICAgaWYgKGhvdmVyZWRJZCAhPT0gaWQpIHtcbiAgICAgIC8vIEV4aXRzIGFyZSBpbnN0YW50XG4gICAgICBzZXRWaXNpYmxlKGZhbHNlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRW50ZXJzIGNhbiBiZSBkZWxheWVkIHVubGVzcyB3ZSB3aXNoIHRvIHNjcmlwdCB0aGUgdHJhbnNpdGlvblxuICAgICAgZW50ZXJUaW1lb3V0LmN1cnJlbnQgPSBzZXRUaW1lb3V0KFxuICAgICAgICAoKSA9PiB7XG4gICAgICAgICAgc2V0VmlzaWJsZSh0cnVlKTtcbiAgICAgICAgfSxcbiAgICAgICAgcmVkdWNlTW90aW9uIHx8IHNraXBUcmFuc2l0aW9uID8gMCA6IEVOVEVSX0RFTEFZX01TXG4gICAgICApO1xuICAgIH1cbiAgfSwgW2hvdmVyZWRJZCwgaWQsIHJlZHVjZU1vdGlvbiwgc2tpcFRyYW5zaXRpb25dKTtcblxuICBmdW5jdGlvbiB1cGRhdGVCb3VuZHMoKTogdm9pZCB7XG4gICAgaWYgKCFjb250ZW50UmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBjb25zdCBib3VuZHMgPSBjb21wdXRlQm91bmRzKCk7XG4gICAgdXBkYXRlQWN0aXZlQ29udGV4dENhcmQoeyBpZCwgLi4uYm91bmRzIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY29tcHV0ZUJvdW5kcyhzaWRlT3ZlcnJpZGU/OiBTaWRlKToge1xuICAgIG9yaWdpbjogUG9pbnQ7XG4gICAgY29udGVudFNpemU6IHsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfTtcbiAgICBzaWRlOiBTaWRlO1xuICAgIGFycm93T2Zmc2V0OiBQb2ludDtcbiAgfSB7XG4gICAgaWYgKCF0cmlnZ2VyUmVmLmN1cnJlbnQpIHRocm93IG5ldyBFcnJvcignVHJpZ2dlciBub3QgZm91bmQnKTtcbiAgICBpZiAoIWNvbnRlbnRSZWYuY3VycmVudCkgdGhyb3cgbmV3IEVycm9yKCdDb250ZW50IG5vdCBmb3VuZCcpO1xuICAgIGNvbnN0IGFwcGxpZWRTaWRlID0gc2lkZU92ZXJyaWRlID8/IHNpZGU7XG4gICAgY29uc3QgdHJpZ2dlclJlY3QgPSB0cmlnZ2VyUmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgY29udGVudFJlY3QgPSBjb250ZW50UmVmLmN1cnJlbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29udGVudFJlZi5jdXJyZW50LnN0eWxlLndpZHRoID0gJ21heC1jb250ZW50JztcbiAgICBjb250ZW50UmVmLmN1cnJlbnQuc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgIGNvbnN0IGNvbnRlbnRTaXplID0ge1xuICAgICAgd2lkdGg6IE1hdGgubWF4KGNvbnRlbnRSZWN0LndpZHRoLCBjb250ZW50UmVmLmN1cnJlbnQub2Zmc2V0V2lkdGgpLFxuICAgICAgaGVpZ2h0OiBjb250ZW50UmVjdC5oZWlnaHQsXG4gICAgfTtcblxuICAgIGxldCBvcmlnaW46IFBvaW50O1xuXG4gICAgY29uc3QgYXJyb3dXaWR0aCA9IDE0O1xuICAgIGNvbnN0IGhhbGZBcnJvd1dpZHRoID0gYXJyb3dXaWR0aCAvIDI7XG4gICAgY29uc3QgaGFsZlRyaWdnZXJXaWR0aCA9IHRyaWdnZXJSZWN0LndpZHRoIC8gMjtcbiAgICBjb25zdCBoYWxmVHJpZ2dlckhlaWdodCA9IHRyaWdnZXJSZWN0LmhlaWdodCAvIDI7XG4gICAgY29uc3QgaGFsZkNvbnRlbnRXaWR0aCA9IGNvbnRlbnRTaXplLndpZHRoIC8gMjtcbiAgICBjb25zdCBoYWxmQ29udGVudEhlaWdodCA9IGNvbnRlbnRTaXplLmhlaWdodCAvIDI7XG5cbiAgICBjb25zdCB0b3AgPSB0cmlnZ2VyUmVjdC50b3A7XG4gICAgY29uc3QgbGVmdCA9IHRyaWdnZXJSZWN0LmxlZnQ7XG5cbiAgICBsZXQgYWxpZ25YID0gbGVmdCArIGhhbGZUcmlnZ2VyV2lkdGggLSBoYWxmQ29udGVudFdpZHRoICsgYWxpZ25PZmZzZXQ7XG4gICAgaWYgKGFsaWduID09PSAnc3RhcnQnKSBhbGlnblggPSBsZWZ0ICsgYWxpZ25PZmZzZXQ7XG4gICAgaWYgKGFsaWduID09PSAnZW5kJylcbiAgICAgIGFsaWduWCA9IGxlZnQgKyB0cmlnZ2VyUmVjdC53aWR0aCAtIGNvbnRlbnRSZWN0LndpZHRoICsgYWxpZ25PZmZzZXQ7XG5cbiAgICBsZXQgYWxpZ25ZID0gdG9wICsgaGFsZlRyaWdnZXJIZWlnaHQgLSBoYWxmQ29udGVudEhlaWdodCArIGFsaWduT2Zmc2V0O1xuICAgIGlmIChhbGlnbiA9PT0gJ3N0YXJ0JykgYWxpZ25ZID0gdG9wICsgYWxpZ25PZmZzZXQ7XG4gICAgaWYgKGFsaWduID09PSAnZW5kJylcbiAgICAgIGFsaWduWSA9IHRvcCArIHRyaWdnZXJSZWN0LmhlaWdodCAtIGNvbnRlbnRSZWN0LmhlaWdodCArIGFsaWduT2Zmc2V0O1xuXG4gICAgc3dpdGNoIChhcHBsaWVkU2lkZSkge1xuICAgICAgY2FzZSAndG9wJzpcbiAgICAgICAgb3JpZ2luID0ge1xuICAgICAgICAgIHg6IGFsaWduWCxcbiAgICAgICAgICB5OiB0b3AgLSBjb250ZW50UmVjdC5oZWlnaHQgLSBzaWRlT2Zmc2V0LFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3JpZ2h0JzpcbiAgICAgICAgb3JpZ2luID0ge1xuICAgICAgICAgIHg6IGxlZnQgKyB0cmlnZ2VyUmVjdC53aWR0aCArIHNpZGVPZmZzZXQsXG4gICAgICAgICAgeTogYWxpZ25ZLFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgIG9yaWdpbiA9IHtcbiAgICAgICAgICB4OiBhbGlnblgsXG4gICAgICAgICAgeTogdG9wICsgdHJpZ2dlclJlY3QuaGVpZ2h0ICsgc2lkZU9mZnNldCxcbiAgICAgICAgfTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgb3JpZ2luID0ge1xuICAgICAgICAgIHg6IGxlZnQgLSBjb250ZW50UmVjdC53aWR0aCAtIHNpZGVPZmZzZXQsXG4gICAgICAgICAgeTogYWxpZ25ZLFxuICAgICAgICB9O1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgY29uc3QgX2V4aGF1c3RpdmU6IG5ldmVyID0gYXBwbGllZFNpZGU7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5rbm93biBzaWRlOiAke1N0cmluZyhfZXhoYXVzdGl2ZSl9YCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3Qgdmlld3BvcnRXaWR0aCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRXaWR0aDtcbiAgICBjb25zdCB2aWV3cG9ydEhlaWdodCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQ7XG5cbiAgICBjb25zdCBpc09mZnNjcmVlbkxlZnQgPSBvcmlnaW4ueCA8IDA7XG4gICAgY29uc3QgaXNPZmZzY3JlZW5SaWdodCA9IG9yaWdpbi54ICsgY29udGVudFJlY3Qud2lkdGggPiB2aWV3cG9ydFdpZHRoO1xuICAgIGNvbnN0IGlzT2Zmc2NyZWVuVG9wID0gb3JpZ2luLnkgPCAwO1xuICAgIGNvbnN0IGlzT2Zmc2NyZWVuQm90dG9tID0gb3JpZ2luLnkgKyBjb250ZW50UmVjdC5oZWlnaHQgPiB2aWV3cG9ydEhlaWdodDtcblxuICAgIGlmICghc2lkZU92ZXJyaWRlKSB7XG4gICAgICBjb25zdCBzcGFjZUFib3ZlID0gdG9wO1xuICAgICAgY29uc3Qgc3BhY2VCZWxvdyA9IHZpZXdwb3J0SGVpZ2h0IC0gKHRvcCArIHRyaWdnZXJSZWN0LmhlaWdodCk7XG4gICAgICBjb25zdCBzcGFjZUxlZnQgPSBsZWZ0O1xuICAgICAgY29uc3Qgc3BhY2VSaWdodCA9IHZpZXdwb3J0V2lkdGggLSAobGVmdCArIHRyaWdnZXJSZWN0LndpZHRoKTtcblxuICAgICAgaWYgKHNpZGUgPT09ICd0b3AnICYmIGlzT2Zmc2NyZWVuVG9wICYmIHNwYWNlQmVsb3cgPiBzcGFjZUFib3ZlKSB7XG4gICAgICAgIHJldHVybiBjb21wdXRlQm91bmRzKCdib3R0b20nKTtcbiAgICAgIH1cbiAgICAgIGlmIChzaWRlID09PSAnYm90dG9tJyAmJiBpc09mZnNjcmVlbkJvdHRvbSAmJiBzcGFjZUFib3ZlID4gc3BhY2VCZWxvdykge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUJvdW5kcygndG9wJyk7XG4gICAgICB9XG5cbiAgICAgIGlmIChzaWRlID09PSAncmlnaHQnICYmIGlzT2Zmc2NyZWVuUmlnaHQgJiYgc3BhY2VMZWZ0ID4gc3BhY2VSaWdodCkge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUJvdW5kcygnbGVmdCcpO1xuICAgICAgfVxuICAgICAgaWYgKHNpZGUgPT09ICdsZWZ0JyAmJiBpc09mZnNjcmVlbkxlZnQgJiYgc3BhY2VSaWdodCA+IHNwYWNlTGVmdCkge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUJvdW5kcygncmlnaHQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAoc2lkZSA9PT0gJ3RvcCcgfHwgc2lkZSA9PT0gJ2JvdHRvbScpICYmXG4gICAgICAgIGlzT2Zmc2NyZWVuTGVmdCAmJlxuICAgICAgICBzcGFjZVJpZ2h0ID4gY29udGVudFJlY3Qud2lkdGhcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUJvdW5kcygncmlnaHQnKTtcbiAgICAgIH1cbiAgICAgIGlmIChcbiAgICAgICAgKHNpZGUgPT09ICd0b3AnIHx8IHNpZGUgPT09ICdib3R0b20nKSAmJlxuICAgICAgICBpc09mZnNjcmVlblJpZ2h0ICYmXG4gICAgICAgIHNwYWNlTGVmdCA+IGNvbnRlbnRSZWN0LndpZHRoXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIGNvbXB1dGVCb3VuZHMoJ2xlZnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKFxuICAgICAgICAoc2lkZSA9PT0gJ2xlZnQnIHx8IHNpZGUgPT09ICdyaWdodCcpICYmXG4gICAgICAgIGlzT2Zmc2NyZWVuVG9wICYmXG4gICAgICAgIHNwYWNlQmVsb3cgPiBjb250ZW50UmVjdC5oZWlnaHRcbiAgICAgICkge1xuICAgICAgICByZXR1cm4gY29tcHV0ZUJvdW5kcygnYm90dG9tJyk7XG4gICAgICB9XG4gICAgICBpZiAoXG4gICAgICAgIChzaWRlID09PSAnbGVmdCcgfHwgc2lkZSA9PT0gJ3JpZ2h0JykgJiZcbiAgICAgICAgaXNPZmZzY3JlZW5Cb3R0b20gJiZcbiAgICAgICAgc3BhY2VBYm92ZSA+IGNvbnRlbnRSZWN0LmhlaWdodFxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiBjb21wdXRlQm91bmRzKCd0b3AnKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCB2aWV3cG9ydFBhZGRpbmcgPSA4O1xuICAgIGlmIChhcHBsaWVkU2lkZSA9PT0gJ2xlZnQnIHx8IGFwcGxpZWRTaWRlID09PSAncmlnaHQnKSB7XG4gICAgICBvcmlnaW4ueSA9IE1hdGgubWF4KFxuICAgICAgICB2aWV3cG9ydFBhZGRpbmcsXG4gICAgICAgIE1hdGgubWluKFxuICAgICAgICAgIG9yaWdpbi55LFxuICAgICAgICAgIHZpZXdwb3J0SGVpZ2h0IC0gY29udGVudFNpemUuaGVpZ2h0IC0gdmlld3BvcnRQYWRkaW5nXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG9yaWdpbi54ID0gTWF0aC5tYXgoXG4gICAgICAgIHZpZXdwb3J0UGFkZGluZyxcbiAgICAgICAgTWF0aC5taW4ob3JpZ2luLngsIHZpZXdwb3J0V2lkdGggLSBjb250ZW50U2l6ZS53aWR0aCAtIHZpZXdwb3J0UGFkZGluZylcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gQWx3YXlzIGNvbnN0cmFpbiBZIHBvc2l0aW9uIHdpdGhpbiB2aWV3cG9ydCBib3VuZHNcbiAgICBvcmlnaW4ueSA9IE1hdGgubWF4KFxuICAgICAgdmlld3BvcnRQYWRkaW5nLFxuICAgICAgTWF0aC5taW4ob3JpZ2luLnksIHZpZXdwb3J0SGVpZ2h0IC0gY29udGVudFNpemUuaGVpZ2h0IC0gdmlld3BvcnRQYWRkaW5nKVxuICAgICk7XG5cbiAgICBjb25zdCB0cmlnZ2VyQ2VudGVyWCA9IGxlZnQgKyBoYWxmVHJpZ2dlcldpZHRoO1xuICAgIGNvbnN0IHRyaWdnZXJDZW50ZXJZID0gdG9wICsgaGFsZlRyaWdnZXJIZWlnaHQ7XG4gICAgY29uc3QgY2FyZENlbnRlclggPSBvcmlnaW4ueCArIGNvbnRlbnRTaXplLndpZHRoIC8gMjtcbiAgICBjb25zdCBjYXJkQ2VudGVyWSA9IG9yaWdpbi55ICsgY29udGVudFNpemUuaGVpZ2h0IC8gMjtcblxuICAgIGxldCBhcnJvd09mZnNldFggPSB0cmlnZ2VyQ2VudGVyWCAtIGNhcmRDZW50ZXJYO1xuICAgIGxldCBhcnJvd09mZnNldFkgPSB0cmlnZ2VyQ2VudGVyWSAtIGNhcmRDZW50ZXJZO1xuXG4gICAgLy8gQ2xhbXAgYXJyb3cgb2Zmc2V0IHRvIGVuc3VyZSBpdCBzdGF5cyB3aXRoaW4gY2FyZCBib3VuZGFyaWVzLlxuICAgIC8vIEFycm93IHNob3VsZCBiZSBhdCBsZWFzdCBoYWxmQXJyb3dXaWR0aCAoN3B4KSBmcm9tIHRoZSBjYXJkIGVkZ2VzLlxuICAgIGNvbnN0IG1heEFycm93T2Zmc2V0WCA9IGhhbGZDb250ZW50V2lkdGggLSBoYWxmQXJyb3dXaWR0aDtcbiAgICBjb25zdCBtYXhBcnJvd09mZnNldFkgPSBoYWxmQ29udGVudEhlaWdodCAtIGhhbGZBcnJvd1dpZHRoO1xuXG4gICAgaWYgKGFwcGxpZWRTaWRlID09PSAndG9wJyB8fCBhcHBsaWVkU2lkZSA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIGFycm93T2Zmc2V0WCA9IE1hdGgubWF4KFxuICAgICAgICAtbWF4QXJyb3dPZmZzZXRYLFxuICAgICAgICBNYXRoLm1pbihhcnJvd09mZnNldFgsIG1heEFycm93T2Zmc2V0WClcbiAgICAgICk7XG4gICAgfVxuXG4gICAgaWYgKGFwcGxpZWRTaWRlID09PSAnbGVmdCcgfHwgYXBwbGllZFNpZGUgPT09ICdyaWdodCcpIHtcbiAgICAgIGFycm93T2Zmc2V0WSA9IE1hdGgubWF4KFxuICAgICAgICAtbWF4QXJyb3dPZmZzZXRZLFxuICAgICAgICBNYXRoLm1pbihhcnJvd09mZnNldFksIG1heEFycm93T2Zmc2V0WSlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgY29uc3QgYXJyb3dPZmZzZXQgPSB7XG4gICAgICB4OiBhcnJvd09mZnNldFgsXG4gICAgICB5OiBhcnJvd09mZnNldFksXG4gICAgfTtcblxuICAgIHJldHVybiB7IG9yaWdpbiwgY29udGVudFNpemUsIHNpZGU6IGFwcGxpZWRTaWRlLCBhcnJvd09mZnNldCB9O1xuICB9XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB1cGRhdGVCb3VuZHMsIHRydWUpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdyZXNpemUnLCB1cGRhdGVCb3VuZHMpO1xuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdzY3JvbGwnLCB1cGRhdGVCb3VuZHMsIHRydWUpO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIHVwZGF0ZUJvdW5kcyk7XG4gICAgfTtcbiAgfSwgW10pO1xuXG4gIGZ1bmN0aW9uIHJlc2V0RGVzdHJ1Y3RpdmVUaW1lb3V0cygpOiB2b2lkIHtcbiAgICBpZiAoYWN0aXZlVGltZW91dC5jdXJyZW50KSBjbGVhclRpbWVvdXQoYWN0aXZlVGltZW91dC5jdXJyZW50KTtcbiAgICBpZiAocGVyc2lzdGluZ1RpbWVvdXQuY3VycmVudCkgY2xlYXJUaW1lb3V0KHBlcnNpc3RpbmdUaW1lb3V0LmN1cnJlbnQpO1xuICAgIGlmIChvcGVuVGltZW91dC5jdXJyZW50KSBjbGVhclRpbWVvdXQob3BlblRpbWVvdXQuY3VycmVudCk7XG4gIH1cblxuICBmdW5jdGlvbiBhdHRlbXB0RGVhY3RpdmF0ZSgpOiB2b2lkIHtcbiAgICBpZiAoYWN0aXZlVGltZW91dC5jdXJyZW50KSBjbGVhclRpbWVvdXQoYWN0aXZlVGltZW91dC5jdXJyZW50KTtcbiAgICBhY3RpdmVUaW1lb3V0LmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmIChhY3RpdmVJZC5jdXJyZW50ICE9PSBpZCkgcmV0dXJuO1xuICAgICAgc2V0QWN0aXZlSWQobnVsbCk7XG4gICAgfSwgaW5hY3RpdmVUaW1lb3V0TXMpO1xuICB9XG5cbiAgZnVuY3Rpb24gYXR0ZW1wdFBlcnNpc3QoKTogdm9pZCB7XG4gICAgc2V0UGVyc2lzdGluZyh0cnVlKTtcbiAgICBpZiAocGVyc2lzdGluZ1RpbWVvdXQuY3VycmVudCkgY2xlYXJUaW1lb3V0KHBlcnNpc3RpbmdUaW1lb3V0LmN1cnJlbnQpO1xuICAgIHBlcnNpc3RpbmdUaW1lb3V0LmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHNldFBlcnNpc3RpbmcoZmFsc2UpO1xuICAgIH0sIFBFUlNJU1RfVElNRU9VVF9NUyk7XG4gIH1cblxuICBmdW5jdGlvbiBvbk1vdXNlRW50ZXIoKTogdm9pZCB7XG4gICAgcmVzZXREZXN0cnVjdGl2ZVRpbWVvdXRzKCk7XG4gICAgc2V0SG92ZXJlZElkKGlkKTtcbiAgICBzZXRMb2NhbEhvdmVyKHRydWUpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25Nb3VzZUxlYXZlKCk6IHZvaWQge1xuICAgIHNldExvY2FsSG92ZXIoZmFsc2UpO1xuICAgIGF0dGVtcHREZWFjdGl2YXRlKCk7XG4gICAgYXR0ZW1wdFBlcnNpc3QoKTtcbiAgfVxuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gY2xvc2UgaW5zdGFudGx5XG4gICAgaWYgKGhpZGUpIHtcbiAgICAgIHNldExvY2FsSG92ZXIoZmFsc2UpO1xuICAgICAgc2V0QWN0aXZlSWQobnVsbCk7XG4gICAgfVxuICB9LCBbaGlkZSwgc2V0QWN0aXZlSWRdKTtcblxuICBmdW5jdGlvbiBoYW5kbGVDbGljayhlOiBSZWFjdC5Nb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgLy8gQ2xvc2UgaWYgY2xpY2tpbmcgYSBsaW5rLiBXZSBhc3N1bWUgd2Ugd2FudCB0aGUgY2FyZCB0byBkaXNhcHBlYXIgaWYgbmF2aWdhdGluZy5cbiAgICBpZiAoZS50YXJnZXQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCAmJiBlLnRhcmdldC5jbG9zZXN0KCdhW2hyZWZdJykpIHtcbiAgICAgIG9uTW91c2VMZWF2ZSgpO1xuICAgIH1cbiAgfVxuXG4gIGNvbnN0IENvbXAgPSBhc0NoaWxkID8gU2xvdFJvb3QgOiAnZGl2JztcblxuICByZXR1cm4gKFxuICAgIDxDb21wXG4gICAgICBjbGFzc05hbWU9e2NuKFxuICAgICAgICAnaW5saW5lLWZsZXggY3Vyc29yLXBvaW50ZXIgZmxleC1bMF8xX2F1dG9dIG92ZXJmbG93LWhpZGRlbicsXG4gICAgICAgIGNsYXNzTmFtZVxuICAgICAgKX1cbiAgICAgIG9uTW91c2VFbnRlcj17b25Nb3VzZUVudGVyfVxuICAgICAgb25Nb3VzZUxlYXZlPXtvbk1vdXNlTGVhdmV9XG4gICAgICBvbkNsaWNrPXtoYW5kbGVDbGlja31cbiAgICAgIHJlZj17dHJpZ2dlclJlZn1cbiAgICA+XG4gICAgICA8U2xvdHRhYmxlPntjaGlsZHJlbn08L1Nsb3R0YWJsZT5cbiAgICAgIHtwb3J0YWxSZWY/LmN1cnJlbnQgJiYgKGxvY2FsSG92ZXIgfHwgcGVyc2lzdGluZylcbiAgICAgICAgPyBjcmVhdGVQb3J0YWwoXG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT17Y24oXG4gICAgICAgICAgICAgICAgJ2Fic29sdXRlIHRvcC0wIHAtMyBsZWZ0LTAgbWF4LXctbWF4IHRyYW5zaXRpb24tW3RyYW5zZm9ybSx3aWR0aCxoZWlnaHRdIGR1cmF0aW9uLTI1MCBlYXNlLVtlYXNpbmctZnVuY3Rpb246Y3ViaWMtYmV6aWVyKDAuMjksMC4zMSwwLjA1LDAuOTYpXSB3aWxsLWNoYW5nZS1bdHJhbnNmb3JtLHdpZHRoLGhlaWdodF0gbW90aW9uLXJlZHVjZTohdHJhbnNpdGlvbi1ub25lJyxcbiAgICAgICAgICAgICAgICBza2lwVHJhbnNpdGlvbiAmJiAnIXRyYW5zaXRpb24tbm9uZSdcbiAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAga2V5PXtpZH1cbiAgICAgICAgICAgICAgcmVmPXtjb250ZW50UmVmfVxuICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgIC4uLihub1BhZGRpbmcgPyB7IHBhZGRpbmc6IDAgfSA6IHt9KSxcbiAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnRzOlxuICAgICAgICAgICAgICAgICAgcm9vdFZpc2libGUgJiYgdmlzaWJsZSAmJiAhaWdub3JlQ2FyZFBvaW50ZXJFdmVudHNcbiAgICAgICAgICAgICAgICAgICAgPyAnYWxsJ1xuICAgICAgICAgICAgICAgICAgICA6ICdub25lJyxcbiAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT17Y24oXG4gICAgICAgICAgICAgICAgICAnbWluLXctbWF4IHRyYW5zaXRpb24tYWxsIGR1cmF0aW9uLTE1MCBlYXNlLVtlYXNpbmctZnVuY3Rpb246Y3ViaWMtYmV6aWVyKDAuMyxfMC41NyxfMC4wNyxfMC45NSldIHdpbGwtY2hhbmdlLVt0cmFuc2Zvcm0sd2lkdGgsaGVpZ2h0XSBtb3Rpb24tcmVkdWNlOiF0cmFuc2l0aW9uLW5vbmUnLFxuICAgICAgICAgICAgICAgICAgc2tpcFRyYW5zaXRpb25cbiAgICAgICAgICAgICAgICAgICAgPyAnIXRyYW5zaXRpb24tbm9uZSdcbiAgICAgICAgICAgICAgICAgICAgOiAndHJhbnNpdGlvbi1bdHJhbnNmb3JtLHdpZHRoLGhlaWdodF0gZHVyYXRpb24tMjUwIGVhc2UtW2Vhc2luZy1mdW5jdGlvbjpjdWJpYy1iZXppZXIoMC4yOSwwLjMxLDAuMDUsMC45NildIHdpbGwtY2hhbmdlLVt0cmFuc2Zvcm0sd2lkdGgsaGVpZ2h0XSBtb3Rpb24tcmVkdWNlOiF0cmFuc2l0aW9uLW5vbmUnXG4gICAgICAgICAgICAgICAgKX1cbiAgICAgICAgICAgICAgICByZWY9e2NvbnRlbnRNZWFzdXJlUmVmfVxuICAgICAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgICAgICBvcGFjaXR5OiBOdW1iZXIodmlzaWJsZSksXG4gICAgICAgICAgICAgICAgfX1cbiAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIHtjb250ZW50fVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PixcbiAgICAgICAgICAgIHBvcnRhbFJlZi5jdXJyZW50XG4gICAgICAgICAgKVxuICAgICAgICA6IG51bGx9XG4gICAgPC9Db21wPlxuICApO1xufVxuIl19
@@ -1,6 +1,39 @@
1
1
  import type { ReactNode } from 'react';
2
- export declare function TimestampTooltip({ date, children, }: {
2
+ import { type ContextCardTriggerProps } from './context-card';
3
+ /**
4
+ * Detailed relative time string that auto-updates every second
5
+ * (e.g. "2 hours, 15 minutes, 30 seconds ago"). Used inside the hover card.
6
+ */
7
+ export declare function useTimeAgo(date: number): string;
8
+ /**
9
+ * Short relative time string that auto-updates every minute
10
+ * (e.g. "3 days ago", "5 hours ago"). Returns an empty string if `date` is
11
+ * nullish.
12
+ */
13
+ export declare function useShortTimeAgo(date: number | null | undefined): string;
14
+ type RelativeTimeCardProps = Omit<ContextCardTriggerProps, 'content' | 'children'> & {
15
+ /** Timestamp in milliseconds to display as a relative time. */
16
+ date?: number | null;
17
+ /** Custom content to render instead of the default relative time text. */
18
+ children?: ReactNode;
19
+ };
20
+ /**
21
+ * Relative time label that reveals a context card with detailed UTC and local
22
+ * timestamps on hover. Renders a default short relative time label (e.g.
23
+ * "3 days ago") when `children` is omitted; renders just the children without
24
+ * the hover card when `date` is nullish.
25
+ */
26
+ export declare function RelativeTimeCard({ date, children: _children, ...props }: RelativeTimeCardProps): ReactNode;
27
+ /**
28
+ * Wraps an already-formatted timestamp display with a relative-time hover
29
+ * card. Self-mounts a {@link ContextCardProvider} when one isn't already
30
+ * present so it works anywhere, but shares a provider (enabling the animated
31
+ * card morph between adjacent timestamps) when rendered inside one.
32
+ */
33
+ export declare function TimestampTooltip({ date, children, side, }: {
3
34
  date: number | Date | string | null | undefined;
4
35
  children: ReactNode;
36
+ side?: ContextCardTriggerProps['side'];
5
37
  }): ReactNode;
38
+ export {};
6
39
  //# sourceMappingURL=timestamp-tooltip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"timestamp-tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/ui/timestamp-tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAiQvC,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,QAAQ,EAAE,SAAS,CAAC;CACrB,GAAG,SAAS,CA4DZ"}
1
+ {"version":3,"file":"timestamp-tooltip.d.ts","sourceRoot":"","sources":["../../../src/components/ui/timestamp-tooltip.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvC,OAAO,EAGL,KAAK,uBAAuB,EAE7B,MAAM,gBAAgB,CAAC;AAoCxB;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAgB/C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAgCvE;AAsFD,KAAK,qBAAqB,GAAG,IAAI,CAC/B,uBAAuB,EACvB,SAAS,GAAG,UAAU,CACvB,GAAG;IACF,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EAAE,SAAS,EACnB,GAAG,KAAK,EACT,EAAE,qBAAqB,GAAG,SAAS,CAcnC;AAMD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,IAAI,EACJ,QAAQ,EACR,IAAY,GACb,EAAE;IACD,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAChD,QAAQ,EAAE,SAAS,CAAC;IACpB,IAAI,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;CACxC,GAAG,SAAS,CAmBZ"}