@workflow/web-shared 5.0.0-beta.37 → 5.0.0-beta.39
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/README.md +3 -3
- package/dist/components/event-list-view.d.ts.map +1 -1
- package/dist/components/event-list-view.js +10 -10
- package/dist/components/index.d.ts +4 -5
- package/dist/components/index.d.ts.map +1 -1
- package/dist/components/index.js +4 -5
- package/dist/components/sidebar/attribute-panel.d.ts.map +1 -1
- package/dist/components/sidebar/attribute-panel.js +32 -8
- package/dist/components/sidebar/attributes-block.js +3 -3
- package/dist/components/sidebar/copyable-data-block.js +2 -2
- package/dist/components/sidebar/entity-detail-panel.js +3 -3
- package/dist/components/sidebar/events-list.js +2 -2
- package/dist/components/stream-viewer-skeleton.d.ts +2 -0
- package/dist/components/stream-viewer-skeleton.d.ts.map +1 -0
- package/dist/components/stream-viewer-skeleton.js +12 -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 +9 -26
- package/dist/components/trace-viewer/components/copy-button.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/copy-button.js +27 -0
- package/dist/components/trace-viewer/components/detail-panel-width.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/detail-panel-width.js +67 -0
- package/dist/components/trace-viewer/components/detail-panel.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/detail-panel.js +122 -0
- package/dist/components/trace-viewer/components/draggable-border.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/draggable-border.js +140 -0
- package/dist/components/trace-viewer/components/event-list.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/event-list.js +47 -0
- package/dist/components/trace-viewer/components/middle-truncate/copy-selection.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/middle-truncate/copy-selection.js +54 -0
- package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/middle-truncate/middle-truncate.js +81 -0
- package/dist/components/trace-viewer/components/middle-truncate/truncate.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/middle-truncate/truncate.js +101 -0
- package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/middle-truncate/use-middle-truncate.js +114 -0
- package/dist/components/trace-viewer/components/minimap.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/minimap.js +337 -0
- package/dist/components/trace-viewer/components/pane-constants.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/pane-constants.js +16 -0
- package/dist/components/trace-viewer/components/span-markers.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/span-markers.js +85 -0
- package/dist/components/trace-viewer/components/split-pane.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/split-pane.js +41 -0
- package/dist/components/trace-viewer/components/timeline.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/timeline.js +321 -0
- package/dist/components/trace-viewer/components/trace-shortcut-helper.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/trace-shortcut-helper.js +55 -0
- package/dist/components/trace-viewer/components/trace-viewer-skeleton.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/trace-viewer-skeleton.js +26 -0
- package/dist/components/trace-viewer/components/use-element-width.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/use-element-width.js +25 -0
- package/dist/components/trace-viewer/components/use-row-window.d.ts.map +1 -0
- package/dist/components/trace-viewer/components/use-row-window.js +107 -0
- package/dist/components/trace-viewer/context.d.ts +14 -182
- package/dist/components/trace-viewer/context.d.ts.map +1 -1
- package/dist/components/trace-viewer/context.js +44 -351
- package/dist/components/trace-viewer/icons.d.ts.map +1 -0
- package/dist/components/trace-viewer/icons.js +15 -0
- package/dist/components/trace-viewer/search.d.ts.map +1 -0
- package/dist/components/trace-viewer/search.js +134 -0
- package/dist/components/trace-viewer/trace-viewer.d.ts +7 -28
- package/dist/components/trace-viewer/trace-viewer.d.ts.map +1 -1
- package/dist/components/trace-viewer/trace-viewer.js +306 -356
- package/dist/components/trace-viewer/types.d.ts +2 -211
- package/dist/components/trace-viewer/types.d.ts.map +1 -1
- package/dist/components/trace-viewer/types.js +1 -1
- package/dist/components/trace-viewer/utils.d.ts.map +1 -0
- package/dist/components/trace-viewer/utils.js +430 -0
- package/dist/components/{trace-viewer-new.d.ts → trace-viewer.d.ts} +3 -3
- package/dist/components/trace-viewer.d.ts.map +1 -0
- package/dist/components/trace-viewer.js +21 -0
- package/dist/components/ui/alert.js +2 -2
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.d.ts.map +1 -1
- package/dist/components/ui/button.js +3 -3
- package/dist/components/ui/card.d.ts.map +1 -1
- package/dist/components/ui/card.js +3 -3
- package/dist/components/ui/error-card.js +2 -2
- package/dist/components/ui/error-stack-block.js +4 -4
- package/dist/components/ui/kbd.js +3 -3
- package/dist/components/ui/timestamp-tooltip.js +3 -3
- package/dist/components/workflow-traces/trace-span-construction.d.ts +1 -1
- package/dist/components/workflow-traces/trace-span-construction.js +1 -1
- package/dist/lib/trace-builder.d.ts +1 -1
- package/dist/lib/trace-builder.d.ts.map +1 -1
- package/dist/lib/trace-builder.js +1 -1
- package/dist/lib/trace-types.d.ts +54 -0
- package/dist/lib/trace-types.d.ts.map +1 -0
- package/dist/lib/trace-types.js +2 -0
- package/package.json +6 -6
- package/src/components/event-list-view.tsx +12 -9
- package/src/components/index.ts +4 -5
- package/src/components/sidebar/attribute-panel.tsx +46 -8
- package/src/components/sidebar/attributes-block.tsx +2 -2
- package/src/components/sidebar/copyable-data-block.tsx +1 -1
- package/src/components/sidebar/entity-detail-panel.tsx +3 -3
- package/src/components/sidebar/events-list.tsx +1 -1
- package/src/components/stream-viewer-skeleton.tsx +34 -0
- package/src/components/stream-viewer.tsx +34 -106
- package/src/components/{new-trace-viewer → trace-viewer}/components/event-list.tsx +1 -1
- package/src/components/{new-trace-viewer → trace-viewer}/components/minimap.tsx +1 -4
- package/src/components/{new-trace-viewer → trace-viewer}/components/timeline.tsx +2 -5
- package/src/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.tsx +1 -1
- package/src/components/trace-viewer/context.tsx +63 -656
- package/src/components/trace-viewer/trace-viewer.tsx +563 -531
- package/src/components/trace-viewer/types.ts +2 -234
- package/src/components/{new-trace-viewer → trace-viewer}/utils.ts +2 -2
- package/src/components/{trace-viewer-new.tsx → trace-viewer.tsx} +5 -5
- package/src/components/ui/alert.tsx +1 -1
- package/src/components/ui/button.tsx +3 -3
- package/src/components/ui/card.tsx +2 -9
- package/src/components/ui/error-card.tsx +3 -3
- package/src/components/ui/error-stack-block.tsx +3 -3
- package/src/components/ui/kbd.tsx +2 -2
- package/src/components/ui/timestamp-tooltip.tsx +4 -4
- package/src/components/workflow-traces/trace-span-construction.ts +1 -1
- package/src/lib/trace-builder.ts +1 -1
- package/src/lib/trace-types.ts +56 -0
- package/dist/components/new-trace-viewer/components/copy-button.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/copy-button.js +0 -27
- package/dist/components/new-trace-viewer/components/detail-panel-width.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/detail-panel-width.js +0 -67
- package/dist/components/new-trace-viewer/components/detail-panel.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/detail-panel.js +0 -122
- package/dist/components/new-trace-viewer/components/draggable-border.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/draggable-border.js +0 -140
- package/dist/components/new-trace-viewer/components/event-list.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/event-list.js +0 -47
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/copy-selection.js +0 -54
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/middle-truncate.js +0 -81
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/truncate.js +0 -101
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/middle-truncate/use-middle-truncate.js +0 -114
- package/dist/components/new-trace-viewer/components/minimap.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/minimap.js +0 -337
- package/dist/components/new-trace-viewer/components/pane-constants.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/pane-constants.js +0 -16
- package/dist/components/new-trace-viewer/components/span-markers.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/span-markers.js +0 -85
- package/dist/components/new-trace-viewer/components/split-pane.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/split-pane.js +0 -41
- package/dist/components/new-trace-viewer/components/timeline.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/timeline.js +0 -321
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/trace-shortcut-helper.js +0 -55
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/trace-viewer-skeleton.js +0 -26
- package/dist/components/new-trace-viewer/components/use-element-width.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/use-element-width.js +0 -25
- package/dist/components/new-trace-viewer/components/use-row-window.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/components/use-row-window.js +0 -107
- package/dist/components/new-trace-viewer/context.d.ts +0 -17
- package/dist/components/new-trace-viewer/context.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/context.js +0 -48
- package/dist/components/new-trace-viewer/icons.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/icons.js +0 -15
- package/dist/components/new-trace-viewer/search.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/search.js +0 -134
- package/dist/components/new-trace-viewer/trace-viewer.d.ts +0 -11
- package/dist/components/new-trace-viewer/trace-viewer.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/trace-viewer.js +0 -336
- package/dist/components/new-trace-viewer/types.d.ts +0 -3
- package/dist/components/new-trace-viewer/types.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/types.js +0 -2
- package/dist/components/new-trace-viewer/utils.d.ts.map +0 -1
- package/dist/components/new-trace-viewer/utils.js +0 -430
- package/dist/components/run-trace-view.d.ts +0 -23
- package/dist/components/run-trace-view.d.ts.map +0 -1
- package/dist/components/run-trace-view.js +0 -11
- package/dist/components/trace-viewer/components/map.d.ts +0 -8
- package/dist/components/trace-viewer/components/map.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/map.js +0 -162
- package/dist/components/trace-viewer/components/markers.d.ts +0 -23
- package/dist/components/trace-viewer/components/markers.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/markers.js +0 -416
- package/dist/components/trace-viewer/components/node.d.ts +0 -35
- package/dist/components/trace-viewer/components/node.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/node.js +0 -286
- package/dist/components/trace-viewer/components/search-input.d.ts +0 -9
- package/dist/components/trace-viewer/components/search-input.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/search-input.js +0 -9
- package/dist/components/trace-viewer/components/search.d.ts +0 -3
- package/dist/components/trace-viewer/components/search.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/search.js +0 -25
- package/dist/components/trace-viewer/components/span-content.d.ts +0 -19
- package/dist/components/trace-viewer/components/span-content.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/span-content.js +0 -137
- package/dist/components/trace-viewer/components/span-detail-panel.d.ts +0 -10
- package/dist/components/trace-viewer/components/span-detail-panel.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/span-detail-panel.js +0 -285
- package/dist/components/trace-viewer/components/span-segments.d.ts +0 -50
- package/dist/components/trace-viewer/components/span-segments.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/span-segments.js +0 -445
- package/dist/components/trace-viewer/components/span-strategies.d.ts +0 -46
- package/dist/components/trace-viewer/components/span-strategies.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/span-strategies.js +0 -108
- package/dist/components/trace-viewer/components/ui.d.ts +0 -28
- package/dist/components/trace-viewer/components/ui.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/ui.js +0 -39
- package/dist/components/trace-viewer/components/zoom-button.d.ts +0 -3
- package/dist/components/trace-viewer/components/zoom-button.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/zoom-button.js +0 -29
- package/dist/components/trace-viewer/components/zoom-icons.d.ts +0 -11
- package/dist/components/trace-viewer/components/zoom-icons.d.ts.map +0 -1
- package/dist/components/trace-viewer/components/zoom-icons.js +0 -11
- package/dist/components/trace-viewer/index.d.ts +0 -5
- package/dist/components/trace-viewer/index.d.ts.map +0 -1
- package/dist/components/trace-viewer/index.js +0 -4
- package/dist/components/trace-viewer/trace-viewer.module.css +0 -1465
- package/dist/components/trace-viewer/util/constants.d.ts +0 -9
- package/dist/components/trace-viewer/util/constants.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/constants.js +0 -9
- package/dist/components/trace-viewer/util/scrollbar-width.d.ts +0 -2
- package/dist/components/trace-viewer/util/scrollbar-width.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/scrollbar-width.js +0 -14
- package/dist/components/trace-viewer/util/tree.d.ts +0 -13
- package/dist/components/trace-viewer/util/tree.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/tree.js +0 -227
- package/dist/components/trace-viewer/util/use-immediate-style.d.ts +0 -15
- package/dist/components/trace-viewer/util/use-immediate-style.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/use-immediate-style.js +0 -23
- package/dist/components/trace-viewer/util/use-streaming-spans.d.ts +0 -8
- package/dist/components/trace-viewer/util/use-streaming-spans.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/use-streaming-spans.js +0 -345
- package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts +0 -6
- package/dist/components/trace-viewer/util/use-trackpad-zoom.d.ts.map +0 -1
- package/dist/components/trace-viewer/util/use-trackpad-zoom.js +0 -39
- package/dist/components/trace-viewer/worker.d.ts +0 -2
- package/dist/components/trace-viewer/worker.d.ts.map +0 -1
- package/dist/components/trace-viewer/worker.js +0 -109
- package/dist/components/trace-viewer-new.d.ts.map +0 -1
- package/dist/components/trace-viewer-new.js +0 -21
- package/dist/components/workflow-trace-view.d.ts +0 -39
- package/dist/components/workflow-trace-view.d.ts.map +0 -1
- package/dist/components/workflow-trace-view.js +0 -690
- package/dist/components/workflow-traces/trace-colors.d.ts +0 -15
- package/dist/components/workflow-traces/trace-colors.d.ts.map +0 -1
- package/dist/components/workflow-traces/trace-colors.js +0 -86
- package/src/components/new-trace-viewer/context.tsx +0 -93
- package/src/components/new-trace-viewer/trace-viewer.tsx +0 -632
- package/src/components/new-trace-viewer/types.ts +0 -2
- package/src/components/run-trace-view.tsx +0 -80
- package/src/components/trace-viewer/components/map.tsx +0 -226
- package/src/components/trace-viewer/components/markers.tsx +0 -612
- package/src/components/trace-viewer/components/node.tsx +0 -506
- package/src/components/trace-viewer/components/search-input.tsx +0 -52
- package/src/components/trace-viewer/components/search.tsx +0 -47
- package/src/components/trace-viewer/components/span-content.tsx +0 -247
- package/src/components/trace-viewer/components/span-detail-panel.tsx +0 -655
- package/src/components/trace-viewer/components/span-segments.ts +0 -585
- package/src/components/trace-viewer/components/span-strategies.ts +0 -205
- package/src/components/trace-viewer/components/ui.tsx +0 -156
- package/src/components/trace-viewer/components/zoom-button.tsx +0 -61
- package/src/components/trace-viewer/components/zoom-icons.tsx +0 -65
- package/src/components/trace-viewer/index.tsx +0 -4
- package/src/components/trace-viewer/trace-viewer.module.css +0 -1465
- package/src/components/trace-viewer/util/constants.ts +0 -8
- package/src/components/trace-viewer/util/scrollbar-width.ts +0 -13
- package/src/components/trace-viewer/util/tree.ts +0 -277
- package/src/components/trace-viewer/util/use-immediate-style.ts +0 -38
- package/src/components/trace-viewer/util/use-streaming-spans.ts +0 -426
- package/src/components/trace-viewer/util/use-trackpad-zoom.tsx +0 -51
- package/src/components/trace-viewer/worker.ts +0 -131
- package/src/components/workflow-trace-view.tsx +0 -1166
- package/src/components/workflow-traces/trace-colors.ts +0 -112
- package/dist/components/{new-trace-viewer → trace-viewer}/components/copy-button.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/detail-panel.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/draggable-border.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/event-list.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/minimap.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/pane-constants.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/span-markers.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/split-pane.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/timeline.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/timeline.module.css +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.module.css +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/trace-viewer-skeleton.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/use-element-width.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/components/use-row-window.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/icons.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/search.d.ts +0 -0
- package/dist/components/{new-trace-viewer → trace-viewer}/utils.d.ts +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/copy-button.tsx +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.test.ts +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel-width.ts +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/detail-panel.tsx +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/draggable-border.tsx +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/copy-selection.ts +0 -0
- package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/middle-truncate.tsx +1 -1
- /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/truncate.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/middle-truncate/use-middle-truncate.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/pane-constants.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/span-markers.tsx +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/split-pane.tsx +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/timeline.module.css +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/trace-shortcut-helper.module.css +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/trace-viewer-skeleton.tsx +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/use-element-width.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/components/use-row-window.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/icons.tsx +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/search.ts +0 -0
- /package/src/components/{new-trace-viewer → trace-viewer}/utils.test.ts +0 -0
- /package/src/{components/trace-viewer/modules.d.ts → modules.d.ts} +0 -0
|
@@ -1,386 +1,336 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
4
|
-
import { useCallback, useEffect,
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
status: {
|
|
35
|
-
code: 1,
|
|
36
|
-
},
|
|
37
|
-
attributes: {
|
|
38
|
-
'vercel.ownerId': 'team_abc',
|
|
39
|
-
},
|
|
40
|
-
traceFlags: 1,
|
|
41
|
-
events: [],
|
|
42
|
-
links: [],
|
|
43
|
-
},
|
|
44
|
-
],
|
|
45
|
-
resources: [
|
|
46
|
-
{
|
|
47
|
-
name: 'vercel.runtime',
|
|
48
|
-
attributes: {},
|
|
49
|
-
},
|
|
50
|
-
],
|
|
51
|
-
rootSpanId: 'root',
|
|
52
|
-
};
|
|
53
|
-
export function TraceViewerTimeline({ trace = skeletonTrace, className = '', scrollLock = false, height, withPanel = false, highlightedSpans, eagerRender = false, isLive = false, footer, knownDurationMs, hasMoreData = false, }) {
|
|
54
|
-
const isSkeleton = trace === skeletonTrace;
|
|
55
|
-
const { state, dispatch } = useTraceViewer();
|
|
56
|
-
const { timelineRef, scrollSnapshotRef } = state;
|
|
57
|
-
const memoCache = state.memoCacheRef.current;
|
|
58
|
-
const hideSearchBar = (highlightedSpans?.length ?? 0) > 0;
|
|
59
|
-
const hasInitializedRef = useRef(false);
|
|
60
|
-
const prevSpanKeyRef = useRef('');
|
|
61
|
-
const prevRootRef = useRef(null);
|
|
62
|
-
const prevSpanMapRef = useRef({});
|
|
63
|
-
const prevSizeRef = useRef(null);
|
|
64
|
-
useEffect(() => {
|
|
65
|
-
const { root: newRoot, map: newSpanMap } = parseTrace(trace);
|
|
66
|
-
const isInitial = !hasInitializedRef.current;
|
|
67
|
-
hasInitializedRef.current = true;
|
|
68
|
-
// Build a structural key from span IDs + lightweight event signatures.
|
|
69
|
-
// When only timing changes (same spans and boundary events), we can skip the
|
|
70
|
-
// worker restart. When events change (step completed, etc.) we need a
|
|
71
|
-
// full update because the VisibleSpan objects rendered by React hold
|
|
72
|
-
// copies of the events from the worker — in-place mutation won't reach them.
|
|
73
|
-
const spanKey = Object.keys(newSpanMap)
|
|
74
|
-
.sort()
|
|
75
|
-
.map((id) => {
|
|
76
|
-
const events = newSpanMap[id].events;
|
|
77
|
-
const count = events?.length ?? 0;
|
|
78
|
-
const first = count ? events?.[0] : undefined;
|
|
79
|
-
const last = count ? events?.[count - 1] : undefined;
|
|
80
|
-
const eventSignature = `${first?.event.name ?? 'none'}@${first?.timestamp ?? 0}|${last?.event.name ?? 'none'}@${last?.timestamp ?? 0}`;
|
|
81
|
-
return `${id}:${count}:${eventSignature}`;
|
|
82
|
-
})
|
|
83
|
-
.join(',');
|
|
84
|
-
if (!isInitial &&
|
|
85
|
-
spanKey === prevSpanKeyRef.current &&
|
|
86
|
-
prevRootRef.current) {
|
|
87
|
-
// Same span set, same event counts — only timing changed.
|
|
88
|
-
// Mutate in-place so the worker effect (which depends on root/spanMap
|
|
89
|
-
// references) does NOT restart.
|
|
90
|
-
const oldRoot = prevRootRef.current;
|
|
91
|
-
const oldSpanMap = prevSpanMapRef.current;
|
|
92
|
-
let didChange = false;
|
|
93
|
-
if (oldRoot.endTime !== newRoot.endTime ||
|
|
94
|
-
oldRoot.duration !== newRoot.duration) {
|
|
95
|
-
oldRoot.endTime = newRoot.endTime;
|
|
96
|
-
oldRoot.duration = newRoot.duration;
|
|
97
|
-
didChange = true;
|
|
98
|
-
}
|
|
99
|
-
for (const [id, newNode] of Object.entries(newSpanMap)) {
|
|
100
|
-
const oldNode = oldSpanMap[id];
|
|
101
|
-
if (oldNode) {
|
|
102
|
-
if (oldNode.endTime !== newNode.endTime ||
|
|
103
|
-
oldNode.duration !== newNode.duration) {
|
|
104
|
-
oldNode.endTime = newNode.endTime;
|
|
105
|
-
oldNode.duration = newNode.duration;
|
|
106
|
-
didChange = true;
|
|
107
|
-
}
|
|
108
|
-
Object.assign(oldNode.span, newNode.span);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (!didChange) {
|
|
112
|
-
return;
|
|
113
|
-
}
|
|
114
|
-
// Trigger re-render (scale/markers) without restarting the worker.
|
|
115
|
-
// useLiveTick handles continuous scale recalculation for live runs.
|
|
116
|
-
dispatch({ type: 'forceRender' });
|
|
117
|
-
return;
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { RotateCcw, Search, ZoomIn, ZoomOut } from 'lucide-react';
|
|
4
|
+
import { useCallback, useDeferredValue, useEffect, useMemo, useRef, useState, } from 'react';
|
|
5
|
+
import { useLoadMoreOnScroll } from '../../hooks/use-load-more-on-scroll';
|
|
6
|
+
import { useReducedMotion } from '../../hooks/use-reduced-motion';
|
|
7
|
+
import { IconButton } from '../ui/icon-button';
|
|
8
|
+
import { Kbd } from '../ui/kbd';
|
|
9
|
+
import { Spinner } from '../ui/spinner';
|
|
10
|
+
import { TooltipProvider } from '../ui/tooltip';
|
|
11
|
+
import { TraceDetailPanel } from './components/detail-panel';
|
|
12
|
+
import EventList from './components/event-list';
|
|
13
|
+
import { Minimap } from './components/minimap';
|
|
14
|
+
import { SplitPane } from './components/split-pane';
|
|
15
|
+
import { TIMELINE_PADDING_PX, Timeline, TimelineHeader, } from './components/timeline';
|
|
16
|
+
import { TraceShortcutHelper } from './components/trace-shortcut-helper';
|
|
17
|
+
import { ROW_HEIGHT_PX, scrollRowIntoView } from './components/use-row-window';
|
|
18
|
+
import { ActiveSpanProvider, useActiveSpan } from './context';
|
|
19
|
+
import { searchSpans } from './search';
|
|
20
|
+
import { formatDurationPrecise, getHighResInMs } from './util/timing';
|
|
21
|
+
import { clampViewportToRoot, computeRootBounds, computeTimeMarkers, wheelDeltaToPixels, wheelZoomScaleFactor, } from './utils';
|
|
22
|
+
const MIN_VIEWPORT_MS = 0.001;
|
|
23
|
+
const ZOOM_DEBOUNCE_MS = 150;
|
|
24
|
+
function useAnimatedViewport(initial) {
|
|
25
|
+
const [viewport, setViewportState] = useState(initial);
|
|
26
|
+
const animRef = useRef(null);
|
|
27
|
+
const currentRef = useRef(initial);
|
|
28
|
+
currentRef.current = viewport;
|
|
29
|
+
const reducedMotion = useReducedMotion();
|
|
30
|
+
const cancel = useCallback(() => {
|
|
31
|
+
if (animRef.current) {
|
|
32
|
+
cancelAnimationFrame(animRef.current.raf);
|
|
33
|
+
animRef.current = null;
|
|
118
34
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
root: newRoot,
|
|
126
|
-
spanMap: newSpanMap,
|
|
127
|
-
resources: trace.resources || [],
|
|
128
|
-
});
|
|
129
|
-
}, [dispatch, trace]);
|
|
130
|
-
const { rows, spans, events, scale } = useStreamingSpans(highlightedSpans, eagerRender);
|
|
131
|
-
const ref = useRef(null);
|
|
132
|
-
useLayoutEffect(() => {
|
|
133
|
-
const $el = ref.current;
|
|
134
|
-
if (!$el)
|
|
35
|
+
}, []);
|
|
36
|
+
const animateTo = useCallback((target) => {
|
|
37
|
+
cancel();
|
|
38
|
+
if (reducedMotion) {
|
|
39
|
+
currentRef.current = target;
|
|
40
|
+
setViewportState(target);
|
|
135
41
|
return;
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
prevSizeRef.current = { width: nextWidth, height: nextHeight };
|
|
148
|
-
dispatch({
|
|
149
|
-
type: 'setSize',
|
|
150
|
-
width: nextWidth,
|
|
151
|
-
height: nextHeight,
|
|
42
|
+
}
|
|
43
|
+
const from = currentRef.current;
|
|
44
|
+
const anim = { raf: 0, from, to: target, start: performance.now() };
|
|
45
|
+
const tick = () => {
|
|
46
|
+
const t = Math.min((performance.now() - anim.start) / 240, 1);
|
|
47
|
+
const e = t < 0.5 ? 8 * t * t * t * t : 1 - (-2 * t + 2) ** 4 / 2;
|
|
48
|
+
setViewportState({
|
|
49
|
+
start: anim.from.start + (anim.to.start - anim.from.start) * e,
|
|
50
|
+
end: anim.from.end + (anim.to.end - anim.from.end) * e,
|
|
152
51
|
});
|
|
52
|
+
if (t < 1)
|
|
53
|
+
anim.raf = requestAnimationFrame(tick);
|
|
54
|
+
else
|
|
55
|
+
animRef.current = null;
|
|
153
56
|
};
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
57
|
+
animRef.current = anim;
|
|
58
|
+
anim.raf = requestAnimationFrame(tick);
|
|
59
|
+
}, [cancel, reducedMotion]);
|
|
60
|
+
const setViewport = useCallback((update) => {
|
|
61
|
+
cancel();
|
|
62
|
+
if (typeof update === 'function') {
|
|
63
|
+
setViewportState((prev) => {
|
|
64
|
+
const next = update(prev);
|
|
65
|
+
currentRef.current = next;
|
|
66
|
+
return next;
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
currentRef.current = update;
|
|
71
|
+
setViewportState(update);
|
|
72
|
+
}
|
|
73
|
+
}, [cancel]);
|
|
74
|
+
useEffect(() => cancel, [cancel]);
|
|
75
|
+
return { viewport, setViewport, animateTo };
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// Root component
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
export function TraceViewer({ trace, onLoadMore, hasMore, isLoadingMore, }) {
|
|
81
|
+
return (_jsx(TooltipProvider, { delayDuration: 300, children: _jsx(ActiveSpanProvider, { spans: trace.spans, children: _jsx(TraceViewerContent, { trace: trace, onLoadMore: onLoadMore, hasMore: hasMore, isLoadingMore: isLoadingMore }) }) }));
|
|
82
|
+
}
|
|
83
|
+
function TraceViewerContent({ trace, onLoadMore, hasMore, isLoadingMore, }) {
|
|
84
|
+
const { activeSpanId, setActiveSpan, clearActiveSpan } = useActiveSpan();
|
|
85
|
+
const reducedMotion = useReducedMotion();
|
|
86
|
+
const [searchQuery, setSearchQuery] = useState('');
|
|
87
|
+
const deferredSearchQuery = useDeferredValue(searchQuery);
|
|
88
|
+
const paneRootRef = useRef(null);
|
|
89
|
+
const searchResult = useMemo(() => searchSpans(trace.spans, deferredSearchQuery), [trace.spans, deferredSearchQuery]);
|
|
90
|
+
const root = useMemo(() => computeRootBounds(trace.spans), [trace.spans]);
|
|
91
|
+
const scrollContainerRef = useRef(null);
|
|
92
|
+
const loadMore = useCallback(() => {
|
|
93
|
+
void onLoadMore?.();
|
|
94
|
+
}, [onLoadMore]);
|
|
95
|
+
const loadMoreSentinelRef = useLoadMoreOnScroll(loadMore, {
|
|
96
|
+
hasMore: Boolean(onLoadMore && hasMore),
|
|
97
|
+
isLoadingMore: Boolean(isLoadingMore),
|
|
98
|
+
rootRef: scrollContainerRef,
|
|
168
99
|
});
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
});
|
|
187
|
-
return;
|
|
100
|
+
const { viewport, setViewport, animateTo } = useAnimatedViewport({
|
|
101
|
+
start: root.startTime,
|
|
102
|
+
end: root.startTime + root.duration,
|
|
103
|
+
});
|
|
104
|
+
const prevRootRef = useRef({
|
|
105
|
+
start: root.startTime,
|
|
106
|
+
end: root.startTime + root.duration,
|
|
107
|
+
});
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
const prevRoot = prevRootRef.current;
|
|
110
|
+
const newStart = root.startTime;
|
|
111
|
+
const newEnd = root.startTime + root.duration;
|
|
112
|
+
setViewport((prev) => {
|
|
113
|
+
const wasAtFullExtent = Math.abs(prev.start - prevRoot.start) < 0.01 &&
|
|
114
|
+
Math.abs(prev.end - prevRoot.end) < 0.01;
|
|
115
|
+
if (wasAtFullExtent) {
|
|
116
|
+
return { start: newStart, end: newEnd };
|
|
188
117
|
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
118
|
+
return prev;
|
|
119
|
+
});
|
|
120
|
+
prevRootRef.current = { start: newStart, end: newEnd };
|
|
121
|
+
}, [root.startTime, root.duration, setViewport]);
|
|
122
|
+
const viewDuration = viewport.end - viewport.start;
|
|
123
|
+
// Keep a ref to the live viewport so zoom callbacks can read the current
|
|
124
|
+
// range without being recreated on every pan (which would bust TimelineBar's
|
|
125
|
+
// memo and re-render every row each animation frame).
|
|
126
|
+
const viewportRef = useRef(viewport);
|
|
127
|
+
viewportRef.current = viewport;
|
|
128
|
+
const timeMarkers = useMemo(() => computeTimeMarkers(viewDuration, viewport.start - root.startTime), [viewDuration, viewport.start, root.startTime]);
|
|
129
|
+
const resetZoom = useCallback(() => {
|
|
130
|
+
animateTo({ start: root.startTime, end: root.startTime + root.duration });
|
|
131
|
+
}, [animateTo, root.startTime, root.duration]);
|
|
132
|
+
const clampToRoot = useCallback((next) => clampViewportToRoot(next, root.startTime, root.endTime, MIN_VIEWPORT_MS), [root.startTime, root.endTime]);
|
|
133
|
+
// Pan (keeping the current zoom) so `timeMs` is centered in view — used by the
|
|
134
|
+
// off-screen marker indicators to scroll their marker into view.
|
|
135
|
+
const handleRevealTime = useCallback((timeMs) => {
|
|
136
|
+
const { start, end } = viewportRef.current;
|
|
137
|
+
const duration = end - start;
|
|
138
|
+
animateTo(clampToRoot({
|
|
139
|
+
start: timeMs - duration / 2,
|
|
140
|
+
end: timeMs + duration / 2,
|
|
141
|
+
}));
|
|
142
|
+
}, [animateTo, clampToRoot]);
|
|
143
|
+
const ZOOM_FACTOR = 0.5;
|
|
144
|
+
const zoomBy = useCallback((factor) => {
|
|
145
|
+
const { start, end } = viewportRef.current;
|
|
146
|
+
const center = (start + end) / 2;
|
|
147
|
+
const newDuration = Math.max(MIN_VIEWPORT_MS, (end - start) * factor);
|
|
148
|
+
animateTo(clampToRoot({
|
|
149
|
+
start: center - newDuration / 2,
|
|
150
|
+
end: center + newDuration / 2,
|
|
151
|
+
}));
|
|
152
|
+
}, [animateTo, clampToRoot]);
|
|
153
|
+
const zoomIn = useCallback(() => zoomBy(ZOOM_FACTOR), [zoomBy]);
|
|
154
|
+
const zoomOut = useCallback(() => zoomBy(1 / ZOOM_FACTOR), [zoomBy]);
|
|
155
|
+
const isAtMinZoom = viewDuration >= root.duration;
|
|
156
|
+
const isAtMaxZoom = viewDuration <= MIN_VIEWPORT_MS;
|
|
157
|
+
const focusViewportOnSpan = useCallback((spanId) => {
|
|
158
|
+
const span = trace.spans.find((s) => s.spanId === spanId);
|
|
159
|
+
if (!span)
|
|
197
160
|
return;
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
161
|
+
const spanStart = getHighResInMs(span.startTime);
|
|
162
|
+
const spanEnd = getHighResInMs(span.endTime);
|
|
163
|
+
const spanDuration = spanEnd - spanStart;
|
|
164
|
+
if (spanDuration > root.duration * 0.8) {
|
|
165
|
+
animateTo({ start: root.startTime, end: root.endTime });
|
|
201
166
|
return;
|
|
202
|
-
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
167
|
+
}
|
|
168
|
+
const padding = Math.max(spanDuration * 0.2, MIN_VIEWPORT_MS / 2);
|
|
169
|
+
let newStart = spanStart - padding;
|
|
170
|
+
let newEnd = spanEnd + padding;
|
|
171
|
+
if (newEnd - newStart < MIN_VIEWPORT_MS) {
|
|
172
|
+
const center = (spanStart + spanEnd) / 2;
|
|
173
|
+
newStart = center - MIN_VIEWPORT_MS / 2;
|
|
174
|
+
newEnd = center + MIN_VIEWPORT_MS / 2;
|
|
175
|
+
}
|
|
176
|
+
animateTo(clampToRoot({ start: newStart, end: newEnd }));
|
|
177
|
+
}, [
|
|
178
|
+
animateTo,
|
|
179
|
+
trace.spans,
|
|
180
|
+
root.startTime,
|
|
181
|
+
root.endTime,
|
|
182
|
+
root.duration,
|
|
183
|
+
clampToRoot,
|
|
184
|
+
]);
|
|
185
|
+
// Bring a row into view when keyboard/button navigation lands on a span that
|
|
186
|
+
// sits outside the shared scroll container's visible area. The list is
|
|
187
|
+
// windowed, so an off-screen row has no DOM node to `scrollIntoView` —
|
|
188
|
+
// `scrollRowIntoView` computes the target offset from the span's index.
|
|
189
|
+
const scrollSpanIntoView = useCallback((spanId) => {
|
|
190
|
+
const index = trace.spans.findIndex((s) => s.spanId === spanId);
|
|
191
|
+
if (index === -1)
|
|
211
192
|
return;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
193
|
+
const list = scrollContainerRef.current?.querySelector('#event-list') ??
|
|
194
|
+
null;
|
|
195
|
+
scrollRowIntoView(list, index, ROW_HEIGHT_PX, {
|
|
196
|
+
behavior: reducedMotion ? 'auto' : 'smooth',
|
|
215
197
|
});
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
// user from scrolling horizontally.
|
|
223
|
-
useLayoutEffect(() => {
|
|
224
|
-
const $timeline = timelineRef.current;
|
|
225
|
-
if (!$timeline)
|
|
226
|
-
return;
|
|
227
|
-
const snapshot = scrollSnapshotRef.current;
|
|
228
|
-
if (snapshot) {
|
|
229
|
-
$timeline.scrollLeft = snapshot.anchorT * scale - snapshot.anchorX;
|
|
230
|
-
scrollSnapshotRef.current = undefined;
|
|
198
|
+
}, [trace.spans, reducedMotion]);
|
|
199
|
+
const zoomTimerRef = useRef(null);
|
|
200
|
+
const cancelPendingZoom = useCallback(() => {
|
|
201
|
+
if (zoomTimerRef.current !== null) {
|
|
202
|
+
clearTimeout(zoomTimerRef.current);
|
|
203
|
+
zoomTimerRef.current = null;
|
|
231
204
|
}
|
|
232
|
-
}, [
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
205
|
+
}, []);
|
|
206
|
+
useEffect(() => cancelPendingZoom, [cancelPendingZoom]);
|
|
207
|
+
const handleClearActiveSpan = useCallback(() => {
|
|
208
|
+
cancelPendingZoom();
|
|
209
|
+
clearActiveSpan();
|
|
210
|
+
}, [cancelPendingZoom, clearActiveSpan]);
|
|
211
|
+
const handleSelectSpan = useCallback((spanId) => {
|
|
212
|
+
cancelPendingZoom();
|
|
213
|
+
if (spanId === activeSpanId) {
|
|
214
|
+
clearActiveSpan();
|
|
237
215
|
return;
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
return () => {
|
|
259
|
-
clearTimeout(timeout);
|
|
260
|
-
};
|
|
261
|
-
}, [state.selected, state.timelineRef]);
|
|
262
|
-
// Global keyboard shortcuts
|
|
216
|
+
}
|
|
217
|
+
setActiveSpan(spanId);
|
|
218
|
+
focusViewportOnSpan(spanId);
|
|
219
|
+
}, [
|
|
220
|
+
cancelPendingZoom,
|
|
221
|
+
activeSpanId,
|
|
222
|
+
clearActiveSpan,
|
|
223
|
+
setActiveSpan,
|
|
224
|
+
focusViewportOnSpan,
|
|
225
|
+
]);
|
|
226
|
+
const navigateToSpan = useCallback((spanId) => {
|
|
227
|
+
setActiveSpan(spanId);
|
|
228
|
+
scrollSpanIntoView(spanId);
|
|
229
|
+
cancelPendingZoom();
|
|
230
|
+
zoomTimerRef.current = setTimeout(() => {
|
|
231
|
+
zoomTimerRef.current = null;
|
|
232
|
+
focusViewportOnSpan(spanId);
|
|
233
|
+
}, ZOOM_DEBOUNCE_MS);
|
|
234
|
+
}, [setActiveSpan, scrollSpanIntoView, cancelPendingZoom, focusViewportOnSpan]);
|
|
235
|
+
const [altHeld, setAltHeld] = useState(false);
|
|
263
236
|
useEffect(() => {
|
|
264
237
|
const onKeyDown = (e) => {
|
|
265
238
|
if (e.key === 'Escape') {
|
|
266
|
-
|
|
267
|
-
type: 'escape',
|
|
268
|
-
});
|
|
239
|
+
handleClearActiveSpan();
|
|
269
240
|
}
|
|
241
|
+
else if (e.key === 'Alt') {
|
|
242
|
+
setAltHeld(true);
|
|
243
|
+
}
|
|
244
|
+
};
|
|
245
|
+
const onKeyUp = (e) => {
|
|
246
|
+
if (e.key === 'Alt')
|
|
247
|
+
setAltHeld(false);
|
|
270
248
|
};
|
|
249
|
+
const onBlur = () => setAltHeld(false);
|
|
271
250
|
window.addEventListener('keydown', onKeyDown);
|
|
251
|
+
window.addEventListener('keyup', onKeyUp);
|
|
252
|
+
window.addEventListener('blur', onBlur);
|
|
272
253
|
return () => {
|
|
273
254
|
window.removeEventListener('keydown', onKeyDown);
|
|
255
|
+
window.removeEventListener('keyup', onKeyUp);
|
|
256
|
+
window.removeEventListener('blur', onBlur);
|
|
274
257
|
};
|
|
275
|
-
}, [
|
|
276
|
-
|
|
258
|
+
}, [handleClearActiveSpan]);
|
|
259
|
+
const timelineRef = useRef(null);
|
|
260
|
+
const [hover, setHover] = useState(null);
|
|
261
|
+
const hoverInfo = useMemo(() => {
|
|
262
|
+
if (hover == null)
|
|
263
|
+
return null;
|
|
264
|
+
const absTime = viewport.start + hover.fraction * viewDuration;
|
|
265
|
+
const offset = absTime - root.startTime;
|
|
266
|
+
return { fraction: hover.fraction, label: formatDurationPrecise(offset) };
|
|
267
|
+
}, [hover, viewport.start, viewDuration, root.startTime]);
|
|
268
|
+
const handleTimelineMouseMove = useCallback((e) => {
|
|
269
|
+
const el = timelineRef.current;
|
|
270
|
+
if (!el)
|
|
271
|
+
return;
|
|
272
|
+
const rect = el.getBoundingClientRect();
|
|
273
|
+
const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
|
|
274
|
+
if (contentWidth <= 0)
|
|
275
|
+
return;
|
|
276
|
+
const fraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
|
|
277
|
+
setHover({
|
|
278
|
+
fraction,
|
|
279
|
+
rowIndex: Math.floor((e.clientY - rect.top) / ROW_HEIGHT_PX),
|
|
280
|
+
});
|
|
281
|
+
}, []);
|
|
282
|
+
const handleTimelineMouseLeave = useCallback(() => {
|
|
283
|
+
setHover(null);
|
|
284
|
+
}, []);
|
|
277
285
|
useEffect(() => {
|
|
278
|
-
|
|
286
|
+
const el = timelineRef.current;
|
|
287
|
+
if (!el || root.duration <= 0)
|
|
279
288
|
return;
|
|
280
|
-
const
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
289
|
+
const onWheel = (e) => {
|
|
290
|
+
const isZoomGesture = e.ctrlKey || e.metaKey;
|
|
291
|
+
const hasDeltaX = Math.abs(e.deltaX) > Math.abs(e.deltaY);
|
|
292
|
+
if (!isZoomGesture && !hasDeltaX)
|
|
293
|
+
return;
|
|
294
|
+
e.preventDefault();
|
|
295
|
+
const rect = el.getBoundingClientRect();
|
|
296
|
+
const contentWidth = rect.width - TIMELINE_PADDING_PX * 2;
|
|
297
|
+
if (contentWidth <= 0)
|
|
298
|
+
return;
|
|
299
|
+
if (isZoomGesture) {
|
|
300
|
+
const cursorFraction = Math.max(0, Math.min(1, (e.clientX - rect.left - TIMELINE_PADDING_PX) / contentWidth));
|
|
301
|
+
const scaleFactor = wheelZoomScaleFactor(e);
|
|
302
|
+
setViewport((prev) => {
|
|
303
|
+
const prevDuration = prev.end - prev.start;
|
|
304
|
+
const cursorTime = prev.start + cursorFraction * prevDuration;
|
|
305
|
+
// Clamp the duration before anchoring so the cursor keeps its
|
|
306
|
+
// fraction even when the zoom hits the min/max bounds.
|
|
307
|
+
const newDuration = Math.max(MIN_VIEWPORT_MS, Math.min(root.duration, prevDuration * scaleFactor));
|
|
308
|
+
return clampToRoot({
|
|
309
|
+
start: cursorTime - cursorFraction * newDuration,
|
|
310
|
+
end: cursorTime + (1 - cursorFraction) * newDuration,
|
|
311
|
+
});
|
|
312
|
+
});
|
|
287
313
|
}
|
|
288
314
|
else {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
315
|
+
const dx = wheelDeltaToPixels(e.deltaX, e.deltaMode);
|
|
316
|
+
setViewport((prev) => {
|
|
317
|
+
const panAmount = (dx / contentWidth) * (prev.end - prev.start);
|
|
318
|
+
return clampToRoot({
|
|
319
|
+
start: prev.start + panAmount,
|
|
320
|
+
end: prev.end + panAmount,
|
|
321
|
+
});
|
|
293
322
|
});
|
|
294
323
|
}
|
|
295
324
|
};
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
const timelineHeight = Math.max(state.timelineHeight - state.scrollbarWidth, MARKER_HEIGHT +
|
|
307
|
-
ROW_PADDING +
|
|
308
|
-
rows.length * (ROW_HEIGHT + ROW_PADDING) -
|
|
309
|
-
ROW_PADDING +
|
|
310
|
-
// When there are enough spans to be near the bottom edge, add some extra padding
|
|
311
|
-
// to avoid overlapping with the zoom buttons, etc.
|
|
312
|
-
84);
|
|
313
|
-
const inert = Boolean(state.isMobile && state.selected);
|
|
314
|
-
return (_jsxs("div", { className: clsx(styles.traceViewer, isSkeleton && styles.skeleton, className), onClickCapture: onClick, ref: ref, style: {
|
|
315
|
-
height,
|
|
316
|
-
'--timeline-padding': `${TIMELINE_PADDING}px`,
|
|
317
|
-
'--row-height': `${ROW_HEIGHT}px`,
|
|
318
|
-
'--row-padding': `${ROW_PADDING}px`,
|
|
319
|
-
'--search-height': `${!hideSearchBar ? SEARCH_HEIGHT : 0}px`,
|
|
320
|
-
'--search-gap': `${!hideSearchBar ? SEARCH_GAP : 2}px`,
|
|
321
|
-
'--map-height': `${MAP_HEIGHT}px`,
|
|
322
|
-
'--timeline-width': `${state.timelineWidth}px`,
|
|
323
|
-
'--timeline-height': `${state.timelineHeight}px`,
|
|
324
|
-
'--timeline-scroll-width': `${Math.round(state.root.duration * state.scale)}px`,
|
|
325
|
-
'--panel-width': `${state.panelWidth}px`,
|
|
326
|
-
'--panel-height': `${state.panelHeight}px`,
|
|
327
|
-
'--height': `${state.height}px`,
|
|
328
|
-
'--scrollbar-width': `${state.scrollbarWidth}px`,
|
|
329
|
-
'--marker-height': `${MARKER_HEIGHT}px`,
|
|
330
|
-
'--marker-notch-height': `${MARKER_NOTCH_HEIGHT}px`,
|
|
331
|
-
}, children: [!hideSearchBar ? _jsx(SearchBar, {}) : null, _jsx(MiniMap, { rows: rows, scale: scale, timelineRef: timelineRef }), _jsxs("div", { className: clsx(styles.traceViewerContent, inert && styles.inert), children: [_jsxs("div", { className: styles.timeline, ref: timelineRef, children: [_jsx("div", { style: {
|
|
332
|
-
position: 'relative',
|
|
333
|
-
width: state.timelineWidth,
|
|
334
|
-
minHeight: state.timelineHeight - TIMELINE_PADDING * 2,
|
|
335
|
-
padding: TIMELINE_PADDING,
|
|
336
|
-
paddingBottom: 0,
|
|
337
|
-
}, children: _jsxs("div", { className: styles.traceNode, style: {
|
|
338
|
-
width: state.root.duration * scale || undefined,
|
|
339
|
-
height: timelineHeight - TIMELINE_PADDING * 2,
|
|
340
|
-
}, children: [_jsx(Markers, { scale: scale, isLive: isLive }), _jsx(EventMarkers, { events: events, root: state.root, scale: scale }), _jsx(CursorMarker, { dispatch: dispatch, events: events, memoCacheRef: state.memoCacheRef, root: state.root, scale: scale, scrollSnapshotRef: scrollSnapshotRef, spans: spans, timelineRef: timelineRef }), _jsx(SpanNodes, { cacheKey: memoCache.get(''), cache: memoCache, customSpanClassNameFunc: state.customSpanClassNameFunc, customSpanEventClassNameFunc: state.customSpanEventClassNameFunc, isLive: isLive, root: state.root, scale: scale, scrollSnapshotRef: scrollSnapshotRef, spans: spans }), knownDurationMs != null &&
|
|
341
|
-
knownDurationMs > 0 &&
|
|
342
|
-
(hasMoreData || isLive) &&
|
|
343
|
-
state.root.duration > 0 &&
|
|
344
|
-
(() => {
|
|
345
|
-
const knownPx = knownDurationMs * scale;
|
|
346
|
-
const totalPx = state.root.duration * scale;
|
|
347
|
-
const unknownWidth = totalPx - knownPx;
|
|
348
|
-
// Only show if the unknown region is meaningfully wide
|
|
349
|
-
if (unknownWidth < 4)
|
|
350
|
-
return null;
|
|
351
|
-
// Offset ~5% into the unknown region so it doesn't touch spans
|
|
352
|
-
const insetPx = Math.min(unknownWidth * 0.05, 20);
|
|
353
|
-
return (_jsx("div", { style: {
|
|
354
|
-
position: 'absolute',
|
|
355
|
-
top: 0,
|
|
356
|
-
left: knownPx + insetPx,
|
|
357
|
-
width: unknownWidth - insetPx,
|
|
358
|
-
height: '100%',
|
|
359
|
-
pointerEvents: 'none',
|
|
360
|
-
zIndex: 1,
|
|
361
|
-
maskImage: 'linear-gradient(to right, transparent 1%, black 3%)',
|
|
362
|
-
WebkitMaskImage: 'linear-gradient(to right, transparent 1%, black 3%)',
|
|
363
|
-
background: 'repeating-linear-gradient(-45deg, var(--ds-background-200) 0, var(--ds-background-200) 11px, var(--ds-gray-200) 11px, var(--ds-gray-200) 12px)',
|
|
364
|
-
} }));
|
|
365
|
-
})()] }) }), footer] }), _jsx("div", { className: styles.zoomButtonTraceViewer, children: _jsx(ZoomButton, {}) })] }), withPanel ? (_jsx("div", { className: clsx(styles.spanDetailPanelTraceViewer, !state.selected && styles.hidden, state.isMobile && styles.mobile), children: _jsx(SpanDetailPanel, { attached: true }) })) : null] }));
|
|
366
|
-
}
|
|
367
|
-
export function TraceViewerPanel({ className = '', children = null, }) {
|
|
368
|
-
const { state } = useTraceViewer();
|
|
369
|
-
if (!state.selected) {
|
|
370
|
-
return children;
|
|
371
|
-
}
|
|
372
|
-
return (_jsx("div", { className: clsx(styles.spanDetailPanelTraceViewer, className), style: {
|
|
373
|
-
position: 'relative',
|
|
374
|
-
'--search-height': '0',
|
|
375
|
-
'--search-gap': '0',
|
|
376
|
-
'--map-height': '0',
|
|
377
|
-
'--panel-width': `100%`,
|
|
378
|
-
'--panel-height': `100%`,
|
|
379
|
-
'--height': `100%`,
|
|
380
|
-
'--scrollbar-width': `${state.scrollbarWidth}px`,
|
|
381
|
-
}, children: _jsx(SpanDetailPanel, {}) }));
|
|
382
|
-
}
|
|
383
|
-
export function TraceViewer(props) {
|
|
384
|
-
return (_jsx(TraceViewerContextProvider, { getQuickLinks: props.getQuickLinks, withPanel: true, children: _jsx(TraceViewerTimeline, { withPanel: true, ...props }) }));
|
|
325
|
+
el.addEventListener('wheel', onWheel, { passive: false });
|
|
326
|
+
return () => el.removeEventListener('wheel', onWheel);
|
|
327
|
+
}, [root.duration, setViewport, clampToRoot]);
|
|
328
|
+
return (_jsxs("div", { ref: paneRootRef, "data-pane": "pane-root", className: "relative flex w-full h-full max-h-full", children: [_jsxs("div", { id: "trace-parent", className: "@container flex-1 min-w-0 grid grid-rows-[auto_1fr] h-full min-h-0 overflow-hidden relative bg-background-100", children: [_jsx(Minimap, { spans: trace.spans, root: root, viewport: viewport, minViewportMs: MIN_VIEWPORT_MS, onViewportChange: setViewport, onAnimateTo: animateTo }), _jsxs(SplitPane, { scrollContainerRef: scrollContainerRef, startHeader: _jsxs("div", { className: "bg-background-100 border-b border-gray-alpha-400 h-10 min-h-10 flex items-center pl-4 pr-2 gap-1.5", children: [_jsx(Search, { className: "w-3.5 h-3.5 shrink-0 text-gray-800" }), _jsx("input", { id: "trace-viewer-search", name: "trace-viewer-search", type: "text", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), onKeyDown: (e) => {
|
|
329
|
+
if (e.key === 'Escape' && searchQuery) {
|
|
330
|
+
e.preventDefault();
|
|
331
|
+
e.stopPropagation();
|
|
332
|
+
setSearchQuery('');
|
|
333
|
+
}
|
|
334
|
+
}, placeholder: "Search spans...", "aria-label": "Search spans", className: "flex-1 min-w-0 bg-transparent text-label-14 text-gray-1000 placeholder:text-gray-800 outline-none" }), searchQuery && (_jsx("button", { type: "button", "aria-label": "Clear search", onClick: () => setSearchQuery(''), className: "-mr-2 hidden h-full max-w-full shrink-0 cursor-pointer items-center rounded-r-md border-0 bg-transparent px-2.5 font-inherit text-label-16 text-gray-900 no-underline transition-colors duration-150 ease-in hover:text-gray-1000 focus-visible:-outline-offset-1 focus-visible:outline focus-visible:outline-2 focus-visible:outline-[var(--ds-focus-color)] min-[961px]:flex", children: _jsx(Kbd, { variant: "outline", size: "search", children: "Esc" }) }))] }), endHeader: _jsx(TimelineHeader, { markers: timeMarkers, hoverInfo: hoverInfo }), children: [_jsxs("div", { className: "block overflow-visible", children: [_jsx(EventList, { spans: trace.spans, activeSpanId: activeSpanId, searchResult: searchResult, onSelectSpan: handleSelectSpan }), _jsx("div", { ref: loadMoreSentinelRef, className: "flex justify-center", children: isLoadingMore ? (_jsxs("div", { className: "flex items-center justify-center gap-2 py-3 text-label-14 text-gray-800", children: [_jsx(Spinner, { size: 14 }), _jsx("span", { children: "Loading spans\u2026" })] })) : null })] }), _jsx("div", { ref: timelineRef, id: "trace-timeline", className: "@container block min-h-0 overflow-visible relative", onDoubleClick: resetZoom, onMouseMove: handleTimelineMouseMove, onMouseLeave: handleTimelineMouseLeave, children: _jsx(Timeline, { spans: trace.spans, viewStart: viewport.start, viewEnd: viewport.end, markers: timeMarkers, selectedId: activeSpanId, searchResult: searchResult, onSelect: handleSelectSpan, onRevealTime: handleRevealTime, hover: hover, altHeld: altHeld }) }), _jsxs(_Fragment, { children: [_jsx(TraceShortcutHelper, { hasMultipleSpans: trace.spans.length > 1, reducedMotion: reducedMotion }), _jsxs("div", { className: "pointer-events-auto flex items-center border border-gray-alpha-400 rounded-md bg-background-100 shadow-sm overflow-hidden divide-x divide-gray-alpha-400", children: [_jsx(IconButton, { variant: "muted", size: "small", onClick: zoomOut, disabled: isAtMinZoom, "aria-label": "Zoom out", children: _jsx(ZoomOut, { className: "w-4 h-4" }) }), _jsx(IconButton, { variant: "muted", size: "small", onClick: resetZoom, "aria-label": "Reset zoom", children: _jsx(RotateCcw, { className: "w-3.5 h-3.5" }) }), _jsx(IconButton, { variant: "muted", size: "small", onClick: zoomIn, disabled: isAtMaxZoom, "aria-label": "Zoom in", children: _jsx(ZoomIn, { className: "w-4 h-4" }) })] })] })] })] }), _jsx(TraceDetailPanel, { containerRef: paneRootRef, onNavigateToSpan: navigateToSpan, onClose: handleClearActiveSpan })] }));
|
|
385
335
|
}
|
|
386
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2Utdmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdHJhY2Utdmlld2VyL3RyYWNlLXZpZXdlci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOztBQUViLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFNUIsT0FBTyxFQUFFLFdBQVcsRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxNQUFNLE9BQU8sQ0FBQztBQUN4RSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0MsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDM0UsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDakUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3RELE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxjQUFjLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDdkUsT0FBTyxNQUFNLE1BQU0sMkJBQTJCLENBQUM7QUFFL0MsT0FBTyxFQUNMLFVBQVUsRUFDVixhQUFhLEVBQ2IsbUJBQW1CLEVBQ25CLFVBQVUsRUFDVixXQUFXLEVBQ1gsVUFBVSxFQUNWLGFBQWEsRUFDYixnQkFBZ0IsR0FDakIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBZ0IvRCxNQUFNLFVBQVUsbUJBQW1CLENBQUMsRUFDbEMsYUFBYSxFQUNiLFFBQVEsR0FHVDtJQUND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RUFBRSxLQUFLLEVBQUUsR0FBRyxjQUFjLEVBQUUsQ0FBQztJQUVuQyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3BCLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7SUFFRCxPQUFPLENBQ0wsY0FDRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQywwQkFBMEIsRUFBRSxTQUFTLENBQUMsRUFDN0QsS0FBSyxFQUNIO1lBQ0UsUUFBUSxFQUFFLFVBQVU7WUFDcEIsaUJBQWlCLEVBQUUsR0FBRztZQUN0QixjQUFjLEVBQUUsR0FBRztZQUNuQixjQUFjLEVBQUUsR0FBRztZQUNuQixlQUFlLEVBQUUsTUFBTTtZQUN2QixnQkFBZ0IsRUFBRSxNQUFNO1lBQ3hCLFVBQVUsRUFBRSxNQUFNO1lBQ2xCLG1CQUFtQixFQUFFLEdBQUcsS0FBSyxDQUFDLGNBQWMsSUFBSTtTQUNoQyxZQUdwQixLQUFDLGVBQWUsS0FBRyxHQUNmLENBQ1AsQ0FBQztBQUNKLENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFDLEtBQXVCO0lBQ2pELE9BQU8sQ0FDTCxLQUFDLDBCQUEwQixJQUFDLGFBQWEsRUFBRSxLQUFLLENBQUMsYUFBYSxFQUFFLFNBQVMsa0JBQ3ZFLEtBQUMsbUJBQW1CLElBQUMsU0FBUyxXQUFLLEtBQUssR0FBSSxHQUNqQixDQUM5QixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIid1c2UgY2xpZW50JztcblxuaW1wb3J0IHsgY2xzeCB9IGZyb20gJ2Nsc3gnO1xuaW1wb3J0IHR5cGUgeyBDU1NQcm9wZXJ0aWVzLCBNb3VzZUV2ZW50SGFuZGxlciwgUmVhY3ROb2RlIH0gZnJvbSAncmVhY3QnO1xuaW1wb3J0IHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlTGF5b3V0RWZmZWN0LCB1c2VSZWYgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBNaW5pTWFwIH0gZnJvbSAnLi9jb21wb25lbnRzL21hcCc7XG5pbXBvcnQgeyBDdXJzb3JNYXJrZXIsIEV2ZW50TWFya2VycywgTWFya2VycyB9IGZyb20gJy4vY29tcG9uZW50cy9tYXJrZXJzJztcbmltcG9ydCB7IFNwYW5Ob2RlcyB9IGZyb20gJy4vY29tcG9uZW50cy9ub2RlJztcbmltcG9ydCB7IFNlYXJjaEJhciB9IGZyb20gJy4vY29tcG9uZW50cy9zZWFyY2gnO1xuaW1wb3J0IHsgU3BhbkRldGFpbFBhbmVsIH0gZnJvbSAnLi9jb21wb25lbnRzL3NwYW4tZGV0YWlsLXBhbmVsJztcbmltcG9ydCB7IFpvb21CdXR0b24gfSBmcm9tICcuL2NvbXBvbmVudHMvem9vbS1idXR0b24nO1xuaW1wb3J0IHsgVHJhY2VWaWV3ZXJDb250ZXh0UHJvdmlkZXIsIHVzZVRyYWNlVmlld2VyIH0gZnJvbSAnLi9jb250ZXh0JztcbmltcG9ydCBzdHlsZXMgZnJvbSAnLi90cmFjZS12aWV3ZXIubW9kdWxlLmNzcyc7XG5pbXBvcnQgdHlwZSB7IEdldFF1aWNrTGlua3MsIFRyYWNlIH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQge1xuICBNQVBfSEVJR0hULFxuICBNQVJLRVJfSEVJR0hULFxuICBNQVJLRVJfTk9UQ0hfSEVJR0hULFxuICBST1dfSEVJR0hULFxuICBST1dfUEFERElORyxcbiAgU0VBUkNIX0dBUCxcbiAgU0VBUkNIX0hFSUdIVCxcbiAgVElNRUxJTkVfUEFERElORyxcbn0gZnJvbSAnLi91dGlsL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBwYXJzZVRyYWNlIH0gZnJvbSAnLi91dGlsL3RyZWUnO1xuaW1wb3J0IHsgdXNlU3RyZWFtaW5nU3BhbnMgfSBmcm9tICcuL3V0aWwvdXNlLXN0cmVhbWluZy1zcGFucyc7XG5cbmludGVyZmFjZSBUcmFjZVZpZXdlclByb3BzIHtcbiAgdHJhY2U/OiBUcmFjZTtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBzY3JvbGxMb2NrPzogYm9vbGVhbjtcbiAgaGVpZ2h0Pzogc3RyaW5nIHwgbnVtYmVyO1xuICB3aXRoUGFuZWw/OiBib29sZWFuO1xuICBnZXRRdWlja0xpbmtzPzogR2V0UXVpY2tMaW5rcztcbiAgaGlnaGxpZ2h0ZWRTcGFucz86IHN0cmluZ1tdO1xuICAvKiogUmVuZGVyIGFsbCBzcGFucyBpbW1lZGlhdGVseSAobm8gcHJvZ3Jlc3NpdmUgc3RyZWFtaW5nKS4gKi9cbiAgZWFnZXJSZW5kZXI/OiBib29sZWFuO1xuICAvKiogV2hldGhlciB0aGUgdHJhY2UgaXMgbGl2ZSAoZm9yIGNvbnRpbnVvdXMgdGljayB1cGRhdGVzKS4gKi9cbiAgaXNMaXZlPzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyUHJvdmlkZXIoe1xuICBnZXRRdWlja0xpbmtzLFxuICBjaGlsZHJlbixcbn06IFBpY2s8VHJhY2VWaWV3ZXJQcm9wcywgJ2dldFF1aWNrTGlua3MnPiAmIHtcbiAgY2hpbGRyZW46IFJlYWN0Tm9kZTtcbn0pOiBSZWFjdE5vZGUge1xuICByZXR1cm4gKFxuICAgIDxUcmFjZVZpZXdlckNvbnRleHRQcm92aWRlciBnZXRRdWlja0xpbmtzPXtnZXRRdWlja0xpbmtzfT5cbiAgICAgIHtjaGlsZHJlbn1cbiAgICA8L1RyYWNlVmlld2VyQ29udGV4dFByb3ZpZGVyPlxuICApO1xufVxuXG5pbnRlcmZhY2UgTGFzdENsaWNrUmVmIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHQ6IG51bWJlcjtcbiAgc3BhbklkOiBzdHJpbmc7XG59XG5cbmNvbnN0IHNrZWxldG9uVHJhY2U6IFRyYWNlID0ge1xuICB0cmFjZUlkOiAnc2tlbGV0b24nLFxuICBzcGFuczogW1xuICAgIHtcbiAgICAgIHBhcmVudFNwYW5JZDogJycsXG4gICAgICBzcGFuSWQ6ICdyb290JyxcbiAgICAgIG5hbWU6ICdyb290IHNwYW4nLFxuICAgICAga2luZDogMSxcbiAgICAgIHJlc291cmNlOiAndmVyY2VsLnJ1bnRpbWUnLFxuICAgICAgc3RhcnRUaW1lOiBbNTAwMCwgMF0sXG4gICAgICBlbmRUaW1lOiBbNjAwMCwgMF0sXG4gICAgICBkdXJhdGlvbjogWzEwMDAsIDBdLFxuICAgICAgbGlicmFyeToge1xuICAgICAgICBuYW1lOiAndmVyY2VsLXNpdGUnLFxuICAgICAgfSxcbiAgICAgIHN0YXR1czoge1xuICAgICAgICBjb2RlOiAxLFxuICAgICAgfSxcbiAgICAgIGF0dHJpYnV0ZXM6IHtcbiAgICAgICAgJ3ZlcmNlbC5vd25lcklkJzogJ3RlYW1fYWJjJyxcbiAgICAgIH0sXG4gICAgICB0cmFjZUZsYWdzOiAxLFxuICAgICAgZXZlbnRzOiBbXSxcbiAgICAgIGxpbmtzOiBbXSxcbiAgICB9LFxuICBdLFxuICByZXNvdXJjZXM6IFtcbiAgICB7XG4gICAgICBuYW1lOiAndmVyY2VsLnJ1bnRpbWUnLFxuICAgICAgYXR0cmlidXRlczoge30sXG4gICAgfSxcbiAgXSxcbiAgcm9vdFNwYW5JZDogJ3Jvb3QnLFxufTtcblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyVGltZWxpbmUoe1xuICB0cmFjZSA9IHNrZWxldG9uVHJhY2UsXG4gIGNsYXNzTmFtZSA9ICcnLFxuICBzY3JvbGxMb2NrID0gZmFsc2UsXG4gIGhlaWdodCxcbiAgd2l0aFBhbmVsID0gZmFsc2UsXG4gIGhpZ2hsaWdodGVkU3BhbnMsXG4gIGVhZ2VyUmVuZGVyID0gZmFsc2UsXG4gIGlzTGl2ZSA9IGZhbHNlLFxuICBmb290ZXIsXG4gIGtub3duRHVyYXRpb25NcyxcbiAgaGFzTW9yZURhdGEgPSBmYWxzZSxcbn06IE9taXQ8VHJhY2VWaWV3ZXJQcm9wcywgJ2dldFF1aWNrTGlua3MnPiAmIHtcbiAgZm9vdGVyPzogUmVhY3ROb2RlO1xuICAvKiogRHVyYXRpb24gaW4gbXMgZnJvbSB0cmFjZSBzdGFydCB0byB0aGUgbGF0ZXN0IGtub3duIGV2ZW50LiBVc2VkIHRvIHJlbmRlciB0aGUgdW5rbm93bi10aW1lIG92ZXJsYXkuICovXG4gIGtub3duRHVyYXRpb25Ncz86IG51bWJlcjtcbiAgLyoqIFdoZXRoZXIgbW9yZSBkYXRhIHBhZ2VzIGFyZSBleHBlY3RlZC4gQ29udHJvbHMgdGhlIHVua25vd24tZGF0YSBvdmVybGF5IHZpc2liaWxpdHkuICovXG4gIGhhc01vcmVEYXRhPzogYm9vbGVhbjtcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCBpc1NrZWxldG9uID0gdHJhY2UgPT09IHNrZWxldG9uVHJhY2U7XG4gIGNvbnN0IHsgc3RhdGUsIGRpc3BhdGNoIH0gPSB1c2VUcmFjZVZpZXdlcigpO1xuICBjb25zdCB7IHRpbWVsaW5lUmVmLCBzY3JvbGxTbmFwc2hvdFJlZiB9ID0gc3RhdGU7XG4gIGNvbnN0IG1lbW9DYWNoZSA9IHN0YXRlLm1lbW9DYWNoZVJlZi5jdXJyZW50O1xuICBjb25zdCBoaWRlU2VhcmNoQmFyID0gKGhpZ2hsaWdodGVkU3BhbnM/Lmxlbmd0aCA/PyAwKSA+IDA7XG5cbiAgY29uc3QgaGFzSW5pdGlhbGl6ZWRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBwcmV2U3BhbktleVJlZiA9IHVzZVJlZignJyk7XG4gIGNvbnN0IHByZXZSb290UmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHBhcnNlVHJhY2U+Wydyb290J10gfCBudWxsPihcbiAgICBudWxsXG4gICk7XG4gIGNvbnN0IHByZXZTcGFuTWFwUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHBhcnNlVHJhY2U+WydtYXAnXT4oe30pO1xuICBjb25zdCBwcmV2U2l6ZVJlZiA9IHVzZVJlZjx7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0gfCBudWxsPihudWxsKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IHsgcm9vdDogbmV3Um9vdCwgbWFwOiBuZXdTcGFuTWFwIH0gPSBwYXJzZVRyYWNlKHRyYWNlKTtcbiAgICBjb25zdCBpc0luaXRpYWwgPSAhaGFzSW5pdGlhbGl6ZWRSZWYuY3VycmVudDtcbiAgICBoYXNJbml0aWFsaXplZFJlZi5jdXJyZW50ID0gdHJ1ZTtcblxuICAgIC8vIEJ1aWxkIGEgc3RydWN0dXJhbCBrZXkgZnJvbSBzcGFuIElEcyArIGxpZ2h0d2VpZ2h0IGV2ZW50IHNpZ25hdHVyZXMuXG4gICAgLy8gV2hlbiBvbmx5IHRpbWluZyBjaGFuZ2VzIChzYW1lIHNwYW5zIGFuZCBib3VuZGFyeSBldmVudHMpLCB3ZSBjYW4gc2tpcCB0aGVcbiAgICAvLyB3b3JrZXIgcmVzdGFydC4gV2hlbiBldmVudHMgY2hhbmdlIChzdGVwIGNvbXBsZXRlZCwgZXRjLikgd2UgbmVlZCBhXG4gICAgLy8gZnVsbCB1cGRhdGUgYmVjYXVzZSB0aGUgVmlzaWJsZVNwYW4gb2JqZWN0cyByZW5kZXJlZCBieSBSZWFjdCBob2xkXG4gICAgLy8gY29waWVzIG9mIHRoZSBldmVudHMgZnJvbSB0aGUgd29ya2VyIOKAlCBpbi1wbGFjZSBtdXRhdGlvbiB3b24ndCByZWFjaCB0aGVtLlxuICAgIGNvbnN0IHNwYW5LZXkgPSBPYmplY3Qua2V5cyhuZXdTcGFuTWFwKVxuICAgICAgLnNvcnQoKVxuICAgICAgLm1hcCgoaWQpID0+IHtcbiAgICAgICAgY29uc3QgZXZlbnRzID0gbmV3U3Bhbk1hcFtpZF0uZXZlbnRzO1xuICAgICAgICBjb25zdCBjb3VudCA9IGV2ZW50cz8ubGVuZ3RoID8/IDA7XG4gICAgICAgIGNvbnN0IGZpcnN0ID0gY291bnQgPyBldmVudHM/LlswXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgbGFzdCA9IGNvdW50ID8gZXZlbnRzPy5bY291bnQgLSAxXSA6IHVuZGVmaW5lZDtcbiAgICAgICAgY29uc3QgZXZlbnRTaWduYXR1cmUgPSBgJHtmaXJzdD8uZXZlbnQubmFtZSA/PyAnbm9uZSd9QCR7Zmlyc3Q/LnRpbWVzdGFtcCA/PyAwfXwke2xhc3Q/LmV2ZW50Lm5hbWUgPz8gJ25vbmUnfUAke2xhc3Q/LnRpbWVzdGFtcCA/PyAwfWA7XG4gICAgICAgIHJldHVybiBgJHtpZH06JHtjb3VudH06JHtldmVudFNpZ25hdHVyZX1gO1xuICAgICAgfSlcbiAgICAgIC5qb2luKCcsJyk7XG5cbiAgICBpZiAoXG4gICAgICAhaXNJbml0aWFsICYmXG4gICAgICBzcGFuS2V5ID09PSBwcmV2U3BhbktleVJlZi5jdXJyZW50ICYmXG4gICAgICBwcmV2Um9vdFJlZi5jdXJyZW50XG4gICAgKSB7XG4gICAgICAvLyBTYW1lIHNwYW4gc2V0LCBzYW1lIGV2ZW50IGNvdW50cyDigJQgb25seSB0aW1pbmcgY2hhbmdlZC5cbiAgICAgIC8vIE11dGF0ZSBpbi1wbGFjZSBzbyB0aGUgd29ya2VyIGVmZmVjdCAod2hpY2ggZGVwZW5kcyBvbiByb290L3NwYW5NYXBcbiAgICAgIC8vIHJlZmVyZW5jZXMpIGRvZXMgTk9UIHJlc3RhcnQuXG4gICAgICBjb25zdCBvbGRSb290ID0gcHJldlJvb3RSZWYuY3VycmVudDtcbiAgICAgIGNvbnN0IG9sZFNwYW5NYXAgPSBwcmV2U3Bhbk1hcFJlZi5jdXJyZW50O1xuICAgICAgbGV0IGRpZENoYW5nZSA9IGZhbHNlO1xuXG4gICAgICBpZiAoXG4gICAgICAgIG9sZFJvb3QuZW5kVGltZSAhPT0gbmV3Um9vdC5lbmRUaW1lIHx8XG4gICAgICAgIG9sZFJvb3QuZHVyYXRpb24gIT09IG5ld1Jvb3QuZHVyYXRpb25cbiAgICAgICkge1xuICAgICAgICBvbGRSb290LmVuZFRpbWUgPSBuZXdSb290LmVuZFRpbWU7XG4gICAgICAgIG9sZFJvb3QuZHVyYXRpb24gPSBuZXdSb290LmR1cmF0aW9uO1xuICAgICAgICBkaWRDaGFuZ2UgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICBmb3IgKGNvbnN0IFtpZCwgbmV3Tm9kZV0gb2YgT2JqZWN0LmVudHJpZXMobmV3U3Bhbk1hcCkpIHtcbiAgICAgICAgY29uc3Qgb2xkTm9kZSA9IG9sZFNwYW5NYXBbaWRdO1xuICAgICAgICBpZiAob2xkTm9kZSkge1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9sZE5vZGUuZW5kVGltZSAhPT0gbmV3Tm9kZS5lbmRUaW1lIHx8XG4gICAgICAgICAgICBvbGROb2RlLmR1cmF0aW9uICE9PSBuZXdOb2RlLmR1cmF0aW9uXG4gICAgICAgICAgKSB7XG4gICAgICAgICAgICBvbGROb2RlLmVuZFRpbWUgPSBuZXdOb2RlLmVuZFRpbWU7XG4gICAgICAgICAgICBvbGROb2RlLmR1cmF0aW9uID0gbmV3Tm9kZS5kdXJhdGlvbjtcbiAgICAgICAgICAgIGRpZENoYW5nZSA9IHRydWU7XG4gICAgICAgICAgfVxuICAgICAgICAgIE9iamVjdC5hc3NpZ24ob2xkTm9kZS5zcGFuLCBuZXdOb2RlLnNwYW4pO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmICghZGlkQ2hhbmdlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gVHJpZ2dlciByZS1yZW5kZXIgKHNjYWxlL21hcmtlcnMpIHdpdGhvdXQgcmVzdGFydGluZyB0aGUgd29ya2VyLlxuICAgICAgLy8gdXNlTGl2ZVRpY2sgaGFuZGxlcyBjb250aW51b3VzIHNjYWxlIHJlY2FsY3VsYXRpb24gZm9yIGxpdmUgcnVucy5cbiAgICAgIGRpc3BhdGNoKHsgdHlwZTogJ2ZvcmNlUmVuZGVyJyB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBTdHJ1Y3R1cmUgY2hhbmdlZCBvciBpbml0aWFsIGxvYWQg4oCUIGZ1bGwgZGlzcGF0Y2ggKHdvcmtlciBjb21wdXRlcyBuZXcgcm93cylcbiAgICBwcmV2U3BhbktleVJlZi5jdXJyZW50ID0gc3BhbktleTtcbiAgICBwcmV2Um9vdFJlZi5jdXJyZW50ID0gbmV3Um9vdDtcbiAgICBwcmV2U3Bhbk1hcFJlZi5jdXJyZW50ID0gbmV3U3Bhbk1hcDtcbiAgICBkaXNwYXRjaCh7XG4gICAgICB0eXBlOiBpc0luaXRpYWwgPyAnc2V0Um9vdCcgOiAndXBkYXRlUm9vdCcsXG4gICAgICByb290OiBuZXdSb290LFxuICAgICAgc3Bhbk1hcDogbmV3U3Bhbk1hcCxcbiAgICAgIHJlc291cmNlczogdHJhY2UucmVzb3VyY2VzIHx8IFtdLFxuICAgIH0pO1xuICB9LCBbZGlzcGF0Y2gsIHRyYWNlXSk7XG5cbiAgY29uc3QgeyByb3dzLCBzcGFucywgZXZlbnRzLCBzY2FsZSB9ID0gdXNlU3RyZWFtaW5nU3BhbnMoXG4gICAgaGlnaGxpZ2h0ZWRTcGFucyxcbiAgICBlYWdlclJlbmRlclxuICApO1xuXG4gIGNvbnN0IHJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG4gIHVzZUxheW91dEVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgJGVsID0gcmVmLmN1cnJlbnQ7XG4gICAgaWYgKCEkZWwpIHJldHVybjtcblxuICAgIGNvbnN0IG9uUmVzaXplID0gKCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgcGFkZGluZyA9IDIgKiBUSU1FTElORV9QQURESU5HO1xuICAgICAgY29uc3QgcmVjdCA9ICRlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IG5leHRXaWR0aCA9IHJlY3Qud2lkdGggLSBwYWRkaW5nO1xuICAgICAgY29uc3QgbmV4dEhlaWdodCA9IHJlY3QuaGVpZ2h0O1xuICAgICAgY29uc3QgcHJldlNpemUgPSBwcmV2U2l6ZVJlZi5jdXJyZW50O1xuXG4gICAgICBpZiAoXG4gICAgICAgIHByZXZTaXplICYmXG4gICAgICAgIHByZXZTaXplLndpZHRoID09PSBuZXh0V2lkdGggJiZcbiAgICAgICAgcHJldlNpemUuaGVpZ2h0ID09PSBuZXh0SGVpZ2h0XG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcHJldlNpemVSZWYuY3VycmVudCA9IHsgd2lkdGg6IG5leHRXaWR0aCwgaGVpZ2h0OiBuZXh0SGVpZ2h0IH07XG5cbiAgICAgIGRpc3BhdGNoKHtcbiAgICAgICAgdHlwZTogJ3NldFNpemUnLFxuICAgICAgICB3aWR0aDogbmV4dFdpZHRoLFxuICAgICAgICBoZWlnaHQ6IG5leHRIZWlnaHQsXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgb25SZXNpemUoKTtcblxuICAgIGNvbnN0IG9ic2VydmVyID0gbmV3IFJlc2l6ZU9ic2VydmVyKG9uUmVzaXplKTtcbiAgICBvYnNlcnZlci5vYnNlcnZlKCRlbCk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsIG9uUmVzaXplKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcigncmVzaXplJywgb25SZXNpemUpO1xuICAgIH07XG4gIH0sIFtkaXNwYXRjaF0pO1xuXG4gIGNvbnN0IGxhc3RDbGlja1JlZiA9IHVzZVJlZjxMYXN0Q2xpY2tSZWY+KHtcbiAgICB0OiAwLFxuICAgIHg6IC0xLFxuICAgIHk6IC0xLFxuICAgIHNwYW5JZDogJycsXG4gIH0pO1xuICBjb25zdCBvbkNsaWNrOiBNb3VzZUV2ZW50SGFuZGxlciA9IHVzZUNhbGxiYWNrKFxuICAgIChldmVudCkgPT4ge1xuICAgICAgLy8gTk9URSh3aXRzKTogV2UgbWFudWFsbHkgaW1wbGVtZW50IGRvdWJsZS1jbGljayBsb2dpYyBoZXJlIHNvIHRoYXQgd2UgY2FuIHN1cHBvcnQgZG91YmxlXG4gICAgICAvLyBjbGlja2luZyBhIHNwYW4gZXZlbiBpZiB0aGUgZmlyc3QgY2xpY2sgbW92ZXMgdGhlIHNwYW4gdGhhdCB0aGUgdXNlciBpcyBjbGlja2luZyBvbiBkdWVcbiAgICAgIC8vIHRvIHRoZSBwYW5lbCBvcGVuaW5nLiBJZiB3ZSB1c2VkIGEgcmVndWxhciBkb3VibGUgY2xpY2sgbGlzdGVuZXIgd2Ugd291bGQgbmVlZCB0byBkZWxheVxuICAgICAgLy8gdGhlIG9wZW5pbmcgb2YgdGhlIHBhbmVsIGFydGlmaWNpYWxseS4gVGhpcyBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgdXMgdG8gYWx3YXlzIGJlXG4gICAgICAvLyBGQVNUIHdoaWxlIGFsc28gYXZvaWRpbmcgYSBGUlVTVFJBVElORyBzaXR1YXRpb24uXG4gICAgICBjb25zdCBwcmV2ID0gbGFzdENsaWNrUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCB0ID0gRGF0ZS5ub3coKTtcbiAgICAgIGNvbnN0IHsgY2xpZW50WDogeCwgY2xpZW50WTogeSB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCBkID0gTWF0aC5zcXJ0KCh4IC0gcHJldi54KSAqKiAyICsgKHkgLSBwcmV2LnkpICoqIDIpO1xuICAgICAgLy8gZG91YmxlIGNsaWNrXG4gICAgICBpZiAodCAtIHByZXYudCA8PSA1MDAgJiYgZCA8PSA4KSB7XG4gICAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoIXByZXYuc3BhbklkKSB7XG4gICAgICAgICAgZGlzcGF0Y2goe1xuICAgICAgICAgICAgdHlwZTogJ3Jlc2V0U2NhbGUnLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBkaXNwYXRjaCh7XG4gICAgICAgICAgdHlwZTogJ3NlbGVjdCcsXG4gICAgICAgICAgaWQ6IHByZXYuc3BhbklkLFxuICAgICAgICB9KTtcbiAgICAgICAgZGlzcGF0Y2goe1xuICAgICAgICAgIHR5cGU6ICdzY2FsZVRvTm9kZScsXG4gICAgICAgICAgaWQ6IHByZXYuc3BhbklkLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgICAgaWYgKCF0YXJnZXQuY2xvc2VzdChgLiR7U3RyaW5nKHN0eWxlcy50aW1lbGluZSl9YCkpIHJldHVybjtcbiAgICAgIGNvbnN0ICRidXR0b24gPSB0YXJnZXQuY2xvc2VzdDxIVE1MQnV0dG9uRWxlbWVudD4oJ1tkYXRhLXNwYW4taWRdJyk7XG4gICAgICBjb25zdCBzcGFuSWQgPSAkYnV0dG9uPy5kYXRhc2V0LnNwYW5JZCB8fCAnJztcbiAgICAgIGxhc3RDbGlja1JlZi5jdXJyZW50ID0ge1xuICAgICAgICB4LFxuICAgICAgICB5LFxuICAgICAgICB0LFxuICAgICAgICBzcGFuSWQsXG4gICAgICB9O1xuICAgICAgaWYgKCFzcGFuSWQpIHJldHVybjtcbiAgICAgIGRpc3BhdGNoKHtcbiAgICAgICAgdHlwZTogJ3RvZ2dsZVNlbGVjdGlvbicsXG4gICAgICAgIGlkOiBzcGFuSWQsXG4gICAgICB9KTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH0sXG4gICAgW2Rpc3BhdGNoXVxuICApO1xuXG4gIC8vIFpvb20gaGVscGVyIOKAlCBhcHBseSB0aGUgc2Nyb2xsIHNuYXBzaG90IG9uY2UgYWZ0ZXIgYSB6b29tIG9wZXJhdGlvbiBzb1xuICAvLyB0aGUgYW5jaG9yIHBvaW50IHN0YXlzIGF0IHRoZSBzYW1lIHNjcmVlbiBwb3NpdGlvbiwgdGhlbiBjbGVhciBpdC5cbiAgLy8gV2l0aG91dCBjbGVhcmluZywgbGl2ZSBydW5zICh3aGVyZSBzY2FsZSBjaGFuZ2VzIGV2ZXJ5IGZyYW1lIHZpYVxuICAvLyBkZXRlY3RCYXNlU2NhbGUpIHdvdWxkIGNvbnRpbnVvdXNseSByZXNldCBzY3JvbGxMZWZ0IGFuZCBwcmV2ZW50IHRoZVxuICAvLyB1c2VyIGZyb20gc2Nyb2xsaW5nIGhvcml6b250YWxseS5cbiAgdXNlTGF5b3V0RWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCAkdGltZWxpbmUgPSB0aW1lbGluZVJlZi5jdXJyZW50O1xuICAgIGlmICghJHRpbWVsaW5lKSByZXR1cm47XG5cbiAgICBjb25zdCBzbmFwc2hvdCA9IHNjcm9sbFNuYXBzaG90UmVmLmN1cnJlbnQ7XG4gICAgaWYgKHNuYXBzaG90KSB7XG4gICAgICAkdGltZWxpbmUuc2Nyb2xsTGVmdCA9IHNuYXBzaG90LmFuY2hvclQgKiBzY2FsZSAtIHNuYXBzaG90LmFuY2hvclg7XG4gICAgICBzY3JvbGxTbmFwc2hvdFJlZi5jdXJyZW50ID0gdW5kZWZpbmVkO1xuICAgIH1cbiAgfSwgW3Njcm9sbFNuYXBzaG90UmVmLCB0aW1lbGluZVJlZiwgc2NhbGVdKTtcblxuICAvLyBTZWxlY3Rpb24gaGVscGVyXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3Qgc3BhbklkID0gc3RhdGUuc2VsZWN0ZWQ/LnNwYW4uc3BhbklkO1xuICAgIGlmICghc3BhbklkKSByZXR1cm47XG5cbiAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCAkdGltZWxpbmUgPSBzdGF0ZS50aW1lbGluZVJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgJHNwYW4gPSAkdGltZWxpbmU/LnF1ZXJ5U2VsZWN0b3IoYFtkYXRhLXNwYW4taWQ9XCIke3NwYW5JZH1cIl1gKTtcbiAgICAgIGlmICghJHRpbWVsaW5lIHx8ICEkc3BhbikgcmV0dXJuO1xuXG4gICAgICBjb25zdCB2aWV3UmVjdCA9ICR0aW1lbGluZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IHNwYW5SZWN0ID0gJHNwYW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAgIC8vIElmIHRoZSBzZWxlY3RlZCBzcGFuIGlzIG5hcnJvd2VyIHRoYW4gdGhlIHRpbWVsaW5lLCBzY3JvbGwgaXQgaW50byB2aWV3XG4gICAgICBpZiAoXG4gICAgICAgIHNwYW5SZWN0LndpZHRoIDwgdmlld1JlY3Qud2lkdGggJiZcbiAgICAgICAgKHNwYW5SZWN0LmxlZnQgPCB2aWV3UmVjdC5sZWZ0IHx8XG4gICAgICAgICAgc3BhblJlY3QucmlnaHQgPiB2aWV3UmVjdC5yaWdodCB8fFxuICAgICAgICAgIHNwYW5SZWN0LnRvcCA8IHZpZXdSZWN0LnRvcCB8fFxuICAgICAgICAgIHNwYW5SZWN0LmJvdHRvbSA+IHZpZXdSZWN0LmJvdHRvbSlcbiAgICAgICkge1xuICAgICAgICAkc3Bhbi5zY3JvbGxJbnRvVmlldyh7XG4gICAgICAgICAgYmxvY2s6ICduZWFyZXN0JyxcbiAgICAgICAgICBpbmxpbmU6ICdjZW50ZXInLFxuICAgICAgICAgIGJlaGF2aW9yOiAnc21vb3RoJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgNTAwKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgfTtcbiAgfSwgW3N0YXRlLnNlbGVjdGVkLCBzdGF0ZS50aW1lbGluZVJlZl0pO1xuXG4gIC8vIEdsb2JhbCBrZXlib2FyZCBzaG9ydGN1dHNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBvbktleURvd24gPSAoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGUua2V5ID09PSAnRXNjYXBlJykge1xuICAgICAgICBkaXNwYXRjaCh7XG4gICAgICAgICAgdHlwZTogJ2VzY2FwZScsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH07XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCBvbktleURvd24pO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICB9O1xuICB9LCBbZGlzcGF0Y2hdKTtcblxuICAvLyBTY3JvbGwgbG9ja2luZ1xuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghc2Nyb2xsTG9jaykgcmV0dXJuO1xuXG4gICAgY29uc3QgJGh0bWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgY29uc3QgJGJvZHkgPSBkb2N1bWVudC5ib2R5O1xuXG4gICAgJGh0bWwuc3R5bGUub3ZlcmZsb3cgPSAnY2xpcCc7XG4gICAgJGJvZHkuc3R5bGUub3ZlcmZsb3cgPSAnY2xpcCc7XG5cbiAgICBjb25zdCBvblNjcm9sbCA9IChldmVudD86IEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBpZiAoZXZlbnQ/LmNhbmNlbGFibGUpIHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbyh7XG4gICAgICAgICAgbGVmdDogMCxcbiAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgYmVoYXZpb3I6ICdpbnN0YW50JyxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBvblNjcm9sbCgpO1xuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdzY3JvbGwnLCBvblNjcm9sbCwge1xuICAgICAgcGFzc2l2ZTogZmFsc2UsXG4gICAgfSk7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgJGh0bWwuc3R5bGUub3ZlcmZsb3cgPSAnJztcbiAgICAgICRib2R5LnN0eWxlLm92ZXJmbG93ID0gJyc7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgb25TY3JvbGwpO1xuICAgIH07XG4gIH0sIFtzY3JvbGxMb2NrXSk7XG5cbiAgY29uc3QgdGltZWxpbmVIZWlnaHQgPSBNYXRoLm1heChcbiAgICBzdGF0ZS50aW1lbGluZUhlaWdodCAtIHN0YXRlLnNjcm9sbGJhcldpZHRoLFxuICAgIE1BUktFUl9IRUlHSFQgK1xuICAgICAgUk9XX1BBRERJTkcgK1xuICAgICAgcm93cy5sZW5ndGggKiAoUk9XX0hFSUdIVCArIFJPV19QQURESU5HKSAtXG4gICAgICBST1dfUEFERElORyArXG4gICAgICAvLyBXaGVuIHRoZXJlIGFyZSBlbm91Z2ggc3BhbnMgdG8gYmUgbmVhciB0aGUgYm90dG9tIGVkZ2UsIGFkZCBzb21lIGV4dHJhIHBhZGRpbmdcbiAgICAgIC8vIHRvIGF2b2lkIG92ZXJsYXBwaW5nIHdpdGggdGhlIHpvb20gYnV0dG9ucywgZXRjLlxuICAgICAgODRcbiAgKTtcblxuICBjb25zdCBpbmVydCA9IEJvb2xlYW4oc3RhdGUuaXNNb2JpbGUgJiYgc3RhdGUuc2VsZWN0ZWQpO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgY2xhc3NOYW1lPXtjbHN4KFxuICAgICAgICBzdHlsZXMudHJhY2VWaWV3ZXIsXG4gICAgICAgIGlzU2tlbGV0b24gJiYgc3R5bGVzLnNrZWxldG9uLFxuICAgICAgICBjbGFzc05hbWVcbiAgICAgICl9XG4gICAgICBvbkNsaWNrQ2FwdHVyZT17b25DbGlja31cbiAgICAgIHJlZj17cmVmfVxuICAgICAgc3R5bGU9e1xuICAgICAgICB7XG4gICAgICAgICAgaGVpZ2h0LFxuICAgICAgICAgICctLXRpbWVsaW5lLXBhZGRpbmcnOiBgJHtUSU1FTElORV9QQURESU5HfXB4YCxcbiAgICAgICAgICAnLS1yb3ctaGVpZ2h0JzogYCR7Uk9XX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tcm93LXBhZGRpbmcnOiBgJHtST1dfUEFERElOR31weGAsXG4gICAgICAgICAgJy0tc2VhcmNoLWhlaWdodCc6IGAkeyFoaWRlU2VhcmNoQmFyID8gU0VBUkNIX0hFSUdIVCA6IDB9cHhgLFxuICAgICAgICAgICctLXNlYXJjaC1nYXAnOiBgJHshaGlkZVNlYXJjaEJhciA/IFNFQVJDSF9HQVAgOiAyfXB4YCxcbiAgICAgICAgICAnLS1tYXAtaGVpZ2h0JzogYCR7TUFQX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tdGltZWxpbmUtd2lkdGgnOiBgJHtzdGF0ZS50aW1lbGluZVdpZHRofXB4YCxcbiAgICAgICAgICAnLS10aW1lbGluZS1oZWlnaHQnOiBgJHtzdGF0ZS50aW1lbGluZUhlaWdodH1weGAsXG4gICAgICAgICAgJy0tdGltZWxpbmUtc2Nyb2xsLXdpZHRoJzogYCR7TWF0aC5yb3VuZChzdGF0ZS5yb290LmR1cmF0aW9uICogc3RhdGUuc2NhbGUpfXB4YCxcbiAgICAgICAgICAnLS1wYW5lbC13aWR0aCc6IGAke3N0YXRlLnBhbmVsV2lkdGh9cHhgLFxuICAgICAgICAgICctLXBhbmVsLWhlaWdodCc6IGAke3N0YXRlLnBhbmVsSGVpZ2h0fXB4YCxcbiAgICAgICAgICAnLS1oZWlnaHQnOiBgJHtzdGF0ZS5oZWlnaHR9cHhgLFxuICAgICAgICAgICctLXNjcm9sbGJhci13aWR0aCc6IGAke3N0YXRlLnNjcm9sbGJhcldpZHRofXB4YCxcbiAgICAgICAgICAnLS1tYXJrZXItaGVpZ2h0JzogYCR7TUFSS0VSX0hFSUdIVH1weGAsXG4gICAgICAgICAgJy0tbWFya2VyLW5vdGNoLWhlaWdodCc6IGAke01BUktFUl9OT1RDSF9IRUlHSFR9cHhgLFxuICAgICAgICB9IGFzIENTU1Byb3BlcnRpZXNcbiAgICAgIH1cbiAgICA+XG4gICAgICB7IWhpZGVTZWFyY2hCYXIgPyA8U2VhcmNoQmFyIC8+IDogbnVsbH1cbiAgICAgIDxNaW5pTWFwIHJvd3M9e3Jvd3N9IHNjYWxlPXtzY2FsZX0gdGltZWxpbmVSZWY9e3RpbWVsaW5lUmVmfSAvPlxuICAgICAgPGRpdiBjbGFzc05hbWU9e2Nsc3goc3R5bGVzLnRyYWNlVmlld2VyQ29udGVudCwgaW5lcnQgJiYgc3R5bGVzLmluZXJ0KX0+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtzdHlsZXMudGltZWxpbmV9IHJlZj17dGltZWxpbmVSZWZ9PlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIHN0eWxlPXt7XG4gICAgICAgICAgICAgIHBvc2l0aW9uOiAncmVsYXRpdmUnLFxuICAgICAgICAgICAgICB3aWR0aDogc3RhdGUudGltZWxpbmVXaWR0aCxcbiAgICAgICAgICAgICAgbWluSGVpZ2h0OiBzdGF0ZS50aW1lbGluZUhlaWdodCAtIFRJTUVMSU5FX1BBRERJTkcgKiAyLFxuICAgICAgICAgICAgICBwYWRkaW5nOiBUSU1FTElORV9QQURESU5HLFxuICAgICAgICAgICAgICBwYWRkaW5nQm90dG9tOiAwLFxuICAgICAgICAgICAgfX1cbiAgICAgICAgICA+XG4gICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgIGNsYXNzTmFtZT17c3R5bGVzLnRyYWNlTm9kZX1cbiAgICAgICAgICAgICAgc3R5bGU9e3tcbiAgICAgICAgICAgICAgICB3aWR0aDogc3RhdGUucm9vdC5kdXJhdGlvbiAqIHNjYWxlIHx8IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRpbWVsaW5lSGVpZ2h0IC0gVElNRUxJTkVfUEFERElORyAqIDIsXG4gICAgICAgICAgICAgIH19XG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxNYXJrZXJzIHNjYWxlPXtzY2FsZX0gaXNMaXZlPXtpc0xpdmV9IC8+XG4gICAgICAgICAgICAgIDxFdmVudE1hcmtlcnMgZXZlbnRzPXtldmVudHN9IHJvb3Q9e3N0YXRlLnJvb3R9IHNjYWxlPXtzY2FsZX0gLz5cbiAgICAgICAgICAgICAgPEN1cnNvck1hcmtlclxuICAgICAgICAgICAgICAgIGRpc3BhdGNoPXtkaXNwYXRjaH1cbiAgICAgICAgICAgICAgICBldmVudHM9e2V2ZW50c31cbiAgICAgICAgICAgICAgICBtZW1vQ2FjaGVSZWY9e3N0YXRlLm1lbW9DYWNoZVJlZn1cbiAgICAgICAgICAgICAgICByb290PXtzdGF0ZS5yb290fVxuICAgICAgICAgICAgICAgIHNjYWxlPXtzY2FsZX1cbiAgICAgICAgICAgICAgICBzY3JvbGxTbmFwc2hvdFJlZj17c2Nyb2xsU25hcHNob3RSZWZ9XG4gICAgICAgICAgICAgICAgc3BhbnM9e3NwYW5zfVxuICAgICAgICAgICAgICAgIHRpbWVsaW5lUmVmPXt0aW1lbGluZVJlZn1cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPFNwYW5Ob2Rlc1xuICAgICAgICAgICAgICAgIGNhY2hlS2V5PXttZW1vQ2FjaGUuZ2V0KCcnKX1cbiAgICAgICAgICAgICAgICBjYWNoZT17bWVtb0NhY2hlfVxuICAgICAgICAgICAgICAgIGN1c3RvbVNwYW5DbGFzc05hbWVGdW5jPXtzdGF0ZS5jdXN0b21TcGFuQ2xhc3NOYW1lRnVuY31cbiAgICAgICAgICAgICAgICBjdXN0b21TcGFuRXZlbnRDbGFzc05hbWVGdW5jPXtcbiAgICAgICAgICAgICAgICAgIHN0YXRlLmN1c3RvbVNwYW5FdmVudENsYXNzTmFtZUZ1bmNcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaXNMaXZlPXtpc0xpdmV9XG4gICAgICAgICAgICAgICAgcm9vdD17c3RhdGUucm9vdH1cbiAgICAgICAgICAgICAgICBzY2FsZT17c2NhbGV9XG4gICAgICAgICAgICAgICAgc2Nyb2xsU25hcHNob3RSZWY9e3Njcm9sbFNuYXBzaG90UmVmfVxuICAgICAgICAgICAgICAgIHNwYW5zPXtzcGFuc31cbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgey8qIEhvcml6b250YWwgXCJ1bmtub3duIHRpbWVcIiBvdmVybGF5IOKAlCBjb3ZlcnMgdGhlIHJlZ2lvbiB0byB0aGVcbiAgICAgICAgICAgICAgICAgIHJpZ2h0IG9mIHRoZSBsYXRlc3Qga25vd24gZXZlbnQsIGluZGljYXRpbmcgZGF0YSBiZXlvbmQgdGhpc1xuICAgICAgICAgICAgICAgICAgcG9pbnQgaGFzbid0IGJlZW4gbG9hZGVkIHlldC4gKi99XG4gICAgICAgICAgICAgIHtrbm93bkR1cmF0aW9uTXMgIT0gbnVsbCAmJlxuICAgICAgICAgICAgICAgIGtub3duRHVyYXRpb25NcyA+IDAgJiZcbiAgICAgICAgICAgICAgICAoaGFzTW9yZURhdGEgfHwgaXNMaXZlKSAmJlxuICAgICAgICAgICAgICAgIHN0YXRlLnJvb3QuZHVyYXRpb24gPiAwICYmXG4gICAgICAgICAgICAgICAgKCgpID0+IHtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IGtub3duUHggPSBrbm93bkR1cmF0aW9uTXMgKiBzY2FsZTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IHRvdGFsUHggPSBzdGF0ZS5yb290LmR1cmF0aW9uICogc2NhbGU7XG4gICAgICAgICAgICAgICAgICBjb25zdCB1bmtub3duV2lkdGggPSB0b3RhbFB4IC0ga25vd25QeDtcbiAgICAgICAgICAgICAgICAgIC8vIE9ubHkgc2hvdyBpZiB0aGUgdW5rbm93biByZWdpb24gaXMgbWVhbmluZ2Z1bGx5IHdpZGVcbiAgICAgICAgICAgICAgICAgIGlmICh1bmtub3duV2lkdGggPCA0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgIC8vIE9mZnNldCB+NSUgaW50byB0aGUgdW5rbm93biByZWdpb24gc28gaXQgZG9lc24ndCB0b3VjaCBzcGFuc1xuICAgICAgICAgICAgICAgICAgY29uc3QgaW5zZXRQeCA9IE1hdGgubWluKHVua25vd25XaWR0aCAqIDAuMDUsIDIwKTtcbiAgICAgICAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICBzdHlsZT17e1xuICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0OiBrbm93blB4ICsgaW5zZXRQeCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHdpZHRoOiB1bmtub3duV2lkdGggLSBpbnNldFB4LFxuICAgICAgICAgICAgICAgICAgICAgICAgaGVpZ2h0OiAnMTAwJScsXG4gICAgICAgICAgICAgICAgICAgICAgICBwb2ludGVyRXZlbnRzOiAnbm9uZScsXG4gICAgICAgICAgICAgICAgICAgICAgICB6SW5kZXg6IDEsXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXNrSW1hZ2U6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdsaW5lYXItZ3JhZGllbnQodG8gcmlnaHQsIHRyYW5zcGFyZW50IDElLCBibGFjayAzJSknLFxuICAgICAgICAgICAgICAgICAgICAgICAgV2Via2l0TWFza0ltYWdlOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAnbGluZWFyLWdyYWRpZW50KHRvIHJpZ2h0LCB0cmFuc3BhcmVudCAxJSwgYmxhY2sgMyUpJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICdyZXBlYXRpbmctbGluZWFyLWdyYWRpZW50KC00NWRlZywgdmFyKC0tZHMtYmFja2dyb3VuZC0yMDApIDAsIHZhcigtLWRzLWJhY2tncm91bmQtMjAwKSAxMXB4LCB2YXIoLS1kcy1ncmF5LTIwMCkgMTFweCwgdmFyKC0tZHMtZ3JheS0yMDApIDEycHgpJyxcbiAgICAgICAgICAgICAgICAgICAgICB9fVxuICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9KSgpfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAge2Zvb3Rlcn1cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgY2xhc3NOYW1lPXtzdHlsZXMuem9vbUJ1dHRvblRyYWNlVmlld2VyfT5cbiAgICAgICAgICA8Wm9vbUJ1dHRvbiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAge3dpdGhQYW5lbCA/IChcbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzTmFtZT17Y2xzeChcbiAgICAgICAgICAgIHN0eWxlcy5zcGFuRGV0YWlsUGFuZWxUcmFjZVZpZXdlcixcbiAgICAgICAgICAgICFzdGF0ZS5zZWxlY3RlZCAmJiBzdHlsZXMuaGlkZGVuLFxuICAgICAgICAgICAgc3RhdGUuaXNNb2JpbGUgJiYgc3R5bGVzLm1vYmlsZVxuICAgICAgICAgICl9XG4gICAgICAgID5cbiAgICAgICAgICA8U3BhbkRldGFpbFBhbmVsIGF0dGFjaGVkIC8+XG4gICAgICAgIDwvZGl2PlxuICAgICAgKSA6IG51bGx9XG4gICAgPC9kaXY+XG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBUcmFjZVZpZXdlclBhbmVsKHtcbiAgY2xhc3NOYW1lID0gJycsXG4gIGNoaWxkcmVuID0gbnVsbCxcbn06IHtcbiAgY2xhc3NOYW1lPzogc3RyaW5nO1xuICBjaGlsZHJlbj86IFJlYWN0Tm9kZTtcbn0pOiBSZWFjdE5vZGUge1xuICBjb25zdCB7IHN0YXRlIH0gPSB1c2VUcmFjZVZpZXdlcigpO1xuXG4gIGlmICghc3RhdGUuc2VsZWN0ZWQpIHtcbiAgICByZXR1cm4gY2hpbGRyZW47XG4gIH1cblxuICByZXR1cm4gKFxuICAgIDxkaXZcbiAgICAgIGNsYXNzTmFtZT17Y2xzeChzdHlsZXMuc3BhbkRldGFpbFBhbmVsVHJhY2VWaWV3ZXIsIGNsYXNzTmFtZSl9XG4gICAgICBzdHlsZT17XG4gICAgICAgIHtcbiAgICAgICAgICBwb3NpdGlvbjogJ3JlbGF0aXZlJyxcbiAgICAgICAgICAnLS1zZWFyY2gtaGVpZ2h0JzogJzAnLFxuICAgICAgICAgICctLXNlYXJjaC1nYXAnOiAnMCcsXG4gICAgICAgICAgJy0tbWFwLWhlaWdodCc6ICcwJyxcbiAgICAgICAgICAnLS1wYW5lbC13aWR0aCc6IGAxMDAlYCxcbiAgICAgICAgICAnLS1wYW5lbC1oZWlnaHQnOiBgMTAwJWAsXG4gICAgICAgICAgJy0taGVpZ2h0JzogYDEwMCVgLFxuICAgICAgICAgICctLXNjcm9sbGJhci13aWR0aCc6IGAke3N0YXRlLnNjcm9sbGJhcldpZHRofXB4YCxcbiAgICAgICAgfSBhcyBDU1NQcm9wZXJ0aWVzXG4gICAgICB9XG4gICAgPlxuICAgICAgPFNwYW5EZXRhaWxQYW5lbCAvPlxuICAgIDwvZGl2PlxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gVHJhY2VWaWV3ZXIocHJvcHM6IFRyYWNlVmlld2VyUHJvcHMpOiBSZWFjdE5vZGUge1xuICByZXR1cm4gKFxuICAgIDxUcmFjZVZpZXdlckNvbnRleHRQcm92aWRlciBnZXRRdWlja0xpbmtzPXtwcm9wcy5nZXRRdWlja0xpbmtzfSB3aXRoUGFuZWw+XG4gICAgICA8VHJhY2VWaWV3ZXJUaW1lbGluZSB3aXRoUGFuZWwgey4uLnByb3BzfSAvPlxuICAgIDwvVHJhY2VWaWV3ZXJDb250ZXh0UHJvdmlkZXI+XG4gICk7XG59XG4iXX0=
|
|
336
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhY2Utdmlld2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL2NvbXBvbmVudHMvdHJhY2Utdmlld2VyL3RyYWNlLXZpZXdlci50c3giXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOztBQUViLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDbEUsT0FBTyxFQUVMLFdBQVcsRUFDWCxnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULE9BQU8sRUFDUCxNQUFNLEVBQ04sUUFBUSxHQUNULE1BQU0sT0FBTyxDQUFDO0FBQ2YsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDaEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQzdELE9BQU8sU0FBUyxNQUFNLHlCQUF5QixDQUFDO0FBQ2hELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMvQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUNMLG1CQUFtQixFQUNuQixRQUFRLEVBQ1IsY0FBYyxHQUVmLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDekUsT0FBTyxFQUFFLGFBQWEsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDZC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RSxnQkFBZ0IsRUFDOUIsS0FBSyxFQUFFLEtBQUssRUFDWixPQUFPLEVBQUUsT0FBTyxHQUNoQixHQUNFLEVBQ04sOEJBQ0UsS0FBQyxtQkFBbUIsSUFDbEIsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUN4QyxhQUFhLEVBQUUsYUFBYSxHQUM1QixFQUNGLGVBQUssU0FBUyxFQUFDLDBKQUEwSixhQUN2SyxLQUFDLFVBQVUsSUFDVCxPQUFPLEVBQUMsT0FBTyxFQUNmLElBQUksRUFBQyxPQUFPLEVBQ1osT0FBTyxFQUFFLE9BQU8sRUFDaEIsUUFBUSxFQUFFLFdBQVcsZ0JBQ1YsVUFBVSxZQUVyQixLQUFDLE9BQU8sSUFBQyxTQUFTLEVBQUMsU0FBUyxHQUFHLEdBQ3BCLEVBQ2IsS0FBQyxVQUFVLElBQ1QsT0FBTyxFQUFDLE9BQU8sRUFDZixJQUFJLEVBQUMsT0FBTyxFQUNaLE9BQU8sRUFBRSxTQUFTLGdCQUNQLFlBQVksWUFFdkIsS0FBQyxTQUFTLElBQUMsU0FBUyxFQUFDLGFBQWEsR0FBRyxHQUMxQixFQUNiLEtBQUMsVUFBVSxJQUNULE9BQU8sRUFBQyxPQUFPLEVBQ2YsSUFBSSxFQUFDLE9BQU8sRUFDWixPQUFPLEVBQUUsTUFBTSxFQUNmLFFBQVEsRUFBRSxXQUFXLGdCQUNWLFNBQVMsWUFFcEIsS0FBQyxNQUFNLElBQUMsU0FBUyxFQUFDLFNBQVMsR0FBRyxHQUNuQixJQUNULElBQ0wsSUFDTyxJQUNSLEVBRU4sS0FBQyxnQkFBZ0IsSUFDZixZQUFZLEVBQUUsV0FBVyxFQUN6QixnQkFBZ0IsRUFBRSxjQUFjLEVBQ2hDLE9BQU8sRUFBRSxxQkFBcUIsR0FDOUIsSUFDRSxDQUNQLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBjbGllbnQnO1xuXG5pbXBvcnQgeyBSb3RhdGVDY3csIFNlYXJjaCwgWm9vbUluLCBab29tT3V0IH0gZnJvbSAnbHVjaWRlLXJlYWN0JztcbmltcG9ydCB7XG4gIHR5cGUgUmVhY3ROb2RlLFxuICB1c2VDYWxsYmFjayxcbiAgdXNlRGVmZXJyZWRWYWx1ZSxcbiAgdXNlRWZmZWN0LFxuICB1c2VNZW1vLFxuICB1c2VSZWYsXG4gIHVzZVN0YXRlLFxufSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyB1c2VMb2FkTW9yZU9uU2Nyb2xsIH0gZnJvbSAnLi4vLi4vaG9va3MvdXNlLWxvYWQtbW9yZS1vbi1zY3JvbGwnO1xuaW1wb3J0IHsgdXNlUmVkdWNlZE1vdGlvbiB9IGZyb20gJy4uLy4uL2hvb2tzL3VzZS1yZWR1Y2VkLW1vdGlvbic7XG5pbXBvcnQgeyBJY29uQnV0dG9uIH0gZnJvbSAnLi4vdWkvaWNvbi1idXR0b24nO1xuaW1wb3J0IHsgS2JkIH0gZnJvbSAnLi4vdWkva2JkJztcbmltcG9ydCB7IFNwaW5uZXIgfSBmcm9tICcuLi91aS9zcGlubmVyJztcbmltcG9ydCB7IFRvb2x0aXBQcm92aWRlciB9IGZyb20gJy4uL3VpL3Rvb2x0aXAnO1xuaW1wb3J0IHsgVHJhY2VEZXRhaWxQYW5lbCB9IGZyb20gJy4vY29tcG9uZW50cy9kZXRhaWwtcGFuZWwnO1xuaW1wb3J0IEV2ZW50TGlzdCBmcm9tICcuL2NvbXBvbmVudHMvZXZlbnQtbGlzdCc7XG5pbXBvcnQgeyBNaW5pbWFwIH0gZnJvbSAnLi9jb21wb25lbnRzL21pbmltYXAnO1xuaW1wb3J0IHsgU3BsaXRQYW5lIH0gZnJvbSAnLi9jb21wb25lbnRzL3NwbGl0LXBhbmUnO1xuaW1wb3J0IHtcbiAgVElNRUxJTkVfUEFERElOR19QWCxcbiAgVGltZWxpbmUsXG4gIFRpbWVsaW5lSGVhZGVyLFxuICB0eXBlIFRpbWVsaW5lSG92ZXIsXG59IGZyb20gJy4vY29tcG9uZW50cy90aW1lbGluZSc7XG5pbXBvcnQgeyBUcmFjZVNob3J0Y3V0SGVscGVyIH0gZnJvbSAnLi9jb21wb25lbnRzL3RyYWNlLXNob3J0Y3V0LWhlbHBlcic7XG5pbXBvcnQgeyBST1dfSEVJR0hUX1BYLCBzY3JvbGxSb3dJbnRvVmlldyB9IGZyb20gJy4vY29tcG9uZW50cy91c2Utcm93LXdpbmRvdyc7XG5pbXBvcnQgeyBBY3RpdmVTcGFuUHJvdmlkZXIsIHVzZUFjdGl2ZVNwYW4gfSBmcm9tICcuL2NvbnRleHQnO1xuaW1wb3J0IHsgc2VhcmNoU3BhbnMgfSBmcm9tICcuL3NlYXJjaCc7XG5pbXBvcnQgdHlwZSB7IFRyYWNlV2l0aE1ldGEgfSBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7IGZvcm1hdER1cmF0aW9uUHJlY2lzZSwgZ2V0SGlnaFJlc0luTXMgfSBmcm9tICcuL3V0aWwvdGltaW5nJztcbmltcG9ydCB7XG4gIGNsYW1wVmlld3BvcnRUb1Jvb3QsXG4gIGNvbXB1dGVSb290Qm91bmRzLFxuICBjb21wdXRlVGltZU1hcmtlcnMsXG4gIHR5cGUgVmlld3BvcnRSYW5nZSxcbiAgd2hlZWxEZWx0YVRvUGl4ZWxzLFxuICB3aGVlbFpvb21TY2FsZUZhY3Rvcixcbn0gZnJvbSAnLi91dGlscyc7XG5cbmludGVyZmFjZSBUcmFjZVZpZXdlclByb3BzIHtcbiAgdHJhY2U6IFRyYWNlV2l0aE1ldGE7XG4gIG9uTG9hZE1vcmU/OiAoKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPjtcbiAgaGFzTW9yZT86IGJvb2xlYW47XG4gIGlzTG9hZGluZ01vcmU/OiBib29sZWFuO1xufVxuXG5jb25zdCBNSU5fVklFV1BPUlRfTVMgPSAwLjAwMTtcblxuY29uc3QgWk9PTV9ERUJPVU5DRV9NUyA9IDE1MDtcblxuZnVuY3Rpb24gdXNlQW5pbWF0ZWRWaWV3cG9ydChpbml0aWFsOiBWaWV3cG9ydFJhbmdlKSB7XG4gIGNvbnN0IFt2aWV3cG9ydCwgc2V0Vmlld3BvcnRTdGF0ZV0gPSB1c2VTdGF0ZTxWaWV3cG9ydFJhbmdlPihpbml0aWFsKTtcbiAgY29uc3QgYW5pbVJlZiA9IHVzZVJlZjx7XG4gICAgcmFmOiBudW1iZXI7XG4gICAgZnJvbTogVmlld3BvcnRSYW5nZTtcbiAgICB0bzogVmlld3BvcnRSYW5nZTtcbiAgICBzdGFydDogbnVtYmVyO1xuICB9IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGN1cnJlbnRSZWYgPSB1c2VSZWYoaW5pdGlhbCk7XG4gIGN1cnJlbnRSZWYuY3VycmVudCA9IHZpZXdwb3J0O1xuICBjb25zdCByZWR1Y2VkTW90aW9uID0gdXNlUmVkdWNlZE1vdGlvbigpO1xuXG4gIGNvbnN0IGNhbmNlbCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBpZiAoYW5pbVJlZi5jdXJyZW50KSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZShhbmltUmVmLmN1cnJlbnQucmFmKTtcbiAgICAgIGFuaW1SZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3QgYW5pbWF0ZVRvID0gdXNlQ2FsbGJhY2soXG4gICAgKHRhcmdldDogVmlld3BvcnRSYW5nZSkgPT4ge1xuICAgICAgY2FuY2VsKCk7XG5cbiAgICAgIGlmIChyZWR1Y2VkTW90aW9uKSB7XG4gICAgICAgIGN1cnJlbnRSZWYuY3VycmVudCA9IHRhcmdldDtcbiAgICAgICAgc2V0Vmlld3BvcnRTdGF0ZSh0YXJnZXQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGZyb20gPSBjdXJyZW50UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBhbmltID0geyByYWY6IDAsIGZyb20sIHRvOiB0YXJnZXQsIHN0YXJ0OiBwZXJmb3JtYW5jZS5ub3coKSB9O1xuXG4gICAgICBjb25zdCB0aWNrID0gKCkgPT4ge1xuICAgICAgICBjb25zdCB0ID0gTWF0aC5taW4oKHBlcmZvcm1hbmNlLm5vdygpIC0gYW5pbS5zdGFydCkgLyAyNDAsIDEpO1xuICAgICAgICBjb25zdCBlID0gdCA8IDAuNSA/IDggKiB0ICogdCAqIHQgKiB0IDogMSAtICgtMiAqIHQgKyAyKSAqKiA0IC8gMjtcbiAgICAgICAgc2V0Vmlld3BvcnRTdGF0ZSh7XG4gICAgICAgICAgc3RhcnQ6IGFuaW0uZnJvbS5zdGFydCArIChhbmltLnRvLnN0YXJ0IC0gYW5pbS5mcm9tLnN0YXJ0KSAqIGUsXG4gICAgICAgICAgZW5kOiBhbmltLmZyb20uZW5kICsgKGFuaW0udG8uZW5kIC0gYW5pbS5mcm9tLmVuZCkgKiBlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKHQgPCAxKSBhbmltLnJhZiA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSh0aWNrKTtcbiAgICAgICAgZWxzZSBhbmltUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgfTtcblxuICAgICAgYW5pbVJlZi5jdXJyZW50ID0gYW5pbTtcbiAgICAgIGFuaW0ucmFmID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRpY2spO1xuICAgIH0sXG4gICAgW2NhbmNlbCwgcmVkdWNlZE1vdGlvbl1cbiAgKTtcblxuICBjb25zdCBzZXRWaWV3cG9ydCA9IHVzZUNhbGxiYWNrKFxuICAgICh1cGRhdGU6IFZpZXdwb3J0UmFuZ2UgfCAoKHByZXY6IFZpZXdwb3J0UmFuZ2UpID0+IFZpZXdwb3J0UmFuZ2UpKSA9PiB7XG4gICAgICBjYW5jZWwoKTtcbiAgICAgIGlmICh0eXBlb2YgdXBkYXRlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHNldFZpZXdwb3J0U3RhdGUoKHByZXYpID0+IHtcbiAgICAgICAgICBjb25zdCBuZXh0ID0gdXBkYXRlKHByZXYpO1xuICAgICAgICAgIGN1cnJlbnRSZWYuY3VycmVudCA9IG5leHQ7XG4gICAgICAgICAgcmV0dXJuIG5leHQ7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudFJlZi5jdXJyZW50ID0gdXBkYXRlO1xuICAgICAgICBzZXRWaWV3cG9ydFN0YXRlKHVwZGF0ZSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBbY2FuY2VsXVxuICApO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiBjYW5jZWwsIFtjYW5jZWxdKTtcblxuICByZXR1cm4geyB2aWV3cG9ydCwgc2V0Vmlld3BvcnQsIGFuaW1hdGVUbyB9O1xufVxuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJvb3QgY29tcG9uZW50XG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuZXhwb3J0IGZ1bmN0aW9uIFRyYWNlVmlld2VyKHtcbiAgdHJhY2UsXG4gIG9uTG9hZE1vcmUsXG4gIGhhc01vcmUsXG4gIGlzTG9hZGluZ01vcmUsXG59OiBUcmFjZVZpZXdlclByb3BzKTogUmVhY3ROb2RlIHtcbiAgcmV0dXJuIChcbiAgICA8VG9vbHRpcFByb3ZpZGVyIGRlbGF5RHVyYXRpb249ezMwMH0+XG4gICAgICA8QWN0aXZlU3BhblByb3ZpZGVyIHNwYW5zPXt0cmFjZS5zcGFuc30+XG4gICAgICAgIDxUcmFjZVZpZXdlckNvbnRlbnRcbiAgICAgICAgICB0cmFjZT17dHJhY2V9XG4gICAgICAgICAgb25Mb2FkTW9yZT17b25Mb2FkTW9yZX1cbiAgICAgICAgICBoYXNNb3JlPXtoYXNNb3JlfVxuICAgICAgICAgIGlzTG9hZGluZ01vcmU9e2lzTG9hZGluZ01vcmV9XG4gICAgICAgIC8+XG4gICAgICA8L0FjdGl2ZVNwYW5Qcm92aWRlcj5cbiAgICA8L1Rvb2x0aXBQcm92aWRlcj5cbiAgKTtcbn1cblxuZnVuY3Rpb24gVHJhY2VWaWV3ZXJDb250ZW50KHtcbiAgdHJhY2UsXG4gIG9uTG9hZE1vcmUsXG4gIGhhc01vcmUsXG4gIGlzTG9hZGluZ01vcmUsXG59OiBUcmFjZVZpZXdlclByb3BzKTogUmVhY3ROb2RlIHtcbiAgY29uc3QgeyBhY3RpdmVTcGFuSWQsIHNldEFjdGl2ZVNwYW4sIGNsZWFyQWN0aXZlU3BhbiB9ID0gdXNlQWN0aXZlU3BhbigpO1xuXG4gIGNvbnN0IHJlZHVjZWRNb3Rpb24gPSB1c2VSZWR1Y2VkTW90aW9uKCk7XG5cbiAgY29uc3QgW3NlYXJjaFF1ZXJ5LCBzZXRTZWFyY2hRdWVyeV0gPSB1c2VTdGF0ZSgnJyk7XG4gIGNvbnN0IGRlZmVycmVkU2VhcmNoUXVlcnkgPSB1c2VEZWZlcnJlZFZhbHVlKHNlYXJjaFF1ZXJ5KTtcblxuICBjb25zdCBwYW5lUm9vdFJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG5cbiAgY29uc3Qgc2VhcmNoUmVzdWx0ID0gdXNlTWVtbyhcbiAgICAoKSA9PiBzZWFyY2hTcGFucyh0cmFjZS5zcGFucywgZGVmZXJyZWRTZWFyY2hRdWVyeSksXG4gICAgW3RyYWNlLnNwYW5zLCBkZWZlcnJlZFNlYXJjaFF1ZXJ5XVxuICApO1xuXG4gIGNvbnN0IHJvb3QgPSB1c2VNZW1vKCgpID0+IGNvbXB1dGVSb290Qm91bmRzKHRyYWNlLnNwYW5zKSwgW3RyYWNlLnNwYW5zXSk7XG5cbiAgY29uc3Qgc2Nyb2xsQ29udGFpbmVyUmVmID0gdXNlUmVmPEhUTUxEaXZFbGVtZW50PihudWxsKTtcbiAgY29uc3QgbG9hZE1vcmUgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgdm9pZCBvbkxvYWRNb3JlPy4oKTtcbiAgfSwgW29uTG9hZE1vcmVdKTtcbiAgY29uc3QgbG9hZE1vcmVTZW50aW5lbFJlZiA9IHVzZUxvYWRNb3JlT25TY3JvbGwobG9hZE1vcmUsIHtcbiAgICBoYXNNb3JlOiBCb29sZWFuKG9uTG9hZE1vcmUgJiYgaGFzTW9yZSksXG4gICAgaXNMb2FkaW5nTW9yZTogQm9vbGVhbihpc0xvYWRpbmdNb3JlKSxcbiAgICByb290UmVmOiBzY3JvbGxDb250YWluZXJSZWYsXG4gIH0pO1xuXG4gIGNvbnN0IHsgdmlld3BvcnQsIHNldFZpZXdwb3J0LCBhbmltYXRlVG8gfSA9IHVzZUFuaW1hdGVkVmlld3BvcnQoe1xuICAgIHN0YXJ0OiByb290LnN0YXJ0VGltZSxcbiAgICBlbmQ6IHJvb3Quc3RhcnRUaW1lICsgcm9vdC5kdXJhdGlvbixcbiAgfSk7XG5cbiAgY29uc3QgcHJldlJvb3RSZWYgPSB1c2VSZWY8Vmlld3BvcnRSYW5nZT4oe1xuICAgIHN0YXJ0OiByb290LnN0YXJ0VGltZSxcbiAgICBlbmQ6IHJvb3Quc3RhcnRUaW1lICsgcm9vdC5kdXJhdGlvbixcbiAgfSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBwcmV2Um9vdCA9IHByZXZSb290UmVmLmN1cnJlbnQ7XG4gICAgY29uc3QgbmV3U3RhcnQgPSByb290LnN0YXJ0VGltZTtcbiAgICBjb25zdCBuZXdFbmQgPSByb290LnN0YXJ0VGltZSArIHJvb3QuZHVyYXRpb247XG5cbiAgICBzZXRWaWV3cG9ydCgocHJldikgPT4ge1xuICAgICAgY29uc3Qgd2FzQXRGdWxsRXh0ZW50ID1cbiAgICAgICAgTWF0aC5hYnMocHJldi5zdGFydCAtIHByZXZSb290LnN0YXJ0KSA8IDAuMDEgJiZcbiAgICAgICAgTWF0aC5hYnMocHJldi5lbmQgLSBwcmV2Um9vdC5lbmQpIDwgMC4wMTtcblxuICAgICAgaWYgKHdhc0F0RnVsbEV4dGVudCkge1xuICAgICAgICByZXR1cm4geyBzdGFydDogbmV3U3RhcnQsIGVuZDogbmV3RW5kIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gcHJldjtcbiAgICB9KTtcblxuICAgIHByZXZSb290UmVmLmN1cnJlbnQgPSB7IHN0YXJ0OiBuZXdTdGFydCwgZW5kOiBuZXdFbmQgfTtcbiAgfSwgW3Jvb3Quc3RhcnRUaW1lLCByb290LmR1cmF0aW9uLCBzZXRWaWV3cG9ydF0pO1xuXG4gIGNvbnN0IHZpZXdEdXJhdGlvbiA9IHZpZXdwb3J0LmVuZCAtIHZpZXdwb3J0LnN0YXJ0O1xuXG4gIC8vIEtlZXAgYSByZWYgdG8gdGhlIGxpdmUgdmlld3BvcnQgc28gem9vbSBjYWxsYmFja3MgY2FuIHJlYWQgdGhlIGN1cnJlbnRcbiAgLy8gcmFuZ2Ugd2l0aG91dCBiZWluZyByZWNyZWF0ZWQgb24gZXZlcnkgcGFuICh3aGljaCB3b3VsZCBidXN0IFRpbWVsaW5lQmFyJ3NcbiAgLy8gbWVtbyBhbmQgcmUtcmVuZGVyIGV2ZXJ5IHJvdyBlYWNoIGFuaW1hdGlvbiBmcmFtZSkuXG4gIGNvbnN0IHZpZXdwb3J0UmVmID0gdXNlUmVmKHZpZXdwb3J0KTtcbiAgdmlld3BvcnRSZWYuY3VycmVudCA9IHZpZXdwb3J0O1xuXG4gIGNvbnN0IHRpbWVNYXJrZXJzID0gdXNlTWVtbyhcbiAgICAoKSA9PiBjb21wdXRlVGltZU1hcmtlcnModmlld0R1cmF0aW9uLCB2aWV3cG9ydC5zdGFydCAtIHJvb3Quc3RhcnRUaW1lKSxcbiAgICBbdmlld0R1cmF0aW9uLCB2aWV3cG9ydC5zdGFydCwgcm9vdC5zdGFydFRpbWVdXG4gICk7XG5cbiAgY29uc3QgcmVzZXRab29tID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGFuaW1hdGVUbyh7IHN0YXJ0OiByb290LnN0YXJ0VGltZSwgZW5kOiByb290LnN0YXJ0VGltZSArIHJvb3QuZHVyYXRpb24gfSk7XG4gIH0sIFthbmltYXRlVG8sIHJvb3Quc3RhcnRUaW1lLCByb290LmR1cmF0aW9uXSk7XG5cbiAgY29uc3QgY2xhbXBUb1Jvb3QgPSB1c2VDYWxsYmFjayhcbiAgICAobmV4dDogVmlld3BvcnRSYW5nZSk6IFZpZXdwb3J0UmFuZ2UgPT5cbiAgICAgIGNsYW1wVmlld3BvcnRUb1Jvb3QobmV4dCwgcm9vdC5zdGFydFRpbWUsIHJvb3QuZW5kVGltZSwgTUlOX1ZJRVdQT1JUX01TKSxcbiAgICBbcm9vdC5zdGFydFRpbWUsIHJvb3QuZW5kVGltZV1cbiAgKTtcblxuICAvLyBQYW4gKGtlZXBpbmcgdGhlIGN1cnJlbnQgem9vbSkgc28gYHRpbWVNc2AgaXMgY2VudGVyZWQgaW4gdmlldyDigJQgdXNlZCBieSB0aGVcbiAgLy8gb2ZmLXNjcmVlbiBtYXJrZXIgaW5kaWNhdG9ycyB0byBzY3JvbGwgdGhlaXIgbWFya2VyIGludG8gdmlldy5cbiAgY29uc3QgaGFuZGxlUmV2ZWFsVGltZSA9IHVzZUNhbGxiYWNrKFxuICAgICh0aW1lTXM6IG51bWJlcikgPT4ge1xuICAgICAgY29uc3QgeyBzdGFydCwgZW5kIH0gPSB2aWV3cG9ydFJlZi5jdXJyZW50O1xuICAgICAgY29uc3QgZHVyYXRpb24gPSBlbmQgLSBzdGFydDtcbiAgICAgIGFuaW1hdGVUbyhcbiAgICAgICAgY2xhbXBUb1Jvb3Qoe1xuICAgICAgICAgIHN0YXJ0OiB0aW1lTXMgLSBkdXJhdGlvbiAvIDIsXG4gICAgICAgICAgZW5kOiB0aW1lTXMgKyBkdXJhdGlvbiAvIDIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FuaW1hdGVUbywgY2xhbXBUb1Jvb3RdXG4gICk7XG5cbiAgY29uc3QgWk9PTV9GQUNUT1IgPSAwLjU7XG5cbiAgY29uc3Qgem9vbUJ5ID0gdXNlQ2FsbGJhY2soXG4gICAgKGZhY3RvcjogbnVtYmVyKSA9PiB7XG4gICAgICBjb25zdCB7IHN0YXJ0LCBlbmQgfSA9IHZpZXdwb3J0UmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBjZW50ZXIgPSAoc3RhcnQgKyBlbmQpIC8gMjtcbiAgICAgIGNvbnN0IG5ld0R1cmF0aW9uID0gTWF0aC5tYXgoTUlOX1ZJRVdQT1JUX01TLCAoZW5kIC0gc3RhcnQpICogZmFjdG9yKTtcbiAgICAgIGFuaW1hdGVUbyhcbiAgICAgICAgY2xhbXBUb1Jvb3Qoe1xuICAgICAgICAgIHN0YXJ0OiBjZW50ZXIgLSBuZXdEdXJhdGlvbiAvIDIsXG4gICAgICAgICAgZW5kOiBjZW50ZXIgKyBuZXdEdXJhdGlvbiAvIDIsXG4gICAgICAgIH0pXG4gICAgICApO1xuICAgIH0sXG4gICAgW2FuaW1hdGVUbywgY2xhbXBUb1Jvb3RdXG4gICk7XG5cbiAgY29uc3Qgem9vbUluID0gdXNlQ2FsbGJhY2soKCkgPT4gem9vbUJ5KFpPT01fRkFDVE9SKSwgW3pvb21CeV0pO1xuICBjb25zdCB6b29tT3V0ID0gdXNlQ2FsbGJhY2soKCkgPT4gem9vbUJ5KDEgLyBaT09NX0ZBQ1RPUiksIFt6b29tQnldKTtcbiAgY29uc3QgaXNBdE1pblpvb20gPSB2aWV3RHVyYXRpb24gPj0gcm9vdC5kdXJhdGlvbjtcbiAgY29uc3QgaXNBdE1heFpvb20gPSB2aWV3RHVyYXRpb24gPD0gTUlOX1ZJRVdQT1JUX01TO1xuXG4gIGNvbnN0IGZvY3VzVmlld3BvcnRPblNwYW4gPSB1c2VDYWxsYmFjayhcbiAgICAoc3BhbklkOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHNwYW4gPSB0cmFjZS5zcGFucy5maW5kKChzKSA9PiBzLnNwYW5JZCA9PT0gc3BhbklkKTtcbiAgICAgIGlmICghc3BhbikgcmV0dXJuO1xuXG4gICAgICBjb25zdCBzcGFuU3RhcnQgPSBnZXRIaWdoUmVzSW5NcyhzcGFuLnN0YXJ0VGltZSk7XG4gICAgICBjb25zdCBzcGFuRW5kID0gZ2V0SGlnaFJlc0luTXMoc3Bhbi5lbmRUaW1lKTtcbiAgICAgIGNvbnN0IHNwYW5EdXJhdGlvbiA9IHNwYW5FbmQgLSBzcGFuU3RhcnQ7XG5cbiAgICAgIGlmIChzcGFuRHVyYXRpb24gPiByb290LmR1cmF0aW9uICogMC44KSB7XG4gICAgICAgIGFuaW1hdGVUbyh7IHN0YXJ0OiByb290LnN0YXJ0VGltZSwgZW5kOiByb290LmVuZFRpbWUgfSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGFkZGluZyA9IE1hdGgubWF4KHNwYW5EdXJhdGlvbiAqIDAuMiwgTUlOX1ZJRVdQT1JUX01TIC8gMik7XG4gICAgICBsZXQgbmV3U3RhcnQgPSBzcGFuU3RhcnQgLSBwYWRkaW5nO1xuICAgICAgbGV0IG5ld0VuZCA9IHNwYW5FbmQgKyBwYWRkaW5nO1xuXG4gICAgICBpZiAobmV3RW5kIC0gbmV3U3RhcnQgPCBNSU5fVklFV1BPUlRfTVMpIHtcbiAgICAgICAgY29uc3QgY2VudGVyID0gKHNwYW5TdGFydCArIHNwYW5FbmQpIC8gMjtcbiAgICAgICAgbmV3U3RhcnQgPSBjZW50ZXIgLSBNSU5fVklFV1BPUlRfTVMgLyAyO1xuICAgICAgICBuZXdFbmQgPSBjZW50ZXIgKyBNSU5fVklFV1BPUlRfTVMgLyAyO1xuICAgICAgfVxuXG4gICAgICBhbmltYXRlVG8oY2xhbXBUb1Jvb3QoeyBzdGFydDogbmV3U3RhcnQsIGVuZDogbmV3RW5kIH0pKTtcbiAgICB9LFxuICAgIFtcbiAgICAgIGFuaW1hdGVUbyxcbiAgICAgIHRyYWNlLnNwYW5zLFxuICAgICAgcm9vdC5zdGFydFRpbWUsXG4gICAgICByb290LmVuZFRpbWUsXG4gICAgICByb290LmR1cmF0aW9uLFxuICAgICAgY2xhbXBUb1Jvb3QsXG4gICAgXVxuICApO1xuXG4gIC8vIEJyaW5nIGEgcm93IGludG8gdmlldyB3aGVuIGtleWJvYXJkL2J1dHRvbiBuYXZpZ2F0aW9uIGxhbmRzIG9uIGEgc3BhbiB0aGF0XG4gIC8vIHNpdHMgb3V0c2lkZSB0aGUgc2hhcmVkIHNjcm9sbCBjb250YWluZXIncyB2aXNpYmxlIGFyZWEuIFRoZSBsaXN0IGlzXG4gIC8vIHdpbmRvd2VkLCBzbyBhbiBvZmYtc2NyZWVuIHJvdyBoYXMgbm8gRE9NIG5vZGUgdG8gYHNjcm9sbEludG9WaWV3YCDigJRcbiAgLy8gYHNjcm9sbFJvd0ludG9WaWV3YCBjb21wdXRlcyB0aGUgdGFyZ2V0IG9mZnNldCBmcm9tIHRoZSBzcGFuJ3MgaW5kZXguXG4gIGNvbnN0IHNjcm9sbFNwYW5JbnRvVmlldyA9IHVzZUNhbGxiYWNrKFxuICAgIChzcGFuSWQ6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgaW5kZXggPSB0cmFjZS5zcGFucy5maW5kSW5kZXgoKHMpID0+IHMuc3BhbklkID09PSBzcGFuSWQpO1xuICAgICAgaWYgKGluZGV4ID09PSAtMSkgcmV0dXJuO1xuXG4gICAgICBjb25zdCBsaXN0ID1cbiAgICAgICAgc2Nyb2xsQ29udGFpbmVyUmVmLmN1cnJlbnQ/LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KCcjZXZlbnQtbGlzdCcpID8/XG4gICAgICAgIG51bGw7XG4gICAgICBzY3JvbGxSb3dJbnRvVmlldyhsaXN0LCBpbmRleCwgUk9XX0hFSUdIVF9QWCwge1xuICAgICAgICBiZWhhdmlvcjogcmVkdWNlZE1vdGlvbiA/ICdhdXRvJyA6ICdzbW9vdGgnLFxuICAgICAgfSk7XG4gICAgfSxcbiAgICBbdHJhY2Uuc3BhbnMsIHJlZHVjZWRNb3Rpb25dXG4gICk7XG5cbiAgY29uc3Qgem9vbVRpbWVyUmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGNhbmNlbFBlbmRpbmdab29tID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICh6b29tVGltZXJSZWYuY3VycmVudCAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHpvb21UaW1lclJlZi5jdXJyZW50KTtcbiAgICAgIHpvb21UaW1lclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH0sIFtdKTtcbiAgdXNlRWZmZWN0KCgpID0+IGNhbmNlbFBlbmRpbmdab29tLCBbY2FuY2VsUGVuZGluZ1pvb21dKTtcblxuICBjb25zdCBoYW5kbGVDbGVhckFjdGl2ZVNwYW4gPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgY2FuY2VsUGVuZGluZ1pvb20oKTtcbiAgICBjbGVhckFjdGl2ZVNwYW4oKTtcbiAgfSwgW2NhbmNlbFBlbmRpbmdab29tLCBjbGVhckFjdGl2ZVNwYW5dKTtcblxuICBjb25zdCBoYW5kbGVTZWxlY3RTcGFuID0gdXNlQ2FsbGJhY2soXG4gICAgKHNwYW5JZDogc3RyaW5nKSA9PiB7XG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSgpO1xuICAgICAgaWYgKHNwYW5JZCA9PT0gYWN0aXZlU3BhbklkKSB7XG4gICAgICAgIGNsZWFyQWN0aXZlU3BhbigpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXRBY3RpdmVTcGFuKHNwYW5JZCk7XG4gICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuKHNwYW5JZCk7XG4gICAgfSxcbiAgICBbXG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSxcbiAgICAgIGFjdGl2ZVNwYW5JZCxcbiAgICAgIGNsZWFyQWN0aXZlU3BhbixcbiAgICAgIHNldEFjdGl2ZVNwYW4sXG4gICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBuYXZpZ2F0ZVRvU3BhbiA9IHVzZUNhbGxiYWNrKFxuICAgIChzcGFuSWQ6IHN0cmluZykgPT4ge1xuICAgICAgc2V0QWN0aXZlU3BhbihzcGFuSWQpO1xuICAgICAgc2Nyb2xsU3BhbkludG9WaWV3KHNwYW5JZCk7XG4gICAgICBjYW5jZWxQZW5kaW5nWm9vbSgpO1xuICAgICAgem9vbVRpbWVyUmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgem9vbVRpbWVyUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgICAgICBmb2N1c1ZpZXdwb3J0T25TcGFuKHNwYW5JZCk7XG4gICAgICB9LCBaT09NX0RFQk9VTkNFX01TKTtcbiAgICB9LFxuICAgIFtzZXRBY3RpdmVTcGFuLCBzY3JvbGxTcGFuSW50b1ZpZXcsIGNhbmNlbFBlbmRpbmdab29tLCBmb2N1c1ZpZXdwb3J0T25TcGFuXVxuICApO1xuXG4gIGNvbnN0IFthbHRIZWxkLCBzZXRBbHRIZWxkXSA9IHVzZVN0YXRlKGZhbHNlKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGNvbnN0IG9uS2V5RG93biA9IChlOiBLZXlib2FyZEV2ZW50KTogdm9pZCA9PiB7XG4gICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnKSB7XG4gICAgICAgIGhhbmRsZUNsZWFyQWN0aXZlU3BhbigpO1xuICAgICAgfSBlbHNlIGlmIChlLmtleSA9PT0gJ0FsdCcpIHtcbiAgICAgICAgc2V0QWx0SGVsZCh0cnVlKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IG9uS2V5VXAgPSAoZTogS2V5Ym9hcmRFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgaWYgKGUua2V5ID09PSAnQWx0Jykgc2V0QWx0SGVsZChmYWxzZSk7XG4gICAgfTtcbiAgICBjb25zdCBvbkJsdXIgPSAoKTogdm9pZCA9PiBzZXRBbHRIZWxkKGZhbHNlKTtcblxuICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigna2V5dXAnLCBvbktleVVwKTtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmx1cicsIG9uQmx1cik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgb25LZXlEb3duKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXl1cCcsIG9uS2V5VXApO1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2JsdXInLCBvbkJsdXIpO1xuICAgIH07XG4gIH0sIFtoYW5kbGVDbGVhckFjdGl2ZVNwYW5dKTtcblxuICBjb25zdCB0aW1lbGluZVJlZiA9IHVzZVJlZjxIVE1MRGl2RWxlbWVudD4obnVsbCk7XG4gIGNvbnN0IFtob3Zlciwgc2V0SG92ZXJdID0gdXNlU3RhdGU8VGltZWxpbmVIb3ZlciB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IGhvdmVySW5mbyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChob3ZlciA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBhYnNUaW1lID0gdmlld3BvcnQuc3RhcnQgKyBob3Zlci5mcmFjdGlvbiAqIHZpZXdEdXJhdGlvbjtcbiAgICBjb25zdCBvZmZzZXQgPSBhYnNUaW1lIC0gcm9vdC5zdGFydFRpbWU7XG4gICAgcmV0dXJuIHsgZnJhY3Rpb246IGhvdmVyLmZyYWN0aW9uLCBsYWJlbDogZm9ybWF0RHVyYXRpb25QcmVjaXNlKG9mZnNldCkgfTtcbiAgfSwgW2hvdmVyLCB2aWV3cG9ydC5zdGFydCwgdmlld0R1cmF0aW9uLCByb290LnN0YXJ0VGltZV0pO1xuXG4gIGNvbnN0IGhhbmRsZVRpbWVsaW5lTW91c2VNb3ZlID0gdXNlQ2FsbGJhY2soXG4gICAgKGU6IFJlYWN0Lk1vdXNlRXZlbnQ8SFRNTERpdkVsZW1lbnQ+KSA9PiB7XG4gICAgICBjb25zdCBlbCA9IHRpbWVsaW5lUmVmLmN1cnJlbnQ7XG4gICAgICBpZiAoIWVsKSByZXR1cm47XG4gICAgICBjb25zdCByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBjb250ZW50V2lkdGggPSByZWN0LndpZHRoIC0gVElNRUxJTkVfUEFERElOR19QWCAqIDI7XG4gICAgICBpZiAoY29udGVudFdpZHRoIDw9IDApIHJldHVybjtcbiAgICAgIGNvbnN0IGZyYWN0aW9uID0gTWF0aC5tYXgoXG4gICAgICAgIDAsXG4gICAgICAgIE1hdGgubWluKFxuICAgICAgICAgIDEsXG4gICAgICAgICAgKGUuY2xpZW50WCAtIHJlY3QubGVmdCAtIFRJTUVMSU5FX1BBRERJTkdfUFgpIC8gY29udGVudFdpZHRoXG4gICAgICAgIClcbiAgICAgICk7XG4gICAgICBzZXRIb3Zlcih7XG4gICAgICAgIGZyYWN0aW9uLFxuICAgICAgICByb3dJbmRleDogTWF0aC5mbG9vcigoZS5jbGllbnRZIC0gcmVjdC50b3ApIC8gUk9XX0hFSUdIVF9QWCksXG4gICAgICB9KTtcbiAgICB9LFxuICAgIFtdXG4gICk7XG5cbiAgY29uc3QgaGFuZGxlVGltZWxpbmVNb3VzZUxlYXZlID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIHNldEhvdmVyKG51bGwpO1xuICB9LCBbXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCBlbCA9IHRpbWVsaW5lUmVmLmN1cnJlbnQ7XG4gICAgaWYgKCFlbCB8fCByb290LmR1cmF0aW9uIDw9IDApIHJldHVybjtcblxuICAgIGNvbnN0IG9uV2hlZWwgPSAoZTogV2hlZWxFdmVudCk6IHZvaWQgPT4ge1xuICAgICAgY29uc3QgaXNab29tR2VzdHVyZSA9IGUuY3RybEtleSB8fCBlLm1ldGFLZXk7XG4gICAgICBjb25zdCBoYXNEZWx0YVggPSBNYXRoLmFicyhlLmRlbHRhWCkgPiBNYXRoLmFicyhlLmRlbHRhWSk7XG5cbiAgICAgIGlmICghaXNab29tR2VzdHVyZSAmJiAhaGFzRGVsdGFYKSByZXR1cm47XG4gICAgICBlLnByZXZlbnREZWZhdWx0KCk7XG5cbiAgICAgIGNvbnN0IHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IGNvbnRlbnRXaWR0aCA9IHJlY3Qud2lkdGggLSBUSU1FTElORV9QQURESU5HX1BYICogMjtcbiAgICAgIGlmIChjb250ZW50V2lkdGggPD0gMCkgcmV0dXJuO1xuXG4gICAgICBpZiAoaXNab29tR2VzdHVyZSkge1xuICAgICAgICBjb25zdCBjdXJzb3JGcmFjdGlvbiA9IE1hdGgubWF4KFxuICAgICAgICAgIDAsXG4gICAgICAgICAgTWF0aC5taW4oXG4gICAgICAgICAgICAxLFxuICAgICAgICAgICAgKGUuY2xpZW50WCAtIHJlY3QubGVmdCAtIFRJTUVMSU5FX1BBRERJTkdfUFgpIC8gY29udGVudFdpZHRoXG4gICAgICAgICAgKVxuICAgICAgICApO1xuICAgICAgICBjb25zdCBzY2FsZUZhY3RvciA9IHdoZWVsWm9vbVNjYWxlRmFjdG9yKGUpO1xuXG4gICAgICAgIHNldFZpZXdwb3J0KChwcmV2KSA9PiB7XG4gICAgICAgICAgY29uc3QgcHJldkR1cmF0aW9uID0gcHJldi5lbmQgLSBwcmV2LnN0YXJ0O1xuICAgICAgICAgIGNvbnN0IGN1cnNvclRpbWUgPSBwcmV2LnN0YXJ0ICsgY3Vyc29yRnJhY3Rpb24gKiBwcmV2RHVyYXRpb247XG4gICAgICAgICAgLy8gQ2xhbXAgdGhlIGR1cmF0aW9uIGJlZm9yZSBhbmNob3Jpbmcgc28gdGhlIGN1cnNvciBrZWVwcyBpdHNcbiAgICAgICAgICAvLyBmcmFjdGlvbiBldmVuIHdoZW4gdGhlIHpvb20gaGl0cyB0aGUgbWluL21heCBib3VuZHMuXG4gICAgICAgICAgY29uc3QgbmV3RHVyYXRpb24gPSBNYXRoLm1heChcbiAgICAgICAgICAgIE1JTl9WSUVXUE9SVF9NUyxcbiAgICAgICAgICAgIE1hdGgubWluKHJvb3QuZHVyYXRpb24sIHByZXZEdXJhdGlvbiAqIHNjYWxlRmFjdG9yKVxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIGNsYW1wVG9Sb290KHtcbiAgICAgICAgICAgIHN0YXJ0OiBjdXJzb3JUaW1lIC0gY3Vyc29yRnJhY3Rpb24gKiBuZXdEdXJhdGlvbixcbiAgICAgICAgICAgIGVuZDogY3Vyc29yVGltZSArICgxIC0gY3Vyc29yRnJhY3Rpb24pICogbmV3RHVyYXRpb24sXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgZHggPSB3aGVlbERlbHRhVG9QaXhlbHMoZS5kZWx0YVgsIGUuZGVsdGFNb2RlKTtcbiAgICAgICAgc2V0Vmlld3BvcnQoKHByZXYpID0+IHtcbiAgICAgICAgICBjb25zdCBwYW5BbW91bnQgPSAoZHggLyBjb250ZW50V2lkdGgpICogKHByZXYuZW5kIC0gcHJldi5zdGFydCk7XG4gICAgICAgICAgcmV0dXJuIGNsYW1wVG9Sb290KHtcbiAgICAgICAgICAgIHN0YXJ0OiBwcmV2LnN0YXJ0ICsgcGFuQW1vdW50LFxuICAgICAgICAgICAgZW5kOiBwcmV2LmVuZCArIHBhbkFtb3VudCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGVsLmFkZEV2ZW50TGlzdGVuZXIoJ3doZWVsJywgb25XaGVlbCwgeyBwYXNzaXZlOiBmYWxzZSB9KTtcbiAgICByZXR1cm4gKCkgPT4gZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignd2hlZWwnLCBvbldoZWVsKTtcbiAgfSwgW3Jvb3QuZHVyYXRpb24sIHNldFZpZXdwb3J0LCBjbGFtcFRvUm9vdF0pO1xuXG4gIHJldHVybiAoXG4gICAgPGRpdlxuICAgICAgcmVmPXtwYW5lUm9vdFJlZn1cbiAgICAgIGRhdGEtcGFuZT1cInBhbmUtcm9vdFwiXG4gICAgICBjbGFzc05hbWU9XCJyZWxhdGl2ZSBmbGV4IHctZnVsbCBoLWZ1bGwgbWF4LWgtZnVsbFwiXG4gICAgPlxuICAgICAgPGRpdlxuICAgICAgICBpZD1cInRyYWNlLXBhcmVudFwiXG4gICAgICAgIGNsYXNzTmFtZT1cIkBjb250YWluZXIgZmxleC0xIG1pbi13LTAgZ3JpZCBncmlkLXJvd3MtW2F1dG9fMWZyXSBoLWZ1bGwgbWluLWgtMCBvdmVyZmxvdy1oaWRkZW4gcmVsYXRpdmUgYmctYmFja2dyb3VuZC0xMDBcIlxuICAgICAgPlxuICAgICAgICA8TWluaW1hcFxuICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICByb290PXtyb290fVxuICAgICAgICAgIHZpZXdwb3J0PXt2aWV3cG9ydH1cbiAgICAgICAgICBtaW5WaWV3cG9ydE1zPXtNSU5fVklFV1BPUlRfTVN9XG4gICAgICAgICAgb25WaWV3cG9ydENoYW5nZT17c2V0Vmlld3BvcnR9XG4gICAgICAgICAgb25BbmltYXRlVG89e2FuaW1hdGVUb31cbiAgICAgICAgLz5cbiAgICAgICAgPFNwbGl0UGFuZVxuICAgICAgICAgIHNjcm9sbENvbnRhaW5lclJlZj17c2Nyb2xsQ29udGFpbmVyUmVmfVxuICAgICAgICAgIHN0YXJ0SGVhZGVyPXtcbiAgICAgICAgICAgIDxkaXYgY2xhc3NOYW1lPVwiYmctYmFja2dyb3VuZC0xMDAgYm9yZGVyLWIgYm9yZGVyLWdyYXktYWxwaGEtNDAwIGgtMTAgbWluLWgtMTAgZmxleCBpdGVtcy1jZW50ZXIgcGwtNCBwci0yIGdhcC0xLjVcIj5cbiAgICAgICAgICAgICAgPFNlYXJjaCBjbGFzc05hbWU9XCJ3LTMuNSBoLTMuNSBzaHJpbmstMCB0ZXh0LWdyYXktODAwXCIgLz5cbiAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgaWQ9XCJ0cmFjZS12aWV3ZXItc2VhcmNoXCJcbiAgICAgICAgICAgICAgICBuYW1lPVwidHJhY2Utdmlld2VyLXNlYXJjaFwiXG4gICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgIHZhbHVlPXtzZWFyY2hRdWVyeX1cbiAgICAgICAgICAgICAgICBvbkNoYW5nZT17KGUpID0+IHNldFNlYXJjaFF1ZXJ5KGUudGFyZ2V0LnZhbHVlKX1cbiAgICAgICAgICAgICAgICBvbktleURvd249eyhlKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoZS5rZXkgPT09ICdFc2NhcGUnICYmIHNlYXJjaFF1ZXJ5KSB7XG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgc2V0U2VhcmNoUXVlcnkoJycpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH19XG4gICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJTZWFyY2ggc3BhbnMuLi5cIlxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZWFyY2ggc3BhbnNcIlxuICAgICAgICAgICAgICAgIGNsYXNzTmFtZT1cImZsZXgtMSBtaW4tdy0wIGJnLXRyYW5zcGFyZW50IHRleHQtbGFiZWwtMTQgdGV4dC1ncmF5LTEwMDAgcGxhY2Vob2xkZXI6dGV4dC1ncmF5LTgwMCBvdXRsaW5lLW5vbmVcIlxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICB7c2VhcmNoUXVlcnkgJiYgKFxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIkNsZWFyIHNlYXJjaFwiXG4gICAgICAgICAgICAgICAgICBvbkNsaWNrPXsoKSA9PiBzZXRTZWFyY2hRdWVyeSgnJyl9XG4gICAgICAgICAgICAgICAgICBjbGFzc05hbWU9XCItbXItMiBoaWRkZW4gaC1mdWxsIG1heC13LWZ1bGwgc2hyaW5rLTAgY3Vyc29yLXBvaW50ZXIgaXRlbXMtY2VudGVyIHJvdW5kZWQtci1tZCBib3JkZXItMCBiZy10cmFuc3BhcmVudCBweC0yLjUgZm9udC1pbmhlcml0IHRleHQtbGFiZWwtMTYgdGV4dC1ncmF5LTkwMCBuby11bmRlcmxpbmUgdHJhbnNpdGlvbi1jb2xvcnMgZHVyYXRpb24tMTUwIGVhc2UtaW4gaG92ZXI6dGV4dC1ncmF5LTEwMDAgZm9jdXMtdmlzaWJsZTotb3V0bGluZS1vZmZzZXQtMSBmb2N1cy12aXNpYmxlOm91dGxpbmUgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLTIgZm9jdXMtdmlzaWJsZTpvdXRsaW5lLVt2YXIoLS1kcy1mb2N1cy1jb2xvcildIG1pbi1bOTYxcHhdOmZsZXhcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIDxLYmQgdmFyaWFudD1cIm91dGxpbmVcIiBzaXplPVwic2VhcmNoXCI+XG4gICAgICAgICAgICAgICAgICAgIEVzY1xuICAgICAgICAgICAgICAgICAgPC9LYmQ+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgICAgZW5kSGVhZGVyPXtcbiAgICAgICAgICAgIDxUaW1lbGluZUhlYWRlciBtYXJrZXJzPXt0aW1lTWFya2Vyc30gaG92ZXJJbmZvPXtob3ZlckluZm99IC8+XG4gICAgICAgICAgfVxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJibG9jayBvdmVyZmxvdy12aXNpYmxlXCI+XG4gICAgICAgICAgICA8RXZlbnRMaXN0XG4gICAgICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICAgICAgYWN0aXZlU3BhbklkPXthY3RpdmVTcGFuSWR9XG4gICAgICAgICAgICAgIHNlYXJjaFJlc3VsdD17c2VhcmNoUmVzdWx0fVxuICAgICAgICAgICAgICBvblNlbGVjdFNwYW49e2hhbmRsZVNlbGVjdFNwYW59XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPGRpdiByZWY9e2xvYWRNb3JlU2VudGluZWxSZWZ9IGNsYXNzTmFtZT1cImZsZXgganVzdGlmeS1jZW50ZXJcIj5cbiAgICAgICAgICAgICAge2lzTG9hZGluZ01vcmUgPyAoXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzc05hbWU9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNlbnRlciBnYXAtMiBweS0zIHRleHQtbGFiZWwtMTQgdGV4dC1ncmF5LTgwMFwiPlxuICAgICAgICAgICAgICAgICAgPFNwaW5uZXIgc2l6ZT17MTR9IC8+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5Mb2FkaW5nIHNwYW5z4oCmPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICApIDogbnVsbH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIHsvKiBiaW9tZS1pZ25vcmUgbGludC9hMTF5L25vU3RhdGljRWxlbWVudEludGVyYWN0aW9uczogdGltZWxpbmUgaG92ZXIgYW5kIHdoZWVsIGdlc3R1cmVzIGFyZSBwb2ludGVyLW9ubHkgYW5ub3RhdGlvbnMgKi99XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgcmVmPXt0aW1lbGluZVJlZn1cbiAgICAgICAgICAgIGlkPVwidHJhY2UtdGltZWxpbmVcIlxuICAgICAgICAgICAgY2xhc3NOYW1lPVwiQGNvbnRhaW5lciBibG9jayBtaW4taC0wIG92ZXJmbG93LXZpc2libGUgcmVsYXRpdmVcIlxuICAgICAgICAgICAgb25Eb3VibGVDbGljaz17cmVzZXRab29tfVxuICAgICAgICAgICAgb25Nb3VzZU1vdmU9e2hhbmRsZVRpbWVsaW5lTW91c2VNb3ZlfVxuICAgICAgICAgICAgb25Nb3VzZUxlYXZlPXtoYW5kbGVUaW1lbGluZU1vdXNlTGVhdmV9XG4gICAgICAgICAgPlxuICAgICAgICAgICAgPFRpbWVsaW5lXG4gICAgICAgICAgICAgIHNwYW5zPXt0cmFjZS5zcGFuc31cbiAgICAgICAgICAgICAgdmlld1N0YXJ0PXt2aWV3cG9ydC5zdGFydH1cbiAgICAgICAgICAgICAgdmlld0VuZD17dmlld3BvcnQuZW5kfVxuICAgICAgICAgICAgICBtYXJrZXJzPXt0aW1lTWFya2Vyc31cbiAgICAgICAgICAgICAgc2VsZWN0ZWRJZD17YWN0aXZlU3BhbklkfVxuICAgICAgICAgICAgICBzZWFyY2hSZXN1bHQ9e3NlYXJjaFJlc3VsdH1cbiAgICAgICAgICAgICAgb25TZWxlY3Q9e2hhbmRsZVNlbGVjdFNwYW59XG4gICAgICAgICAgICAgIG9uUmV2ZWFsVGltZT17aGFuZGxlUmV2ZWFsVGltZX1cbiAgICAgICAgICAgICAgaG92ZXI9e2hvdmVyfVxuICAgICAgICAgICAgICBhbHRIZWxkPXthbHRIZWxkfVxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8PlxuICAgICAgICAgICAgPFRyYWNlU2hvcnRjdXRIZWxwZXJcbiAgICAgICAgICAgICAgaGFzTXVsdGlwbGVTcGFucz17dHJhY2Uuc3BhbnMubGVuZ3RoID4gMX1cbiAgICAgICAgICAgICAgcmVkdWNlZE1vdGlvbj17cmVkdWNlZE1vdGlvbn1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzTmFtZT1cInBvaW50ZXItZXZlbnRzLWF1dG8gZmxleCBpdGVtcy1jZW50ZXIgYm9yZGVyIGJvcmRlci1ncmF5LWFscGhhLTQwMCByb3VuZGVkLW1kIGJnLWJhY2tncm91bmQtMTAwIHNoYWRvdy1zbSBvdmVyZmxvdy1oaWRkZW4gZGl2aWRlLXggZGl2aWRlLWdyYXktYWxwaGEtNDAwXCI+XG4gICAgICAgICAgICAgIDxJY29uQnV0dG9uXG4gICAgICAgICAgICAgICAgdmFyaWFudD1cIm11dGVkXCJcbiAgICAgICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICAgIG9uQ2xpY2s9e3pvb21PdXR9XG4gICAgICAgICAgICAgICAgZGlzYWJsZWQ9e2lzQXRNaW5ab29tfVxuICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJab29tIG91dFwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8Wm9vbU91dCBjbGFzc05hbWU9XCJ3LTQgaC00XCIgLz5cbiAgICAgICAgICAgICAgPC9JY29uQnV0dG9uPlxuICAgICAgICAgICAgICA8SWNvbkJ1dHRvblxuICAgICAgICAgICAgICAgIHZhcmlhbnQ9XCJtdXRlZFwiXG4gICAgICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICAgICAgICBvbkNsaWNrPXtyZXNldFpvb219XG4gICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlJlc2V0IHpvb21cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgPFJvdGF0ZUNjdyBjbGFzc05hbWU9XCJ3LTMuNSBoLTMuNVwiIC8+XG4gICAgICAgICAgICAgIDwvSWNvbkJ1dHRvbj5cbiAgICAgICAgICAgICAgPEljb25CdXR0b25cbiAgICAgICAgICAgICAgICB2YXJpYW50PVwibXV0ZWRcIlxuICAgICAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICAgICAgb25DbGljaz17em9vbUlufVxuICAgICAgICAgICAgICAgIGRpc2FibGVkPXtpc0F0TWF4Wm9vbX1cbiAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiWm9vbSBpblwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8Wm9vbUluIGNsYXNzTmFtZT1cInctNCBoLTRcIiAvPlxuICAgICAgICAgICAgICA8L0ljb25CdXR0b24+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8Lz5cbiAgICAgICAgPC9TcGxpdFBhbmU+XG4gICAgICA8L2Rpdj5cblxuICAgICAgPFRyYWNlRGV0YWlsUGFuZWxcbiAgICAgICAgY29udGFpbmVyUmVmPXtwYW5lUm9vdFJlZn1cbiAgICAgICAgb25OYXZpZ2F0ZVRvU3Bhbj17bmF2aWdhdGVUb1NwYW59XG4gICAgICAgIG9uQ2xvc2U9e2hhbmRsZUNsZWFyQWN0aXZlU3Bhbn1cbiAgICAgIC8+XG4gICAgPC9kaXY+XG4gICk7XG59XG4iXX0=
|