@scion/workbench 18.0.0-beta.1 → 18.0.0-beta.10
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/_index.scss +7 -5
- package/design/_workbench-global-styles.scss +18 -0
- package/design/_workbench-icon-font.scss +1 -1
- package/design/_workbench-popup-global-styles.scss +1 -1
- package/design/{_workbench-view-drag-image-global-styles.scss → _workbench-view-global-styles.scss} +1 -2
- package/esm2022/lib/common/class-list.mjs +67 -29
- package/esm2022/lib/common/math.util.mjs +16 -0
- package/esm2022/lib/common/objects.util.mjs +7 -1
- package/esm2022/lib/common/operators.mjs +1 -12
- package/esm2022/lib/common/uid.util.mjs +22 -0
- package/esm2022/lib/content-projection/content-as-overlay.component.mjs +85 -28
- package/esm2022/lib/content-projection/workbench-element-references.mjs +32 -0
- package/esm2022/lib/dialog/dialog-header/dialog-header.component.mjs +3 -8
- package/esm2022/lib/dialog/movable.directive.mjs +3 -3
- package/esm2022/lib/dialog/resizable.directive.mjs +3 -3
- package/esm2022/lib/dialog/workbench-dialog.component.mjs +25 -23
- package/esm2022/lib/dialog/workbench-dialog.mjs +61 -1
- package/esm2022/lib/dialog//311/265workbench-dialog.mjs +98 -60
- package/esm2022/lib/dialog//311/265workbench-dialog.service.mjs +26 -23
- package/esm2022/lib/executor/latest-task-executor.mjs +55 -0
- package/esm2022/lib/executor/single-task-executor.mjs +9 -19
- package/esm2022/lib/filter-field/filter-field.component.mjs +5 -5
- package/esm2022/lib/layout/grid-element/grid-element.component.mjs +8 -18
- package/esm2022/lib/layout/main-area-layout/main-area-layout.component.mjs +18 -21
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v5.model.mjs +11 -0
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v6.model.mjs +11 -0
- package/esm2022/lib/layout/migration/workbench-layout-migration-v3.service.mjs +4 -4
- package/esm2022/lib/layout/migration/workbench-layout-migration-v5.service.mjs +67 -0
- package/esm2022/lib/layout/migration/workbench-layout-migration-v6.service.mjs +59 -0
- package/esm2022/lib/layout/stringifier.mjs +70 -0
- package/esm2022/lib/layout/workbench-layout.component.mjs +18 -22
- package/esm2022/lib/layout/workbench-layout.mjs +1 -1
- package/esm2022/lib/layout/workbench-layout.model.mjs +1 -1
- package/esm2022/lib/layout/workbench-layout.service.mjs +26 -24
- package/esm2022/lib/layout/workbench-layouts.util.mjs +1 -9
- package/esm2022/lib/layout/workench-layout-serializer.service.mjs +19 -27
- package/esm2022/lib/layout//311/265workbench-layout.factory.mjs +3 -2
- package/esm2022/lib/layout//311/265workbench-layout.mjs +73 -62
- package/esm2022/lib/logging/logging-support.mjs +7 -13
- package/esm2022/lib/logging//311/265logger.mjs +10 -10
- package/esm2022/lib/message-box/message-box-footer/message-box-footer.component.mjs +7 -6
- package/esm2022/lib/message-box/message-box-header/message-box-header.component.mjs +3 -3
- package/esm2022/lib/message-box/workbench-message-box.component.mjs +2 -2
- package/esm2022/lib/message-box//311/265workbench-message-box.service.mjs +3 -2
- package/esm2022/lib/microfrontend-platform/common/microfrontend.util.mjs +22 -6
- package/esm2022/lib/microfrontend-platform/initialization/microfrontend-platform-initializer.service.mjs +28 -21
- package/esm2022/lib/microfrontend-platform/initialization/ng-zone-observable-decorator.mjs +3 -3
- package/esm2022/lib/microfrontend-platform/initialization/workbench-host-manifest-interceptor.service.mjs +11 -1
- package/esm2022/lib/microfrontend-platform/manifest-object-cache.service.mjs +63 -0
- package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog-capability-validator.interceptor.mjs +5 -4
- package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog.component.mjs +6 -10
- package/esm2022/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.mjs +18 -9
- package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.mjs +7 -6
- package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/text-message/text-message.component.mjs +3 -3
- package/esm2022/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.mjs +15 -13
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-capability-validator.interceptor.mjs +3 -2
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box.component.mjs +6 -11
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-capability-validator.interceptor.mjs +39 -0
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-installer.service.mjs +120 -0
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-intent-handler.interceptor.mjs +55 -0
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/workbench-perspective-data.mjs +19 -0
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-capability-validator.interceptor.mjs +4 -3
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-intent-handler.interceptor.mjs +11 -12
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.mjs +12 -28
- package/esm2022/lib/microfrontend-platform/microfrontend-splash/microfrontend-splash.component.mjs +3 -3
- package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view-command-handler.service.mjs +11 -27
- package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view.component.mjs +91 -71
- package/esm2022/lib/microfrontend-platform/public_api.mjs +2 -1
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-capability-validator.interceptor.mjs +5 -4
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-intent-handler.interceptor.mjs +18 -16
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-routes.mjs +30 -8
- package/esm2022/lib/microfrontend-platform/stable-capability-id-assigner.interceptor.mjs +32 -0
- package/esm2022/lib/microfrontend-platform/workbench-microfrontend-support.mjs +26 -8
- package/esm2022/lib/notification/notification-list.component.mjs +4 -8
- package/esm2022/lib/notification/notification.component.mjs +4 -5
- package/esm2022/lib/notification/notification.service.mjs +5 -4
- package/esm2022/lib/page-not-found/page-not-found.component.mjs +5 -7
- package/esm2022/lib/part/part-action-bar/part-action-bar.component.mjs +11 -19
- package/esm2022/lib/part/part-action-bar/part-action.directive.mjs +4 -4
- package/esm2022/lib/part/part-bar/part-bar.component.mjs +333 -264
- package/esm2022/lib/part/part-portal.pipe.mjs +8 -8
- package/esm2022/lib/part/part.component.mjs +33 -42
- package/esm2022/lib/part/view-context-menu/text.component.mjs +16 -12
- package/esm2022/lib/part/view-context-menu/view-menu.component.mjs +4 -6
- package/esm2022/lib/part/view-context-menu/view-menu.directive.mjs +2 -2
- package/esm2022/lib/part/view-context-menu/view-menu.service.mjs +48 -49
- package/esm2022/lib/part/view-list/view-list.component.mjs +41 -48
- package/esm2022/lib/part/view-list-button/view-list-button.component.mjs +22 -26
- package/esm2022/lib/part/view-list-item/view-list-item.component.mjs +15 -17
- package/esm2022/lib/part/view-tab/view-tab.component.mjs +99 -110
- package/esm2022/lib/part/view-tab-content/view-tab-content.component.mjs +3 -4
- package/esm2022/lib/part/view-tab-drag-image/view-tab-drag-image.component.mjs +16 -17
- package/esm2022/lib/part/workbench-part-action.registry.mjs +18 -42
- package/esm2022/lib/part/workbench-part.model.mjs +10 -1
- package/esm2022/lib/part/workbench-part.registry.mjs +11 -45
- package/esm2022/lib/part//311/265workbench-part.model.mjs +71 -55
- package/esm2022/lib/perspective/workbench-grid-merger.service.mjs +3 -3
- package/esm2022/lib/perspective/workbench-perspective.model.mjs +1 -1
- package/esm2022/lib/perspective/workbench-perspective.registry.mjs +11 -43
- package/esm2022/lib/perspective/workbench-perspective.service.mjs +71 -62
- package/esm2022/lib/perspective/workench-perspective-serializer.service.mjs +2 -2
- package/esm2022/lib/perspective//311/265workbench-perspective.model.mjs +62 -47
- package/esm2022/lib/popup/popup.component.mjs +3 -3
- package/esm2022/lib/popup/popup.config.mjs +27 -25
- package/esm2022/lib/popup/popup.service.mjs +169 -174
- package/esm2022/lib/portal/wb-component-portal.mjs +18 -17
- package/esm2022/lib/public_api.mjs +1 -1
- package/esm2022/lib/registry/workbench-object-registry.mjs +38 -17
- package/esm2022/lib/routing/public_api.mjs +2 -2
- package/esm2022/lib/routing/routing.model.mjs +1 -1
- package/esm2022/lib/routing/routing.util.mjs +215 -0
- package/esm2022/lib/routing/workbench-auxiliary-route-installer.service.mjs +110 -0
- package/esm2022/lib/routing/workbench-dialog-differ.mjs +3 -3
- package/esm2022/lib/routing/workbench-layout-differ.mjs +3 -10
- package/esm2022/lib/routing/workbench-message-box-differ.mjs +3 -3
- package/esm2022/lib/routing/workbench-navigational-states.mjs +2 -2
- package/esm2022/lib/routing/workbench-popup-differ.mjs +3 -3
- package/esm2022/lib/routing/workbench-route-guards.mjs +57 -0
- package/esm2022/lib/routing/workbench-url-observer.service.mjs +140 -148
- package/esm2022/lib/routing/workbench-view-outlet-differ.mjs +58 -0
- package/esm2022/lib/routing//311/265workbench-router.service.mjs +119 -74
- package/esm2022/lib/startup/splash/splash.component.mjs +3 -3
- package/esm2022/lib/startup/workbench-launcher.service.mjs +22 -10
- package/esm2022/lib/testing/workbench.provider.mjs +2 -2
- package/esm2022/lib/theme/workbench-theme-switcher.service.mjs +15 -19
- package/esm2022/lib/view/public_api.mjs +1 -2
- package/esm2022/lib/view/view-move-handler.service.mjs +71 -56
- package/esm2022/lib/view/view-portal.pipe.mjs +7 -7
- package/esm2022/lib/view/view.component.mjs +54 -42
- package/esm2022/lib/view/workbench-view.model.mjs +1 -1
- package/esm2022/lib/view/workbench-view.registry.mjs +11 -45
- package/esm2022/lib/view//311/265workbench-view.model.mjs +183 -153
- package/esm2022/lib/view-dnd/grid-drop-targets.util.mjs +2 -2
- package/esm2022/lib/view-dnd/view-drag.service.mjs +87 -71
- package/esm2022/lib/view-dnd/view-drop-placeholder-renderer.service.mjs +6 -6
- package/esm2022/lib/view-dnd/view-drop-zone.directive.mjs +6 -6
- package/esm2022/lib/view-dnd/view-tab-drag-image-renderer.service.mjs +43 -56
- package/esm2022/lib/workbench-config.mjs +2 -2
- package/esm2022/lib/workbench-id.mjs +3 -3
- package/esm2022/lib/workbench.component.mjs +66 -54
- package/esm2022/lib/workbench.constants.mjs +1 -5
- package/esm2022/lib/workbench.model.mjs +1 -1
- package/esm2022/lib/workbench.provider.mjs +3 -9
- package/esm2022/lib/workbench.service.mjs +1 -1
- package/esm2022/lib//311/265workbench.service.mjs +38 -42
- package/fesm2022/scion-workbench.mjs +4054 -3276
- package/fesm2022/scion-workbench.mjs.map +1 -1
- package/lib/common/class-list.d.ts +35 -22
- package/lib/common/math.util.d.ts +7 -0
- package/lib/common/objects.util.d.ts +4 -0
- package/lib/common/operators.d.ts +1 -6
- package/lib/common/uid.util.d.ts +9 -0
- package/lib/content-projection/content-as-overlay.component.d.ts +39 -22
- package/lib/content-projection/workbench-element-references.d.ts +13 -0
- package/lib/dialog/workbench-dialog.component.d.ts +3 -2
- package/lib/dialog/workbench-dialog.d.ts +57 -13
- package/lib/dialog//311/265workbench-dialog.d.ts +38 -24
- package/lib/dialog//311/265workbench-dialog.service.d.ts +10 -11
- package/lib/executor/latest-task-executor.d.ts +26 -0
- package/lib/executor/single-task-executor.d.ts +5 -8
- package/lib/filter-field/filter-field.component.d.ts +1 -1
- package/lib/layout/grid-element/grid-element.component.d.ts +1 -8
- package/lib/layout/main-area-layout/main-area-layout.component.d.ts +0 -4
- package/lib/layout/migration/model/workbench-layout-migration-v5.model.d.ts +36 -0
- package/lib/layout/migration/model/workbench-layout-migration-v6.model.d.ts +35 -0
- package/lib/layout/migration/workbench-layout-migration-v5.service.d.ts +12 -0
- package/lib/layout/migration/workbench-layout-migration-v6.service.d.ts +12 -0
- package/lib/layout/stringifier.d.ts +26 -0
- package/lib/layout/workbench-layout.component.d.ts +4 -5
- package/lib/layout/workbench-layout.d.ts +9 -6
- package/lib/layout/workbench-layout.model.d.ts +4 -3
- package/lib/layout/workbench-layout.service.d.ts +14 -16
- package/lib/layout/workbench-layouts.util.d.ts +0 -6
- package/lib/layout/workench-layout-serializer.service.d.ts +13 -16
- package/lib/layout//311/265workbench-layout.d.ts +18 -19
- package/lib/layout//311/265workbench-layout.factory.d.ts +3 -2
- package/lib/logging//311/265logger.d.ts +2 -3
- package/lib/microfrontend-platform/common/microfrontend.util.d.ts +5 -1
- package/lib/microfrontend-platform/initialization/microfrontend-platform-initializer.service.d.ts +7 -3
- package/lib/microfrontend-platform/manifest-object-cache.service.d.ts +33 -0
- package/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.d.ts +3 -6
- package/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.d.ts +2 -1
- package/lib/microfrontend-platform/microfrontend-host-message-box/text-message/text-message.component.d.ts +1 -1
- package/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.d.ts +2 -1
- package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-capability-validator.interceptor.d.ts +10 -0
- package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-installer.service.d.ts +24 -0
- package/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-intent-handler.interceptor.d.ts +20 -0
- package/lib/microfrontend-platform/microfrontend-perspective/workbench-perspective-data.d.ts +9 -0
- package/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-intent-handler.interceptor.d.ts +4 -8
- package/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.d.ts +0 -4
- package/lib/microfrontend-platform/microfrontend-view/microfrontend-view-command-handler.service.d.ts +5 -12
- package/lib/microfrontend-platform/microfrontend-view/microfrontend-view.component.d.ts +23 -33
- package/lib/microfrontend-platform/public_api.d.ts +1 -0
- package/lib/microfrontend-platform/routing/microfrontend-view-capability-validator.interceptor.d.ts +1 -1
- package/lib/microfrontend-platform/routing/microfrontend-view-intent-handler.interceptor.d.ts +3 -7
- package/lib/microfrontend-platform/routing/microfrontend-view-routes.d.ts +9 -2
- package/lib/microfrontend-platform/stable-capability-id-assigner.interceptor.d.ts +11 -0
- package/lib/notification/notification-list.component.d.ts +0 -2
- package/lib/page-not-found/page-not-found.component.d.ts +1 -0
- package/lib/part/part-action-bar/part-action-bar.component.d.ts +3 -4
- package/lib/part/part-action-bar/part-action.directive.d.ts +2 -2
- package/lib/part/part-bar/part-bar.component.d.ts +73 -63
- package/lib/part/part-portal.pipe.d.ts +3 -5
- package/lib/part/part.component.d.ts +9 -12
- package/lib/part/view-context-menu/text.component.d.ts +3 -4
- package/lib/part/view-context-menu/view-menu.directive.d.ts +1 -1
- package/lib/part/view-context-menu/view-menu.service.d.ts +13 -17
- package/lib/part/view-list/view-list.component.d.ts +8 -21
- package/lib/part/view-list-button/view-list-button.component.d.ts +8 -11
- package/lib/part/view-list-item/view-list-item.component.d.ts +3 -7
- package/lib/part/view-tab/view-tab.component.d.ts +19 -29
- package/lib/part/view-tab-drag-image/view-tab-drag-image.component.d.ts +4 -4
- package/lib/part/workbench-part-action.registry.d.ts +3 -23
- package/lib/part/workbench-part.model.d.ts +8 -27
- package/lib/part/workbench-part.registry.d.ts +3 -26
- package/lib/part//311/265workbench-part.model.d.ts +23 -17
- package/lib/perspective/workbench-perspective.model.d.ts +18 -25
- package/lib/perspective/workbench-perspective.registry.d.ts +3 -26
- package/lib/perspective/workbench-perspective.service.d.ts +16 -14
- package/lib/perspective/workench-perspective-serializer.service.d.ts +1 -1
- package/lib/perspective//311/265workbench-perspective.model.d.ts +30 -21
- package/lib/popup/popup.config.d.ts +11 -10
- package/lib/popup/popup.service.d.ts +15 -28
- package/lib/portal/wb-component-portal.d.ts +21 -5
- package/lib/public_api.d.ts +1 -1
- package/lib/registry/workbench-object-registry.d.ts +10 -6
- package/lib/routing/public_api.d.ts +2 -2
- package/lib/routing/routing.model.d.ts +25 -13
- package/lib/routing/{router.util.d.ts → routing.util.d.ts} +28 -1
- package/lib/routing/{workbench-auxiliary-routes-registrator.service.d.ts → workbench-auxiliary-route-installer.service.d.ts} +10 -3
- package/lib/routing/workbench-layout-differ.d.ts +1 -2
- package/lib/routing/workbench-navigational-states.d.ts +8 -4
- package/lib/{view/workbench-view-route-guards.d.ts → routing/workbench-route-guards.d.ts} +8 -2
- package/lib/routing/workbench-url-observer.service.d.ts +31 -55
- package/lib/routing/workbench-view-outlet-differ.d.ts +32 -0
- package/lib/routing//311/265workbench-router.service.d.ts +22 -18
- package/lib/startup/workbench-launcher.service.d.ts +4 -5
- package/lib/testing/workbench.provider.d.ts +3 -1
- package/lib/theme/workbench-theme-switcher.service.d.ts +4 -6
- package/lib/view/public_api.d.ts +0 -1
- package/lib/view/view-move-handler.service.d.ts +16 -14
- package/lib/view/view-portal.pipe.d.ts +1 -3
- package/lib/view/view.component.d.ts +21 -12
- package/lib/view/workbench-view.model.d.ts +88 -36
- package/lib/view/workbench-view.registry.d.ts +3 -27
- package/lib/view//311/265workbench-view.model.d.ts +62 -71
- package/lib/view-dnd/view-drag.service.d.ts +79 -49
- package/lib/view-dnd/view-drop-placeholder-renderer.service.d.ts +1 -1
- package/lib/view-dnd/view-tab-drag-image-renderer.service.d.ts +12 -36
- package/lib/workbench-config.d.ts +19 -7
- package/lib/workbench.component.d.ts +16 -30
- package/lib/workbench.constants.d.ts +0 -5
- package/lib/workbench.model.d.ts +31 -3
- package/lib/workbench.service.d.ts +58 -56
- package/lib//311/265workbench.service.d.ts +18 -31
- package/package.json +5 -5
- package/esm2022/lib/common/filter-by-predicate.pipe.mjs +0 -27
- package/esm2022/lib/common/filter-by-text.pipe.mjs +0 -39
- package/esm2022/lib/common/uuid.util.mjs +0 -17
- package/esm2022/lib/content-projection/content-projection.directive.mjs +0 -101
- package/esm2022/lib/content-projection/view-container.reference.mjs +0 -68
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-capability-id-assigner.interceptor.mjs +0 -41
- package/esm2022/lib/page-not-found/format-url.pipe.mjs +0 -26
- package/esm2022/lib/part/part-action-bar/part-action-filter.pipe.mjs +0 -26
- package/esm2022/lib/routing/router.util.mjs +0 -126
- package/esm2022/lib/routing/workbench-auxiliary-routes-registrator.service.mjs +0 -94
- package/esm2022/lib/view/workbench-view-route-guards.mjs +0 -47
- package/lib/common/filter-by-predicate.pipe.d.ts +0 -10
- package/lib/common/filter-by-text.pipe.d.ts +0 -12
- package/lib/common/uuid.util.d.ts +0 -8
- package/lib/content-projection/content-projection.directive.d.ts +0 -30
- package/lib/content-projection/view-container.reference.d.ts +0 -42
- package/lib/microfrontend-platform/routing/microfrontend-view-capability-id-assigner.interceptor.d.ts +0 -10
- package/lib/page-not-found/format-url.pipe.d.ts +0 -11
- package/lib/part/part-action-bar/part-action-filter.pipe.d.ts +0 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2018-
|
|
2
|
+
* Copyright (c) 2018-2024 Swiss Federal Railways
|
|
3
3
|
*
|
|
4
4
|
* This program and the accompanying materials are made
|
|
5
5
|
* available under the terms of the Eclipse Public License 2.0
|
|
@@ -7,43 +7,43 @@
|
|
|
7
7
|
*
|
|
8
8
|
* SPDX-License-Identifier: EPL-2.0
|
|
9
9
|
*/
|
|
10
|
-
import { Component, ElementRef, HostListener,
|
|
10
|
+
import { Component, computed, effect, ElementRef, HostListener, inject, NgZone, signal, untracked, viewChild, viewChildren } from '@angular/core';
|
|
11
11
|
import { ViewTabComponent } from '../view-tab/view-tab.component';
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
12
|
+
import { map, mergeMap, takeUntil } from 'rxjs/operators';
|
|
13
|
+
import { from, fromEvent, merge, Observable, Subject, timer } from 'rxjs';
|
|
14
|
+
import { ViewTabDragImageRenderer } from '../../view-dnd/view-tab-drag-image-renderer.service';
|
|
15
|
+
import { ViewDragService } from '../../view-dnd/view-drag.service';
|
|
15
16
|
import { getCssTranslation, setCssClass, setCssVariable, unsetCssClass, unsetCssVariable } from '../../common/dom.util';
|
|
16
|
-
import {
|
|
17
|
+
import { ɵWorkbenchPart } from '../ɵworkbench-part.model';
|
|
18
|
+
import { filterArray, subscribeIn } from '@scion/toolkit/operators';
|
|
17
19
|
import { SciViewportComponent } from '@scion/components/viewport';
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
+
import { ɵWorkbenchRouter } from '../../routing/ɵworkbench-router.service';
|
|
21
|
+
import { boundingClientRect, dimension } from '@scion/components/dimension';
|
|
20
22
|
import { PartActionBarComponent } from '../part-action-bar/part-action-bar.component';
|
|
21
23
|
import { ViewListButtonComponent } from '../view-list-button/view-list-button.component';
|
|
22
24
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
23
|
-
import { fromDimension$ } from '@scion/toolkit/observable';
|
|
24
25
|
import { WORKBENCH_ID } from '../../workbench-id';
|
|
26
|
+
import { clamp } from '../../common/math.util';
|
|
25
27
|
import * as i0 from "@angular/core";
|
|
26
|
-
import * as i1 from "../../layout/workbench-layout.service";
|
|
27
|
-
import * as i2 from "../../routing/\u0275workbench-router.service";
|
|
28
|
-
import * as i3 from "../../view-dnd/view-tab-drag-image-renderer.service";
|
|
29
|
-
import * as i4 from "../\u0275workbench-part.model";
|
|
30
|
-
import * as i5 from "../../view-dnd/view-drag.service";
|
|
31
|
-
import * as i6 from "@scion/components/dimension";
|
|
32
28
|
/**
|
|
33
29
|
* Renders view tabs and actions of a {@link WorkbenchPart}.
|
|
34
30
|
*
|
|
35
31
|
* Tabs are added to a viewport, which the user can scroll if not enough space. The viewport grows with its tabs,
|
|
36
32
|
* allowing actions to be placed directly after the last tab or on the right side.
|
|
37
33
|
*
|
|
38
|
-
* ## Drag
|
|
34
|
+
* ## Drag and Drop
|
|
35
|
+
* This component subscribes to drag events to visualize tabs during a drag operation. The drag operation is initiated in {@link ViewTabComponent}.
|
|
36
|
+
*
|
|
39
37
|
* We use native drag and drop to support dragging views to other windows.
|
|
40
38
|
*
|
|
41
|
-
*
|
|
42
|
-
* -
|
|
43
|
-
* -
|
|
44
|
-
* -
|
|
45
|
-
* -
|
|
46
|
-
* -
|
|
39
|
+
* Following events are triggered:
|
|
40
|
+
* - dragstart: when start dragging a tab (only received in the tabbar where the drag operation has started)
|
|
41
|
+
* - dragend: when end dragging a tab, either via drop or cancel (only received in the tabbar where the drag operation has started)
|
|
42
|
+
* - dragenter: when a tab enters the tabbar
|
|
43
|
+
* - dragover: when dragging a tab over the tabbar, every few hundred milliseconds
|
|
44
|
+
* - dragleave: when a tab leaves the tabbar
|
|
45
|
+
* - drop: when the user drops a tab in the tabbar
|
|
46
|
+
*
|
|
47
47
|
* - Note that `dragleave` event is not fired on drop action. Therefore, always handle both events, `dragleave` and `drop` events, respectively.
|
|
48
48
|
*
|
|
49
49
|
* ## Terminology
|
|
@@ -53,34 +53,34 @@ import * as i6 from "@scion/components/dimension";
|
|
|
53
53
|
* e.g., to snap the drag image to the tabbar when dragging near it.
|
|
54
54
|
*/
|
|
55
55
|
export class PartBarComponent {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
.pipe(startWith(queryList), takeUntilDestroyed(this._destroyRef))
|
|
59
|
-
.subscribe(queryList => this._viewTabs$.next(queryList.toArray()));
|
|
60
|
-
}
|
|
61
|
-
constructor(host, _workbenchId, _workbenchLayoutService, _router, _viewTabDragImageRenderer, _part, _viewDragService, _destroyRef, _zone) {
|
|
62
|
-
this._workbenchId = _workbenchId;
|
|
63
|
-
this._workbenchLayoutService = _workbenchLayoutService;
|
|
64
|
-
this._router = _router;
|
|
65
|
-
this._viewTabDragImageRenderer = _viewTabDragImageRenderer;
|
|
66
|
-
this._part = _part;
|
|
67
|
-
this._viewDragService = _viewDragService;
|
|
68
|
-
this._destroyRef = _destroyRef;
|
|
69
|
-
this._zone = _zone;
|
|
56
|
+
constructor() {
|
|
57
|
+
this._host = inject((ElementRef)).nativeElement;
|
|
70
58
|
this._viewportChange$ = new Subject();
|
|
71
|
-
this.
|
|
72
|
-
this.
|
|
73
|
-
this.
|
|
74
|
-
this.
|
|
59
|
+
this._workbenchId = inject(WORKBENCH_ID);
|
|
60
|
+
this._router = inject(ɵWorkbenchRouter);
|
|
61
|
+
this._viewTabDragImageRenderer = inject(ViewTabDragImageRenderer);
|
|
62
|
+
this._viewDragService = inject(ViewDragService);
|
|
63
|
+
this._zone = inject(NgZone);
|
|
64
|
+
this._viewTabs = viewChildren(ViewTabComponent);
|
|
65
|
+
this._hostBoundingClientRect = boundingClientRect(inject(ElementRef));
|
|
66
|
+
this._viewportComponent = viewChild.required(SciViewportComponent);
|
|
67
|
+
this._viewportComponentElement = viewChild.required(SciViewportComponent, { read: (ElementRef) });
|
|
68
|
+
this._tabCornerRadiusElement = viewChild.required('tab_corner_radius', { read: (ElementRef) });
|
|
69
|
+
this._paddingInlineElement = viewChild.required('padding_inline', { read: (ElementRef) });
|
|
70
|
+
this._fillerElement = viewChild.required('filler');
|
|
71
|
+
this._viewportBoundingBox = boundingClientRect(this._viewportComponentElement);
|
|
72
|
+
this.part = inject(ɵWorkbenchPart);
|
|
73
|
+
this.startActions = computed(() => this.part.actions().filter(action => action.align !== 'end'));
|
|
74
|
+
this.endActions = computed(() => this.part.actions().filter(action => action.align === 'end'));
|
|
75
75
|
/**
|
|
76
76
|
* Reference to the tab before which to insert the drag source on drop, or `end` if dropping it after the last tab.
|
|
77
77
|
*/
|
|
78
|
-
this.dropTargetViewTab = null;
|
|
78
|
+
this.dropTargetViewTab = signal(null);
|
|
79
79
|
/**
|
|
80
80
|
* Reference to the tab where the drag operation was started.
|
|
81
81
|
* This reference is only set if the drag operation started on a tab of this tabbar.
|
|
82
82
|
*/
|
|
83
|
-
this.dragSourceViewTab = null;
|
|
83
|
+
this.dragSourceViewTab = signal(null);
|
|
84
84
|
/**
|
|
85
85
|
* Transfer data of the tab being dragged over this tabbar.
|
|
86
86
|
*/
|
|
@@ -89,6 +89,10 @@ export class PartBarComponent {
|
|
|
89
89
|
* Function for snapping the drag image to the tabbar when dragging near it.
|
|
90
90
|
*/
|
|
91
91
|
this._constrainFn = null;
|
|
92
|
+
/**
|
|
93
|
+
* Signals when unsetting drag state.
|
|
94
|
+
*/
|
|
95
|
+
this._onUnsetDragState = signal(undefined, { equal: () => false });
|
|
92
96
|
/**
|
|
93
97
|
* Tabbar indents where to display the rounded bottom corners of the first and last view tab.
|
|
94
98
|
*/
|
|
@@ -96,171 +100,186 @@ export class PartBarComponent {
|
|
|
96
100
|
left: 0,
|
|
97
101
|
right: 0,
|
|
98
102
|
};
|
|
99
|
-
|
|
100
|
-
* Notifies when the drag animation has finished, i.e., tabs have transitioned to their final position.
|
|
101
|
-
*/
|
|
102
|
-
this._dragAnimationStable$ = interval(0, animationFrameScheduler)
|
|
103
|
-
.pipe(filter(() => this.isDragAnimationStable()), subscribeInside(continueFn => this._zone.runOutsideAngular(continueFn)), observeInside(continueFn => this._zone.run(continueFn)), map(() => undefined));
|
|
104
|
-
this._host = host.nativeElement;
|
|
105
|
-
this.dragover$ = this._viewDragService.tabbarDragOver$.pipe(map(partId => partId === this._part.id));
|
|
106
|
-
}
|
|
107
|
-
ngOnInit() {
|
|
103
|
+
this._maxViewportWidth = this.calculateMaxViewportWidth();
|
|
108
104
|
this.installActiveViewScroller();
|
|
109
105
|
this.installScrolledIntoViewUpdater();
|
|
110
106
|
this.installViewDragListener();
|
|
111
|
-
this.
|
|
112
|
-
this.
|
|
107
|
+
this.installTabbarIndentSizeTracker();
|
|
108
|
+
this.installViewportChangeTracker();
|
|
113
109
|
}
|
|
114
110
|
onDoubleClick(event) {
|
|
115
|
-
if (this.
|
|
111
|
+
if (this.part.isInMainArea) {
|
|
116
112
|
this._router.navigate(layout => layout.toggleMaximized()).then();
|
|
117
113
|
}
|
|
118
114
|
event.stopPropagation();
|
|
119
115
|
}
|
|
120
|
-
get viewIds$() {
|
|
121
|
-
return this._part.viewIds$;
|
|
122
|
-
}
|
|
123
|
-
onTabbarViewportDimensionChange() {
|
|
124
|
-
this._viewportChange$.next();
|
|
125
|
-
}
|
|
126
|
-
onScroll() {
|
|
127
|
-
this._viewportChange$.next();
|
|
128
|
-
}
|
|
129
116
|
/**
|
|
130
|
-
* Method invoked when the user starts dragging a tab of this tabbar.
|
|
117
|
+
* Method invoked when the user starts dragging a tab of this tabbar, only in the tabbar where the drag started.
|
|
131
118
|
*/
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const dragSourceViewTab = this._viewTabs[dragSourceIndex];
|
|
139
|
-
const dropTargetViewTab = this._viewTabs[dragSourceIndex + 1] ?? 'end';
|
|
140
|
-
// Constrain function for snapping the drag image to the tabbar when dragging near it.
|
|
119
|
+
onTabDragStart() {
|
|
120
|
+
// Memoize drag data.
|
|
121
|
+
this._dragData = this._viewDragService.viewDragData();
|
|
122
|
+
// Indicate dragging over this tabbar.
|
|
123
|
+
this._viewDragService.signalTabbarDragEnter(this.part.id);
|
|
124
|
+
// Snap drag image to tabbar when dragging near it.
|
|
141
125
|
this._constrainFn = this.createDragImageConstrainFn();
|
|
142
126
|
this._viewTabDragImageRenderer.setConstrainDragImageRectFn(this._constrainFn);
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
//
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
// When dragging a tab very quickly out of this tabbar, only the `dragstart` event gets fired, but not the `dragenter` event.
|
|
155
|
-
// Therefore, we subscribe to global `dragenter` events and manually invoke `onTabbarDragLeave` to correctly display the tabs and the active view.
|
|
156
|
-
this._viewDragService.viewDrag$(window, { eventType: ['dragenter'] })
|
|
157
|
-
.pipe(take(1), takeUntil(this._dragend$), takeUntilDestroyed(this._destroyRef))
|
|
127
|
+
// Disable pointer events to not break the drag operation (in Firefox, but not Chrome and Edge).
|
|
128
|
+
requestAnimationFrame(() => setCssClass(this._host, 'pointer-events-disabled'));
|
|
129
|
+
// Set CSS class to not animate start dragging.
|
|
130
|
+
setCssClass(this._host, 'on-drag-start');
|
|
131
|
+
this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-start'));
|
|
132
|
+
// Check if the user continues dragging over this tabbar.
|
|
133
|
+
// If not, the user has quickly dragged the tab out of the tabbar, so manually call `onTabbarDragEnter` and `onTabbarDragLeave`.
|
|
134
|
+
fromEvent(window, 'dragenter', { once: true })
|
|
135
|
+
.pipe(takeUntil(merge(fromEvent(this._host, 'dragenter'), fromEvent(this._host, 'dragend'))))
|
|
158
136
|
.subscribe(event => {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if ((this._host.compareDocumentPosition(event.target) & Node.DOCUMENT_POSITION_CONTAINED_BY) === 0) {
|
|
162
|
-
this.onTabbarDragLeave();
|
|
163
|
-
}
|
|
137
|
+
this.onTabbarDragEnter(event);
|
|
138
|
+
this.onTabbarDragLeave(event);
|
|
164
139
|
});
|
|
165
140
|
}
|
|
166
141
|
/**
|
|
167
|
-
* Method invoked when the user ends dragging a tab of this tabbar.
|
|
168
|
-
*
|
|
169
|
-
* Invoked only in the tabbar where the drag operation started, regardless of whether the drag operation was completed or canceled.
|
|
142
|
+
* Method invoked when the user ends dragging a tab of this tabbar, either by drop or cancel, only in the tabbar where the drag started.
|
|
170
143
|
*/
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
144
|
+
onTabDragEnd(event) {
|
|
145
|
+
// Unset drag state only on cancel, not on drop, to prevent tabs from temporarily reverting to their pre-drag state. Drag state is reset in `onTabMoved` after a drop.
|
|
146
|
+
if (event.dataTransfer.dropEffect === 'none') {
|
|
147
|
+
// Reactivate the drag source view on cancel.
|
|
148
|
+
this.dragSourceViewTab()?.view().activate({ skipLocationChange: true }).then();
|
|
149
|
+
// Unset drag state.
|
|
150
|
+
this.unsetDragState();
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Method invoked when the layout has changed after a drop. The drop may not be related to a tab of this tabbar.
|
|
155
|
+
*/
|
|
156
|
+
onTabMoved(event) {
|
|
157
|
+
// Unset drag state only if no new drag has started since the drop.
|
|
158
|
+
if (this._dragData?.uid === event.dragData?.uid) {
|
|
159
|
+
this.unsetDragState();
|
|
160
|
+
}
|
|
174
161
|
}
|
|
175
162
|
/**
|
|
176
163
|
* Method invoked when the user drags a tab into this tabbar.
|
|
177
164
|
*/
|
|
178
165
|
onTabbarDragEnter(event) {
|
|
179
|
-
|
|
180
|
-
this._viewDragService.
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
166
|
+
// Memoize drag data.
|
|
167
|
+
const dragData = this._dragData = this._viewDragService.viewDragData();
|
|
168
|
+
// Indicate dragging over this tabbar.
|
|
169
|
+
this._viewDragService.signalTabbarDragEnter(this.part.id);
|
|
170
|
+
// Snap drag image to tabbar when dragging near it.
|
|
171
|
+
this._constrainFn = this.createDragImageConstrainFn();
|
|
172
|
+
this._viewTabDragImageRenderer.setConstrainDragImageRectFn(this._constrainFn);
|
|
173
|
+
// Set drag source, but only if started the drag operation in this part.
|
|
174
|
+
// We do not set the drag source in `dragstart` to not break the drag operation (in Chrome and Edge, but not Firefox).
|
|
175
|
+
if (this._host.classList.contains('on-drag-start')) {
|
|
176
|
+
this.dragSourceViewTab.set(this._viewTabs().find(viewTab => viewTab.viewId === dragData.viewId) ?? null);
|
|
177
|
+
setCssVariable(this._host, { '--ɵpart-bar-drag-placeholder-width': `${dragData.viewTabWidth}px` });
|
|
186
178
|
}
|
|
187
|
-
// Locate
|
|
188
|
-
this.dropTargetViewTab
|
|
189
|
-
//
|
|
190
|
-
setCssClass(this._host, '
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
'--ɵpart-bar-drag-image-placeholder-width': `${this._dragData.viewTabWidth}px`,
|
|
197
|
-
});
|
|
179
|
+
// Locate the tab the user is dragging over.
|
|
180
|
+
this.dropTargetViewTab.set(this.computeDropTarget(event));
|
|
181
|
+
// Disable pointer events on the tabbar for a smoother drag and drop experience when quickly swapping tabs.
|
|
182
|
+
setCssClass(this._host, 'pointer-events-disabled');
|
|
183
|
+
// Set CSS class to animate entering the tabbar.
|
|
184
|
+
setCssClass(this._host, 'on-drag-enter');
|
|
185
|
+
this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-enter'));
|
|
186
|
+
// Inject drag source width into CSS.
|
|
187
|
+
setCssVariable(this._host, { '--ɵpart-bar-drag-source-width': `${dragData.viewTabWidth}px` });
|
|
198
188
|
}
|
|
199
189
|
/**
|
|
200
190
|
* Method invoked when the user drags a tab out of this tabbar.
|
|
201
191
|
*/
|
|
202
|
-
onTabbarDragLeave() {
|
|
203
|
-
|
|
204
|
-
//
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
.
|
|
208
|
-
.subscribe({ complete: () => unsetCssClass(this._host, 'drag-leave') });
|
|
209
|
-
this.unsetDragState({ unsetDragSource: false });
|
|
210
|
-
// Activate the view next to the view being dragged out of this tabbar. But, do not push the navigation into browsing history stack.
|
|
211
|
-
if (this.dragSourceViewTab && this.dragSourceViewTab.active) {
|
|
212
|
-
this._router.navigate(layout => layout.activateAdjacentView(this.dragSourceViewTab.viewId), { skipLocationChange: true }).then();
|
|
192
|
+
onTabbarDragLeave(event) {
|
|
193
|
+
// Set CSS class to animate leaving the tabbar, but not when canceling the drag operation for instant reset.
|
|
194
|
+
// Pointer coordinates are not set when the drag operation is canceled or when dragging the tab out of the window.
|
|
195
|
+
if (event.screenX || event.screenY) {
|
|
196
|
+
setCssClass(this._host, 'on-drag-leave');
|
|
197
|
+
this.onDragAnimationStable(() => unsetCssClass(this._host, 'on-drag-leave'));
|
|
213
198
|
}
|
|
199
|
+
// Activate the adjacent tab, only if the drag operation is not canceled.
|
|
200
|
+
// The drag event does not provide information about cancelation. Therefore, we wait for a macrotask, canceling it when receiving `dragend`, i.e., the drag operation has been canceled.
|
|
201
|
+
if (this.dragSourceViewTab()?.active) {
|
|
202
|
+
timer(0)
|
|
203
|
+
.pipe(takeUntil(fromEvent(window, 'dragend')))
|
|
204
|
+
.subscribe(() => this._router.navigate(layout => layout.activateAdjacentView(this.dragSourceViewTab().viewId), { skipLocationChange: true }));
|
|
205
|
+
}
|
|
206
|
+
// Clean up drag state.
|
|
207
|
+
this.unsetDragState({ unsetDragSource: false, unsetDragData: false });
|
|
214
208
|
}
|
|
215
209
|
/**
|
|
216
|
-
* Method invoked
|
|
210
|
+
* Method invoked when the user is dragging a tab over this tabbar.
|
|
217
211
|
*/
|
|
218
|
-
onTabbarDragOver(event) {
|
|
212
|
+
onTabbarDragOver(event, dragDistance, scrollDistance) {
|
|
213
|
+
NgZone.assertNotInAngularZone();
|
|
219
214
|
event.preventDefault(); // allow view drop
|
|
220
|
-
// Locate the tab
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
215
|
+
// Locate the tab the user is dragging over.
|
|
216
|
+
// - Run in animation frame for better performance, most noticeable on lower CPU power.
|
|
217
|
+
// - Do not wait for the drag animation to complete for a smoother drag and drop experience when quickly moving the tab in the tabbar.
|
|
218
|
+
requestAnimationFrame(() => {
|
|
219
|
+
// Skip if the drag operation has ended.
|
|
220
|
+
if (this._viewDragService.isDragOverTabbar !== this.part.id) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
// Ignore the drag distance if `drag-enter` animation is in progress to avoid incorrect drop target computation when dragging a tab from the left.
|
|
224
|
+
if (this._host.classList.contains('on-drag-enter')) {
|
|
225
|
+
this.dropTargetViewTab.set(this.computeDropTarget(event, 0));
|
|
226
|
+
}
|
|
227
|
+
// Compute drop target only when moving the drag pointer to prevent tabs from sliding back and forth (while animation is in progress)
|
|
228
|
+
else if (dragDistance) {
|
|
229
|
+
this.dropTargetViewTab.set(this.computeDropTarget(event, dragDistance));
|
|
230
|
+
}
|
|
231
|
+
// Compute drop target when scrolling the viewport, i.e., not moving the drag pointer but scrolling the viewport because placed the drag pointer at the viewport edges.
|
|
232
|
+
else if (scrollDistance) {
|
|
233
|
+
this.dropTargetViewTab.set(this.computeDropTarget(event, scrollDistance));
|
|
234
|
+
}
|
|
235
|
+
// Set CSS class to animate dragging over the tabbar.
|
|
236
|
+
setCssClass(this._host, 'drag-over');
|
|
237
|
+
// Calculate the new size of the drag source placeholder.
|
|
238
|
+
// The placeholder expands the viewport when dragging a tab to the right, moving part actions along with the dragover event.
|
|
239
|
+
setCssVariable(this._host, { '--ɵpart-bar-drag-placeholder-width': `${this.calculateDragPlaceholderWidth(event)}px` });
|
|
240
|
+
});
|
|
226
241
|
}
|
|
227
242
|
/**
|
|
228
243
|
* Method invoked when the user drops a tab in this tabbar.
|
|
229
244
|
*/
|
|
230
|
-
onTabbarDrop() {
|
|
245
|
+
async onTabbarDrop() {
|
|
246
|
+
const dragData = this._dragData;
|
|
247
|
+
const dropTargetViewTab = this.dropTargetViewTab();
|
|
248
|
+
const dropPosition = dropTargetViewTab === 'end' ? 'end' : this._viewTabs().indexOf(dropTargetViewTab);
|
|
231
249
|
this._viewDragService.dispatchViewMoveEvent({
|
|
232
250
|
source: {
|
|
233
|
-
workbenchId:
|
|
234
|
-
partId:
|
|
235
|
-
viewId:
|
|
236
|
-
alternativeViewId:
|
|
237
|
-
viewUrlSegments:
|
|
238
|
-
navigationHint:
|
|
239
|
-
|
|
251
|
+
workbenchId: dragData.workbenchId,
|
|
252
|
+
partId: dragData.partId,
|
|
253
|
+
viewId: dragData.viewId,
|
|
254
|
+
alternativeViewId: dragData.alternativeViewId,
|
|
255
|
+
viewUrlSegments: dragData.viewUrlSegments,
|
|
256
|
+
navigationHint: dragData.navigationHint,
|
|
257
|
+
navigationData: dragData.navigationData,
|
|
258
|
+
classList: dragData.classList,
|
|
240
259
|
},
|
|
241
260
|
target: {
|
|
242
261
|
workbenchId: this._workbenchId,
|
|
243
|
-
position:
|
|
244
|
-
elementId: this.
|
|
262
|
+
position: dropPosition,
|
|
263
|
+
elementId: this.part.id,
|
|
245
264
|
},
|
|
246
|
-
|
|
247
|
-
// Wait undoing the drag state until flushed tab changes to the DOM, i.e., after the layout routing cycle completes.
|
|
248
|
-
// If we were to undo the drag state immediately during the course of the drop event, the tab layout would temporarily
|
|
249
|
-
// revert to the state before the drag operation, resulting in an ugly flicker.
|
|
250
|
-
firstValueFrom(this._workbenchLayoutService.onLayoutChange$).then(() => {
|
|
251
|
-
this.unsetDragState();
|
|
265
|
+
dragData: dragData,
|
|
252
266
|
});
|
|
253
267
|
}
|
|
254
268
|
/**
|
|
255
269
|
* Locates the tab before which the dragged tab is to be inserted when it is dropped. Dragging beyond the last tab returns `end`.
|
|
256
270
|
*/
|
|
257
|
-
computeDropTarget(event) {
|
|
258
|
-
const
|
|
259
|
-
const viewTabs = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab);
|
|
271
|
+
computeDropTarget(event, dragDistanceX = 0) {
|
|
272
|
+
const dragImage = this._viewTabDragImageRenderer.calculateDragImageRect(this._dragData, event);
|
|
273
|
+
const viewTabs = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab());
|
|
260
274
|
for (const viewTab of viewTabs) {
|
|
261
|
-
const
|
|
262
|
-
const
|
|
263
|
-
|
|
275
|
+
const { left, width } = viewTab.boundingClientRect();
|
|
276
|
+
const viewTabHCenter = left + (width / 2);
|
|
277
|
+
// Moving the pointer to the left.
|
|
278
|
+
if (dragDistanceX <= 0 && dragImage.left < viewTabHCenter) {
|
|
279
|
+
return viewTab;
|
|
280
|
+
}
|
|
281
|
+
// Moving the pinter to the right.
|
|
282
|
+
if (dragDistanceX > 0 && dragImage.right < viewTabHCenter) {
|
|
264
283
|
return viewTab;
|
|
265
284
|
}
|
|
266
285
|
}
|
|
@@ -270,49 +289,32 @@ export class PartBarComponent {
|
|
|
270
289
|
* Creates the function for snapping the drag image to the tabbar when dragging near it.
|
|
271
290
|
*/
|
|
272
291
|
createDragImageConstrainFn() {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
return new ViewDragImageRect({
|
|
278
|
-
x: Math.min(Math.max(hostLeft + this._tabbarIndent.left, rect.x), hostLeft + maxViewportWidth - rect.width - this._tabbarIndent.right),
|
|
279
|
-
y: viewportBoundingBox.top,
|
|
280
|
-
width: rect.width,
|
|
281
|
-
height: viewportBoundingBox.height, // fit into tabbar, e.g., when dragging a tab into a tabbar of a different height
|
|
282
|
-
});
|
|
283
|
-
};
|
|
292
|
+
return (dragImage) => new DOMRect(clamp(dragImage.x, {
|
|
293
|
+
min: this._hostBoundingClientRect().left + this._tabbarIndent.left,
|
|
294
|
+
max: this._hostBoundingClientRect().left + this._maxViewportWidth() - dragImage.width - this._tabbarIndent.right,
|
|
295
|
+
}), this._viewportBoundingBox().top, dragImage.width, this._viewportBoundingBox().height);
|
|
284
296
|
}
|
|
285
297
|
/**
|
|
286
|
-
* Calculates the maximum width of the tabbar viewport before an overflow would occur
|
|
287
|
-
*
|
|
288
|
-
* To calculate the effective width, we need to simulate an overflow in the DOM. Therefore, call this method only from `dragstart` and not
|
|
289
|
-
* from `dragover` and disable animations.
|
|
298
|
+
* Calculates the maximum width of the tabbar viewport before an overflow would occur.
|
|
299
|
+
* Use to constrain the drag image to the tabbar bounds.
|
|
290
300
|
*/
|
|
291
301
|
calculateMaxViewportWidth() {
|
|
292
|
-
const
|
|
293
|
-
|
|
294
|
-
setCssClass(this._host, 'calculating-max-viewport-width');
|
|
295
|
-
setCssVariable(this._host, { '--ɵpart-bar-drag-image-placeholder-width': `${this._host.clientWidth}px` });
|
|
296
|
-
try {
|
|
297
|
-
return this._viewportElement.nativeElement.getBoundingClientRect().width;
|
|
298
|
-
}
|
|
299
|
-
finally {
|
|
300
|
-
setCssVariable(this._host, { '--ɵpart-bar-drag-image-placeholder-width': currentWidth || null });
|
|
301
|
-
unsetCssClass(this._host, 'calculating-max-viewport-width');
|
|
302
|
-
}
|
|
302
|
+
const fillerDimension = dimension(this._fillerElement);
|
|
303
|
+
return computed(() => this._viewportBoundingBox().width + fillerDimension().offsetWidth);
|
|
303
304
|
}
|
|
304
305
|
/**
|
|
305
|
-
* Calculates the width for the drag
|
|
306
|
+
* Calculates the width for the drag placeholder.
|
|
306
307
|
*
|
|
308
|
+
* The placeholder expands the viewport when dragging a tab to the right, moving part actions along with the dragover event.
|
|
309
|
+
*
|
|
310
|
+
* Calculation:
|
|
307
311
|
* - When dragging over tabs, the width is equal to the width of the drag source.
|
|
308
|
-
* - When dragging to the right of the last tab, the width of the placeholder is
|
|
309
|
-
* last tab and the position of the dragover event. Applying this width will resize the viewport, moving part actions along
|
|
310
|
-
* with the dragover event.
|
|
312
|
+
* - When dragging to the right of the last tab, the width of the placeholder is the distance between the last tab and the position of the drag pointer.
|
|
311
313
|
*/
|
|
312
|
-
|
|
314
|
+
calculateDragPlaceholderWidth(event) {
|
|
313
315
|
const viewDragImageRect = this._viewTabDragImageRenderer.calculateDragImageRect(this._dragData, event);
|
|
314
|
-
const lastViewTab = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab).at(-1);
|
|
315
|
-
const lastViewTabRight = lastViewTab?.
|
|
316
|
+
const lastViewTab = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab()).at(-1);
|
|
317
|
+
const lastViewTabRight = lastViewTab?.boundingClientRect().right ?? this._hostBoundingClientRect().left + this._tabbarIndent.left;
|
|
316
318
|
return Math.max(lastViewTabRight + viewDragImageRect.width, viewDragImageRect.right) - lastViewTabRight;
|
|
317
319
|
}
|
|
318
320
|
/**
|
|
@@ -320,11 +322,12 @@ export class PartBarComponent {
|
|
|
320
322
|
* The animation is considered stable when all tabs have moved to their final position.
|
|
321
323
|
*/
|
|
322
324
|
isDragAnimationStable() {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
+
const dropTargetViewTab = this.dropTargetViewTab();
|
|
326
|
+
if (this._viewDragService.isDragOverTabbar !== this.part.id) {
|
|
327
|
+
return this._viewTabs().every(viewTab => getCssTranslation(viewTab.host).translateX === 'none');
|
|
325
328
|
}
|
|
326
|
-
const viewTabs = this._viewTabs.filter(viewTab => viewTab !== this.dragSourceViewTab);
|
|
327
|
-
const dropTargetIndex =
|
|
329
|
+
const viewTabs = this._viewTabs().filter(viewTab => viewTab !== this.dragSourceViewTab());
|
|
330
|
+
const dropTargetIndex = dropTargetViewTab === 'end' ? viewTabs.length : viewTabs.indexOf(dropTargetViewTab);
|
|
328
331
|
const dragSourceWidth = this._dragData.viewTabWidth;
|
|
329
332
|
return viewTabs.every((viewTab, i) => {
|
|
330
333
|
const viewTabTranslateX = getCssTranslation(viewTab.host).translateX;
|
|
@@ -339,33 +342,63 @@ export class PartBarComponent {
|
|
|
339
342
|
return true;
|
|
340
343
|
});
|
|
341
344
|
}
|
|
345
|
+
/**
|
|
346
|
+
* Cleans up the drag state, unsetting drag data and drag source based on provided options.
|
|
347
|
+
*/
|
|
342
348
|
unsetDragState(options) {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
}
|
|
346
|
-
this.dropTargetViewTab = null;
|
|
347
|
-
this._dragData = null;
|
|
349
|
+
this.dropTargetViewTab.set(null);
|
|
350
|
+
this._onUnsetDragState.set();
|
|
348
351
|
this._viewTabDragImageRenderer.unsetConstrainDragImageRectFn(this._constrainFn);
|
|
352
|
+
this._viewDragService.signalTabbarDragLeave(this.part.id);
|
|
349
353
|
this._constrainFn = null;
|
|
350
|
-
unsetCssClass(this._host, 'drag-over');
|
|
351
|
-
unsetCssVariable(this._host, '--ɵpart-bar-drag-source-width', '--ɵpart-bar-drag-
|
|
352
|
-
|
|
354
|
+
unsetCssClass(this._host, 'drag-over', 'pointer-events-disabled');
|
|
355
|
+
unsetCssVariable(this._host, '--ɵpart-bar-drag-source-width', '--ɵpart-bar-drag-placeholder-width');
|
|
356
|
+
if (options?.unsetDragSource ?? true) {
|
|
357
|
+
this.dragSourceViewTab.set(null);
|
|
358
|
+
}
|
|
359
|
+
if (options?.unsetDragData ?? true) {
|
|
360
|
+
this._dragData = null;
|
|
361
|
+
}
|
|
353
362
|
}
|
|
354
|
-
|
|
355
|
-
|
|
363
|
+
/**
|
|
364
|
+
* Executes given function when the drag animation has finished, i.e., tabs have transitioned to their final position.
|
|
365
|
+
*/
|
|
366
|
+
onDragAnimationStable(callback) {
|
|
367
|
+
if (NgZone.isInAngularZone()) {
|
|
368
|
+
this._zone.runOutsideAngular(() => this.onDragAnimationStable(callback));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
requestAnimationFrame(() => this.isDragAnimationStable() ? callback() : this.onDragAnimationStable(callback));
|
|
356
372
|
}
|
|
357
373
|
/**
|
|
358
374
|
* Scrolls the tab of the active view into view.
|
|
359
375
|
*/
|
|
360
376
|
installActiveViewScroller() {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
.
|
|
364
|
-
// There may be no active view
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
this._viewportComponent.scrollIntoView(activeViewTab.host);
|
|
377
|
+
effect(() => {
|
|
378
|
+
// Track the active view.
|
|
379
|
+
const activeViewId = this.part.activeViewId();
|
|
380
|
+
// There may be no active view, e.g., if no view has been activated, or when dragging the last view out of the tabbar.
|
|
381
|
+
if (!activeViewId) {
|
|
382
|
+
return;
|
|
368
383
|
}
|
|
384
|
+
// Do not track rendered tabs in general to prevent unwanted scrolling when opening or closing inactive tabs.
|
|
385
|
+
const viewTabs = untracked(() => this._viewTabs());
|
|
386
|
+
// Get a reference to the currently rendered active tab, waiting if necessary by tracking the rendered tabs.
|
|
387
|
+
const activeViewTab = viewTabs.find(viewTab => viewTab.viewId === activeViewId);
|
|
388
|
+
if (!activeViewTab) {
|
|
389
|
+
this._viewTabs(); // Track rendered tabs to re-execute once rendered.
|
|
390
|
+
return;
|
|
391
|
+
}
|
|
392
|
+
// Track navigation of the active view, scrolling its tab into view if necessary.
|
|
393
|
+
activeViewTab.view().navigationId();
|
|
394
|
+
// Track unsetting drag state to ensure the active view is scrolled into view after drop or cancel.
|
|
395
|
+
this._onUnsetDragState();
|
|
396
|
+
// Scroll the tab into view if scrolled out of view.
|
|
397
|
+
untracked(() => requestAnimationFrame(() => {
|
|
398
|
+
if (!this._viewportComponent().isElementInView(activeViewTab.host, 'full')) {
|
|
399
|
+
this._viewportComponent().scrollIntoView(activeViewTab.host);
|
|
400
|
+
}
|
|
401
|
+
}));
|
|
369
402
|
});
|
|
370
403
|
}
|
|
371
404
|
/**
|
|
@@ -373,87 +406,123 @@ export class PartBarComponent {
|
|
|
373
406
|
*/
|
|
374
407
|
installScrolledIntoViewUpdater() {
|
|
375
408
|
this._viewportChange$
|
|
376
|
-
.pipe(map(() => this._viewTabs), filterArray(viewTab => viewTab !== this.dragSourceViewTab), // skip drag source as always scrolled out of view
|
|
377
|
-
mergeMap(viewTabs => from(viewTabs)), takeUntilDestroyed(
|
|
409
|
+
.pipe(map(() => this._viewTabs()), filterArray(viewTab => viewTab !== this.dragSourceViewTab()), // skip drag source as always scrolled out of view
|
|
410
|
+
mergeMap(viewTabs => from(viewTabs)), takeUntilDestroyed())
|
|
378
411
|
.subscribe(viewTab => {
|
|
379
|
-
viewTab.view.scrolledIntoView = this._viewportComponent.isElementInView(viewTab.host, 'full');
|
|
412
|
+
viewTab.view().scrolledIntoView = this._viewportComponent().isElementInView(viewTab.host, 'full');
|
|
380
413
|
});
|
|
381
414
|
}
|
|
415
|
+
/**
|
|
416
|
+
* Subscribes to drag events.
|
|
417
|
+
*/
|
|
382
418
|
installViewDragListener() {
|
|
419
|
+
const zone = inject(NgZone);
|
|
420
|
+
// Subscribe to drag events relevant for this tabbar.
|
|
383
421
|
this._viewDragService.viewDrag$(this._host)
|
|
384
|
-
.pipe(
|
|
385
|
-
|
|
422
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), calculateDistance(() => this._viewportComponent()), // provide viewport lazily because not injected yet
|
|
423
|
+
takeUntilDestroyed())
|
|
424
|
+
.subscribe(({ event, dragDistance, scrollDistance }) => {
|
|
386
425
|
switch (event.type) {
|
|
426
|
+
case 'dragstart':
|
|
427
|
+
this.onTabDragStart();
|
|
428
|
+
break;
|
|
429
|
+
case 'dragend':
|
|
430
|
+
this.onTabDragEnd(event);
|
|
431
|
+
break;
|
|
387
432
|
case 'dragenter':
|
|
388
433
|
this.onTabbarDragEnter(event);
|
|
389
434
|
break;
|
|
390
435
|
case 'dragover':
|
|
391
|
-
this.onTabbarDragOver(event);
|
|
436
|
+
this.onTabbarDragOver(event, dragDistance, scrollDistance);
|
|
392
437
|
break;
|
|
393
438
|
case 'dragleave':
|
|
394
|
-
this.onTabbarDragLeave();
|
|
439
|
+
this.onTabbarDragLeave(event);
|
|
395
440
|
break;
|
|
396
441
|
case 'drop':
|
|
397
|
-
this.onTabbarDrop();
|
|
442
|
+
this.onTabbarDrop().then();
|
|
398
443
|
break;
|
|
399
444
|
}
|
|
400
445
|
});
|
|
446
|
+
// Get notified when a view has moved in the layout.
|
|
447
|
+
this._viewDragService.viewMoved$
|
|
448
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)), takeUntilDestroyed())
|
|
449
|
+
.subscribe(event => this.onTabMoved(event));
|
|
450
|
+
/**
|
|
451
|
+
* Calculates the distance the drag pointer and viewport have moved since the last drag event.
|
|
452
|
+
*/
|
|
453
|
+
function calculateDistance(viewport) {
|
|
454
|
+
return source$ => new Observable(observer => {
|
|
455
|
+
let lastScreenX;
|
|
456
|
+
let lastScrollLeft;
|
|
457
|
+
const subscription = source$.subscribe(event => {
|
|
458
|
+
observer.next({
|
|
459
|
+
event,
|
|
460
|
+
dragDistance: event.screenX - (lastScreenX ?? event.screenX),
|
|
461
|
+
scrollDistance: viewport().scrollLeft - (lastScrollLeft ?? viewport().scrollLeft),
|
|
462
|
+
});
|
|
463
|
+
lastScreenX = event.screenX;
|
|
464
|
+
lastScrollLeft = viewport().scrollLeft;
|
|
465
|
+
});
|
|
466
|
+
return () => subscription.unsubscribe();
|
|
467
|
+
});
|
|
468
|
+
}
|
|
401
469
|
}
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
470
|
+
/**
|
|
471
|
+
* Emits on {@link _viewportChange$} when the viewport size or scroll position changes.
|
|
472
|
+
*/
|
|
473
|
+
installViewportChangeTracker() {
|
|
474
|
+
const viewportSize = dimension(computed(() => this._viewportComponentElement().nativeElement));
|
|
475
|
+
const viewportClientSize = dimension(computed(() => this._viewportComponent().viewportClientElement));
|
|
476
|
+
const zone = inject(NgZone);
|
|
477
|
+
// Detect resizing.
|
|
478
|
+
effect(() => {
|
|
479
|
+
// Track viewport and viewport client sizes.
|
|
480
|
+
viewportSize();
|
|
481
|
+
viewportClientSize();
|
|
482
|
+
untracked(() => this._viewportChange$.next());
|
|
483
|
+
});
|
|
484
|
+
// Detect scrolling.
|
|
485
|
+
effect(onCleanup => {
|
|
486
|
+
const viewport = this._viewportComponent().viewportElement;
|
|
487
|
+
untracked(() => {
|
|
488
|
+
const subscription = fromEvent(viewport, 'scroll')
|
|
489
|
+
.pipe(subscribeIn(fn => zone.runOutsideAngular(fn)))
|
|
490
|
+
.subscribe(() => this._viewportChange$.next());
|
|
491
|
+
onCleanup(() => subscription.unsubscribe());
|
|
492
|
+
});
|
|
493
|
+
});
|
|
406
494
|
}
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
495
|
+
/**
|
|
496
|
+
* Tracks the tabbar indents.
|
|
497
|
+
*/
|
|
498
|
+
installTabbarIndentSizeTracker() {
|
|
499
|
+
const tabCornerRadiusDimension = dimension(this._tabCornerRadiusElement);
|
|
500
|
+
const paddingInlineDimension = dimension(this._paddingInlineElement);
|
|
501
|
+
effect(() => {
|
|
502
|
+
const indent = tabCornerRadiusDimension().clientWidth + paddingInlineDimension().clientWidth;
|
|
503
|
+
this._tabbarIndent = { left: indent, right: indent };
|
|
504
|
+
setCssVariable(this._host, {
|
|
505
|
+
'--ɵpart-bar-indent-left': `${this._tabbarIndent.left}px`,
|
|
506
|
+
'--ɵpart-bar-indent-right': `${this._tabbarIndent.right}px`,
|
|
507
|
+
});
|
|
414
508
|
});
|
|
415
509
|
}
|
|
416
|
-
|
|
417
|
-
|
|
510
|
+
ngOnDestroy() {
|
|
511
|
+
this.unsetDragState();
|
|
512
|
+
}
|
|
513
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PartBarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
514
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.0.2", type: PartBarComponent, isStandalone: true, selector: "wb-part-bar", host: { listeners: { "dblclick": "onDoubleClick($event)" } }, viewQueries: [{ propertyName: "_viewTabs", predicate: ViewTabComponent, descendants: true, isSignal: true }, { propertyName: "_viewportComponent", first: true, predicate: SciViewportComponent, descendants: true, isSignal: true }, { propertyName: "_viewportComponentElement", first: true, predicate: SciViewportComponent, descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_tabCornerRadiusElement", first: true, predicate: ["tab_corner_radius"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_paddingInlineElement", first: true, predicate: ["padding_inline"], descendants: true, read: ElementRef, isSignal: true }, { propertyName: "_fillerElement", first: true, predicate: ["filler"], descendants: true, isSignal: true }], ngImport: i0, template: "<sci-viewport class=\"tabbar e2e-tabbar\" scrollbarStyle=\"hidden\">\n @for (viewId of part.viewIds(); track viewId) {\n @if (viewtab === dropTargetViewTab()) {\n <div class=\"divider\"></div>\n }\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab()\"\n [class.drop-target]=\"viewtab === dropTargetViewTab()\"/>\n <div class=\"divider\"></div>\n }\n\n <!-- Placeholder for expanding the viewport when dragging a tab to the right, moving part actions along with the dragover event. -->\n <div class=\"drag-placeholder\"></div>\n</sci-viewport>\n\n<!-- Actions -->\n@if (startActions().length) {\n <wb-part-action-bar [actions]=\"startActions()\" class=\"start\"/>\n}\n<div class=\"filler\" #filler></div>\n@if (endActions().length) {\n <wb-part-action-bar [actions]=\"endActions()\" class=\"end\"/>\n}\n\n<!-- View List Dropdown -->\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-placeholder{flex:none;width:var(--\\275part-bar-drag-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host:not(.drag-over)>sci-viewport.tabbar:not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>wb-part-action-bar.start{flex:none;padding-left:var(--sci-workbench-part-bar-actions-padding-inline)}:host>div.filler{flex:auto}:host>wb-part-action-bar.end{flex:none;padding-right:var(--sci-workbench-part-bar-actions-padding-inline)}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host.on-drag-enter:not(.on-drag-start) wb-view-tab,:host.on-drag-enter:not(.on-drag-start) div.divider,:host.drag-over wb-view-tab,:host.drag-over div.divider,:host.on-drag-leave wb-view-tab,:host.on-drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host.on-drag-enter:not(.on-drag-start) div.drag-placeholder,:host.on-drag-leave div.drag-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}:host:not(:has(wb-view-tab.drag-source)):not(:has(wb-view-tab.drop-target)):not(.drag-over) div.drag-placeholder{display:none}:host.pointer-events-disabled>sci-viewport.tabbar::part(content){pointer-events:none}\n"], dependencies: [{ kind: "component", type: SciViewportComponent, selector: "sci-viewport", inputs: ["scrollbarStyle"], outputs: ["scroll"] }, { kind: "component", type: ViewTabComponent, selector: "wb-view-tab", inputs: ["viewId"] }, { kind: "component", type: PartActionBarComponent, selector: "wb-part-action-bar", inputs: ["actions"] }, { kind: "component", type: ViewListButtonComponent, selector: "wb-view-list-button" }] }); }
|
|
418
515
|
}
|
|
419
516
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PartBarComponent, decorators: [{
|
|
420
517
|
type: Component,
|
|
421
518
|
args: [{ selector: 'wb-part-bar', standalone: true, imports: [
|
|
422
|
-
NgFor,
|
|
423
|
-
AsyncPipe,
|
|
424
519
|
SciViewportComponent,
|
|
425
|
-
SciDimensionModule,
|
|
426
520
|
ViewTabComponent,
|
|
427
521
|
PartActionBarComponent,
|
|
428
522
|
ViewListButtonComponent,
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: undefined, decorators: [{
|
|
432
|
-
type: Inject,
|
|
433
|
-
args: [WORKBENCH_ID]
|
|
434
|
-
}] }, { type: i1.WorkbenchLayoutService }, { type: i2.ɵWorkbenchRouter }, { type: i3.ViewTabDragImageRenderer }, { type: i4.ɵWorkbenchPart }, { type: i5.ViewDragService }, { type: i0.DestroyRef }, { type: i0.NgZone }], propDecorators: { _viewportElement: [{
|
|
435
|
-
type: ViewChild,
|
|
436
|
-
args: [SciViewportComponent, { static: true, read: ElementRef }]
|
|
437
|
-
}], _viewportComponent: [{
|
|
438
|
-
type: ViewChild,
|
|
439
|
-
args: [SciViewportComponent, { static: true }]
|
|
440
|
-
}], _tabCornerRadiusElement: [{
|
|
441
|
-
type: ViewChild,
|
|
442
|
-
args: ['tab_corner_radius', { static: true }]
|
|
443
|
-
}], _paddingInlineElement: [{
|
|
444
|
-
type: ViewChild,
|
|
445
|
-
args: ['padding_inline', { static: true }]
|
|
446
|
-
}], injectViewTabs: [{
|
|
447
|
-
type: ViewChildren,
|
|
448
|
-
args: [ViewTabComponent]
|
|
449
|
-
}], onDoubleClick: [{
|
|
523
|
+
], template: "<sci-viewport class=\"tabbar e2e-tabbar\" scrollbarStyle=\"hidden\">\n @for (viewId of part.viewIds(); track viewId) {\n @if (viewtab === dropTargetViewTab()) {\n <div class=\"divider\"></div>\n }\n <wb-view-tab #viewtab\n [viewId]=\"viewId\"\n [class.drag-source]=\"viewtab === dragSourceViewTab()\"\n [class.drop-target]=\"viewtab === dropTargetViewTab()\"/>\n <div class=\"divider\"></div>\n }\n\n <!-- Placeholder for expanding the viewport when dragging a tab to the right, moving part actions along with the dragover event. -->\n <div class=\"drag-placeholder\"></div>\n</sci-viewport>\n\n<!-- Actions -->\n@if (startActions().length) {\n <wb-part-action-bar [actions]=\"startActions()\" class=\"start\"/>\n}\n<div class=\"filler\" #filler></div>\n@if (endActions().length) {\n <wb-part-action-bar [actions]=\"endActions()\" class=\"end\"/>\n}\n\n<!-- View List Dropdown -->\n<wb-view-list-button/>\n\n<!-- Element for injecting the corner radius into the component. -->\n<div class=\"tab-corner-radius\" #tab_corner_radius></div>\n<!-- Element for injecting the tabbar padding into the component. -->\n<div class=\"padding-inline\" #padding_inline></div>\n", styles: ["@charset \"UTF-8\";:host{--\\275part-bar-indent-left: 0;--\\275part-bar-indent-right: 0;--\\275part-bar-drag-source-width: 0;--\\275part-bar-drag-placeholder-width: 0;display:flex;color:var(--sci-workbench-tab-text-color);background-color:var(--sci-workbench-part-bar-background-color);border-top:var(--sci-workbench-part-bar-padding-top) solid transparent;background-clip:border-box;height:var(--sci-workbench-tab-height);box-sizing:content-box;position:relative;container-name:viewtab;container-type:size}wb-workbench:has(wb-main-area-layout) wb-part:not(.main-area) :host{background-color:var(--sci-workbench-part-peripheral-bar-background-color)}:host>sci-viewport.tabbar{flex:initial}:host>sci-viewport.tabbar::part(content){display:flex;padding-left:var(--\\275part-bar-indent-left);padding-right:var(--\\275part-bar-indent-right)}:host>sci-viewport.tabbar>wb-view-tab{flex:none}:host>sci-viewport.tabbar>wb-view-tab.drag-source{display:none}:host>sci-viewport.tabbar>div.divider{flex:none;display:flex;position:relative;width:0}:host>sci-viewport.tabbar>div.divider:after{flex:none;align-self:center;content:\"\";position:absolute;width:1px;left:-1px;height:65%;background-color:var(--sci-workbench-part-bar-divider-color)}:host>sci-viewport.tabbar>div.drag-placeholder{flex:none;width:var(--\\275part-bar-drag-placeholder-width)}:host>sci-viewport.tabbar>wb-view-tab.drop-target,:host>sci-viewport.tabbar wb-view-tab.drop-target~:is(wb-view-tab,div.divider),:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drop-target){transform:translate(var(--\\275part-bar-drag-source-width))}:host>sci-viewport.tabbar>wb-view-tab:is(.active,.drag-source)+div.divider{display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.active:not(.drag-source)){display:none}:host>sci-viewport.tabbar>div.divider:has(+wb-view-tab.drag-source:not(.active)){display:none}:host:not(.drag-over)>sci-viewport.tabbar:not(:has(wb-view-tab:not(.drag-source)))::part(content){padding-right:0}:host>wb-part-action-bar.start{flex:none;padding-left:var(--sci-workbench-part-bar-actions-padding-inline)}:host>div.filler{flex:auto}:host>wb-part-action-bar.end{flex:none;padding-right:var(--sci-workbench-part-bar-actions-padding-inline)}:host>wb-view-list-button{flex:none}:host:before{content:\"\";position:absolute;bottom:0;left:0;right:0;height:1px;background-color:var(--sci-workbench-tab-border-color)}:host>div.tab-corner-radius{position:absolute;visibility:hidden;width:var(--sci-workbench-tab-border-radius)}:host>div.padding-inline{position:absolute;visibility:hidden;width:var(--sci-workbench-part-bar-padding-inline)}:host.on-drag-enter:not(.on-drag-start) wb-view-tab,:host.on-drag-enter:not(.on-drag-start) div.divider,:host.drag-over wb-view-tab,:host.drag-over div.divider,:host.on-drag-leave wb-view-tab,:host.on-drag-leave div.divider{transition:transform 175ms cubic-bezier(0,0,.2,1)}:host.on-drag-enter:not(.on-drag-start) div.drag-placeholder,:host.on-drag-leave div.drag-placeholder{transition:width 175ms cubic-bezier(0,0,.2,1)}:host:not(:has(wb-view-tab.drag-source)):not(:has(wb-view-tab.drop-target)):not(.drag-over) div.drag-placeholder{display:none}:host.pointer-events-disabled>sci-viewport.tabbar::part(content){pointer-events:none}\n"] }]
|
|
524
|
+
}], ctorParameters: () => [], propDecorators: { onDoubleClick: [{
|
|
450
525
|
type: HostListener,
|
|
451
526
|
args: ['dblclick', ['$event']]
|
|
452
|
-
}], onViewDragStart: [{
|
|
453
|
-
type: HostListener,
|
|
454
|
-
args: ['dragstart', ['$event']]
|
|
455
|
-
}], onViewDragEnd: [{
|
|
456
|
-
type: HostListener,
|
|
457
|
-
args: ['dragend']
|
|
458
527
|
}] } });
|
|
459
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydC1iYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vd29ya2JlbmNoL3NyYy9saWIvcGFydC9wYXJ0LWJhci9wYXJ0LWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi93b3JrYmVuY2gvc3JjL2xpYi9wYXJ0L3BhcnQtYmFyL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBYyxVQUFVLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBNkIsU0FBUyxFQUFFLFlBQVksRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMxSSxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSxnQ0FBZ0MsQ0FBQztBQUVoRSxPQUFPLEVBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFDLE1BQU0sZ0JBQWdCLENBQUM7QUFDNUYsT0FBTyxFQUFDLHVCQUF1QixFQUFFLGVBQWUsRUFBRSxhQUFhLEVBQUUsY0FBYyxFQUFFLElBQUksRUFBRSxRQUFRLEVBQWMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQ2xJLE9BQU8sRUFBYyxpQkFBaUIsRUFBMkIsTUFBTSxxREFBcUQsQ0FBQztBQUU3SCxPQUFPLEVBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUV0SCxPQUFPLEVBQUMsV0FBVyxFQUFFLFFBQVEsRUFBRSxhQUFhLEVBQUUsZUFBZSxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDL0YsT0FBTyxFQUFDLG9CQUFvQixFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFFaEUsT0FB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a0I7d0JBQ2xCLGdCQUFnQjt3QkFDaEIsc0JBQXNCO3dCQUN0Qix1QkFBdUI7d0JBQ3ZCLElBQUk7cUJBQ0w7OzBCQXdFWSxNQUFNOzJCQUFDLFlBQVk7NlBBM0R4QixnQkFBZ0I7c0JBRHZCLFNBQVM7dUJBQUMsb0JBQW9CLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUM7Z0JBSXpELGtCQUFrQjtzQkFEekIsU0FBUzt1QkFBQyxvQkFBb0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7Z0JBSXZDLHVCQUF1QjtzQkFEOUIsU0FBUzt1QkFBQyxtQkFBbUIsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7Z0JBSXRDLHFCQUFxQjtzQkFENUIsU0FBUzt1QkFBQyxnQkFBZ0IsRUFBRSxFQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUM7Z0JBSWhDLGNBQWM7c0JBRHhCLFlBQVk7dUJBQUMsZ0JBQWdCO2dCQXFFdkIsYUFBYTtzQkFEbkIsWUFBWTt1QkFBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBd0I3QixlQUFlO3NCQURyQixZQUFZO3VCQUFDLFdBQVcsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkE4QzlCLGFBQWE7c0JBRG5CLFlBQVk7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTgtMjAyMyBTd2lzcyBGZWRlcmFsIFJhaWx3YXlzXG4gKlxuICogVGhpcyBwcm9ncmFtIGFuZCB0aGUgYWNjb21wYW55aW5nIG1hdGVyaWFscyBhcmUgbWFkZVxuICogYXZhaWxhYmxlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgRWNsaXBzZSBQdWJsaWMgTGljZW5zZSAyLjBcbiAqIHdoaWNoIGlzIGF2YWlsYWJsZSBhdCBodHRwczovL3d3dy5lY2xpcHNlLm9yZy9sZWdhbC9lcGwtMi4wL1xuICpcbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBFUEwtMi4wXG4gKi9cblxuaW1wb3J0IHtDb21wb25lbnQsIERlc3Ryb3lSZWYsIEVsZW1lbnRSZWYsIEhvc3RMaXN0ZW5lciwgSW5qZWN0LCBOZ1pvbmUsIE9uSW5pdCwgUXVlcnlMaXN0LCBWaWV3Q2hpbGQsIFZpZXdDaGlsZHJlbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge1ZpZXdUYWJDb21wb25lbnR9IGZyb20gJy4uL3ZpZXctdGFiL3ZpZXctdGFiLmNvbXBvbmVudCc7XG5pbXBvcnQge1dvcmtiZW5jaExheW91dFNlcnZpY2V9IGZyb20gJy4uLy4uL2xheW91dC93b3JrYmVuY2gtbGF5b3V0LnNlcnZpY2UnO1xuaW1wb3J0IHtmaWx0ZXIsIG1hcCwgbWVyZ2VNYXAsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YWtlLCB0YWtlVW50aWx9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7YW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIsIEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgZmlyc3RWYWx1ZUZyb20sIGZyb20sIGludGVydmFsLCBPYnNlcnZhYmxlLCBTdWJqZWN0fSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q29uc3RyYWluRm4sIFZpZXdEcmFnSW1hZ2VSZWN0LCBWaWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXJ9IGZyb20gJy4uLy4uL3ZpZXctZG5kL3ZpZXctdGFiLWRyYWctaW1hZ2UtcmVuZGVyZXIuc2VydmljZSc7XG5pbXBvcnQge1ZpZXdEcmFnRGF0YSwgVmlld0RyYWdTZXJ2aWNlfSBmcm9tICcuLi8uLi92aWV3LWRuZC92aWV3LWRyYWcuc2VydmljZSc7XG5pbXBvcnQge2dldENzc1RyYW5zbGF0aW9uLCBzZXRDc3NDbGFzcywgc2V0Q3NzVmFyaWFibGUsIHVuc2V0Q3NzQ2xhc3MsIHVuc2V0Q3NzVmFyaWFibGV9IGZyb20gJy4uLy4uL2NvbW1vbi9kb20udXRpbCc7XG5pbXBvcnQge8m1V29ya2JlbmNoUGFydH0gZnJvbSAnLi4vybV3b3JrYmVuY2gtcGFydC5tb2RlbCc7XG5pbXBvcnQge2ZpbHRlckFycmF5LCBtYXBBcnJheSwgb2JzZXJ2ZUluc2lkZSwgc3Vic2NyaWJlSW5zaWRlfSBmcm9tICdAc2Npb24vdG9vbGtpdC9vcGVyYXRvcnMnO1xuaW1wb3J0IHtTY2lWaWV3cG9ydENvbXBvbmVudH0gZnJvbSAnQHNjaW9uL2NvbXBvbmVudHMvdmlld3BvcnQnO1xuaW1wb3J0IHvJtVdvcmtiZW5jaFJvdXRlcn0gZnJvbSAnLi4vLi4vcm91dGluZy/JtXdvcmtiZW5jaC1yb3V0ZXIuc2VydmljZSc7XG5pbXBvcnQge1NjaURpbWVuc2lvbk1vZHVsZX0gZnJvbSAnQHNjaW9uL2NvbXBvbmVudHMvZGltZW5zaW9uJztcbmltcG9ydCB7QXN5bmNQaXBlLCBOZ0ZvciwgTmdJZn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7UGFydEFjdGlvbkJhckNvbXBvbmVudH0gZnJvbSAnLi4vcGFydC1hY3Rpb24tYmFyL3BhcnQtYWN0aW9uLWJhci5jb21wb25lbnQnO1xuaW1wb3J0IHtWaWV3TGlzdEJ1dHRvbkNvbXBvbmVudH0gZnJvbSAnLi4vdmlldy1saXN0LWJ1dHRvbi92aWV3LWxpc3QtYnV0dG9uLmNvbXBvbmVudCc7XG5pbXBvcnQge3Rha2VVbnRpbERlc3Ryb3llZH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHtmcm9tRGltZW5zaW9uJH0gZnJvbSAnQHNjaW9uL3Rvb2xraXQvb2JzZXJ2YWJsZSc7XG5pbXBvcnQge1dPUktCRU5DSF9JRH0gZnJvbSAnLi4vLi4vd29ya2JlbmNoLWlkJztcbmltcG9ydCB7Vmlld0lkfSBmcm9tICcuLi8uLi92aWV3L3dvcmtiZW5jaC12aWV3Lm1vZGVsJztcblxuLyoqXG4gKiBSZW5kZXJzIHZpZXcgdGFicyBhbmQgYWN0aW9ucyBvZiBhIHtAbGluayBXb3JrYmVuY2hQYXJ0fS5cbiAqXG4gKiBUYWJzIGFyZSBhZGRlZCB0byBhIHZpZXdwb3J0LCB3aGljaCB0aGUgdXNlciBjYW4gc2Nyb2xsIGlmIG5vdCBlbm91Z2ggc3BhY2UuIFRoZSB2aWV3cG9ydCBncm93cyB3aXRoIGl0cyB0YWJzLFxuICogYWxsb3dpbmcgYWN0aW9ucyB0byBiZSBwbGFjZWQgZGlyZWN0bHkgYWZ0ZXIgdGhlIGxhc3QgdGFiIG9yIG9uIHRoZSByaWdodCBzaWRlLlxuICpcbiAqICMjIERyYWcgRXZlbnRzXG4gKiBXZSB1c2UgbmF0aXZlIGRyYWcgYW5kIGRyb3AgdG8gc3VwcG9ydCBkcmFnZ2luZyB2aWV3cyB0byBvdGhlciB3aW5kb3dzLlxuICpcbiAqIEJ5IGxpc3RlbmluZyB0byBkcmFnIGV2ZW50cywgdGhlIHRhYmJhciB2aXN1YWxpemVzIHRhYnMgZHVyaW5nIGEgZHJhZyBvcGVyYXRpb24uIFRoZSBkcmFnIG9wZXJhdGlvbiBpcyBpbml0aWF0ZWQgaW4ge0BsaW5rIFZpZXdUYWJDb21wb25lbnR9LlxuICogLSBgZHJhZ3N0YXJ0YCBhbmQgYGRyYWdlbmRgIGV2ZW50cyBhcmUgZmlyZWQgaW4gdGhlIHRhYmJhciB3aGVyZSB0aGUgZHJhZyBvcGVyYXRpb24gd2FzIGluaXRpYXRlZC5cbiAqIC0gYGRyYWdlbnRlcmAgZXZlbnQgaXMgZmlyZWQgd2hlbiBhIHRhYiBlbnRlcnMgdGhlIHRhYmJhci5cbiAqIC0gYGRyYWdvdmVyYCBldmVudHMgYXJlIGZpcmVkIHdoZW4gZHJhZ2dpbmcgYSB0YWIgb3ZlciB0aGUgdGFiYmFyLlxuICogLSBgZHJhZ2xlYXZlYCBldmVudCBpcyBmaXJlZCB3aGVuIGEgdGFiIGxlYXZlcyB0aGUgdGFiYmFyLlxuICogLSBgZHJvcGAgZXZlbnQgaXMgZmlyZWQgd2hlbiB0aGUgdXNlciBkcm9wcyBhIHRhYiBpbiB0aGUgdGFiYmFyLlxuICogLSBOb3RlIHRoYXQgYGRyYWdsZWF2ZWAgZXZlbnQgaXMgbm90IGZpcmVkIG9uIGRyb3AgYWN0aW9uLiBUaGVyZWZvcmUsIGFsd2F5cyBoYW5kbGUgYm90aCBldmVudHMsIGBkcmFnbGVhdmVgIGFuZCBgZHJvcGAgZXZlbnRzLCByZXNwZWN0aXZlbHkuXG4gKlxuICogIyMgVGVybWlub2xvZ3lcbiAqIC0gRHJhZyBzb3VyY2U6IFRhYiB0aGF0IGlzIGJlaW5nIGRyYWdnZWQuXG4gKiAtIERyb3AgdGFyZ2V0OiBUYWIgYmVmb3JlIHdoaWNoIHRvIGluc2VydCB0aGUgZHJhZyBzb3VyY2Ugb24gZHJvcCwgb3IgYGVuZGAgaWYgZHJvcHBpbmcgaXQgYWZ0ZXIgdGhlIGxhc3QgdGFiLlxuICogLSBEcmFnIGltYWdlOiAgSW1hZ2UgZm9yIHRoZSB0YWIgdG8gYmUgZHJhZ2dlZC4gV2UgZG8gbm90IHVzZSB0aGUgbmF0aXZlIGRyYWcgaW1hZ2Ugc3VwcG9ydCB0byBjb250cm9sIGRyYWcgaW1hZ2UgcG9zaXRpb24gYW5kIHNpemUsXG4gKiAgICAgICAgICAgICAgICBlLmcuLCB0byBzbmFwIHRoZSBkcmFnIGltYWdlIHRvIHRoZSB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd3Yi1wYXJ0LWJhcicsXG4gIHRlbXBsYXRlVXJsOiAnLi9wYXJ0LWJhci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3BhcnQtYmFyLmNvbXBvbmVudC5zY3NzJ10sXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBOZ0ZvcixcbiAgICBBc3luY1BpcGUsXG4gICAgU2NpVmlld3BvcnRDb21wb25lbnQsXG4gICAgU2NpRGltZW5zaW9uTW9kdWxlLFxuICAgIFZpZXdUYWJDb21wb25lbnQsXG4gICAgUGFydEFjdGlvbkJhckNvbXBvbmVudCxcbiAgICBWaWV3TGlzdEJ1dHRvbkNvbXBvbmVudCxcbiAgICBOZ0lmLFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBQYXJ0QmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9ob3N0OiBIVE1MRWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld1RhYnMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxWaWV3VGFiQ29tcG9uZW50W10+KFtdKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZHJhZ2VudGVyJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RyYWdsZWF2ZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kcmFnZW5kJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHB1YmxpYyByZWFkb25seSBkcmFnb3ZlciQ6IE9ic2VydmFibGU8Ym9vbGVhbj47XG5cbiAgQFZpZXdDaGlsZChTY2lWaWV3cG9ydENvbXBvbmVudCwge3N0YXRpYzogdHJ1ZSwgcmVhZDogRWxlbWVudFJlZn0pXG4gIHByaXZhdGUgX3ZpZXdwb3J0RWxlbWVudCE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGQoU2NpVmlld3BvcnRDb21wb25lbnQsIHtzdGF0aWM6IHRydWV9KVxuICBwcml2YXRlIF92aWV3cG9ydENvbXBvbmVudCE6IFNjaVZpZXdwb3J0Q29tcG9uZW50O1xuXG4gIEBWaWV3Q2hpbGQoJ3RhYl9jb3JuZXJfcmFkaXVzJywge3N0YXRpYzogdHJ1ZX0pXG4gIHByaXZhdGUgX3RhYkNvcm5lclJhZGl1c0VsZW1lbnQhOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICBAVmlld0NoaWxkKCdwYWRkaW5nX2lubGluZScsIHtzdGF0aWM6IHRydWV9KVxuICBwcml2YXRlIF9wYWRkaW5nSW5saW5lRWxlbWVudCE6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+O1xuXG4gIEBWaWV3Q2hpbGRyZW4oVmlld1RhYkNvbXBvbmVudClcbiAgcHVibGljIHNldCBpbmplY3RWaWV3VGFicyhxdWVyeUxpc3Q6IFF1ZXJ5TGlzdDxWaWV3VGFiQ29tcG9uZW50Pikge1xuICAgIHF1ZXJ5TGlzdC5jaGFuZ2VzXG4gICAgICAucGlwZShzdGFydFdpdGgocXVlcnlMaXN0KSwgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZShxdWVyeUxpc3QgPT4gdGhpcy5fdmlld1RhYnMkLm5leHQocXVlcnlMaXN0LnRvQXJyYXkoKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgdGFiIGJlZm9yZSB3aGljaCB0byBpbnNlcnQgdGhlIGRyYWcgc291cmNlIG9uIGRyb3AsIG9yIGBlbmRgIGlmIGRyb3BwaW5nIGl0IGFmdGVyIHRoZSBsYXN0IHRhYi5cbiAgICovXG4gIHB1YmxpYyBkcm9wVGFyZ2V0Vmlld1RhYjogVmlld1RhYkNvbXBvbmVudCB8ICdlbmQnIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgdGFiIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiB3YXMgc3RhcnRlZC5cbiAgICogVGhpcyByZWZlcmVuY2UgaXMgb25seSBzZXQgaWYgdGhlIGRyYWcgb3BlcmF0aW9uIHN0YXJ0ZWQgb24gYSB0YWIgb2YgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwdWJsaWMgZHJhZ1NvdXJjZVZpZXdUYWI6IFZpZXdUYWJDb21wb25lbnQgfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogVHJhbnNmZXIgZGF0YSBvZiB0aGUgdGFiIGJlaW5nIGRyYWdnZWQgb3ZlciB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgX2RyYWdEYXRhOiBWaWV3RHJhZ0RhdGEgfCBudWxsID0gbnVsbDtcblxuICAvKipcbiAgICogRnVuY3Rpb24gZm9yIHNuYXBwaW5nIHRoZSBkcmFnIGltYWdlIHRvIHRoZSB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSBfY29uc3RyYWluRm46IENvbnN0cmFpbkZuIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIFRhYmJhciBpbmRlbnRzIHdoZXJlIHRvIGRpc3BsYXkgdGhlIHJvdW5kZWQgYm90dG9tIGNvcm5lcnMgb2YgdGhlIGZpcnN0IGFuZCBsYXN0IHZpZXcgdGFiLlxuICAgKi9cbiAgcHJpdmF0ZSBfdGFiYmFySW5kZW50ID0ge1xuICAgIGxlZnQ6IDAsXG4gICAgcmlnaHQ6IDAsXG4gIH07XG5cbiAgLyoqXG4gICAqIE5vdGlmaWVzIHdoZW4gdGhlIGRyYWcgYW5pbWF0aW9uIGhhcyBmaW5pc2hlZCwgaS5lLiwgdGFicyBoYXZlIHRyYW5zaXRpb25lZCB0byB0aGVpciBmaW5hbCBwb3NpdGlvbi5cbiAgICovXG4gIHByaXZhdGUgX2RyYWdBbmltYXRpb25TdGFibGUkID0gaW50ZXJ2YWwoMCwgYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIpXG4gICAgLnBpcGUoXG4gICAgICBmaWx0ZXIoKCkgPT4gdGhpcy5pc0RyYWdBbmltYXRpb25TdGFibGUoKSksXG4gICAgICBzdWJzY3JpYmVJbnNpZGUoY29udGludWVGbiA9PiB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKGNvbnRpbnVlRm4pKSxcbiAgICAgIG9ic2VydmVJbnNpZGUoY29udGludWVGbiA9PiB0aGlzLl96b25lLnJ1bihjb250aW51ZUZuKSksXG4gICAgICBtYXAoKCkgPT4gdW5kZWZpbmVkIGFzIHZvaWQpLFxuICAgICk7XG5cbiAgY29uc3RydWN0b3IoaG9zdDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgICAgICAgICAgIEBJbmplY3QoV09SS0JFTkNIX0lEKSBwcml2YXRlIF93b3JrYmVuY2hJZDogc3RyaW5nLFxuICAgICAgICAgICAgICBwcml2YXRlIF93b3JrYmVuY2hMYXlvdXRTZXJ2aWNlOiBXb3JrYmVuY2hMYXlvdXRTZXJ2aWNlLFxuICAgICAgICAgICAgICBwcml2YXRlIF9yb3V0ZXI6IMm1V29ya2JlbmNoUm91dGVyLFxuICAgICAgICAgICAgICBwcml2YXRlIF92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXI6IFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfcGFydDogybVXb3JrYmVuY2hQYXJ0LFxuICAgICAgICAgICAgICBwcml2YXRlIF92aWV3RHJhZ1NlcnZpY2U6IFZpZXdEcmFnU2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfZGVzdHJveVJlZjogRGVzdHJveVJlZixcbiAgICAgICAgICAgICAgcHJpdmF0ZSBfem9uZTogTmdab25lKSB7XG4gICAgdGhpcy5faG9zdCA9IGhvc3QubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLmRyYWdvdmVyJCA9IHRoaXMuX3ZpZXdEcmFnU2VydmljZS50YWJiYXJEcmFnT3ZlciQucGlwZShtYXAocGFydElkID0+IHBhcnRJZCA9PT0gdGhpcy5fcGFydC5pZCkpO1xuICB9XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5zdGFsbEFjdGl2ZVZpZXdTY3JvbGxlcigpO1xuICAgIHRoaXMuaW5zdGFsbFNjcm9sbGVkSW50b1ZpZXdVcGRhdGVyKCk7XG4gICAgdGhpcy5pbnN0YWxsVmlld0RyYWdMaXN0ZW5lcigpO1xuICAgIHRoaXMuaW5zdGFsbFRhYmJhckluZGVudFNpemVEZXRlY3RvcigpO1xuICAgIHRoaXMuaW5zdGFsbFZpZXdwb3J0Q2xpZW50U2l6ZURldGVjdG9yKCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkYmxjbGljaycsIFsnJGV2ZW50J10pXG4gIHB1YmxpYyBvbkRvdWJsZUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3BhcnQuaXNJbk1haW5BcmVhKSB7XG4gICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC50b2dnbGVNYXhpbWl6ZWQoKSkudGhlbigpO1xuICAgIH1cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgdmlld0lkcyQoKTogT2JzZXJ2YWJsZTxWaWV3SWRbXT4ge1xuICAgIHJldHVybiB0aGlzLl9wYXJ0LnZpZXdJZHMkO1xuICB9XG5cbiAgcHVibGljIG9uVGFiYmFyVmlld3BvcnREaW1lbnNpb25DaGFuZ2UoKTogdm9pZCB7XG4gICAgdGhpcy5fdmlld3BvcnRDaGFuZ2UkLm5leHQoKTtcbiAgfVxuXG4gIHB1YmxpYyBvblNjcm9sbCgpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgc3RhcnRzIGRyYWdnaW5nIGEgdGFiIG9mIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgQEhvc3RMaXN0ZW5lcignZHJhZ3N0YXJ0JywgWyckZXZlbnQnXSlcbiAgcHVibGljIG9uVmlld0RyYWdTdGFydChldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl92aWV3RHJhZ1NlcnZpY2UuaXNWaWV3RHJhZ0V2ZW50KGV2ZW50KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGRyYWdEYXRhID0gdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnZpZXdEcmFnRGF0YSE7XG4gICAgY29uc3QgZHJhZ1NvdXJjZUluZGV4ID0gdGhpcy5fdmlld1RhYnMuZmluZEluZGV4KHZpZXdUYWIgPT4gdmlld1RhYi52aWV3SWQgPT09IGRyYWdEYXRhLnZpZXdJZCk7XG4gICAgY29uc3QgZHJhZ1NvdXJjZVZpZXdUYWIgPSB0aGlzLl92aWV3VGFic1tkcmFnU291cmNlSW5kZXhdO1xuICAgIGNvbnN0IGRyb3BUYXJnZXRWaWV3VGFiID0gdGhpcy5fdmlld1RhYnNbZHJhZ1NvdXJjZUluZGV4ICsgMV0gPz8gJ2VuZCc7XG5cbiAgICAvLyBDb25zdHJhaW4gZnVuY3Rpb24gZm9yIHNuYXBwaW5nIHRoZSBkcmFnIGltYWdlIHRvIHRoZSB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgIHRoaXMuX2NvbnN0cmFpbkZuID0gdGhpcy5jcmVhdGVEcmFnSW1hZ2VDb25zdHJhaW5GbigpO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5zZXRDb25zdHJhaW5EcmFnSW1hZ2VSZWN0Rm4odGhpcy5fY29uc3RyYWluRm4pO1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zZXRUYWJiYXJEcmFnb3Zlcih0aGlzLl9wYXJ0LmlkKTtcblxuICAgIC8vIFdoZW4gc3RhcnQgZHJhZ2dpbmcgYSB2aWV3IHRhYiwgd2UgcmVtb3ZlIGl0IGZyb20gdGhlIHRhYmJhciBieSBzZXR0aW5nIGl0cyBgZGlzcGxheWAgdG8gYG5vbmVgIGFuZCByZW5kZXIgaXRzIGRyYWcgaW1hZ2UgaW4gYFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcmAgaW5zdGVhZC5cbiAgICAvLyBIb3dldmVyLCBkbyBub3QgdW5zZXQgdGhlIGBkaXNwbGF5YCBvZiB0aGUgZHJhZyBzb3VyY2UgZHVyaW5nIGBkcmFnc3RhcnRgLiBPdGhlcndpc2UsIHRoZSBuYXRpdmUgZHJhZyBvcGVyYXRpb24gd291bGQgYmUgY29ycnVwdGVkIGluIENocm9tZSBhbmQgRWRnZSAoYnV0IG5vdCBpbiBGaXJlZm94KS5cbiAgICBhbmltYXRpb25GcmFtZVNjaGVkdWxlci5zY2hlZHVsZSgoKSA9PiB7XG4gICAgICB0aGlzLmRyYWdTb3VyY2VWaWV3VGFiID0gZHJhZ1NvdXJjZVZpZXdUYWI7XG4gICAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiID0gZHJvcFRhcmdldFZpZXdUYWI7IC8vIFNldCBkcm9wIHRhcmdldCB0byBhdm9pZCB0YWIgYW5pbWF0aW9uLlxuICAgICAgc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwge1xuICAgICAgICAnLS3JtXBhcnQtYmFyLWRyYWctc291cmNlLXdpZHRoJzogYCR7ZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YCxcbiAgICAgICAgJy0tybVwYXJ0LWJhci1kcmFnLWltYWdlLXBsYWNlaG9sZGVyLXdpZHRoJzogYCR7ZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YCxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgLy8gV2hlbiBkcmFnZ2luZyBhIHRhYiB2ZXJ5IHF1aWNrbHkgb3V0IG9mIHRoaXMgdGFiYmFyLCBvbmx5IHRoZSBgZHJhZ3N0YXJ0YCBldmVudCBnZXRzIGZpcmVkLCBidXQgbm90IHRoZSBgZHJhZ2VudGVyYCBldmVudC5cbiAgICAvLyBUaGVyZWZvcmUsIHdlIHN1YnNjcmliZSB0byBnbG9iYWwgYGRyYWdlbnRlcmAgZXZlbnRzIGFuZCBtYW51YWxseSBpbnZva2UgYG9uVGFiYmFyRHJhZ0xlYXZlYCB0byBjb3JyZWN0bHkgZGlzcGxheSB0aGUgdGFicyBhbmQgdGhlIGFjdGl2ZSB2aWV3LlxuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS52aWV3RHJhZyQod2luZG93LCB7ZXZlbnRUeXBlOiBbJ2RyYWdlbnRlciddfSlcbiAgICAgIC5waXBlKHRha2UoMSksIHRha2VVbnRpbCh0aGlzLl9kcmFnZW5kJCksIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBjb250aW51ZXMgZHJhZ2dpbmcgb3ZlciB0aGlzIHRhYmJhci5cbiAgICAgICAgLy8gSWYgbm90LCB0aGUgdXNlciBoYXMgcXVpY2tseSBkcmFnZ2VkIHRoZSB0YWIgb3V0IG9mIHRoZSB0YWJiYXIgYW5kIHdlICBtYW51YWxseSBjYWxsIGBvblRhYmJhckRyYWdMZWF2ZWAuXG4gICAgICAgIGlmICgodGhpcy5faG9zdC5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihldmVudC50YXJnZXQgYXMgRWxlbWVudCkgJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0NPTlRBSU5FRF9CWSkgPT09IDApIHtcbiAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ0xlYXZlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZW5kcyBkcmFnZ2luZyBhIHRhYiBvZiB0aGlzIHRhYmJhci5cbiAgICpcbiAgICogSW52b2tlZCBvbmx5IGluIHRoZSB0YWJiYXIgd2hlcmUgdGhlIGRyYWcgb3BlcmF0aW9uIHN0YXJ0ZWQsIHJlZ2FyZGxlc3Mgb2Ygd2hldGhlciB0aGUgZHJhZyBvcGVyYXRpb24gd2FzIGNvbXBsZXRlZCBvciBjYW5jZWxlZC5cbiAgICovXG4gIEBIb3N0TGlzdGVuZXIoJ2RyYWdlbmQnKVxuICBwdWJsaWMgb25WaWV3RHJhZ0VuZCgpOiB2b2lkIHtcbiAgICB0aGlzLl9kcmFnZW5kJC5uZXh0KCk7XG4gICAgdGhpcy51bnNldERyYWdTdGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZHJhZ3MgYSB0YWIgaW50byB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgb25UYWJiYXJEcmFnRW50ZXIoZXZlbnQ6IERyYWdFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuX2RyYWdlbnRlciQubmV4dCgpO1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zZXRUYWJiYXJEcmFnb3Zlcih0aGlzLl9wYXJ0LmlkKTtcbiAgICB0aGlzLl9kcmFnRGF0YSA9IHRoaXMuX3ZpZXdEcmFnU2VydmljZS52aWV3RHJhZ0RhdGEhO1xuXG4gICAgLy8gQ29uc3RyYWluIGZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICBpZiAoIXRoaXMuX2NvbnN0cmFpbkZuKSB7XG4gICAgICB0aGlzLl9jb25zdHJhaW5GbiA9IHRoaXMuY3JlYXRlRHJhZ0ltYWdlQ29uc3RyYWluRm4oKTtcbiAgICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5zZXRDb25zdHJhaW5EcmFnSW1hZ2VSZWN0Rm4odGhpcy5fY29uc3RyYWluRm4pO1xuICAgIH1cblxuICAgIC8vIExvY2F0ZSBkcm9wIHRhcmdldCB0byBoYXZlIGEgbmljZSBhbmltYXRpb24gZm9yIHRoZSBkcmFnIHNvdXJjZSBwbGFjZWhvbGRlci5cbiAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiID0gdGhpcy5jb21wdXRlRHJvcFRhcmdldChldmVudCk7XG5cbiAgICAvLyBTZXQgdGhlIENTUyBjbGFzcyAnZHJhZy1lbnRlcicgdG8gaW5kaWNhdGUgZW50ZXJpbmcgdGhlIHRhYmJhci5cbiAgICBzZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnZHJhZy1lbnRlcicsICdkcmFnLW92ZXInKTtcbiAgICB0aGlzLl9kcmFnQW5pbWF0aW9uU3RhYmxlJFxuICAgICAgLnBpcGUodGFrZSgxKSwgdGFrZVVudGlsKHRoaXMuX2RyYWdlbnRlciQpLCB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKHtjb21wbGV0ZTogKCkgPT4gdW5zZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnZHJhZy1lbnRlcicpfSk7XG5cbiAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7XG4gICAgICAnLS3JtXBhcnQtYmFyLWRyYWctc291cmNlLXdpZHRoJzogYCR7dGhpcy5fZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YCxcbiAgICAgICctLcm1cGFydC1iYXItZHJhZy1pbWFnZS1wbGFjZWhvbGRlci13aWR0aCc6IGAke3RoaXMuX2RyYWdEYXRhLnZpZXdUYWJXaWR0aH1weGAsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBkcmFncyBhIHRhYiBvdXQgb2YgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiYmFyRHJhZ0xlYXZlKCk6IHZvaWQge1xuICAgIHRoaXMuX2RyYWdsZWF2ZSQubmV4dCgpO1xuXG4gICAgLy8gU2V0IHRoZSBDU1MgY2xhc3MgJ2RyYWctbGVhdmUnIHRvIGluZGljYXRlIGxlYXZpbmcgdGhlIHRhYmJhci5cbiAgICBzZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnZHJhZy1sZWF2ZScpO1xuICAgIHRoaXMuX2RyYWdBbmltYXRpb25TdGFibGUkXG4gICAgICAucGlwZSh0YWtlKDEpLCB0YWtlVW50aWwodGhpcy5fZHJhZ2xlYXZlJCksIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoe2NvbXBsZXRlOiAoKSA9PiB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLWxlYXZlJyl9KTtcblxuICAgIHRoaXMudW5zZXREcmFnU3RhdGUoe3Vuc2V0RHJhZ1NvdXJjZTogZmFsc2V9KTtcblxuICAgIC8vIEFjdGl2YXRlIHRoZSB2aWV3IG5leHQgdG8gdGhlIHZpZXcgYmVpbmcgZHJhZ2dlZCBvdXQgb2YgdGhpcyB0YWJiYXIuIEJ1dCwgZG8gbm90IHB1c2ggdGhlIG5hdmlnYXRpb24gaW50byBicm93c2luZyBoaXN0b3J5IHN0YWNrLlxuICAgIGlmICh0aGlzLmRyYWdTb3VyY2VWaWV3VGFiICYmIHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIuYWN0aXZlKSB7XG4gICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC5hY3RpdmF0ZUFkamFjZW50Vmlldyh0aGlzLmRyYWdTb3VyY2VWaWV3VGFiIS52aWV3SWQpLCB7c2tpcExvY2F0aW9uQ2hhbmdlOiB0cnVlfSkudGhlbigpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGlsZSB0aGUgdXNlciBpcyBkcmFnZ2luZyBhIHRhYiBvdmVyIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdPdmVyKGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpOyAvLyBhbGxvdyB2aWV3IGRyb3BcblxuICAgIC8vIExvY2F0ZSB0aGUgdGFiIG92ZXIgd2hpY2ggdGhlIHVzZXIgaXMgZHJhZ2dpbmcgdGhlIHRhYiwgYnV0IG9ubHkgYWZ0ZXIgcGVuZGluZyB0cmFuc2l0aW9ucyBoYXZlIGVuZGVkIHRvIHByZXZlbnQgdGFicyBmcm9tIHNsaWRpbmcgYmFjayBhbmQgZm9ydGguXG4gICAgaWYgKHRoaXMuaXNEcmFnQW5pbWF0aW9uU3RhYmxlKCkpIHtcbiAgICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgPSB0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50KTtcbiAgICAgIC8vIFN5bmNocm9uaXplIHRoZSB3aWR0aCBvZiB0aGUgZHJhZyBzb3VyY2UgcGxhY2Vob2xkZXIgd2l0aCB0aGUgZHJhZyBwb2ludGVyIHBvc2l0aW9uIHRvIG1vdmUgYWN0aW9ucyBhbG9uZyB3aXRoIHRoZSBwb2ludGVyLlxuICAgICAgc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwgeyctLcm1cGFydC1iYXItZHJhZy1pbWFnZS1wbGFjZWhvbGRlci13aWR0aCc6IGAke3RoaXMuY2FsY3VsYXRlRHJhZ0ltYWdlUGxhY2Vob2xkZXJXaWR0aChldmVudCl9cHhgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZHJvcHMgYSB0YWIgaW4gdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiYmFyRHJvcCgpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2UuZGlzcGF0Y2hWaWV3TW92ZUV2ZW50KHtcbiAgICAgIHNvdXJjZToge1xuICAgICAgICB3b3JrYmVuY2hJZDogdGhpcy5fZHJhZ0RhdGEhLndvcmtiZW5jaElkLFxuICAgICAgICBwYXJ0SWQ6IHRoaXMuX2RyYWdEYXRhIS5wYXJ0SWQsXG4gICAgICAgIHZpZXdJZDogdGhpcy5fZHJhZ0RhdGEhLnZpZXdJZCxcbiAgICAgICAgYWx0ZXJuYXRpdmVWaWV3SWQ6IHRoaXMuX2RyYWdEYXRhIS5hbHRlcm5hdGl2ZVZpZXdJZCxcbiAgICAgICAgdmlld1VybFNlZ21lbnRzOiB0aGlzLl9kcmFnRGF0YSEudmlld1VybFNlZ21lbnRzLFxuICAgICAgICBuYXZpZ2F0aW9uSGludDogdGhpcy5fZHJhZ0RhdGEhLm5hdmlnYXRpb25IaW50LFxuICAgICAgICBjbGFzc0xpc3Q6IHRoaXMuX2RyYWdEYXRhIS5jbGFzc0xpc3QsXG4gICAgICB9LFxuICAgICAgdGFyZ2V0OiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiB0aGlzLl93b3JrYmVuY2hJZCxcbiAgICAgICAgcG9zaXRpb246IHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgPT09ICdlbmQnID8gJ2VuZCcgOiB0aGlzLl92aWV3VGFicy5pbmRleE9mKHRoaXMuZHJvcFRhcmdldFZpZXdUYWIhKSxcbiAgICAgICAgZWxlbWVudElkOiB0aGlzLl9wYXJ0LmlkLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIC8vIFdhaXQgdW5kb2luZyB0aGUgZHJhZyBzdGF0ZSB1bnRpbCBmbHVzaGVkIHRhYiBjaGFuZ2VzIHRvIHRoZSBET00sIGkuZS4sIGFmdGVyIHRoZSBsYXlvdXQgcm91dGluZyBjeWNsZSBjb21wbGV0ZXMuXG4gICAgLy8gSWYgd2Ugd2VyZSB0byB1bmRvIHRoZSBkcmFnIHN0YXRlIGltbWVkaWF0ZWx5IGR1cmluZyB0aGUgY291cnNlIG9mIHRoZSBkcm9wIGV2ZW50LCB0aGUgdGFiIGxheW91dCB3b3VsZCB0ZW1wb3JhcmlseVxuICAgIC8vIHJldmVydCB0byB0aGUgc3RhdGUgYmVmb3JlIHRoZSBkcmFnIG9wZXJhdGlvbiwgcmVzdWx0aW5nIGluIGFuIHVnbHkgZmxpY2tlci5cbiAgICBmaXJzdFZhbHVlRnJvbSh0aGlzLl93b3JrYmVuY2hMYXlvdXRTZXJ2aWNlLm9uTGF5b3V0Q2hhbmdlJCkudGhlbigoKSA9PiB7XG4gICAgICB0aGlzLnVuc2V0RHJhZ1N0YXRlKCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogTG9jYXRlcyB0aGUgdGFiIGJlZm9yZSB3aGljaCB0aGUgZHJhZ2dlZCB0YWIgaXMgdG8gYmUgaW5zZXJ0ZWQgd2hlbiBpdCBpcyBkcm9wcGVkLiBEcmFnZ2luZyBiZXlvbmQgdGhlIGxhc3QgdGFiIHJldHVybnMgYGVuZGAuXG4gICAqL1xuICBwdWJsaWMgY29tcHV0ZURyb3BUYXJnZXQoZXZlbnQ6IERyYWdFdmVudCk6IFZpZXdUYWJDb21wb25lbnQgfCAnZW5kJyB7XG4gICAgY29uc3Qgdmlld0RyYWdJbWFnZVJlY3QgPSB0aGlzLl92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXIuY2FsY3VsYXRlRHJhZ0ltYWdlUmVjdCh0aGlzLl9kcmFnRGF0YSEsIGV2ZW50KTtcbiAgICBjb25zdCB2aWV3VGFicyA9IHRoaXMuX3ZpZXdUYWJzLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIpO1xuXG4gICAgZm9yIChjb25zdCB2aWV3VGFiIG9mIHZpZXdUYWJzKSB7XG4gICAgICBjb25zdCB2aWV3VGFiUmVjdCA9IHZpZXdUYWIuaG9zdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGNvbnN0IHZpZXdUYWJNaWRkbGUgPSB2aWV3VGFiUmVjdC5sZWZ0ICsgKHZpZXdUYWJSZWN0LndpZHRoIC8gMik7XG4gICAgICBpZiAodmlld0RyYWdJbWFnZVJlY3QubGVmdCA8IHZpZXdUYWJNaWRkbGUgJiYgKHZpZXdUYWIgIT09IHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgfHwgdmlld0RyYWdJbWFnZVJlY3QucmlnaHQgPCB2aWV3VGFiTWlkZGxlKSkge1xuICAgICAgICByZXR1cm4gdmlld1RhYjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICdlbmQnO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRHJhZ0ltYWdlQ29uc3RyYWluRm4oKTogQ29uc3RyYWluRm4ge1xuICAgIGNvbnN0IGhvc3RMZWZ0ID0gdGhpcy5faG9zdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0O1xuICAgIGNvbnN0IG1heFZpZXdwb3J0V2lkdGggPSB0aGlzLmNhbGN1bGF0ZU1heFZpZXdwb3J0V2lkdGgoKTtcbiAgICByZXR1cm4gKHJlY3Q6IFZpZXdEcmFnSW1hZ2VSZWN0KTogVmlld0RyYWdJbWFnZVJlY3QgPT4ge1xuICAgICAgY29uc3Qgdmlld3BvcnRCb3VuZGluZ0JveCA9IHRoaXMuX3ZpZXdwb3J0RWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmV0dXJuIG5ldyBWaWV3RHJhZ0ltYWdlUmVjdCh7XG4gICAgICAgIHg6IE1hdGgubWluKE1hdGgubWF4KGhvc3RMZWZ0ICsgdGhpcy5fdGFiYmFySW5kZW50LmxlZnQsIHJlY3QueCksIGhvc3RMZWZ0ICsgbWF4Vmlld3BvcnRXaWR0aCAtIHJlY3Qud2lkdGggLSB0aGlzLl90YWJiYXJJbmRlbnQucmlnaHQpLFxuICAgICAgICB5OiB2aWV3cG9ydEJvdW5kaW5nQm94LnRvcCxcbiAgICAgICAgd2lkdGg6IHJlY3Qud2lkdGgsXG4gICAgICAgIGhlaWdodDogdmlld3BvcnRCb3VuZGluZ0JveC5oZWlnaHQsIC8vIGZpdCBpbnRvIHRhYmJhciwgZS5nLiwgd2hlbiBkcmFnZ2luZyBhIHRhYiBpbnRvIGEgdGFiYmFyIG9mIGEgZGlmZmVyZW50IGhlaWdodFxuICAgICAgfSk7XG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGVzIHRoZSBtYXhpbXVtIHdpZHRoIG9mIHRoZSB0YWJiYXIgdmlld3BvcnQgYmVmb3JlIGFuIG92ZXJmbG93IHdvdWxkIG9jY3VyLCB3aGljaCBjYW4gdGhlbiBiZSB1c2VkIHRvIGNvbnN0cmFpbiB0aGUgZHJhZyBpbWFnZS5cbiAgICpcbiAgICogVG8gY2FsY3VsYXRlIHRoZSBlZmZlY3RpdmUgd2lkdGgsIHdlIG5lZWQgdG8gc2ltdWxhdGUgYW4gb3ZlcmZsb3cgaW4gdGhlIERPTS4gVGhlcmVmb3JlLCBjYWxsIHRoaXMgbWV0aG9kIG9ubHkgZnJvbSBgZHJhZ3N0YXJ0YCBhbmQgbm90XG4gICAqIGZyb20gYGRyYWdvdmVyYCBhbmQgZGlzYWJsZSBhbmltYXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBjYWxjdWxhdGVNYXhWaWV3cG9ydFdpZHRoKCk6IG51bWJlciB7XG4gICAgY29uc3QgY3VycmVudFdpZHRoID0gdGhpcy5faG9zdC5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKCctLcm1cGFydC1iYXItZHJhZy1pbWFnZS1wbGFjZWhvbGRlci13aWR0aCcpO1xuXG4gICAgLy8gRGlzYWJsZSBhbmltYXRpb25zIGR1cmluZyBjYWxjdWxhdGlvbiBhbmQgZm9yY2UgdGhlIHZpZXdwb3J0IHRvIG92ZXJmbG93LlxuICAgIHNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdjYWxjdWxhdGluZy1tYXgtdmlld3BvcnQtd2lkdGgnKTtcbiAgICBzZXRDc3NWYXJpYWJsZSh0aGlzLl9ob3N0LCB7Jy0tybVwYXJ0LWJhci1kcmFnLWltYWdlLXBsYWNlaG9sZGVyLXdpZHRoJzogYCR7dGhpcy5faG9zdC5jbGllbnRXaWR0aH1weGB9KTtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZpZXdwb3J0RWxlbWVudC5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuICAgIH1cbiAgICBmaW5hbGx5IHtcbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctaW1hZ2UtcGxhY2Vob2xkZXItd2lkdGgnOiBjdXJyZW50V2lkdGggfHwgbnVsbH0pO1xuICAgICAgdW5zZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnY2FsY3VsYXRpbmctbWF4LXZpZXdwb3J0LXdpZHRoJyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZXMgdGhlIHdpZHRoIGZvciB0aGUgZHJhZyBpbWFnZSBwbGFjZWhvbGRlci5cbiAgICpcbiAgICogLSBXaGVuIGRyYWdnaW5nIG92ZXIgdGFicywgdGhlIHdpZHRoIGlzIGVxdWFsIHRvIHRoZSB3aWR0aCBvZiB0aGUgZHJhZyBzb3VyY2UuXG4gICAqIC0gV2hlbiBkcmFnZ2luZyB0byB0aGUgcmlnaHQgb2YgdGhlIGxhc3QgdGFiLCB0aGUgd2lkdGggb2YgdGhlIHBsYWNlaG9sZGVyIGlzIGNhbGN1bGF0ZWQgYXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlXG4gICAqICAgbGFzdCB0YWIgYW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgZHJhZ292ZXIgZXZlbnQuIEFwcGx5aW5nIHRoaXMgd2lkdGggd2lsbCByZXNpemUgdGhlIHZpZXdwb3J0LCBtb3ZpbmcgcGFydCBhY3Rpb25zIGFsb25nXG4gICAqICAgd2l0aCB0aGUgZHJhZ292ZXIgZXZlbnQuXG4gICAqL1xuICBwcml2YXRlIGNhbGN1bGF0ZURyYWdJbWFnZVBsYWNlaG9sZGVyV2lkdGgoZXZlbnQ6IERyYWdFdmVudCk6IG51bWJlciB7XG4gICAgY29uc3Qgdmlld0RyYWdJbWFnZVJlY3QgPSB0aGlzLl92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXIuY2FsY3VsYXRlRHJhZ0ltYWdlUmVjdCh0aGlzLl9kcmFnRGF0YSEsIGV2ZW50KTtcbiAgICBjb25zdCBsYXN0Vmlld1RhYiA9IHRoaXMuX3ZpZXdUYWJzLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIpLmF0KC0xKTtcbiAgICBjb25zdCBsYXN0Vmlld1RhYlJpZ2h0ID0gbGFzdFZpZXdUYWI/Lmhvc3QuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkucmlnaHQgPz8gdGhpcy5faG9zdC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5sZWZ0ICsgdGhpcy5fdGFiYmFySW5kZW50LmxlZnQ7XG4gICAgcmV0dXJuIE1hdGgubWF4KGxhc3RWaWV3VGFiUmlnaHQgKyB2aWV3RHJhZ0ltYWdlUmVjdC53aWR0aCwgdmlld0RyYWdJbWFnZVJlY3QucmlnaHQpIC0gbGFzdFZpZXdUYWJSaWdodDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbmRpY2F0ZXMgd2hldGhlciBDU1MgYW5pbWF0aW9ucyBoYXZlIGZpbmlzaGVkIHdoZW4gZHJhZ2dpbmcgYSB0YWIgb3ZlciB0aGUgdGFiYmFyLlxuICAgKiBUaGUgYW5pbWF0aW9uIGlzIGNvbnNpZGVyZWQgc3RhYmxlIHdoZW4gYWxsIHRhYnMgaGF2ZSBtb3ZlZCB0byB0aGVpciBmaW5hbCBwb3NpdGlvbi5cbiAgICovXG4gIHByaXZhdGUgaXNEcmFnQW5pbWF0aW9uU3RhYmxlKCk6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYikge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZpZXdUYWJzLmV2ZXJ5KHZpZXdUYWIgPT4gZ2V0Q3NzVHJhbnNsYXRpb24odmlld1RhYi5ob3N0KS50cmFuc2xhdGVYID09PSAnbm9uZScpO1xuICAgIH1cblxuICAgIGNvbnN0IHZpZXdUYWJzID0gdGhpcy5fdmlld1RhYnMuZmlsdGVyKHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYik7XG4gICAgY29uc3QgZHJvcFRhcmdldEluZGV4ID0gdGhpcy5kcm9wVGFyZ2V0Vmlld1RhYiA9PT0gJ2VuZCcgPyB2aWV3VGFicy5sZW5ndGggOiB2aWV3VGFicy5pbmRleE9mKHRoaXMuZHJvcFRhcmdldFZpZXdUYWIhKTtcbiAgICBjb25zdCBkcmFnU291cmNlV2lkdGggPSB0aGlzLl9kcmFnRGF0YSEudmlld1RhYldpZHRoO1xuXG4gICAgcmV0dXJuIHZpZXdUYWJzLmV2ZXJ5KCh2aWV3VGFiLCBpKSA9PiB7XG4gICAgICBjb25zdCB2aWV3VGFiVHJhbnNsYXRlWCA9IGdldENzc1RyYW5zbGF0aW9uKHZpZXdUYWIuaG9zdCkudHJhbnNsYXRlWDtcbiAgICAgIC8vIEV4cGVjdCB0YWJzIHByZWNlZGluZyB0aGUgZHJvcCB0YXJnZXQgbm90IHRvIGJlIHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0LlxuICAgICAgaWYgKGkgPCBkcm9wVGFyZ2V0SW5kZXggJiYgdmlld1RhYlRyYW5zbGF0ZVggIT09ICdub25lJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICAvLyBFeHBlY3QgZHJvcCB0YXJnZXQgYW5kIHRhYnMgZm9sbG93aW5nIHRoZSBkcm9wIHRhcmdldCB0byBiZSBzaGlmdGVkIHRvIHRoZSByaWdodC5cbiAgICAgIGlmIChpID49IGRyb3BUYXJnZXRJbmRleCAmJiBNYXRoLmZsb29yKE51bWJlcih2aWV3VGFiVHJhbnNsYXRlWCkpICE9PSBNYXRoLmZsb29yKGRyYWdTb3VyY2VXaWR0aCkpIHsgLy8gY29tcGFyZSBmbG9vcmVkIG51bWJlcnMgYmVjYXVzZSBgdHJhbnNsYXRlWGAgaXMgbm90IHByZWNpc2VcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVuc2V0RHJhZ1N0YXRlKG9wdGlvbnM/OiB7dW5zZXREcmFnU291cmNlPzogYm9vbGVhbn0pOiB2b2lkIHtcbiAgICBpZiAob3B0aW9ucz8udW5zZXREcmFnU291cmNlID8/IHRydWUpIHtcbiAgICAgIHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIgPSBudWxsO1xuICAgIH1cblxuICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIgPSBudWxsO1xuICAgIHRoaXMuX2RyYWdEYXRhID0gbnVsbDtcbiAgICB0aGlzLl92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXIudW5zZXRDb25zdHJhaW5EcmFnSW1hZ2VSZWN0Rm4odGhpcy5fY29uc3RyYWluRm4hKTtcbiAgICB0aGlzLl9jb25zdHJhaW5GbiA9IG51bGw7XG5cbiAgICB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLW92ZXInKTtcbiAgICB1bnNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsICctLcm1cGFydC1iYXItZHJhZy1zb3VyY2Utd2lkdGgnLCAnLS3JtXBhcnQtYmFyLWRyYWctaW1hZ2UtcGxhY2Vob2xkZXItd2lkdGgnKTtcbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2UudW5zZXRUYWJiYXJEcmFnb3Zlcih0aGlzLl9wYXJ0LmlkKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0IF92aWV3VGFicygpOiBWaWV3VGFiQ29tcG9uZW50W10ge1xuICAgIHJldHVybiB0aGlzLl92aWV3VGFicyQudmFsdWU7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyB0aGUgdGFiIG9mIHRoZSBhY3RpdmUgdmlldyBpbnRvIHZpZXcuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxBY3RpdmVWaWV3U2Nyb2xsZXIoKTogdm9pZCB7XG4gICAgdGhpcy5fdmlld1RhYnMkXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKHZpZXdUYWJzID0+IGNvbWJpbmVMYXRlc3Qodmlld1RhYnMubWFwKHZpZXdUYWIgPT4gdmlld1RhYi52aWV3LmFjdGl2ZSQpKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAvLyBUaGVyZSBtYXkgYmUgbm8gYWN0aXZlIHZpZXcgaW4gdGhlIHRhYmJhciwgZS5nLiwgd2hlbiBkcmFnZ2luZyB0aGUgbGFzdCB2aWV3IG91dCBvZiB0aGUgdGFiYmFyLlxuICAgICAgICBjb25zdCBhY3RpdmVWaWV3VGFiID0gdGhpcy5fdmlld1RhYnMuZmluZCh2aWV3VGFiID0+IHZpZXdUYWIuYWN0aXZlKTtcbiAgICAgICAgaWYgKGFjdGl2ZVZpZXdUYWIgJiYgIXRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50LmlzRWxlbWVudEluVmlldyhhY3RpdmVWaWV3VGFiLmhvc3QsICdmdWxsJykpIHtcbiAgICAgICAgICB0aGlzLl92aWV3cG9ydENvbXBvbmVudC5zY3JvbGxJbnRvVmlldyhhY3RpdmVWaWV3VGFiLmhvc3QpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBVcGRhdGVzIHtAbGluayDJtVdvcmtiZW5jaFZpZXd9IHdoZW4gaXRzIHRhYiBpcyBzY3JvbGxlZCBpbnRvIHZpZXcuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxTY3JvbGxlZEludG9WaWV3VXBkYXRlcigpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3cG9ydENoYW5nZSRcbiAgICAgIC5waXBlKFxuICAgICAgICBtYXAoKCkgPT4gdGhpcy5fdmlld1RhYnMpLFxuICAgICAgICBmaWx0ZXJBcnJheSh2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIpLCAvLyBza2lwIGRyYWcgc291cmNlIGFzIGFsd2F5cyBzY3JvbGxlZCBvdXQgb2Ygdmlld1xuICAgICAgICBtZXJnZU1hcCh2aWV3VGFicyA9PiBmcm9tKHZpZXdUYWJzKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUodmlld1RhYiA9PiB7XG4gICAgICAgIHZpZXdUYWIudmlldy5zY3JvbGxlZEludG9WaWV3ID0gdGhpcy5fdmlld3BvcnRDb21wb25lbnQuaXNFbGVtZW50SW5WaWV3KHZpZXdUYWIuaG9zdCwgJ2Z1bGwnKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnN0YWxsVmlld0RyYWdMaXN0ZW5lcigpOiB2b2lkIHtcbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld0RyYWckKHRoaXMuX2hvc3QpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKChldmVudDogRHJhZ0V2ZW50KSA9PiB7XG4gICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xuICAgICAgICAgIGNhc2UgJ2RyYWdlbnRlcic6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ0VudGVyKGV2ZW50KTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ2RyYWdvdmVyJzpcbiAgICAgICAgICAgIHRoaXMub25UYWJiYXJEcmFnT3ZlcihldmVudCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcmFnbGVhdmUnOlxuICAgICAgICAgICAgdGhpcy5vblRhYmJhckRyYWdMZWF2ZSgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJvcCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnN0YWxsVmlld3BvcnRDbGllbnRTaXplRGV0ZWN0b3IoKTogdm9pZCB7XG4gICAgZnJvbURpbWVuc2lvbiQodGhpcy5fdmlld3BvcnRDb21wb25lbnQudmlld3BvcnRDbGllbnRFbGVtZW50KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN1YnNjcmliZUluc2lkZShmbiA9PiB0aGlzLl96b25lLnJ1bihmbikpLFxuICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMuX3ZpZXdwb3J0Q2hhbmdlJC5uZXh0KCkpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbnN0YWxsVGFiYmFySW5kZW50U2l6ZURldGVjdG9yKCk6IHZvaWQge1xuICAgIGNvbWJpbmVMYXRlc3QoW2Zyb21EaW1lbnNpb24kKHRoaXMuX3RhYkNvcm5lclJhZGl1c0VsZW1lbnQubmF0aXZlRWxlbWVudCksIGZyb21EaW1lbnNpb24kKHRoaXMuX3BhZGRpbmdJbmxpbmVFbGVtZW50Lm5hdGl2ZUVsZW1lbnQpXSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzdWJzY3JpYmVJbnNpZGUoZm4gPT4gdGhpcy5fem9uZS5ydW5PdXRzaWRlQW5ndWxhcihmbikpLFxuICAgICAgICBtYXBBcnJheShkaW1lbnNpb24gPT4gZGltZW5zaW9uLmNsaWVudFdpZHRoKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoW3RhYkNvcm5lclJhZGl1cywgcGFkZGluZ0lubGluZV0pID0+IHtcbiAgICAgICAgdGhpcy5fdGFiYmFySW5kZW50ID0ge2xlZnQ6IHRhYkNvcm5lclJhZGl1cyArIHBhZGRpbmdJbmxpbmUsIHJpZ2h0OiB0YWJDb3JuZXJSYWRpdXMgKyBwYWRkaW5nSW5saW5lfTtcbiAgICAgICAgc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwgeyctLcm1cGFydC1iYXItaW5kZW50LWxlZnQnOiBgJHt0aGlzLl90YWJiYXJJbmRlbnQubGVmdH1weGB9KTtcbiAgICAgICAgc2V0Q3NzVmFyaWFibGUodGhpcy5faG9zdCwgeyctLcm1cGFydC1iYXItaW5kZW50LXJpZ2h0JzogYCR7dGhpcy5fdGFiYmFySW5kZW50LnJpZ2h0fXB4YH0pO1xuICAgICAgfSk7XG4gIH1cbn1cbiIsIjxzY2ktdmlld3BvcnQgY2xhc3M9XCJ0YWJiYXJcIiBzY3JvbGxiYXJTdHlsZT1cImhpZGRlblwiXG4gICAgICAgICAgICAgIFtjbGFzcy5kcmFnb3Zlcl09XCJkcmFnb3ZlciQgfCBhc3luY1wiXG4gICAgICAgICAgICAgIHNjaURpbWVuc2lvbiAoc2NpRGltZW5zaW9uQ2hhbmdlKT1cIm9uVGFiYmFyVmlld3BvcnREaW1lbnNpb25DaGFuZ2UoKVwiXG4gICAgICAgICAgICAgIChzY3JvbGwpPVwib25TY3JvbGwoKVwiPlxuICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCB2aWV3SWQgb2Ygdmlld0lkcyQgfCBhc3luYztcIj5cbiAgICA8ZGl2IGNsYXNzPVwiZGl2aWRlclwiICpuZ0lmPVwidmlld3RhYiA9PT0gZHJvcFRhcmdldFZpZXdUYWJcIj48L2Rpdj5cbiAgICA8d2Itdmlldy10YWIgI3ZpZXd0YWJcbiAgICAgICAgICAgICAgICAgW3ZpZXdJZF09XCJ2aWV3SWRcIlxuICAgICAgICAgICAgICAgICBbY2xhc3MuZHJhZy1zb3VyY2VdPVwidmlld3RhYiA9PT0gZHJhZ1NvdXJjZVZpZXdUYWJcIlxuICAgICAgICAgICAgICAgICBbY2xhc3MuZHJvcC10YXJnZXRdPVwidmlld3RhYiA9PT0gZHJvcFRhcmdldFZpZXdUYWJcIj5cbiAgICA8L3diLXZpZXctdGFiPlxuICAgIDxkaXYgY2xhc3M9XCJkaXZpZGVyXCI+PC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDwhLS0gUGxhY2Vob2xkZXIgZWxlbWVudCB0byBncm93IHRoZSB2aWV3cG9ydCB0byBmaXQgdGhlIGRyYWcgaW1hZ2UuIC0tPlxuICA8ZGl2IGNsYXNzPVwiZHJhZy1pbWFnZS1wbGFjZWhvbGRlclwiPjwvZGl2PlxuPC9zY2ktdmlld3BvcnQ+XG48d2ItcGFydC1hY3Rpb24tYmFyLz5cbjx3Yi12aWV3LWxpc3QtYnV0dG9uLz5cblxuPCEtLSBFbGVtZW50IGZvciBpbmplY3RpbmcgdGhlIGNvcm5lciByYWRpdXMgaW50byB0aGUgY29tcG9uZW50LiAtLT5cbjxkaXYgY2xhc3M9XCJ0YWItY29ybmVyLXJhZGl1c1wiICN0YWJfY29ybmVyX3JhZGl1cz48L2Rpdj5cbjwhLS0gRWxlbWVudCBmb3IgaW5qZWN0aW5nIHRoZSB0YWJiYXIgcGFkZGluZyBpbnRvIHRoZSBjb21wb25lbnQuIC0tPlxuPGRpdiBjbGFzcz1cInBhZGRpbmctaW5saW5lXCIgI3BhZGRpbmdfaW5saW5lPjwvZGl2PlxuIl19
|
|
528
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFydC1iYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc2Npb24vd29ya2JlbmNoL3NyYy9saWIvcGFydC9wYXJ0LWJhci9wYXJ0LWJhci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zY2lvbi93b3JrYmVuY2gvc3JjL2xpYi9wYXJ0L3BhcnQtYmFyL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBRUgsT0FBTyxFQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ25LLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBQyxHQUFHLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3hELE9BQU8sRUFBQyxJQUFJLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQW9CLE9BQU8sRUFBRSxLQUFLLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDMUYsT0FBTyxFQUFjLHdCQUF3QixFQUFDLE1BQU0scURBQXFELENBQUM7QUFDMUcsT0FBTyxFQUFlLGVBQWUsRUFBZ0IsTUFBTSxrQ0FBa0MsQ0FBQztBQUM5RixPQUFPLEVBQUMsaUJBQWlCLEVBQUUsV0FBVyxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUN0SCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sMEJBQTBCLENBQUM7QUFDeEQsT0FBTyxFQUFDLFdBQVcsRUFBRSxXQUFXLEVBQUMsTUFBTSww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QkFEdEIsWUFBWTt1QkFBQyxVQUFVLEVBQUUsQ0FBQyxRQUFRLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMjQgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5cbmltcG9ydCB7Q29tcG9uZW50LCBjb21wdXRlZCwgZWZmZWN0LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIGluamVjdCwgTmdab25lLCBPbkRlc3Ryb3ksIFNpZ25hbCwgc2lnbmFsLCB1bnRyYWNrZWQsIHZpZXdDaGlsZCwgdmlld0NoaWxkcmVufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7Vmlld1RhYkNvbXBvbmVudH0gZnJvbSAnLi4vdmlldy10YWIvdmlldy10YWIuY29tcG9uZW50JztcbmltcG9ydCB7bWFwLCBtZXJnZU1hcCwgdGFrZVVudGlsfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge2Zyb20sIGZyb21FdmVudCwgbWVyZ2UsIE9ic2VydmFibGUsIE9wZXJhdG9yRnVuY3Rpb24sIFN1YmplY3QsIHRpbWVyfSBmcm9tICdyeGpzJztcbmltcG9ydCB7Q29uc3RyYWluRm4sIFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcn0gZnJvbSAnLi4vLi4vdmlldy1kbmQvdmlldy10YWItZHJhZy1pbWFnZS1yZW5kZXJlci5zZXJ2aWNlJztcbmltcG9ydCB7Vmlld0RyYWdEYXRhLCBWaWV3RHJhZ1NlcnZpY2UsIFZpZXdNb3ZlRXZlbnR9IGZyb20gJy4uLy4uL3ZpZXctZG5kL3ZpZXctZHJhZy5zZXJ2aWNlJztcbmltcG9ydCB7Z2V0Q3NzVHJhbnNsYXRpb24sIHNldENzc0NsYXNzLCBzZXRDc3NWYXJpYWJsZSwgdW5zZXRDc3NDbGFzcywgdW5zZXRDc3NWYXJpYWJsZX0gZnJvbSAnLi4vLi4vY29tbW9uL2RvbS51dGlsJztcbmltcG9ydCB7ybVXb3JrYmVuY2hQYXJ0fSBmcm9tICcuLi/JtXdvcmtiZW5jaC1wYXJ0Lm1vZGVsJztcbmltcG9ydCB7ZmlsdGVyQXJyYXksIHN1YnNjcmliZUlufSBmcm9tICdAc2Npb24vdG9vbGtpdC9vcGVyYXRvcnMnO1xuaW1wb3J0IHtTY2lWaWV3cG9ydENvbXBvbmVudH0gZnJvbSAnQHNjaW9uL2NvbXBvbmVudHMvdmlld3BvcnQnO1xuaW1wb3J0IHvJtVdvcmtiZW5jaFJvdXRlcn0gZnJvbSAnLi4vLi4vcm91dGluZy/JtXdvcmtiZW5jaC1yb3V0ZXIuc2VydmljZSc7XG5pbXBvcnQge2JvdW5kaW5nQ2xpZW50UmVjdCwgZGltZW5zaW9ufSBmcm9tICdAc2Npb24vY29tcG9uZW50cy9kaW1lbnNpb24nO1xuaW1wb3J0IHtQYXJ0QWN0aW9uQmFyQ29tcG9uZW50fSBmcm9tICcuLi9wYXJ0LWFjdGlvbi1iYXIvcGFydC1hY3Rpb24tYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQge1ZpZXdMaXN0QnV0dG9uQ29tcG9uZW50fSBmcm9tICcuLi92aWV3LWxpc3QtYnV0dG9uL3ZpZXctbGlzdC1idXR0b24uY29tcG9uZW50JztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge1dPUktCRU5DSF9JRH0gZnJvbSAnLi4vLi4vd29ya2JlbmNoLWlkJztcbmltcG9ydCB7Y2xhbXB9IGZyb20gJy4uLy4uL2NvbW1vbi9tYXRoLnV0aWwnO1xuXG4vKipcbiAqIFJlbmRlcnMgdmlldyB0YWJzIGFuZCBhY3Rpb25zIG9mIGEge0BsaW5rIFdvcmtiZW5jaFBhcnR9LlxuICpcbiAqIFRhYnMgYXJlIGFkZGVkIHRvIGEgdmlld3BvcnQsIHdoaWNoIHRoZSB1c2VyIGNhbiBzY3JvbGwgaWYgbm90IGVub3VnaCBzcGFjZS4gVGhlIHZpZXdwb3J0IGdyb3dzIHdpdGggaXRzIHRhYnMsXG4gKiBhbGxvd2luZyBhY3Rpb25zIHRvIGJlIHBsYWNlZCBkaXJlY3RseSBhZnRlciB0aGUgbGFzdCB0YWIgb3Igb24gdGhlIHJpZ2h0IHNpZGUuXG4gKlxuICogIyMgRHJhZyBhbmQgRHJvcFxuICogVGhpcyBjb21wb25lbnQgc3Vic2NyaWJlcyB0byBkcmFnIGV2ZW50cyB0byB2aXN1YWxpemUgdGFicyBkdXJpbmcgYSBkcmFnIG9wZXJhdGlvbi4gVGhlIGRyYWcgb3BlcmF0aW9uIGlzIGluaXRpYXRlZCBpbiB7QGxpbmsgVmlld1RhYkNvbXBvbmVudH0uXG4gKlxuICogV2UgdXNlIG5hdGl2ZSBkcmFnIGFuZCBkcm9wIHRvIHN1cHBvcnQgZHJhZ2dpbmcgdmlld3MgdG8gb3RoZXIgd2luZG93cy5cbiAqXG4gKiBGb2xsb3dpbmcgZXZlbnRzIGFyZSB0cmlnZ2VyZWQ6XG4gKiAtIGRyYWdzdGFydDogd2hlbiBzdGFydCBkcmFnZ2luZyBhIHRhYiAob25seSByZWNlaXZlZCBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgc3RhcnRlZClcbiAqIC0gZHJhZ2VuZDogICB3aGVuIGVuZCBkcmFnZ2luZyBhIHRhYiwgZWl0aGVyIHZpYSBkcm9wIG9yIGNhbmNlbCAob25seSByZWNlaXZlZCBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgc3RhcnRlZClcbiAqIC0gZHJhZ2VudGVyOiB3aGVuIGEgdGFiIGVudGVycyB0aGUgdGFiYmFyXG4gKiAtIGRyYWdvdmVyOiAgd2hlbiBkcmFnZ2luZyBhIHRhYiBvdmVyIHRoZSB0YWJiYXIsIGV2ZXJ5IGZldyBodW5kcmVkIG1pbGxpc2Vjb25kc1xuICogLSBkcmFnbGVhdmU6IHdoZW4gYSB0YWIgbGVhdmVzIHRoZSB0YWJiYXJcbiAqIC0gZHJvcDogICAgICB3aGVuIHRoZSB1c2VyIGRyb3BzIGEgdGFiIGluIHRoZSB0YWJiYXJcbiAqXG4gKiAtIE5vdGUgdGhhdCBgZHJhZ2xlYXZlYCBldmVudCBpcyBub3QgZmlyZWQgb24gZHJvcCBhY3Rpb24uIFRoZXJlZm9yZSwgYWx3YXlzIGhhbmRsZSBib3RoIGV2ZW50cywgYGRyYWdsZWF2ZWAgYW5kIGBkcm9wYCBldmVudHMsIHJlc3BlY3RpdmVseS5cbiAqXG4gKiAjIyBUZXJtaW5vbG9neVxuICogLSBEcmFnIHNvdXJjZTogVGFiIHRoYXQgaXMgYmVpbmcgZHJhZ2dlZC5cbiAqIC0gRHJvcCB0YXJnZXQ6IFRhYiBiZWZvcmUgd2hpY2ggdG8gaW5zZXJ0IHRoZSBkcmFnIHNvdXJjZSBvbiBkcm9wLCBvciBgZW5kYCBpZiBkcm9wcGluZyBpdCBhZnRlciB0aGUgbGFzdCB0YWIuXG4gKiAtIERyYWcgaW1hZ2U6ICBJbWFnZSBmb3IgdGhlIHRhYiB0byBiZSBkcmFnZ2VkLiBXZSBkbyBub3QgdXNlIHRoZSBuYXRpdmUgZHJhZyBpbWFnZSBzdXBwb3J0IHRvIGNvbnRyb2wgZHJhZyBpbWFnZSBwb3NpdGlvbiBhbmQgc2l6ZSxcbiAqICAgICAgICAgICAgICAgIGUuZy4sIHRvIHNuYXAgdGhlIGRyYWcgaW1hZ2UgdG8gdGhlIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3diLXBhcnQtYmFyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3BhcnQtYmFyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcGFydC1iYXIuY29tcG9uZW50LnNjc3MnXSxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIFNjaVZpZXdwb3J0Q29tcG9uZW50LFxuICAgIFZpZXdUYWJDb21wb25lbnQsXG4gICAgUGFydEFjdGlvbkJhckNvbXBvbmVudCxcbiAgICBWaWV3TGlzdEJ1dHRvbkNvbXBvbmVudCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgUGFydEJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfaG9zdCA9IGluamVjdChFbGVtZW50UmVmPEhUTUxFbGVtZW50PikubmF0aXZlRWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRDaGFuZ2UkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfd29ya2JlbmNoSWQgPSBpbmplY3QoV09SS0JFTkNIX0lEKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcm91dGVyID0gaW5qZWN0KMm1V29ya2JlbmNoUm91dGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyID0gaW5qZWN0KFZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdEcmFnU2VydmljZSA9IGluamVjdChWaWV3RHJhZ1NlcnZpY2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF96b25lID0gaW5qZWN0KE5nWm9uZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld1RhYnMgPSB2aWV3Q2hpbGRyZW4oVmlld1RhYkNvbXBvbmVudCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2hvc3RCb3VuZGluZ0NsaWVudFJlY3QgPSBib3VuZGluZ0NsaWVudFJlY3QoaW5qZWN0KEVsZW1lbnRSZWYpKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRDb21wb25lbnQgPSB2aWV3Q2hpbGQucmVxdWlyZWQoU2NpVmlld3BvcnRDb21wb25lbnQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3cG9ydENvbXBvbmVudEVsZW1lbnQgPSB2aWV3Q2hpbGQucmVxdWlyZWQoU2NpVmlld3BvcnRDb21wb25lbnQsIHtyZWFkOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pn0pO1xuICBwcml2YXRlIHJlYWRvbmx5IF90YWJDb3JuZXJSYWRpdXNFbGVtZW50ID0gdmlld0NoaWxkLnJlcXVpcmVkKCd0YWJfY29ybmVyX3JhZGl1cycsIHtyZWFkOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50Pn0pO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wYWRkaW5nSW5saW5lRWxlbWVudCA9IHZpZXdDaGlsZC5yZXF1aXJlZCgncGFkZGluZ19pbmxpbmUnLCB7cmVhZDogRWxlbWVudFJlZjxIVE1MRWxlbWVudD59KTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZmlsbGVyRWxlbWVudCA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ2ZpbGxlcicpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3cG9ydEJvdW5kaW5nQm94ID0gYm91bmRpbmdDbGllbnRSZWN0KHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50RWxlbWVudCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX21heFZpZXdwb3J0V2lkdGg6IFNpZ25hbDxudW1iZXI+O1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBwYXJ0ID0gaW5qZWN0KMm1V29ya2JlbmNoUGFydCk7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdGFydEFjdGlvbnMgPSBjb21wdXRlZCgoKSA9PiB0aGlzLnBhcnQuYWN0aW9ucygpLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLmFsaWduICE9PSAnZW5kJykpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZW5kQWN0aW9ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMucGFydC5hY3Rpb25zKCkuZmlsdGVyKGFjdGlvbiA9PiBhY3Rpb24uYWxpZ24gPT09ICdlbmQnKSk7XG5cbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgdGFiIGJlZm9yZSB3aGljaCB0byBpbnNlcnQgdGhlIGRyYWcgc291cmNlIG9uIGRyb3AsIG9yIGBlbmRgIGlmIGRyb3BwaW5nIGl0IGFmdGVyIHRoZSBsYXN0IHRhYi5cbiAgICovXG4gIHByb3RlY3RlZCBkcm9wVGFyZ2V0Vmlld1RhYiA9IHNpZ25hbDxWaWV3VGFiQ29tcG9uZW50IHwgJ2VuZCcgfCBudWxsPihudWxsKTtcblxuICAvKipcbiAgICogUmVmZXJlbmNlIHRvIHRoZSB0YWIgd2hlcmUgdGhlIGRyYWcgb3BlcmF0aW9uIHdhcyBzdGFydGVkLlxuICAgKiBUaGlzIHJlZmVyZW5jZSBpcyBvbmx5IHNldCBpZiB0aGUgZHJhZyBvcGVyYXRpb24gc3RhcnRlZCBvbiBhIHRhYiBvZiB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByb3RlY3RlZCBkcmFnU291cmNlVmlld1RhYiA9IHNpZ25hbDxWaWV3VGFiQ29tcG9uZW50IHwgbnVsbD4obnVsbCk7XG5cbiAgLyoqXG4gICAqIFRyYW5zZmVyIGRhdGEgb2YgdGhlIHRhYiBiZWluZyBkcmFnZ2VkIG92ZXIgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIF9kcmFnRGF0YTogVmlld0RyYWdEYXRhIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqXG4gICAqIEZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICovXG4gIHByaXZhdGUgX2NvbnN0cmFpbkZuOiBDb25zdHJhaW5GbiB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBTaWduYWxzIHdoZW4gdW5zZXR0aW5nIGRyYWcgc3RhdGUuXG4gICAqL1xuICBwcml2YXRlIF9vblVuc2V0RHJhZ1N0YXRlID0gc2lnbmFsPHZvaWQ+KHVuZGVmaW5lZCwge2VxdWFsOiAoKSA9PiBmYWxzZX0pO1xuXG4gIC8qKlxuICAgKiBUYWJiYXIgaW5kZW50cyB3aGVyZSB0byBkaXNwbGF5IHRoZSByb3VuZGVkIGJvdHRvbSBjb3JuZXJzIG9mIHRoZSBmaXJzdCBhbmQgbGFzdCB2aWV3IHRhYi5cbiAgICovXG4gIHByaXZhdGUgX3RhYmJhckluZGVudCA9IHtcbiAgICBsZWZ0OiAwLFxuICAgIHJpZ2h0OiAwLFxuICB9O1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuX21heFZpZXdwb3J0V2lkdGggPSB0aGlzLmNhbGN1bGF0ZU1heFZpZXdwb3J0V2lkdGgoKTtcbiAgICB0aGlzLmluc3RhbGxBY3RpdmVWaWV3U2Nyb2xsZXIoKTtcbiAgICB0aGlzLmluc3RhbGxTY3JvbGxlZEludG9WaWV3VXBkYXRlcigpO1xuICAgIHRoaXMuaW5zdGFsbFZpZXdEcmFnTGlzdGVuZXIoKTtcbiAgICB0aGlzLmluc3RhbGxUYWJiYXJJbmRlbnRTaXplVHJhY2tlcigpO1xuICAgIHRoaXMuaW5zdGFsbFZpZXdwb3J0Q2hhbmdlVHJhY2tlcigpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZGJsY2xpY2snLCBbJyRldmVudCddKVxuICBwcm90ZWN0ZWQgb25Eb3VibGVDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnBhcnQuaXNJbk1haW5BcmVhKSB7XG4gICAgICB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC50b2dnbGVNYXhpbWl6ZWQoKSkudGhlbigpO1xuICAgIH1cbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSB1c2VyIHN0YXJ0cyBkcmFnZ2luZyBhIHRhYiBvZiB0aGlzIHRhYmJhciwgb25seSBpbiB0aGUgdGFiYmFyIHdoZXJlIHRoZSBkcmFnIHN0YXJ0ZWQuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiRHJhZ1N0YXJ0KCk6IHZvaWQge1xuICAgIC8vIE1lbW9pemUgZHJhZyBkYXRhLlxuICAgIHRoaXMuX2RyYWdEYXRhID0gdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnZpZXdEcmFnRGF0YSgpITtcblxuICAgIC8vIEluZGljYXRlIGRyYWdnaW5nIG92ZXIgdGhpcyB0YWJiYXIuXG4gICAgdGhpcy5fdmlld0RyYWdTZXJ2aWNlLnNpZ25hbFRhYmJhckRyYWdFbnRlcih0aGlzLnBhcnQuaWQpO1xuXG4gICAgLy8gU25hcCBkcmFnIGltYWdlIHRvIHRhYmJhciB3aGVuIGRyYWdnaW5nIG5lYXIgaXQuXG4gICAgdGhpcy5fY29uc3RyYWluRm4gPSB0aGlzLmNyZWF0ZURyYWdJbWFnZUNvbnN0cmFpbkZuKCk7XG4gICAgdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5Gbik7XG5cbiAgICAvLyBEaXNhYmxlIHBvaW50ZXIgZXZlbnRzIHRvIG5vdCBicmVhayB0aGUgZHJhZyBvcGVyYXRpb24gKGluIEZpcmVmb3gsIGJ1dCBub3QgQ2hyb21lIGFuZCBFZGdlKS5cbiAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4gc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ3BvaW50ZXItZXZlbnRzLWRpc2FibGVkJykpO1xuXG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBub3QgYW5pbWF0ZSBzdGFydCBkcmFnZ2luZy5cbiAgICBzZXRDc3NDbGFzcyh0aGlzLl9ob3N0LCAnb24tZHJhZy1zdGFydCcpO1xuICAgIHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKCgpID0+IHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctc3RhcnQnKSk7XG5cbiAgICAvLyBDaGVjayBpZiB0aGUgdXNlciBjb250aW51ZXMgZHJhZ2dpbmcgb3ZlciB0aGlzIHRhYmJhci5cbiAgICAvLyBJZiBub3QsIHRoZSB1c2VyIGhhcyBxdWlja2x5IGRyYWdnZWQgdGhlIHRhYiBvdXQgb2YgdGhlIHRhYmJhciwgc28gbWFudWFsbHkgY2FsbCBgb25UYWJiYXJEcmFnRW50ZXJgIGFuZCBgb25UYWJiYXJEcmFnTGVhdmVgLlxuICAgIGZyb21FdmVudDxEcmFnRXZlbnQ+KHdpbmRvdywgJ2RyYWdlbnRlcicsIHtvbmNlOiB0cnVlfSlcbiAgICAgIC5waXBlKHRha2VVbnRpbChtZXJnZShmcm9tRXZlbnQodGhpcy5faG9zdCwgJ2RyYWdlbnRlcicpLCBmcm9tRXZlbnQodGhpcy5faG9zdCwgJ2RyYWdlbmQnKSkpKVxuICAgICAgLnN1YnNjcmliZShldmVudCA9PiB7XG4gICAgICAgIHRoaXMub25UYWJiYXJEcmFnRW50ZXIoZXZlbnQpO1xuICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ0xlYXZlKGV2ZW50KTtcbiAgICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZW5kcyBkcmFnZ2luZyBhIHRhYiBvZiB0aGlzIHRhYmJhciwgZWl0aGVyIGJ5IGRyb3Agb3IgY2FuY2VsLCBvbmx5IGluIHRoZSB0YWJiYXIgd2hlcmUgdGhlIGRyYWcgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgb25UYWJEcmFnRW5kKGV2ZW50OiBEcmFnRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBVbnNldCBkcmFnIHN0YXRlIG9ubHkgb24gY2FuY2VsLCBub3Qgb24gZHJvcCwgdG8gcHJldmVudCB0YWJzIGZyb20gdGVtcG9yYXJpbHkgcmV2ZXJ0aW5nIHRvIHRoZWlyIHByZS1kcmFnIHN0YXRlLiBEcmFnIHN0YXRlIGlzIHJlc2V0IGluIGBvblRhYk1vdmVkYCBhZnRlciBhIGRyb3AuXG4gICAgaWYgKGV2ZW50LmRhdGFUcmFuc2ZlciEuZHJvcEVmZmVjdCA9PT0gJ25vbmUnKSB7XG4gICAgICAvLyBSZWFjdGl2YXRlIHRoZSBkcmFnIHNvdXJjZSB2aWV3IG9uIGNhbmNlbC5cbiAgICAgIHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKT8udmlldygpLmFjdGl2YXRlKHtza2lwTG9jYXRpb25DaGFuZ2U6IHRydWV9KS50aGVuKCk7XG4gICAgICAvLyBVbnNldCBkcmFnIHN0YXRlLlxuICAgICAgdGhpcy51bnNldERyYWdTdGF0ZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSBsYXlvdXQgaGFzIGNoYW5nZWQgYWZ0ZXIgYSBkcm9wLiBUaGUgZHJvcCBtYXkgbm90IGJlIHJlbGF0ZWQgdG8gYSB0YWIgb2YgdGhpcyB0YWJiYXIuXG4gICAqL1xuICBwcml2YXRlIG9uVGFiTW92ZWQoZXZlbnQ6IFZpZXdNb3ZlRXZlbnQpOiB2b2lkIHtcbiAgICAvLyBVbnNldCBkcmFnIHN0YXRlIG9ubHkgaWYgbm8gbmV3IGRyYWcgaGFzIHN0YXJ0ZWQgc2luY2UgdGhlIGRyb3AuXG4gICAgaWYgKHRoaXMuX2RyYWdEYXRhPy51aWQgPT09IGV2ZW50LmRyYWdEYXRhPy51aWQpIHtcbiAgICAgIHRoaXMudW5zZXREcmFnU3RhdGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTWV0aG9kIGludm9rZWQgd2hlbiB0aGUgdXNlciBkcmFncyBhIHRhYiBpbnRvIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdFbnRlcihldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgLy8gTWVtb2l6ZSBkcmFnIGRhdGEuXG4gICAgY29uc3QgZHJhZ0RhdGEgPSB0aGlzLl9kcmFnRGF0YSA9IHRoaXMuX3ZpZXdEcmFnU2VydmljZS52aWV3RHJhZ0RhdGEoKSE7XG5cbiAgICAvLyBJbmRpY2F0ZSBkcmFnZ2luZyBvdmVyIHRoaXMgdGFiYmFyLlxuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zaWduYWxUYWJiYXJEcmFnRW50ZXIodGhpcy5wYXJ0LmlkKTtcblxuICAgIC8vIFNuYXAgZHJhZyBpbWFnZSB0byB0YWJiYXIgd2hlbiBkcmFnZ2luZyBuZWFyIGl0LlxuICAgIHRoaXMuX2NvbnN0cmFpbkZuID0gdGhpcy5jcmVhdGVEcmFnSW1hZ2VDb25zdHJhaW5GbigpO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci5zZXRDb25zdHJhaW5EcmFnSW1hZ2VSZWN0Rm4odGhpcy5fY29uc3RyYWluRm4pO1xuXG4gICAgLy8gU2V0IGRyYWcgc291cmNlLCBidXQgb25seSBpZiBzdGFydGVkIHRoZSBkcmFnIG9wZXJhdGlvbiBpbiB0aGlzIHBhcnQuXG4gICAgLy8gV2UgZG8gbm90IHNldCB0aGUgZHJhZyBzb3VyY2UgaW4gYGRyYWdzdGFydGAgdG8gbm90IGJyZWFrIHRoZSBkcmFnIG9wZXJhdGlvbiAoaW4gQ2hyb21lIGFuZCBFZGdlLCBidXQgbm90IEZpcmVmb3gpLlxuICAgIGlmICh0aGlzLl9ob3N0LmNsYXNzTGlzdC5jb250YWlucygnb24tZHJhZy1zdGFydCcpKSB7XG4gICAgICB0aGlzLmRyYWdTb3VyY2VWaWV3VGFiLnNldCh0aGlzLl92aWV3VGFicygpLmZpbmQodmlld1RhYiA9PiB2aWV3VGFiLnZpZXdJZCA9PT0gZHJhZ0RhdGEudmlld0lkKSA/PyBudWxsKTtcbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnOiBgJHtkcmFnRGF0YS52aWV3VGFiV2lkdGh9cHhgfSk7XG4gICAgfVxuXG4gICAgLy8gTG9jYXRlIHRoZSB0YWIgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgb3Zlci5cbiAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50KSk7XG5cbiAgICAvLyBEaXNhYmxlIHBvaW50ZXIgZXZlbnRzIG9uIHRoZSB0YWJiYXIgZm9yIGEgc21vb3RoZXIgZHJhZyBhbmQgZHJvcCBleHBlcmllbmNlIHdoZW4gcXVpY2tseSBzd2FwcGluZyB0YWJzLlxuICAgIHNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdwb2ludGVyLWV2ZW50cy1kaXNhYmxlZCcpO1xuXG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBhbmltYXRlIGVudGVyaW5nIHRoZSB0YWJiYXIuXG4gICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctZW50ZXInKTtcbiAgICB0aGlzLm9uRHJhZ0FuaW1hdGlvblN0YWJsZSgoKSA9PiB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdvbi1kcmFnLWVudGVyJykpO1xuXG4gICAgLy8gSW5qZWN0IGRyYWcgc291cmNlIHdpZHRoIGludG8gQ1NTLlxuICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctc291cmNlLXdpZHRoJzogYCR7ZHJhZ0RhdGEudmlld1RhYldpZHRofXB4YH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgZHJhZ3MgYSB0YWIgb3V0IG9mIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBvblRhYmJhckRyYWdMZWF2ZShldmVudDogRHJhZ0V2ZW50KTogdm9pZCB7XG4gICAgLy8gU2V0IENTUyBjbGFzcyB0byBhbmltYXRlIGxlYXZpbmcgdGhlIHRhYmJhciwgYnV0IG5vdCB3aGVuIGNhbmNlbGluZyB0aGUgZHJhZyBvcGVyYXRpb24gZm9yIGluc3RhbnQgcmVzZXQuXG4gICAgLy8gUG9pbnRlciBjb29yZGluYXRlcyBhcmUgbm90IHNldCB3aGVuIHRoZSBkcmFnIG9wZXJhdGlvbiBpcyBjYW5jZWxlZCBvciB3aGVuIGRyYWdnaW5nIHRoZSB0YWIgb3V0IG9mIHRoZSB3aW5kb3cuXG4gICAgaWYgKGV2ZW50LnNjcmVlblggfHwgZXZlbnQuc2NyZWVuWSkge1xuICAgICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctbGVhdmUnKTtcbiAgICAgIHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKCgpID0+IHVuc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ29uLWRyYWctbGVhdmUnKSk7XG4gICAgfVxuXG4gICAgLy8gQWN0aXZhdGUgdGhlIGFkamFjZW50IHRhYiwgb25seSBpZiB0aGUgZHJhZyBvcGVyYXRpb24gaXMgbm90IGNhbmNlbGVkLlxuICAgIC8vIFRoZSBkcmFnIGV2ZW50IGRvZXMgbm90IHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgY2FuY2VsYXRpb24uIFRoZXJlZm9yZSwgd2Ugd2FpdCBmb3IgYSBtYWNyb3Rhc2ssIGNhbmNlbGluZyBpdCB3aGVuIHJlY2VpdmluZyBgZHJhZ2VuZGAsIGkuZS4sIHRoZSBkcmFnIG9wZXJhdGlvbiBoYXMgYmVlbiBjYW5jZWxlZC5cbiAgICBpZiAodGhpcy5kcmFnU291cmNlVmlld1RhYigpPy5hY3RpdmUpIHtcbiAgICAgIHRpbWVyKDApXG4gICAgICAgIC5waXBlKHRha2VVbnRpbChmcm9tRXZlbnQod2luZG93LCAnZHJhZ2VuZCcpKSlcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yb3V0ZXIubmF2aWdhdGUobGF5b3V0ID0+IGxheW91dC5hY3RpdmF0ZUFkamFjZW50Vmlldyh0aGlzLmRyYWdTb3VyY2VWaWV3VGFiKCkhLnZpZXdJZCksIHtza2lwTG9jYXRpb25DaGFuZ2U6IHRydWV9KSk7XG4gICAgfVxuXG4gICAgLy8gQ2xlYW4gdXAgZHJhZyBzdGF0ZS5cbiAgICB0aGlzLnVuc2V0RHJhZ1N0YXRlKHt1bnNldERyYWdTb3VyY2U6IGZhbHNlLCB1bnNldERyYWdEYXRhOiBmYWxzZX0pO1xuICB9XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIHdoZW4gdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYSB0YWIgb3ZlciB0aGlzIHRhYmJhci5cbiAgICovXG4gIHByaXZhdGUgb25UYWJiYXJEcmFnT3ZlcihldmVudDogRHJhZ0V2ZW50LCBkcmFnRGlzdGFuY2U6IG51bWJlciwgc2Nyb2xsRGlzdGFuY2U6IG51bWJlcik6IHZvaWQge1xuICAgIE5nWm9uZS5hc3NlcnROb3RJbkFuZ3VsYXJab25lKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTsgLy8gYWxsb3cgdmlldyBkcm9wXG5cbiAgICAvLyBMb2NhdGUgdGhlIHRhYiB0aGUgdXNlciBpcyBkcmFnZ2luZyBvdmVyLlxuICAgIC8vIC0gUnVuIGluIGFuaW1hdGlvbiBmcmFtZSBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlLCBtb3N0IG5vdGljZWFibGUgb24gbG93ZXIgQ1BVIHBvd2VyLlxuICAgIC8vIC0gRG8gbm90IHdhaXQgZm9yIHRoZSBkcmFnIGFuaW1hdGlvbiB0byBjb21wbGV0ZSBmb3IgYSBzbW9vdGhlciBkcmFnIGFuZCBkcm9wIGV4cGVyaWVuY2Ugd2hlbiBxdWlja2x5IG1vdmluZyB0aGUgdGFiIGluIHRoZSB0YWJiYXIuXG4gICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgIC8vIFNraXAgaWYgdGhlIGRyYWcgb3BlcmF0aW9uIGhhcyBlbmRlZC5cbiAgICAgIGlmICh0aGlzLl92aWV3RHJhZ1NlcnZpY2UuaXNEcmFnT3ZlclRhYmJhciAhPT0gdGhpcy5wYXJ0LmlkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gSWdub3JlIHRoZSBkcmFnIGRpc3RhbmNlIGlmIGBkcmFnLWVudGVyYCBhbmltYXRpb24gaXMgaW4gcHJvZ3Jlc3MgdG8gYXZvaWQgaW5jb3JyZWN0IGRyb3AgdGFyZ2V0IGNvbXB1dGF0aW9uIHdoZW4gZHJhZ2dpbmcgYSB0YWIgZnJvbSB0aGUgbGVmdC5cbiAgICAgIGlmICh0aGlzLl9ob3N0LmNsYXNzTGlzdC5jb250YWlucygnb24tZHJhZy1lbnRlcicpKSB7XG4gICAgICAgIHRoaXMuZHJvcFRhcmdldFZpZXdUYWIuc2V0KHRoaXMuY29tcHV0ZURyb3BUYXJnZXQoZXZlbnQsIDApKTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXB1dGUgZHJvcCB0YXJnZXQgb25seSB3aGVuIG1vdmluZyB0aGUgZHJhZyBwb2ludGVyIHRvIHByZXZlbnQgdGFicyBmcm9tIHNsaWRpbmcgYmFjayBhbmQgZm9ydGggKHdoaWxlIGFuaW1hdGlvbiBpcyBpbiBwcm9ncmVzcylcbiAgICAgIGVsc2UgaWYgKGRyYWdEaXN0YW5jZSkge1xuICAgICAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50LCBkcmFnRGlzdGFuY2UpKTtcbiAgICAgIH1cbiAgICAgIC8vIENvbXB1dGUgZHJvcCB0YXJnZXQgd2hlbiBzY3JvbGxpbmcgdGhlIHZpZXdwb3J0LCBpLmUuLCBub3QgbW92aW5nIHRoZSBkcmFnIHBvaW50ZXIgYnV0IHNjcm9sbGluZyB0aGUgdmlld3BvcnQgYmVjYXVzZSBwbGFjZWQgdGhlIGRyYWcgcG9pbnRlciBhdCB0aGUgdmlld3BvcnQgZWRnZXMuXG4gICAgICBlbHNlIGlmIChzY3JvbGxEaXN0YW5jZSkge1xuICAgICAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldCh0aGlzLmNvbXB1dGVEcm9wVGFyZ2V0KGV2ZW50LCBzY3JvbGxEaXN0YW5jZSkpO1xuICAgICAgfVxuXG4gICAgICAvLyBTZXQgQ1NTIGNsYXNzIHRvIGFuaW1hdGUgZHJhZ2dpbmcgb3ZlciB0aGUgdGFiYmFyLlxuICAgICAgc2V0Q3NzQ2xhc3ModGhpcy5faG9zdCwgJ2RyYWctb3ZlcicpO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgdGhlIG5ldyBzaXplIG9mIHRoZSBkcmFnIHNvdXJjZSBwbGFjZWhvbGRlci5cbiAgICAgIC8vIFRoZSBwbGFjZWhvbGRlciBleHBhbmRzIHRoZSB2aWV3cG9ydCB3aGVuIGRyYWdnaW5nIGEgdGFiIHRvIHRoZSByaWdodCwgbW92aW5nIHBhcnQgYWN0aW9ucyBhbG9uZyB3aXRoIHRoZSBkcmFnb3ZlciBldmVudC5cbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHsnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnOiBgJHt0aGlzLmNhbGN1bGF0ZURyYWdQbGFjZWhvbGRlcldpZHRoKGV2ZW50KX1weGB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCB3aGVuIHRoZSB1c2VyIGRyb3BzIGEgdGFiIGluIHRoaXMgdGFiYmFyLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBvblRhYmJhckRyb3AoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgZHJhZ0RhdGEgPSB0aGlzLl9kcmFnRGF0YSE7XG4gICAgY29uc3QgZHJvcFRhcmdldFZpZXdUYWIgPSB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiKCkhO1xuICAgIGNvbnN0IGRyb3BQb3NpdGlvbiA9IGRyb3BUYXJnZXRWaWV3VGFiID09PSAnZW5kJyA/ICdlbmQnIDogdGhpcy5fdmlld1RhYnMoKS5pbmRleE9mKGRyb3BUYXJnZXRWaWV3VGFiKTtcblxuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5kaXNwYXRjaFZpZXdNb3ZlRXZlbnQoe1xuICAgICAgc291cmNlOiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiBkcmFnRGF0YS53b3JrYmVuY2hJZCxcbiAgICAgICAgcGFydElkOiBkcmFnRGF0YS5wYXJ0SWQsXG4gICAgICAgIHZpZXdJZDogZHJhZ0RhdGEudmlld0lkLFxuICAgICAgICBhbHRlcm5hdGl2ZVZpZXdJZDogZHJhZ0RhdGEuYWx0ZXJuYXRpdmVWaWV3SWQsXG4gICAgICAgIHZpZXdVcmxTZWdtZW50czogZHJhZ0RhdGEudmlld1VybFNlZ21lbnRzLFxuICAgICAgICBuYXZpZ2F0aW9uSGludDogZHJhZ0RhdGEubmF2aWdhdGlvbkhpbnQsXG4gICAgICAgIG5hdmlnYXRpb25EYXRhOiBkcmFnRGF0YS5uYXZpZ2F0aW9uRGF0YSxcbiAgICAgICAgY2xhc3NMaXN0OiBkcmFnRGF0YS5jbGFzc0xpc3QsXG4gICAgICB9LFxuICAgICAgdGFyZ2V0OiB7XG4gICAgICAgIHdvcmtiZW5jaElkOiB0aGlzLl93b3JrYmVuY2hJZCxcbiAgICAgICAgcG9zaXRpb246IGRyb3BQb3NpdGlvbixcbiAgICAgICAgZWxlbWVudElkOiB0aGlzLnBhcnQuaWQsXG4gICAgICB9LFxuICAgICAgZHJhZ0RhdGE6IGRyYWdEYXRhLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIExvY2F0ZXMgdGhlIHRhYiBiZWZvcmUgd2hpY2ggdGhlIGRyYWdnZWQgdGFiIGlzIHRvIGJlIGluc2VydGVkIHdoZW4gaXQgaXMgZHJvcHBlZC4gRHJhZ2dpbmcgYmV5b25kIHRoZSBsYXN0IHRhYiByZXR1cm5zIGBlbmRgLlxuICAgKi9cbiAgcHJpdmF0ZSBjb21wdXRlRHJvcFRhcmdldChldmVudDogRHJhZ0V2ZW50LCBkcmFnRGlzdGFuY2VYID0gMCk6IFZpZXdUYWJDb21wb25lbnQgfCAnZW5kJyB7XG4gICAgY29uc3QgZHJhZ0ltYWdlID0gdGhpcy5fdmlld1RhYkRyYWdJbWFnZVJlbmRlcmVyLmNhbGN1bGF0ZURyYWdJbWFnZVJlY3QodGhpcy5fZHJhZ0RhdGEhLCBldmVudCk7XG4gICAgY29uc3Qgdmlld1RhYnMgPSB0aGlzLl92aWV3VGFicygpLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSk7XG5cbiAgICBmb3IgKGNvbnN0IHZpZXdUYWIgb2Ygdmlld1RhYnMpIHtcbiAgICAgIGNvbnN0IHtsZWZ0LCB3aWR0aH0gPSB2aWV3VGFiLmJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3Qgdmlld1RhYkhDZW50ZXIgPSBsZWZ0ICsgKHdpZHRoIC8gMik7XG5cbiAgICAgIC8vIE1vdmluZyB0aGUgcG9pbnRlciB0byB0aGUgbGVmdC5cbiAgICAgIGlmIChkcmFnRGlzdGFuY2VYIDw9IDAgJiYgZHJhZ0ltYWdlLmxlZnQgPCB2aWV3VGFiSENlbnRlcikge1xuICAgICAgICByZXR1cm4gdmlld1RhYjtcbiAgICAgIH1cbiAgICAgIC8vIE1vdmluZyB0aGUgcGludGVyIHRvIHRoZSByaWdodC5cbiAgICAgIGlmIChkcmFnRGlzdGFuY2VYID4gMCAmJiBkcmFnSW1hZ2UucmlnaHQgPCB2aWV3VGFiSENlbnRlcikge1xuICAgICAgICByZXR1cm4gdmlld1RhYjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuICdlbmQnO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgdGhlIGZ1bmN0aW9uIGZvciBzbmFwcGluZyB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIHdoZW4gZHJhZ2dpbmcgbmVhciBpdC5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlRHJhZ0ltYWdlQ29uc3RyYWluRm4oKTogQ29uc3RyYWluRm4ge1xuICAgIHJldHVybiAoZHJhZ0ltYWdlOiBET01SZWN0KTogRE9NUmVjdCA9PiBuZXcgRE9NUmVjdChcbiAgICAgIGNsYW1wKGRyYWdJbWFnZS54LCB7XG4gICAgICAgIG1pbjogdGhpcy5faG9zdEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgKyB0aGlzLl90YWJiYXJJbmRlbnQubGVmdCxcbiAgICAgICAgbWF4OiB0aGlzLl9ob3N0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCArIHRoaXMuX21heFZpZXdwb3J0V2lkdGgoKSAtIGRyYWdJbWFnZS53aWR0aCAtIHRoaXMuX3RhYmJhckluZGVudC5yaWdodCxcbiAgICAgIH0pLFxuICAgICAgdGhpcy5fdmlld3BvcnRCb3VuZGluZ0JveCgpLnRvcCxcbiAgICAgIGRyYWdJbWFnZS53aWR0aCxcbiAgICAgIHRoaXMuX3ZpZXdwb3J0Qm91bmRpbmdCb3goKS5oZWlnaHQsIC8vIGZpdCBpbnRvIHRhYmJhciwgZS5nLiwgd2hlbiBkcmFnZ2luZyBhIHRhYiBpbnRvIGEgdGFiYmFyIG9mIGEgZGlmZmVyZW50IGhlaWdodFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgbWF4aW11bSB3aWR0aCBvZiB0aGUgdGFiYmFyIHZpZXdwb3J0IGJlZm9yZSBhbiBvdmVyZmxvdyB3b3VsZCBvY2N1ci5cbiAgICogVXNlIHRvIGNvbnN0cmFpbiB0aGUgZHJhZyBpbWFnZSB0byB0aGUgdGFiYmFyIGJvdW5kcy5cbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlTWF4Vmlld3BvcnRXaWR0aCgpOiBTaWduYWw8bnVtYmVyPiB7XG4gICAgY29uc3QgZmlsbGVyRGltZW5zaW9uID0gZGltZW5zaW9uKHRoaXMuX2ZpbGxlckVsZW1lbnQpO1xuICAgIHJldHVybiBjb21wdXRlZCgoKSA9PiB0aGlzLl92aWV3cG9ydEJvdW5kaW5nQm94KCkud2lkdGggKyBmaWxsZXJEaW1lbnNpb24oKS5vZmZzZXRXaWR0aCk7XG4gIH1cblxuICAvKipcbiAgICogQ2FsY3VsYXRlcyB0aGUgd2lkdGggZm9yIHRoZSBkcmFnIHBsYWNlaG9sZGVyLlxuICAgKlxuICAgKiBUaGUgcGxhY2Vob2xkZXIgZXhwYW5kcyB0aGUgdmlld3BvcnQgd2hlbiBkcmFnZ2luZyBhIHRhYiB0byB0aGUgcmlnaHQsIG1vdmluZyBwYXJ0IGFjdGlvbnMgYWxvbmcgd2l0aCB0aGUgZHJhZ292ZXIgZXZlbnQuXG4gICAqXG4gICAqIENhbGN1bGF0aW9uOlxuICAgKiAtIFdoZW4gZHJhZ2dpbmcgb3ZlciB0YWJzLCB0aGUgd2lkdGggaXMgZXF1YWwgdG8gdGhlIHdpZHRoIG9mIHRoZSBkcmFnIHNvdXJjZS5cbiAgICogLSBXaGVuIGRyYWdnaW5nIHRvIHRoZSByaWdodCBvZiB0aGUgbGFzdCB0YWIsIHRoZSB3aWR0aCBvZiB0aGUgcGxhY2Vob2xkZXIgaXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGxhc3QgdGFiIGFuZCB0aGUgcG9zaXRpb24gb2YgdGhlIGRyYWcgcG9pbnRlci5cbiAgICovXG4gIHByaXZhdGUgY2FsY3VsYXRlRHJhZ1BsYWNlaG9sZGVyV2lkdGgoZXZlbnQ6IERyYWdFdmVudCk6IG51bWJlciB7XG4gICAgY29uc3Qgdmlld0RyYWdJbWFnZVJlY3QgPSB0aGlzLl92aWV3VGFiRHJhZ0ltYWdlUmVuZGVyZXIuY2FsY3VsYXRlRHJhZ0ltYWdlUmVjdCh0aGlzLl9kcmFnRGF0YSEsIGV2ZW50KTtcbiAgICBjb25zdCBsYXN0Vmlld1RhYiA9IHRoaXMuX3ZpZXdUYWJzKCkuZmlsdGVyKHZpZXdUYWIgPT4gdmlld1RhYiAhPT0gdGhpcy5kcmFnU291cmNlVmlld1RhYigpKS5hdCgtMSk7XG4gICAgY29uc3QgbGFzdFZpZXdUYWJSaWdodCA9IGxhc3RWaWV3VGFiPy5ib3VuZGluZ0NsaWVudFJlY3QoKS5yaWdodCA/PyB0aGlzLl9ob3N0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCArIHRoaXMuX3RhYmJhckluZGVudC5sZWZ0O1xuICAgIHJldHVybiBNYXRoLm1heChsYXN0Vmlld1RhYlJpZ2h0ICsgdmlld0RyYWdJbWFnZVJlY3Qud2lkdGgsIHZpZXdEcmFnSW1hZ2VSZWN0LnJpZ2h0KSAtIGxhc3RWaWV3VGFiUmlnaHQ7XG4gIH1cblxuICAvKipcbiAgICogSW5kaWNhdGVzIHdoZXRoZXIgQ1NTIGFuaW1hdGlvbnMgaGF2ZSBmaW5pc2hlZCB3aGVuIGRyYWdnaW5nIGEgdGFiIG92ZXIgdGhlIHRhYmJhci5cbiAgICogVGhlIGFuaW1hdGlvbiBpcyBjb25zaWRlcmVkIHN0YWJsZSB3aGVuIGFsbCB0YWJzIGhhdmUgbW92ZWQgdG8gdGhlaXIgZmluYWwgcG9zaXRpb24uXG4gICAqL1xuICBwcml2YXRlIGlzRHJhZ0FuaW1hdGlvblN0YWJsZSgpOiBib29sZWFuIHtcbiAgICBjb25zdCBkcm9wVGFyZ2V0Vmlld1RhYiA9IHRoaXMuZHJvcFRhcmdldFZpZXdUYWIoKTtcbiAgICBpZiAodGhpcy5fdmlld0RyYWdTZXJ2aWNlLmlzRHJhZ092ZXJUYWJiYXIgIT09IHRoaXMucGFydC5pZCkge1xuICAgICAgcmV0dXJuIHRoaXMuX3ZpZXdUYWJzKCkuZXZlcnkodmlld1RhYiA9PiBnZXRDc3NUcmFuc2xhdGlvbih2aWV3VGFiLmhvc3QpLnRyYW5zbGF0ZVggPT09ICdub25lJyk7XG4gICAgfVxuXG4gICAgY29uc3Qgdmlld1RhYnMgPSB0aGlzLl92aWV3VGFicygpLmZpbHRlcih2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSk7XG4gICAgY29uc3QgZHJvcFRhcmdldEluZGV4ID0gZHJvcFRhcmdldFZpZXdUYWIgPT09ICdlbmQnID8gdmlld1RhYnMubGVuZ3RoIDogdmlld1RhYnMuaW5kZXhPZihkcm9wVGFyZ2V0Vmlld1RhYiEpO1xuICAgIGNvbnN0IGRyYWdTb3VyY2VXaWR0aCA9IHRoaXMuX2RyYWdEYXRhIS52aWV3VGFiV2lkdGg7XG5cbiAgICByZXR1cm4gdmlld1RhYnMuZXZlcnkoKHZpZXdUYWIsIGkpID0+IHtcbiAgICAgIGNvbnN0IHZpZXdUYWJUcmFuc2xhdGVYID0gZ2V0Q3NzVHJhbnNsYXRpb24odmlld1RhYi5ob3N0KS50cmFuc2xhdGVYO1xuICAgICAgLy8gRXhwZWN0IHRhYnMgcHJlY2VkaW5nIHRoZSBkcm9wIHRhcmdldCBub3QgdG8gYmUgc2hpZnRlZCB0byB0aGUgcmlnaHQuXG4gICAgICBpZiAoaSA8IGRyb3BUYXJnZXRJbmRleCAmJiB2aWV3VGFiVHJhbnNsYXRlWCAhPT0gJ25vbmUnKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIC8vIEV4cGVjdCBkcm9wIHRhcmdldCBhbmQgdGFicyBmb2xsb3dpbmcgdGhlIGRyb3AgdGFyZ2V0IHRvIGJlIHNoaWZ0ZWQgdG8gdGhlIHJpZ2h0LlxuICAgICAgaWYgKGkgPj0gZHJvcFRhcmdldEluZGV4ICYmIE1hdGguZmxvb3IoTnVtYmVyKHZpZXdUYWJUcmFuc2xhdGVYKSkgIT09IE1hdGguZmxvb3IoZHJhZ1NvdXJjZVdpZHRoKSkgeyAvLyBjb21wYXJlIGZsb29yZWQgbnVtYmVycyBiZWNhdXNlIGB0cmFuc2xhdGVYYCBpcyBub3QgcHJlY2lzZVxuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnMgdXAgdGhlIGRyYWcgc3RhdGUsIHVuc2V0dGluZyBkcmFnIGRhdGEgYW5kIGRyYWcgc291cmNlIGJhc2VkIG9uIHByb3ZpZGVkIG9wdGlvbnMuXG4gICAqL1xuICBwcml2YXRlIHVuc2V0RHJhZ1N0YXRlKG9wdGlvbnM/OiB7dW5zZXREcmFnU291cmNlPzogZmFsc2U7IHVuc2V0RHJhZ0RhdGE/OiBmYWxzZX0pOiB2b2lkIHtcbiAgICB0aGlzLmRyb3BUYXJnZXRWaWV3VGFiLnNldChudWxsKTtcbiAgICB0aGlzLl9vblVuc2V0RHJhZ1N0YXRlLnNldCgpO1xuICAgIHRoaXMuX3ZpZXdUYWJEcmFnSW1hZ2VSZW5kZXJlci51bnNldENvbnN0cmFpbkRyYWdJbWFnZVJlY3RGbih0aGlzLl9jb25zdHJhaW5GbiEpO1xuICAgIHRoaXMuX3ZpZXdEcmFnU2VydmljZS5zaWduYWxUYWJiYXJEcmFnTGVhdmUodGhpcy5wYXJ0LmlkKTtcbiAgICB0aGlzLl9jb25zdHJhaW5GbiA9IG51bGw7XG5cbiAgICB1bnNldENzc0NsYXNzKHRoaXMuX2hvc3QsICdkcmFnLW92ZXInLCAncG9pbnRlci1ldmVudHMtZGlzYWJsZWQnKTtcbiAgICB1bnNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsICctLcm1cGFydC1iYXItZHJhZy1zb3VyY2Utd2lkdGgnLCAnLS3JtXBhcnQtYmFyLWRyYWctcGxhY2Vob2xkZXItd2lkdGgnKTtcblxuICAgIGlmIChvcHRpb25zPy51bnNldERyYWdTb3VyY2UgPz8gdHJ1ZSkge1xuICAgICAgdGhpcy5kcmFnU291cmNlVmlld1RhYi5zZXQobnVsbCk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zPy51bnNldERyYWdEYXRhID8/IHRydWUpIHtcbiAgICAgIHRoaXMuX2RyYWdEYXRhID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgZ2l2ZW4gZnVuY3Rpb24gd2hlbiB0aGUgZHJhZyBhbmltYXRpb24gaGFzIGZpbmlzaGVkLCBpLmUuLCB0YWJzIGhhdmUgdHJhbnNpdGlvbmVkIHRvIHRoZWlyIGZpbmFsIHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBvbkRyYWdBbmltYXRpb25TdGFibGUoY2FsbGJhY2s6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBpZiAoTmdab25lLmlzSW5Bbmd1bGFyWm9uZSgpKSB7XG4gICAgICB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKCgpID0+IHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKGNhbGxiYWNrKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB0aGlzLmlzRHJhZ0FuaW1hdGlvblN0YWJsZSgpID8gY2FsbGJhY2soKSA6IHRoaXMub25EcmFnQW5pbWF0aW9uU3RhYmxlKGNhbGxiYWNrKSk7XG4gIH1cblxuICAvKipcbiAgICogU2Nyb2xscyB0aGUgdGFiIG9mIHRoZSBhY3RpdmUgdmlldyBpbnRvIHZpZXcuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxBY3RpdmVWaWV3U2Nyb2xsZXIoKTogdm9pZCB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIC8vIFRyYWNrIHRoZSBhY3RpdmUgdmlldy5cbiAgICAgIGNvbnN0IGFjdGl2ZVZpZXdJZCA9IHRoaXMucGFydC5hY3RpdmVWaWV3SWQoKTtcbiAgICAgIC8vIFRoZXJlIG1heSBiZSBubyBhY3RpdmUgdmlldywgZS5nLiwgaWYgbm8gdmlldyBoYXMgYmVlbiBhY3RpdmF0ZWQsIG9yIHdoZW4gZHJhZ2dpbmcgdGhlIGxhc3QgdmlldyBvdXQgb2YgdGhlIHRhYmJhci5cbiAgICAgIGlmICghYWN0aXZlVmlld0lkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gRG8gbm90IHRyYWNrIHJlbmRlcmVkIHRhYnMgaW4gZ2VuZXJhbCB0byBwcmV2ZW50IHVud2FudGVkIHNjcm9sbGluZyB3aGVuIG9wZW5pbmcgb3IgY2xvc2luZyBpbmFjdGl2ZSB0YWJzLlxuICAgICAgY29uc3Qgdmlld1RhYnMgPSB1bnRyYWNrZWQoKCkgPT4gdGhpcy5fdmlld1RhYnMoKSk7XG5cbiAgICAgIC8vIEdldCBhIHJlZmVyZW5jZSB0byB0aGUgY3VycmVudGx5IHJlbmRlcmVkIGFjdGl2ZSB0YWIsIHdhaXRpbmcgaWYgbmVjZXNzYXJ5IGJ5IHRyYWNraW5nIHRoZSByZW5kZXJlZCB0YWJzLlxuICAgICAgY29uc3QgYWN0aXZlVmlld1RhYiA9IHZpZXdUYWJzLmZpbmQodmlld1RhYiA9PiB2aWV3VGFiLnZpZXdJZCA9PT0gYWN0aXZlVmlld0lkKTtcbiAgICAgIGlmICghYWN0aXZlVmlld1RhYikge1xuICAgICAgICB0aGlzLl92aWV3VGFicygpOyAvLyBUcmFjayByZW5kZXJlZCB0YWJzIHRvIHJlLWV4ZWN1dGUgb25jZSByZW5kZXJlZC5cbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBUcmFjayBuYXZpZ2F0aW9uIG9mIHRoZSBhY3RpdmUgdmlldywgc2Nyb2xsaW5nIGl0cyB0YWIgaW50byB2aWV3IGlmIG5lY2Vzc2FyeS5cbiAgICAgIGFjdGl2ZVZpZXdUYWIudmlldygpLm5hdmlnYXRpb25JZCgpO1xuXG4gICAgICAvLyBUcmFjayB1bnNldHRpbmcgZHJhZyBzdGF0ZSB0byBlbnN1cmUgdGhlIGFjdGl2ZSB2aWV3IGlzIHNjcm9sbGVkIGludG8gdmlldyBhZnRlciBkcm9wIG9yIGNhbmNlbC5cbiAgICAgIHRoaXMuX29uVW5zZXREcmFnU3RhdGUoKTtcblxuICAgICAgLy8gU2Nyb2xsIHRoZSB0YWIgaW50byB2aWV3IGlmIHNjcm9sbGVkIG91dCBvZiB2aWV3LlxuICAgICAgdW50cmFja2VkKCgpID0+IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5pc0VsZW1lbnRJblZpZXcoYWN0aXZlVmlld1RhYi5ob3N0LCAnZnVsbCcpKSB7XG4gICAgICAgICAgdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5zY3JvbGxJbnRvVmlldyhhY3RpdmVWaWV3VGFiLmhvc3QpO1xuICAgICAgICB9XG4gICAgICB9KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB7QGxpbmsgybVXb3JrYmVuY2hWaWV3fSB3aGVuIGl0cyB0YWIgaXMgc2Nyb2xsZWQgaW50byB2aWV3LlxuICAgKi9cbiAgcHJpdmF0ZSBpbnN0YWxsU2Nyb2xsZWRJbnRvVmlld1VwZGF0ZXIoKTogdm9pZCB7XG4gICAgdGhpcy5fdmlld3BvcnRDaGFuZ2UkXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKCgpID0+IHRoaXMuX3ZpZXdUYWJzKCkpLFxuICAgICAgICBmaWx0ZXJBcnJheSh2aWV3VGFiID0+IHZpZXdUYWIgIT09IHRoaXMuZHJhZ1NvdXJjZVZpZXdUYWIoKSksIC8vIHNraXAgZHJhZyBzb3VyY2UgYXMgYWx3YXlzIHNjcm9sbGVkIG91dCBvZiB2aWV3XG4gICAgICAgIG1lcmdlTWFwKHZpZXdUYWJzID0+IGZyb20odmlld1RhYnMpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKHZpZXdUYWIgPT4ge1xuICAgICAgICB2aWV3VGFiLnZpZXcoKS5zY3JvbGxlZEludG9WaWV3ID0gdGhpcy5fdmlld3BvcnRDb21wb25lbnQoKS5pc0VsZW1lbnRJblZpZXcodmlld1RhYi5ob3N0LCAnZnVsbCcpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3Vic2NyaWJlcyB0byBkcmFnIGV2ZW50cy5cbiAgICovXG4gIHByaXZhdGUgaW5zdGFsbFZpZXdEcmFnTGlzdGVuZXIoKTogdm9pZCB7XG4gICAgY29uc3Qgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gICAgLy8gU3Vic2NyaWJlIHRvIGRyYWcgZXZlbnRzIHJlbGV2YW50IGZvciB0aGlzIHRhYmJhci5cbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld0RyYWckKHRoaXMuX2hvc3QpXG4gICAgICAucGlwZShcbiAgICAgICAgc3Vic2NyaWJlSW4oZm4gPT4gem9uZS5ydW5PdXRzaWRlQW5ndWxhcihmbikpLFxuICAgICAgICBjYWxjdWxhdGVEaXN0YW5jZSgoKSA9PiB0aGlzLl92aWV3cG9ydENvbXBvbmVudCgpKSwgLy8gcHJvdmlkZSB2aWV3cG9ydCBsYXppbHkgYmVjYXVzZSBub3QgaW5qZWN0ZWQgeWV0XG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCgpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoe2V2ZW50LCBkcmFnRGlzdGFuY2UsIHNjcm9sbERpc3RhbmNlfSkgPT4ge1xuICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcbiAgICAgICAgICBjYXNlICdkcmFnc3RhcnQnOlxuICAgICAgICAgICAgdGhpcy5vblRhYkRyYWdTdGFydCgpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJhZ2VuZCc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiRHJhZ0VuZChldmVudCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcmFnZW50ZXInOlxuICAgICAgICAgICAgdGhpcy5vblRhYmJhckRyYWdFbnRlcihldmVudCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdkcmFnb3Zlcic6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJhZ092ZXIoZXZlbnQsIGRyYWdEaXN0YW5jZSwgc2Nyb2xsRGlzdGFuY2UpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJhZ2xlYXZlJzpcbiAgICAgICAgICAgIHRoaXMub25UYWJiYXJEcmFnTGVhdmUoZXZlbnQpO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnZHJvcCc6XG4gICAgICAgICAgICB0aGlzLm9uVGFiYmFyRHJvcCgpLnRoZW4oKTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIC8vIEdldCBub3RpZmllZCB3aGVuIGEgdmlldyBoYXMgbW92ZWQgaW4gdGhlIGxheW91dC5cbiAgICB0aGlzLl92aWV3RHJhZ1NlcnZpY2Uudmlld01vdmVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHN1YnNjcmliZUluKGZuID0+IHpvbmUucnVuT3V0c2lkZUFuZ3VsYXIoZm4pKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKGV2ZW50ID0+IHRoaXMub25UYWJNb3ZlZChldmVudCkpO1xuXG4gICAgLyoqXG4gICAgICogQ2FsY3VsYXRlcyB0aGUgZGlzdGFuY2UgdGhlIGRyYWcgcG9pbnRlciBhbmQgdmlld3BvcnQgaGF2ZSBtb3ZlZCBzaW5jZSB0aGUgbGFzdCBkcmFnIGV2ZW50LlxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGNhbGN1bGF0ZURpc3RhbmNlKHZpZXdwb3J0OiAoKSA9PiBTY2lWaWV3cG9ydENvbXBvbmVudCk6IE9wZXJhdG9yRnVuY3Rpb248RHJhZ0V2ZW50LCBEcmFnRXZlbnRQbHVzRGlzdGFuY2U+IHtcbiAgICAgIHJldHVybiBzb3VyY2UkID0+IG5ldyBPYnNlcnZhYmxlPERyYWdFdmVudFBsdXNEaXN0YW5jZT4ob2JzZXJ2ZXIgPT4ge1xuICAgICAgICBsZXQgbGFzdFNjcmVlblg6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGxhc3RTY3JvbGxMZWZ0OiBudW1iZXIgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gc291cmNlJC5zdWJzY3JpYmUoZXZlbnQgPT4ge1xuICAgICAgICAgIG9ic2VydmVyLm5leHQoe1xuICAgICAgICAgICAgZXZlbnQsXG4gICAgICAgICAgICBkcmFnRGlzdGFuY2U6IGV2ZW50LnNjcmVlblggLSAobGFzdFNjcmVlblggPz8gZXZlbnQuc2NyZWVuWCksXG4gICAgICAgICAgICBzY3JvbGxEaXN0YW5jZTogdmlld3BvcnQoKS5zY3JvbGxMZWZ0IC0gKGxhc3RTY3JvbGxMZWZ0ID8/IHZpZXdwb3J0KCkuc2Nyb2xsTGVmdCksXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgbGFzdFNjcmVlblggPSBldmVudC5zY3JlZW5YO1xuICAgICAgICAgIGxhc3RTY3JvbGxMZWZ0ID0gdmlld3BvcnQoKS5zY3JvbGxMZWZ0O1xuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuICgpID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVtaXRzIG9uIHtAbGluayBfdmlld3BvcnRDaGFuZ2UkfSB3aGVuIHRoZSB2aWV3cG9ydCBzaXplIG9yIHNjcm9sbCBwb3NpdGlvbiBjaGFuZ2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBpbnN0YWxsVmlld3BvcnRDaGFuZ2VUcmFja2VyKCk6IHZvaWQge1xuICAgIGNvbnN0IHZpZXdwb3J0U2l6ZSA9IGRpbWVuc2lvbihjb21wdXRlZCgoKSA9PiB0aGlzLl92aWV3cG9ydENvbXBvbmVudEVsZW1lbnQoKS5uYXRpdmVFbGVtZW50KSk7XG4gICAgY29uc3Qgdmlld3BvcnRDbGllbnRTaXplID0gZGltZW5zaW9uKGNvbXB1dGVkKCgpID0+IHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50KCkudmlld3BvcnRDbGllbnRFbGVtZW50KSk7XG4gICAgY29uc3Qgem9uZSA9IGluamVjdChOZ1pvbmUpO1xuXG4gICAgLy8gRGV0ZWN0IHJlc2l6aW5nLlxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICAvLyBUcmFjayB2aWV3cG9ydCBhbmQgdmlld3BvcnQgY2xpZW50IHNpemVzLlxuICAgICAgdmlld3BvcnRTaXplKCk7XG4gICAgICB2aWV3cG9ydENsaWVudFNpemUoKTtcbiAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpKTtcbiAgICB9KTtcblxuICAgIC8vIERldGVjdCBzY3JvbGxpbmcuXG4gICAgZWZmZWN0KG9uQ2xlYW51cCA9PiB7XG4gICAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuX3ZpZXdwb3J0Q29tcG9uZW50KCkudmlld3BvcnRFbGVtZW50O1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgY29uc3Qgc3Vic2NyaXB0aW9uID0gZnJvbUV2ZW50KHZpZXdwb3J0LCAnc2Nyb2xsJylcbiAgICAgICAgICAucGlwZShzdWJzY3JpYmVJbihmbiA9PiB6b25lLnJ1bk91dHNpZGVBbmd1bGFyKGZuKSkpXG4gICAgICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLl92aWV3cG9ydENoYW5nZSQubmV4dCgpKTtcbiAgICAgICAgb25DbGVhbnVwKCgpID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrcyB0aGUgdGFiYmFyIGluZGVudHMuXG4gICAqL1xuICBwcml2YXRlIGluc3RhbGxUYWJiYXJJbmRlbnRTaXplVHJhY2tlcigpOiB2b2lkIHtcbiAgICBjb25zdCB0YWJDb3JuZXJSYWRpdXNEaW1lbnNpb24gPSBkaW1lbnNpb24odGhpcy5fdGFiQ29ybmVyUmFkaXVzRWxlbWVudCk7XG4gICAgY29uc3QgcGFkZGluZ0lubGluZURpbWVuc2lvbiA9IGRpbWVuc2lvbih0aGlzLl9wYWRkaW5nSW5saW5lRWxlbWVudCk7XG5cbiAgICBlZmZlY3QoKCkgPT4ge1xuICAgICAgY29uc3QgaW5kZW50ID0gdGFiQ29ybmVyUmFkaXVzRGltZW5zaW9uKCkuY2xpZW50V2lkdGggKyBwYWRkaW5nSW5saW5lRGltZW5zaW9uKCkuY2xpZW50V2lkdGg7XG4gICAgICB0aGlzLl90YWJiYXJJbmRlbnQgPSB7bGVmdDogaW5kZW50LCByaWdodDogaW5kZW50fTtcbiAgICAgIHNldENzc1ZhcmlhYmxlKHRoaXMuX2hvc3QsIHtcbiAgICAgICAgJy0tybVwYXJ0LWJhci1pbmRlbnQtbGVmdCc6IGAke3RoaXMuX3RhYmJhckluZGVudC5sZWZ0fXB4YCxcbiAgICAgICAgJy0tybVwYXJ0LWJhci1pbmRlbnQtcmlnaHQnOiBgJHt0aGlzLl90YWJiYXJJbmRlbnQucmlnaHR9cHhgLFxuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy51bnNldERyYWdTdGF0ZSgpO1xuICB9XG59XG5cbi8qKlxuICogQ29udGFpbnMgdGhlIGV2ZW50IHBsdXMgZHJhZyBhbmQgc2Nyb2xsIGRpc3RhbmNlLlxuICovXG5pbnRlcmZhY2UgRHJhZ0V2ZW50UGx1c0Rpc3RhbmNlIHtcbiAgLyoqXG4gICAqIFJlZmVyZW5jZSB0byB0aGUgZHJhZyBldmVudC5cbiAgICovXG4gIGV2ZW50OiBEcmFnRXZlbnQ7XG4gIC8qKlxuICAgKiBEaXN0YW5jZSB0aGUgZHJhZyBwb2ludGVyIGhhcyBtb3ZlZCBzaW5jZSB0aGUgbGFzdCBkcmFnIGV2ZW50LlxuICAgKi9cbiAgZHJhZ0Rpc3RhbmNlOiBudW1iZXI7XG4gIC8qKlxuICAgKiBEaXN0YW5jZSB0aGUgdmlld3BvcnQgaGFzIHNjcm9sbGVkIHNpbmNlIHRoZSBsYXN0IGRyYWcgZXZlbnQuXG4gICAqL1xuICBzY3JvbGxEaXN0YW5jZTogbnVtYmVyO1xufVxuIiwiPHNjaS12aWV3cG9ydCBjbGFzcz1cInRhYmJhciBlMmUtdGFiYmFyXCIgc2Nyb2xsYmFyU3R5bGU9XCJoaWRkZW5cIj5cbiAgQGZvciAodmlld0lkIG9mIHBhcnQudmlld0lkcygpOyB0cmFjayB2aWV3SWQpIHtcbiAgICBAaWYgKHZpZXd0YWIgPT09IGRyb3BUYXJnZXRWaWV3VGFiKCkpIHtcbiAgICAgIDxkaXYgY2xhc3M9XCJkaXZpZGVyXCI+PC9kaXY+XG4gICAgfVxuICAgIDx3Yi12aWV3LXRhYiAjdmlld3RhYlxuICAgICAgICAgICAgICAgICBbdmlld0lkXT1cInZpZXdJZFwiXG4gICAgICAgICAgICAgICAgIFtjbGFzcy5kcmFnLXNvdXJjZV09XCJ2aWV3dGFiID09PSBkcmFnU291cmNlVmlld1RhYigpXCJcbiAgICAgICAgICAgICAgICAgW2NsYXNzLmRyb3AtdGFyZ2V0XT1cInZpZXd0YWIgPT09IGRyb3BUYXJnZXRWaWV3VGFiKClcIi8+XG4gICAgPGRpdiBjbGFzcz1cImRpdmlkZXJcIj48L2Rpdj5cbiAgfVxuXG4gIDwhLS0gUGxhY2Vob2xkZXIgZm9yIGV4cGFuZGluZyB0aGUgdmlld3BvcnQgd2hlbiBkcmFnZ2luZyBhIHRhYiB0byB0aGUgcmlnaHQsIG1vdmluZyBwYXJ0IGFjdGlvbnMgYWxvbmcgd2l0aCB0aGUgZHJhZ292ZXIgZXZlbnQuIC0tPlxuICA8ZGl2IGNsYXNzPVwiZHJhZy1wbGFjZWhvbGRlclwiPjwvZGl2PlxuPC9zY2ktdmlld3BvcnQ+XG5cbjwhLS0gQWN0aW9ucyAtLT5cbkBpZiAoc3RhcnRBY3Rpb25zKCkubGVuZ3RoKSB7XG4gIDx3Yi1wYXJ0LWFjdGlvbi1iYXIgW2FjdGlvbnNdPVwic3RhcnRBY3Rpb25zKClcIiBjbGFzcz1cInN0YXJ0XCIvPlxufVxuPGRpdiBjbGFzcz1cImZpbGxlclwiICNmaWxsZXI+PC9kaXY+XG5AaWYgKGVuZEFjdGlvbnMoKS5sZW5ndGgpIHtcbiAgPHdiLXBhcnQtYWN0aW9uLWJhciBbYWN0aW9uc109XCJlbmRBY3Rpb25zKClcIiBjbGFzcz1cImVuZFwiLz5cbn1cblxuPCEtLSBWaWV3IExpc3QgRHJvcGRvd24gLS0+XG48d2Itdmlldy1saXN0LWJ1dHRvbi8+XG5cbjwhLS0gRWxlbWVudCBmb3IgaW5qZWN0aW5nIHRoZSBjb3JuZXIgcmFkaXVzIGludG8gdGhlIGNvbXBvbmVudC4gLS0+XG48ZGl2IGNsYXNzPVwidGFiLWNvcm5lci1yYWRpdXNcIiAjdGFiX2Nvcm5lcl9yYWRpdXM+PC9kaXY+XG48IS0tIEVsZW1lbnQgZm9yIGluamVjdGluZyB0aGUgdGFiYmFyIHBhZGRpbmcgaW50byB0aGUgY29tcG9uZW50LiAtLT5cbjxkaXYgY2xhc3M9XCJwYWRkaW5nLWlubGluZVwiICNwYWRkaW5nX2lubGluZT48L2Rpdj5cbiJdfQ==
|