@scion/workbench 18.0.0-beta.9 → 19.0.0-beta.1
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/design/_workbench-view-global-styles.scss +0 -1
- package/fesm2022/scion-workbench.mjs +8556 -8622
- package/fesm2022/scion-workbench.mjs.map +1 -1
- package/lib/common/css-class.util.d.ts +5 -0
- package/lib/common/math.util.d.ts +7 -0
- package/lib/common/objects.util.d.ts +1 -1
- package/lib/dialog/workbench-dialog.component.d.ts +1 -2
- package/lib/layout/migration/model/workbench-layout-migration-v6.model.d.ts +35 -0
- package/lib/layout/migration/workbench-layout-migration-v6.service.d.ts +12 -0
- package/lib/layout/workbench-layout.model.d.ts +0 -1
- package/lib/layout/workbench-layout.service.d.ts +10 -12
- package/lib/layout/workench-layout-serializer.service.d.ts +1 -2
- package/lib/part/part-action-bar/part-action-bar.component.d.ts +2 -6
- package/lib/part/part-bar/part-bar.component.d.ts +66 -48
- package/lib/part/view-tab/view-tab.component.d.ts +3 -3
- package/lib/public_api.d.ts +0 -2
- package/lib/routing/routing.util.d.ts +2 -2
- package/lib/view/view-move-handler.service.d.ts +16 -14
- package/lib/view/view.component.d.ts +1 -2
- package/lib/view//311/265workbench-view.model.d.ts +1 -9
- package/lib/view-dnd/grid-drop-targets.util.d.ts +1 -1
- package/lib/view-dnd/view-drag.service.d.ts +72 -49
- package/lib/view-dnd/view-tab-drag-image-renderer.service.d.ts +11 -36
- package/package.json +8 -10
- package/esm2022/lib/activation-instant.provider.mjs +0 -29
- package/esm2022/lib/common/animation-frame.observable.mjs +0 -37
- package/esm2022/lib/common/asserts.util.mjs +0 -31
- package/esm2022/lib/common/class-list.mjs +0 -99
- package/esm2022/lib/common/coerce-observable.pipe.mjs +0 -28
- package/esm2022/lib/common/disposable.mjs +0 -11
- package/esm2022/lib/common/dom.util.mjs +0 -100
- package/esm2022/lib/common/grid-element-if-visible.pipe.mjs +0 -32
- package/esm2022/lib/common/instanceof.pipe.mjs +0 -26
- package/esm2022/lib/common/map-coerce.pipe.mjs +0 -28
- package/esm2022/lib/common/null-if-empty.pipe.mjs +0 -38
- package/esm2022/lib/common/objects.util.mjs +0 -40
- package/esm2022/lib/common/observables.mjs +0 -72
- package/esm2022/lib/common/operators.mjs +0 -27
- package/esm2022/lib/common/public_api.mjs +0 -11
- package/esm2022/lib/common/stringify-error.util.mjs +0 -19
- package/esm2022/lib/common/throw-error.util.mjs +0 -16
- package/esm2022/lib/common/typeof.pipe.mjs +0 -26
- package/esm2022/lib/common/uid.util.mjs +0 -22
- package/esm2022/lib/common//311/265destroy-ref.mjs +0 -36
- package/esm2022/lib/communication/workbench-broadcast-channel.mjs +0 -38
- package/esm2022/lib/content-projection/content-as-overlay.component.mjs +0 -114
- package/esm2022/lib/content-projection/workbench-element-references.mjs +0 -32
- package/esm2022/lib/dialog/dialog-footer/dialog-action-filter.pipe.mjs +0 -26
- package/esm2022/lib/dialog/dialog-footer/dialog-footer.component.mjs +0 -34
- package/esm2022/lib/dialog/dialog-footer/workbench-dialog-action.directive.mjs +0 -51
- package/esm2022/lib/dialog/dialog-footer/workbench-dialog-footer.directive.mjs +0 -46
- package/esm2022/lib/dialog/dialog-header/dialog-header.component.mjs +0 -33
- package/esm2022/lib/dialog/dialog-header/workbench-dialog-header.directive.mjs +0 -46
- package/esm2022/lib/dialog/movable.directive.mjs +0 -126
- package/esm2022/lib/dialog/public_api.mjs +0 -15
- package/esm2022/lib/dialog/resizable.directive.mjs +0 -392
- package/esm2022/lib/dialog/workbench-dialog.component.mjs +0 -250
- package/esm2022/lib/dialog/workbench-dialog.mjs +0 -79
- package/esm2022/lib/dialog/workbench-dialog.options.mjs +0 -11
- package/esm2022/lib/dialog/workbench-dialog.registry.mjs +0 -73
- package/esm2022/lib/dialog/workbench-dialog.service.mjs +0 -96
- package/esm2022/lib/dialog//311/265workbench-dialog.mjs +0 -310
- package/esm2022/lib/dialog//311/265workbench-dialog.service.mjs +0 -98
- package/esm2022/lib/executor/latest-task-executor.mjs +0 -55
- package/esm2022/lib/executor/single-task-executor.mjs +0 -72
- package/esm2022/lib/filter-field/filter-field.component.mjs +0 -130
- package/esm2022/lib/glass-pane/blockable.mjs +0 -11
- package/esm2022/lib/glass-pane/blocking.mjs +0 -11
- package/esm2022/lib/glass-pane/glass-pane.directive.mjs +0 -120
- package/esm2022/lib/layout/grid-element/grid-element.component.mjs +0 -111
- package/esm2022/lib/layout/main-area-layout/main-area-layout.component.mjs +0 -97
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v2.model.mjs +0 -11
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v3.model.mjs +0 -11
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v4.model.mjs +0 -11
- package/esm2022/lib/layout/migration/model/workbench-layout-migration-v5.model.mjs +0 -11
- package/esm2022/lib/layout/migration/workbench-layout-migration-v3.service.mjs +0 -117
- package/esm2022/lib/layout/migration/workbench-layout-migration-v4.service.mjs +0 -57
- package/esm2022/lib/layout/migration/workbench-layout-migration-v5.service.mjs +0 -67
- package/esm2022/lib/layout/public_api.mjs +0 -12
- package/esm2022/lib/layout/stringifier.mjs +0 -70
- package/esm2022/lib/layout/workbench-layout.component.mjs +0 -90
- package/esm2022/lib/layout/workbench-layout.factory.mjs +0 -24
- package/esm2022/lib/layout/workbench-layout.mjs +0 -16
- package/esm2022/lib/layout/workbench-layout.model.mjs +0 -62
- package/esm2022/lib/layout/workbench-layout.service.mjs +0 -68
- package/esm2022/lib/layout/workbench-layouts.util.mjs +0 -58
- package/esm2022/lib/layout/workench-layout-serializer.service.mjs +0 -109
- package/esm2022/lib/layout//311/265workbench-layout.factory.mjs +0 -54
- package/esm2022/lib/layout//311/265workbench-layout.mjs +0 -876
- package/esm2022/lib/logging/console-appender.service.mjs +0 -46
- package/esm2022/lib/logging/index.mjs +0 -15
- package/esm2022/lib/logging/logger-names.mjs +0 -32
- package/esm2022/lib/logging/logger.mjs +0 -36
- package/esm2022/lib/logging/logging-support.mjs +0 -26
- package/esm2022/lib/logging/logging.model.mjs +0 -45
- package/esm2022/lib/logging/public_api.mjs +0 -12
- package/esm2022/lib/logging//311/265logger.mjs +0 -73
- package/esm2022/lib/message-box/message-box-footer/message-box-footer.component.mjs +0 -69
- package/esm2022/lib/message-box/message-box-header/message-box-header.component.mjs +0 -28
- package/esm2022/lib/message-box/public_api.mjs +0 -11
- package/esm2022/lib/message-box/workbench-message-box.component.mjs +0 -102
- package/esm2022/lib/message-box/workbench-message-box.options.mjs +0 -2
- package/esm2022/lib/message-box/workbench-message-box.service.mjs +0 -39
- package/esm2022/lib/message-box//311/265workbench-message-box.service.mjs +0 -45
- package/esm2022/lib/microfrontend-platform/common/microfrontend.util.mjs +0 -71
- package/esm2022/lib/microfrontend-platform/initialization/microfrontend-platform-initializer.service.mjs +0 -126
- package/esm2022/lib/microfrontend-platform/initialization/ng-zone-observable-decorator.mjs +0 -36
- package/esm2022/lib/microfrontend-platform/initialization/workbench-host-manifest-interceptor.service.mjs +0 -84
- package/esm2022/lib/microfrontend-platform/manifest-object-cache.service.mjs +0 -63
- package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog-capability-validator.interceptor.mjs +0 -54
- package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog-intent-handler.interceptor.mjs +0 -85
- package/esm2022/lib/microfrontend-platform/microfrontend-dialog/microfrontend-dialog.component.mjs +0 -140
- package/esm2022/lib/microfrontend-platform/microfrontend-host-dialog/microfrontend-host-dialog.component.mjs +0 -133
- package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/microfrontend-host-message-box.component.mjs +0 -113
- package/esm2022/lib/microfrontend-platform/microfrontend-host-message-box/text-message/text-message.component.mjs +0 -43
- package/esm2022/lib/microfrontend-platform/microfrontend-host-popup/microfrontend-host-popup.component.mjs +0 -101
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-capability-validator.interceptor.mjs +0 -35
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-intent-handler.interceptor.mjs +0 -88
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box-legacy-intent-translator.interceptor.mjs +0 -32
- package/esm2022/lib/microfrontend-platform/microfrontend-message-box/microfrontend-message-box.component.mjs +0 -121
- package/esm2022/lib/microfrontend-platform/microfrontend-notification/microfrontend-notification-intent-handler.service.mjs +0 -45
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-capability-validator.interceptor.mjs +0 -39
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-installer.service.mjs +0 -120
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/microfrontend-perspective-intent-handler.interceptor.mjs +0 -55
- package/esm2022/lib/microfrontend-platform/microfrontend-perspective/workbench-perspective-data.mjs +0 -19
- package/esm2022/lib/microfrontend-platform/microfrontend-platform-config-loader.mjs +0 -13
- package/esm2022/lib/microfrontend-platform/microfrontend-platform.config.mjs +0 -11
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-capability-validator.interceptor.mjs +0 -31
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup-intent-handler.interceptor.mjs +0 -132
- package/esm2022/lib/microfrontend-platform/microfrontend-popup/microfrontend-popup.component.mjs +0 -115
- package/esm2022/lib/microfrontend-platform/microfrontend-splash/microfrontend-splash.component.mjs +0 -21
- package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view-command-handler.service.mjs +0 -112
- package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-view.component.mjs +0 -313
- package/esm2022/lib/microfrontend-platform/microfrontend-view/microfrontend-workbench-view.model.mjs +0 -23
- package/esm2022/lib/microfrontend-platform/public_api.mjs +0 -13
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-capability-validator.interceptor.mjs +0 -31
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-intent-handler.interceptor.mjs +0 -127
- package/esm2022/lib/microfrontend-platform/routing/microfrontend-view-routes.mjs +0 -125
- package/esm2022/lib/microfrontend-platform/stable-capability-id-assigner.interceptor.mjs +0 -32
- package/esm2022/lib/microfrontend-platform/workbench-microfrontend-support.mjs +0 -191
- package/esm2022/lib/migration/workbench-migration.mjs +0 -11
- package/esm2022/lib/migration/workbench-migrator.mjs +0 -38
- package/esm2022/lib/notification/notification-css-classes.pipe.mjs +0 -24
- package/esm2022/lib/notification/notification-list.component.mjs +0 -51
- package/esm2022/lib/notification/notification.component.mjs +0 -109
- package/esm2022/lib/notification/notification.config.mjs +0 -11
- package/esm2022/lib/notification/notification.mjs +0 -19
- package/esm2022/lib/notification/notification.service.mjs +0 -134
- package/esm2022/lib/notification/public_api.mjs +0 -12
- package/esm2022/lib/notification/text-notification.component.mjs +0 -23
- package/esm2022/lib/notification//311/265notification.mjs +0 -42
- package/esm2022/lib/page-not-found/page-not-found.component.mjs +0 -26
- package/esm2022/lib/part/part-action-bar/part-action-bar.component.mjs +0 -31
- package/esm2022/lib/part/part-action-bar/part-action.directive.mjs +0 -77
- package/esm2022/lib/part/part-bar/part-bar.component.mjs +0 -444
- package/esm2022/lib/part/part-portal.pipe.mjs +0 -35
- package/esm2022/lib/part/part.component.mjs +0 -135
- package/esm2022/lib/part/public_api.mjs +0 -13
- package/esm2022/lib/part/view-context-menu/accelerator-format.pipe.mjs +0 -31
- package/esm2022/lib/part/view-context-menu/text.component.mjs +0 -38
- package/esm2022/lib/part/view-context-menu/view-menu.component.mjs +0 -89
- package/esm2022/lib/part/view-context-menu/view-menu.directive.mjs +0 -76
- package/esm2022/lib/part/view-context-menu/view-menu.service.mjs +0 -340
- package/esm2022/lib/part/view-list/view-list.component.mjs +0 -117
- package/esm2022/lib/part/view-list-button/view-list-button.component.mjs +0 -82
- package/esm2022/lib/part/view-list-item/view-list-item.component.mjs +0 -60
- package/esm2022/lib/part/view-tab/view-tab.component.mjs +0 -218
- package/esm2022/lib/part/view-tab-content/view-tab-content.component.mjs +0 -29
- package/esm2022/lib/part/view-tab-drag-image/view-tab-drag-image.component.mjs +0 -81
- package/esm2022/lib/part/workbench-part-action.registry.mjs +0 -23
- package/esm2022/lib/part/workbench-part.model.mjs +0 -19
- package/esm2022/lib/part/workbench-part.registry.mjs +0 -23
- package/esm2022/lib/part//311/265workbench-part.model.mjs +0 -146
- package/esm2022/lib/perspective/migration/model/workbench-perspective-migration-v1.model.mjs +0 -11
- package/esm2022/lib/perspective/migration/model/workbench-perspective-migration-v2.model.mjs +0 -11
- package/esm2022/lib/perspective/migration/workbench-perspective-migration-v2.service.mjs +0 -57
- package/esm2022/lib/perspective/public_api.mjs +0 -11
- package/esm2022/lib/perspective/workbench-grid-merger.service.mjs +0 -39
- package/esm2022/lib/perspective/workbench-perspective-storage.service.mjs +0 -72
- package/esm2022/lib/perspective/workbench-perspective-view-conflict-resolver.service.mjs +0 -50
- package/esm2022/lib/perspective/workbench-perspective.model.mjs +0 -2
- package/esm2022/lib/perspective/workbench-perspective.registry.mjs +0 -23
- package/esm2022/lib/perspective/workbench-perspective.service.mjs +0 -180
- package/esm2022/lib/perspective/workench-perspective-serializer.service.mjs +0 -62
- package/esm2022/lib/perspective//311/265workbench-perspective.model.mjs +0 -210
- package/esm2022/lib/popup/popup.component.mjs +0 -124
- package/esm2022/lib/popup/popup.config.mjs +0 -100
- package/esm2022/lib/popup/popup.origin.mjs +0 -11
- package/esm2022/lib/popup/popup.service.mjs +0 -339
- package/esm2022/lib/popup/public_api.mjs +0 -12
- package/esm2022/lib/portal/wb-component-portal.mjs +0 -130
- package/esm2022/lib/portal/workbench-portal-outlet.directive.mjs +0 -68
- package/esm2022/lib/public_api.mjs +0 -32
- package/esm2022/lib/registry/workbench-object-registry.mjs +0 -104
- package/esm2022/lib/routing/empty-outlet/empty-outlet.component.mjs +0 -31
- package/esm2022/lib/routing/public_api.mjs +0 -14
- package/esm2022/lib/routing/routing.model.mjs +0 -11
- package/esm2022/lib/routing/routing.util.mjs +0 -215
- package/esm2022/lib/routing/url-segment-matcher.mjs +0 -46
- package/esm2022/lib/routing/workbench-auxiliary-route-installer.service.mjs +0 -110
- package/esm2022/lib/routing/workbench-dialog-differ.mjs +0 -51
- package/esm2022/lib/routing/workbench-layout-differ.mjs +0 -61
- package/esm2022/lib/routing/workbench-message-box-differ.mjs +0 -51
- package/esm2022/lib/routing/workbench-navigational-states.mjs +0 -33
- package/esm2022/lib/routing/workbench-popup-differ.mjs +0 -51
- package/esm2022/lib/routing/workbench-route-data.mjs +0 -39
- package/esm2022/lib/routing/workbench-route-guards.mjs +0 -57
- package/esm2022/lib/routing/workbench-router-link.directive.mjs +0 -124
- package/esm2022/lib/routing/workbench-router.service.mjs +0 -19
- package/esm2022/lib/routing/workbench-url-observer.service.mjs +0 -305
- package/esm2022/lib/routing/workbench-view-outlet-differ.mjs +0 -58
- package/esm2022/lib/routing//311/265location.mjs +0 -70
- package/esm2022/lib/routing//311/265workbench-router.service.mjs +0 -359
- package/esm2022/lib/startup/public_api.mjs +0 -12
- package/esm2022/lib/startup/splash/splash.component.mjs +0 -24
- package/esm2022/lib/startup/workbench-initializer.mjs +0 -96
- package/esm2022/lib/startup/workbench-launcher.service.mjs +0 -173
- package/esm2022/lib/storage/public_api.mjs +0 -11
- package/esm2022/lib/storage/workbench-storage.mjs +0 -37
- package/esm2022/lib/testing/public_api.mjs +0 -12
- package/esm2022/lib/testing/workbench-testing.module.mjs +0 -49
- package/esm2022/lib/testing/workbench.provider.mjs +0 -60
- package/esm2022/lib/theme/workbench-theme-switcher.service.mjs +0 -72
- package/esm2022/lib/view/public_api.mjs +0 -11
- package/esm2022/lib/view/view-context-provider.mjs +0 -31
- package/esm2022/lib/view/view-move-handler.service.mjs +0 -145
- package/esm2022/lib/view/view-portal.pipe.mjs +0 -33
- package/esm2022/lib/view/view.component.mjs +0 -128
- package/esm2022/lib/view/workbench-view.model.mjs +0 -12
- package/esm2022/lib/view/workbench-view.registry.mjs +0 -23
- package/esm2022/lib/view//311/265workbench-view.model.mjs +0 -375
- package/esm2022/lib/view-dnd/grid-drop-targets.util.mjs +0 -49
- package/esm2022/lib/view-dnd/requires-drop-zone.pipe.mjs +0 -58
- package/esm2022/lib/view-dnd/view-drag.service.mjs +0 -213
- package/esm2022/lib/view-dnd/view-drop-placeholder-renderer.service.mjs +0 -89
- package/esm2022/lib/view-dnd/view-drop-zone.directive.mjs +0 -183
- package/esm2022/lib/view-dnd/view-tab-drag-image-renderer.service.mjs +0 -224
- package/esm2022/lib/workbench-config.mjs +0 -15
- package/esm2022/lib/workbench-id.mjs +0 -21
- package/esm2022/lib/workbench.component.mjs +0 -146
- package/esm2022/lib/workbench.constants.mjs +0 -41
- package/esm2022/lib/workbench.model.mjs +0 -11
- package/esm2022/lib/workbench.module.mjs +0 -101
- package/esm2022/lib/workbench.provider.mjs +0 -111
- package/esm2022/lib/workbench.service.mjs +0 -29
- package/esm2022/lib//311/265workbench.service.mjs +0 -102
- package/esm2022/public-api.mjs +0 -14
- package/esm2022/scion-workbench.mjs +0 -5
- package/lib/common/animation-frame.observable.d.ts +0 -10
- package/lib/testing/public_api.d.ts +0 -2
- package/lib/testing/workbench-testing.module.d.ts +0 -40
- package/lib/testing/workbench.provider.d.ts +0 -31
- package/lib/workbench.module.d.ts +0 -65
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2018-2022 Swiss Federal Railways
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made
|
|
5
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
*/
|
|
10
|
-
import { assertNotInReactiveContext, computed, createEnvironmentInjector, DestroyRef, effect, ElementRef, EnvironmentInjector, inject, Injectable, Injector, NgZone, runInInjectionContext, untracked } from '@angular/core';
|
|
11
|
-
import { Overlay, OverlayConfig } from '@angular/cdk/overlay';
|
|
12
|
-
import { firstValueFrom, fromEvent } from 'rxjs';
|
|
13
|
-
import { filter } from 'rxjs/operators';
|
|
14
|
-
import { ComponentPortal } from '@angular/cdk/portal';
|
|
15
|
-
import { Popup, ɵPopup } from './popup.config';
|
|
16
|
-
import { FocusMonitor } from '@angular/cdk/a11y';
|
|
17
|
-
import { Observables } from '@scion/toolkit/util';
|
|
18
|
-
import { WORKBENCH_VIEW_REGISTRY } from '../view/workbench-view.registry';
|
|
19
|
-
import { fromResize$ } from '@scion/toolkit/observable';
|
|
20
|
-
import { PopupComponent } from './popup.component';
|
|
21
|
-
import { DOCUMENT } from '@angular/common';
|
|
22
|
-
import { observeIn, subscribeIn } from '@scion/toolkit/operators';
|
|
23
|
-
import { ɵWorkbenchView } from '../view/ɵworkbench-view.model';
|
|
24
|
-
import { takeUntilDestroyed, toObservable, toSignal } from '@angular/core/rxjs-interop';
|
|
25
|
-
import { provideViewContext } from '../view/view-context-provider';
|
|
26
|
-
import { UUID } from '@scion/toolkit/uuid';
|
|
27
|
-
import { boundingClientRect } from '@scion/components/dimension';
|
|
28
|
-
import { coerceElement } from '@angular/cdk/coercion';
|
|
29
|
-
import * as i0 from "@angular/core";
|
|
30
|
-
const NORTH = { originX: 'center', originY: 'top', overlayX: 'center', overlayY: 'bottom', panelClass: 'wb-north' };
|
|
31
|
-
const SOUTH = { originX: 'center', originY: 'bottom', overlayX: 'center', overlayY: 'top', panelClass: 'wb-south' };
|
|
32
|
-
const WEST = { originX: 'start', originY: 'center', overlayX: 'end', overlayY: 'center', panelClass: 'wb-west' };
|
|
33
|
-
const EAST = { originX: 'end', originY: 'center', overlayX: 'start', overlayY: 'center', panelClass: 'wb-east' };
|
|
34
|
-
/**
|
|
35
|
-
* Allows displaying a component in a workbench popup.
|
|
36
|
-
*
|
|
37
|
-
* A popup is a visual workbench component for displaying content above other content. It is positioned relative to an anchor,
|
|
38
|
-
* which can be either a coordinate or an HTML element. The popup moves when the anchor moves.
|
|
39
|
-
*
|
|
40
|
-
* Unlike views, popups are not part of the persistent Workbench navigation, meaning that popups do not survive a page reload.
|
|
41
|
-
*/
|
|
42
|
-
export class PopupService {
|
|
43
|
-
constructor() {
|
|
44
|
-
this._environmentInjector = inject(EnvironmentInjector);
|
|
45
|
-
this._overlay = inject(Overlay);
|
|
46
|
-
this._focusManager = inject(FocusMonitor);
|
|
47
|
-
this._viewRegistry = inject(WORKBENCH_VIEW_REGISTRY);
|
|
48
|
-
this._zone = inject(NgZone);
|
|
49
|
-
this._document = inject(DOCUMENT);
|
|
50
|
-
this._view = inject(ɵWorkbenchView, { optional: true });
|
|
51
|
-
}
|
|
52
|
-
/**
|
|
53
|
-
* Displays the specified component in a popup.
|
|
54
|
-
*
|
|
55
|
-
* To position the popup, provide either a coordinate or an element to serve as the popup anchor.
|
|
56
|
-
*
|
|
57
|
-
* If you use an element as the popup anchor, the popup also moves when the anchor element moves. If you use a coordinate
|
|
58
|
-
* and open the popup in the context of a view, the popup opens relative to the bounds of that view. Otherwise, it
|
|
59
|
-
* is positioned relative to the page viewport. If you move or resize the view or the page, the popup will also be moved
|
|
60
|
-
* depending on the pair of coordinates used.
|
|
61
|
-
*
|
|
62
|
-
* By setting the alignment of the popup, you can control the region where to open the popup relative to its anchor.
|
|
63
|
-
*
|
|
64
|
-
* Optionally, you can pass data to the popup component. The component can inject the popup handle {@link Popup} to
|
|
65
|
-
* read input data or to close the popup.
|
|
66
|
-
*
|
|
67
|
-
* By default, the popup will close on focus loss, or when the user hits the escape key.
|
|
68
|
-
*
|
|
69
|
-
* If opening the popup in the context of a view, the popup is bound to the lifecycle of the view, that is, the popup
|
|
70
|
-
* is displayed only if the view is active and is closed when the view is closed.
|
|
71
|
-
*
|
|
72
|
-
* @param config - Controls popup behavior
|
|
73
|
-
* @returns a promise that:
|
|
74
|
-
* - resolves to the result if closed with a result
|
|
75
|
-
* - resolves to `undefined` if closed without a result
|
|
76
|
-
*/
|
|
77
|
-
async open(config) {
|
|
78
|
-
assertNotInReactiveContext(this.open, 'Call WorkbenchPopupService.open() in a non-reactive (non-tracking) context, such as within the untracked() function.');
|
|
79
|
-
// Ensure to run in Angular zone to display the popup even when called from outside of the Angular zone.
|
|
80
|
-
if (!NgZone.isInAngularZone()) {
|
|
81
|
-
return this._zone.run(() => this.open(config));
|
|
82
|
-
}
|
|
83
|
-
const align = config.align || 'north';
|
|
84
|
-
const contextualView = this.resolveContextualView(config);
|
|
85
|
-
const popup = this.createPopup(config, { view: contextualView });
|
|
86
|
-
const popupDestroyRef = popup.injector.get(DestroyRef);
|
|
87
|
-
const popupOrigin = this.trackPopupOrigin(config, contextualView, popup.injector);
|
|
88
|
-
// Wait for the initial position.
|
|
89
|
-
const initialPosition = await firstValueFrom(toObservable(popupOrigin, { injector: popup.injector }).pipe(filter(Boolean)));
|
|
90
|
-
const overlayPositionStrategy = this._overlay.position()
|
|
91
|
-
.flexibleConnectedTo(initialPosition)
|
|
92
|
-
.withFlexibleDimensions(false)
|
|
93
|
-
.withLockedPosition(false) // If locked, the popup won't attempt to reposition itself if not enough space available.
|
|
94
|
-
.withPositions((() => {
|
|
95
|
-
switch (align) {
|
|
96
|
-
case 'north':
|
|
97
|
-
return [NORTH, SOUTH, WEST, EAST];
|
|
98
|
-
case 'south':
|
|
99
|
-
return [SOUTH, NORTH, WEST, EAST];
|
|
100
|
-
case 'west':
|
|
101
|
-
return [WEST, EAST, NORTH, SOUTH];
|
|
102
|
-
case 'east':
|
|
103
|
-
return [EAST, WEST, NORTH, SOUTH];
|
|
104
|
-
default:
|
|
105
|
-
throw Error('[PopupPositionError] Illegal position; must be north, south, west or east');
|
|
106
|
-
}
|
|
107
|
-
})());
|
|
108
|
-
// Configure the popup overlay.
|
|
109
|
-
const overlayConfig = new OverlayConfig({
|
|
110
|
-
panelClass: 'wb-popup',
|
|
111
|
-
hasBackdrop: false,
|
|
112
|
-
positionStrategy: overlayPositionStrategy,
|
|
113
|
-
scrollStrategy: this._overlay.scrollStrategies.noop(),
|
|
114
|
-
disposeOnNavigation: true,
|
|
115
|
-
});
|
|
116
|
-
// Construct the popup component and attach it to the DOM.
|
|
117
|
-
const overlayRef = this._overlay.create(overlayConfig);
|
|
118
|
-
const popupPortal = new ComponentPortal(PopupComponent, null, Injector.create({
|
|
119
|
-
parent: config.componentConstructOptions?.injector || this._environmentInjector,
|
|
120
|
-
providers: [
|
|
121
|
-
{ provide: ɵPopup, useValue: popup },
|
|
122
|
-
{ provide: Popup, useExisting: ɵPopup },
|
|
123
|
-
provideViewContext(contextualView),
|
|
124
|
-
...[config.componentConstructOptions?.providers || []],
|
|
125
|
-
],
|
|
126
|
-
}));
|
|
127
|
-
const componentRef = overlayRef.attach(popupPortal);
|
|
128
|
-
const popupElement = componentRef.location.nativeElement;
|
|
129
|
-
// Make the popup focusable and request the focus.
|
|
130
|
-
popupElement.setAttribute('tabindex', '-1');
|
|
131
|
-
this._focusManager.focusVia(popupElement, 'program'); // To not close the popup immediately when it opens, if using the 'onFocusLost' strategy.
|
|
132
|
-
// Reposition popup when the anchor is moved.
|
|
133
|
-
effect(() => {
|
|
134
|
-
const origin = popupOrigin();
|
|
135
|
-
untracked(() => {
|
|
136
|
-
if (origin) {
|
|
137
|
-
overlayPositionStrategy.setOrigin(origin);
|
|
138
|
-
overlayRef.updatePosition();
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
}, { injector: popup.injector });
|
|
142
|
-
// Reposition popup when resized.
|
|
143
|
-
fromResize$(overlayRef.overlayElement)
|
|
144
|
-
.pipe(observeIn(fn => this._zone.run(fn)), takeUntilDestroyed(popupDestroyRef))
|
|
145
|
-
.subscribe(() => {
|
|
146
|
-
overlayRef.updatePosition();
|
|
147
|
-
});
|
|
148
|
-
// Close the popup depending on the passed config.
|
|
149
|
-
this.installPopupCloser(config, popupElement, popup, contextualView);
|
|
150
|
-
// Hide the popup when detaching the contextual view, if any.
|
|
151
|
-
if (contextualView) {
|
|
152
|
-
this.hidePopupOnViewDetach(overlayRef, contextualView, popup);
|
|
153
|
-
}
|
|
154
|
-
// Dispose the popup when closing it.
|
|
155
|
-
popupDestroyRef.onDestroy(() => {
|
|
156
|
-
overlayRef.dispose();
|
|
157
|
-
});
|
|
158
|
-
return new Promise((resolve, reject) => {
|
|
159
|
-
popupDestroyRef.onDestroy(() => {
|
|
160
|
-
popup.result instanceof Error ? reject(popup.result) : resolve(popup.result);
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Creates the popup handle.
|
|
166
|
-
*/
|
|
167
|
-
createPopup(config, context) {
|
|
168
|
-
// Construct the handle in an injection context that shares the popup's lifecycle, allowing for automatic cleanup of effects and RxJS interop functions.
|
|
169
|
-
const popupId = config.id ?? UUID.randomUUID();
|
|
170
|
-
const popupEnvironmentInjector = createEnvironmentInjector([provideViewContext(context.view)], this._environmentInjector, `Workbench Popup ${popupId}`);
|
|
171
|
-
return runInInjectionContext(popupEnvironmentInjector, () => new ɵPopup(popupId, config));
|
|
172
|
-
}
|
|
173
|
-
/**
|
|
174
|
-
* Closes the popup depending on the configured popup closing strategy.
|
|
175
|
-
*/
|
|
176
|
-
installPopupCloser(config, popupElement, popup, contextualView) {
|
|
177
|
-
const popupDestroyRef = popup.injector.get(DestroyRef);
|
|
178
|
-
// Close the popup on escape keystroke.
|
|
179
|
-
if (config.closeStrategy?.onEscape ?? true) {
|
|
180
|
-
fromEvent(popupElement, 'keydown')
|
|
181
|
-
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), filter((event) => event.key === 'Escape'), observeIn(fn => this._zone.run(fn)), takeUntilDestroyed(popupDestroyRef))
|
|
182
|
-
.subscribe(() => popup.close());
|
|
183
|
-
}
|
|
184
|
-
// Close the popup on focus loss.
|
|
185
|
-
if (config.closeStrategy?.onFocusLost ?? true) {
|
|
186
|
-
this._focusManager.monitor(popupElement, true)
|
|
187
|
-
.pipe(filter((focusOrigin) => !focusOrigin), takeUntilDestroyed(popupDestroyRef))
|
|
188
|
-
.subscribe(() => popup.close(popup.result));
|
|
189
|
-
}
|
|
190
|
-
// Close the popup when closing the view.
|
|
191
|
-
if (contextualView) {
|
|
192
|
-
effect(() => {
|
|
193
|
-
if (!this._viewRegistry.objects().some(view => view.id === contextualView.id)) {
|
|
194
|
-
untracked(() => popup.close());
|
|
195
|
-
}
|
|
196
|
-
}, { injector: popup.injector });
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
/**
|
|
200
|
-
* Hides the popup when its contextual view is detached, and displays it when it is reattached. Also restores the focus on re-activation.
|
|
201
|
-
* The contextual view is detached if not active, or located in the peripheral area and the main area is maximized.
|
|
202
|
-
*/
|
|
203
|
-
hidePopupOnViewDetach(overlayRef, contextualView, popup) {
|
|
204
|
-
overlayRef.overlayElement.classList.add('wb-view-context');
|
|
205
|
-
const popupDestroyRef = popup.injector.get(DestroyRef);
|
|
206
|
-
let activeElement;
|
|
207
|
-
effect(() => {
|
|
208
|
-
const attached = contextualView.portal.attached();
|
|
209
|
-
untracked(() => {
|
|
210
|
-
if (attached) {
|
|
211
|
-
overlayRef.overlayElement.classList.add('wb-view-attached');
|
|
212
|
-
activeElement?.focus();
|
|
213
|
-
}
|
|
214
|
-
else {
|
|
215
|
-
overlayRef.overlayElement.classList.remove('wb-view-attached');
|
|
216
|
-
}
|
|
217
|
-
});
|
|
218
|
-
}, { injector: popup.injector });
|
|
219
|
-
// Track the focus in the popup to restore it when attaching the popup.
|
|
220
|
-
fromEvent(overlayRef.overlayElement, 'focusin')
|
|
221
|
-
.pipe(subscribeIn(fn => this._zone.runOutsideAngular(fn)), takeUntilDestroyed(popupDestroyRef))
|
|
222
|
-
.subscribe(() => {
|
|
223
|
-
activeElement = this._document.activeElement instanceof HTMLElement ? this._document.activeElement : undefined;
|
|
224
|
-
});
|
|
225
|
-
}
|
|
226
|
-
/**
|
|
227
|
-
* Creates a signal that tracks the position of the popup anchor.
|
|
228
|
-
*/
|
|
229
|
-
trackPopupOrigin(config, contextualView, injector) {
|
|
230
|
-
const hostBounds = boundingClientRect(contextualView?.portal.componentRef.location.nativeElement ?? document.documentElement, { injector });
|
|
231
|
-
if (config.anchor instanceof Element || config.anchor instanceof ElementRef) {
|
|
232
|
-
const anchor = coerceElement(config.anchor);
|
|
233
|
-
const anchorBounds = boundingClientRect(anchor, { injector });
|
|
234
|
-
return computed(() => {
|
|
235
|
-
// Maintain position and size when detached to prevent flickering when attached again and to support for virtual scrolling in popup content.
|
|
236
|
-
if (contextualView && !contextualView.portal.attached()) {
|
|
237
|
-
return undefined;
|
|
238
|
-
}
|
|
239
|
-
// IMPORTANT: Track anchor and host bounds only if attached to prevent flickering.
|
|
240
|
-
// The `boundingClientRect` signal does not detect position changes when the element is scrolled out of view.
|
|
241
|
-
// Consequently, if the popup anchor is scrolled out of view and the view is enlarged, the popup may not align
|
|
242
|
-
// with the view boundaries. Therefore, we read the anchor's bounding box directly from the DOM.
|
|
243
|
-
anchorBounds();
|
|
244
|
-
return constrainClientRect(anchor.getBoundingClientRect(), hostBounds());
|
|
245
|
-
}, { equal: isEqualDomRect });
|
|
246
|
-
}
|
|
247
|
-
else {
|
|
248
|
-
const anchorBounds = toSignal(Observables.coerce(config.anchor), { injector });
|
|
249
|
-
return computed(() => {
|
|
250
|
-
// Maintain position and size when detached to prevent flickering when attached again and to support for virtual scrolling in popup content.
|
|
251
|
-
if (contextualView && !contextualView.portal.attached()) {
|
|
252
|
-
return undefined;
|
|
253
|
-
}
|
|
254
|
-
// IMPORTANT: Track anchor and host bounds only if attached to prevent flickering.
|
|
255
|
-
if (!anchorBounds()) {
|
|
256
|
-
return undefined;
|
|
257
|
-
}
|
|
258
|
-
const { x, y } = mapToPageCoordinates(anchorBounds(), hostBounds());
|
|
259
|
-
const { width, height } = anchorBounds();
|
|
260
|
-
return constrainClientRect(new DOMRect(x, y, width, height), hostBounds());
|
|
261
|
-
}, { equal: isEqualDomRect });
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
/**
|
|
265
|
-
* Resolves the contextual view to which the popup is bound.
|
|
266
|
-
*/
|
|
267
|
-
resolveContextualView(config) {
|
|
268
|
-
if (config.context?.viewId) {
|
|
269
|
-
return this._viewRegistry.get(config.context.viewId);
|
|
270
|
-
}
|
|
271
|
-
if (config.context?.viewId === undefined) { // `null` means to open the popup outside the contextual view
|
|
272
|
-
return this._view ?? null;
|
|
273
|
-
}
|
|
274
|
-
return null;
|
|
275
|
-
}
|
|
276
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PopupService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
277
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PopupService, providedIn: 'root' }); }
|
|
278
|
-
}
|
|
279
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.0.2", ngImport: i0, type: PopupService, decorators: [{
|
|
280
|
-
type: Injectable,
|
|
281
|
-
args: [{ providedIn: 'root' }]
|
|
282
|
-
}] });
|
|
283
|
-
/**
|
|
284
|
-
* Maps given view coordinates to absolute page coordinates.
|
|
285
|
-
*/
|
|
286
|
-
function mapToPageCoordinates(origin, relativeTo) {
|
|
287
|
-
const xy = origin;
|
|
288
|
-
if (xy.x !== undefined && xy.y !== undefined) {
|
|
289
|
-
return {
|
|
290
|
-
x: relativeTo.x + xy.x,
|
|
291
|
-
y: relativeTo.y + xy.y,
|
|
292
|
-
};
|
|
293
|
-
}
|
|
294
|
-
const topLeft = origin;
|
|
295
|
-
if (topLeft.top !== undefined && topLeft.left !== undefined) {
|
|
296
|
-
return {
|
|
297
|
-
x: relativeTo.x + topLeft.left,
|
|
298
|
-
y: relativeTo.y + topLeft.top,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
const topRight = origin;
|
|
302
|
-
if (topRight.top !== undefined && topRight.right !== undefined) {
|
|
303
|
-
return {
|
|
304
|
-
x: relativeTo.x + (relativeTo.width - topRight.right),
|
|
305
|
-
y: relativeTo.y + topRight.top,
|
|
306
|
-
};
|
|
307
|
-
}
|
|
308
|
-
const bottomLeft = origin;
|
|
309
|
-
if (bottomLeft.bottom !== undefined && bottomLeft.left !== undefined) {
|
|
310
|
-
return {
|
|
311
|
-
x: relativeTo.x + bottomLeft.left,
|
|
312
|
-
y: relativeTo.y + (relativeTo.height - bottomLeft.bottom),
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
const bottomRight = origin;
|
|
316
|
-
if (bottomRight.bottom !== undefined && bottomRight.right !== undefined) {
|
|
317
|
-
return {
|
|
318
|
-
x: relativeTo.x + (relativeTo.width - bottomRight.right),
|
|
319
|
-
y: relativeTo.y + (relativeTo.height - bottomRight.bottom),
|
|
320
|
-
};
|
|
321
|
-
}
|
|
322
|
-
throw Error('[PopupOriginError] Illegal popup origin; must be "Point", "TopLeftPoint", "TopRightPoint", "BottomLeftPoint" or "BottomRightPoint".');
|
|
323
|
-
}
|
|
324
|
-
function constrainClientRect(clientRect, constraints) {
|
|
325
|
-
const top = minmax(clientRect.top, { min: constraints.top, max: constraints.bottom });
|
|
326
|
-
const right = minmax(clientRect.right, { min: constraints.left, max: constraints.right });
|
|
327
|
-
const bottom = minmax(clientRect.bottom, { min: constraints.top, max: constraints.bottom });
|
|
328
|
-
const left = minmax(clientRect.left, { min: constraints.left, max: constraints.right });
|
|
329
|
-
const width = right - left;
|
|
330
|
-
const height = bottom - top;
|
|
331
|
-
return new DOMRect(left, top, width, height);
|
|
332
|
-
}
|
|
333
|
-
function minmax(value, minmax) {
|
|
334
|
-
return Math.max(minmax.min, Math.min(value, minmax.max));
|
|
335
|
-
}
|
|
336
|
-
function isEqualDomRect(a, b) {
|
|
337
|
-
return a?.top === b?.top && a?.right === b?.right && a?.bottom === b?.bottom && a?.left === b?.left;
|
|
338
|
-
}
|
|
339
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9wdXAuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NjaW9uL3dvcmtiZW5jaC9zcmMvbGliL3BvcHVwL3BvcHVwLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFFSCxPQUFPLEVBQUMsMEJBQTBCLEVBQUUsUUFBUSxFQUFFLHlCQUF5QixFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLG1CQUFtQixFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxxQkFBcUIsRUFBVSxTQUFTLEVBQUMsTUFBTSxlQUFlLENBQUM7QUFDbk8sT0FBTyxFQUFvQixPQUFPLEVBQUUsYUFBYSxFQUFhLE1BQU0sc0JBQXNCLENBQUM7QUFDM0YsT0FBTyxFQUFDLGNBQWMsRUFBRSxTQUFTLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFDLE1BQU0sRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3RDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsS0FBSyxFQUFlLE1BQU0sRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQzFELE9BQU8sRUFBQyxZQUFZLEVBQWMsTUFBTSxtQkFBbUIsQ0FBQztBQUM1RCxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFDLHVCQUF1QixFQUFDLE1BQU0saUNBQWlDLENBQUM7QUFDeEUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBQ3RELE9BQU8sRUFBQyxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDekMsT0FBTyxFQUFDLFNBQVMsRUFBRSxXQUFXLEVBQUMsTUFBTSwwQkFB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RUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLE1BQU0sRUFBQyxDQUFDLENBQUM7SUFDMUYsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsRUFBQyxHQUFHLEVBQUUsV0FBVyxDQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBQyxDQUFDLENBQUM7SUFDdEYsTUFBTSxLQUFLLEdBQUcsS0FBSyxHQUFHLElBQUksQ0FBQztJQUMzQixNQUFNLE1BQU0sR0FBRyxNQUFNLEdBQUcsR0FBRyxDQUFDO0lBQzVCLE9BQU8sSUFBSSxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDL0MsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFDLEtBQWEsRUFBRSxNQUFrQztJQUMvRCxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztBQUMzRCxDQUFDO0FBRUQsU0FBUyxjQUFjLENBQUMsQ0FBc0IsRUFBRSxDQUFzQjtJQUNwRSxPQUFPLENBQUMsRUFBRSxHQUFHLEtBQUssQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsS0FBSyxLQUFLLENBQUMsRUFBRSxLQUFLLElBQUksQ0FBQyxFQUFFLE1BQU0sS0FBSyxDQUFDLEVBQUUsTUFBTSxJQUFJLENBQUMsRUFBRSxJQUFJLEtBQUssQ0FBQyxFQUFFLElBQUksQ0FBQztBQUN0RyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOC0yMDIyIFN3aXNzIEZlZGVyYWwgUmFpbHdheXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlXG4gKiBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIDIuMFxuICogd2hpY2ggaXMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge2Fzc2VydE5vdEluUmVhY3RpdmVDb250ZXh0LCBjb21wdXRlZCwgY3JlYXRlRW52aXJvbm1lbnRJbmplY3RvciwgRGVzdHJveVJlZiwgZWZmZWN0LCBFbGVtZW50UmVmLCBFbnZpcm9ubWVudEluamVjdG9yLCBpbmplY3QsIEluamVjdGFibGUsIEluamVjdG9yLCBOZ1pvbmUsIHJ1bkluSW5qZWN0aW9uQ29udGV4dCwgU2lnbmFsLCB1bnRyYWNrZWR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtDb25uZWN0ZWRQb3NpdGlvbiwgT3ZlcmxheSwgT3ZlcmxheUNvbmZpZywgT3ZlcmxheVJlZn0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHtmaXJzdFZhbHVlRnJvbSwgZnJvbUV2ZW50fSBmcm9tICdyeGpzJztcbmltcG9ydCB7ZmlsdGVyfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQge0NvbXBvbmVudFBvcnRhbH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5pbXBvcnQge1BvcHVwLCBQb3B1cENvbmZpZywgybVQb3B1cH0gZnJvbSAnLi9wb3B1cC5jb25maWcnO1xuaW1wb3J0IHtGb2N1c01vbml0b3IsIEZvY3VzT3JpZ2lufSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQge09ic2VydmFibGVzfSBmcm9tICdAc2Npb24vdG9vbGtpdC91dGlsJztcbmltcG9ydCB7V09SS0JFTkNIX1ZJRVdfUkVHSVNUUll9IGZyb20gJy4uL3ZpZXcvd29ya2JlbmNoLXZpZXcucmVnaXN0cnknO1xuaW1wb3J0IHtmcm9tUmVzaXplJH0gZnJvbSAnQHNjaW9uL3Rvb2xraXQvb2JzZXJ2YWJsZSc7XG5pbXBvcnQge1BvcHVwQ29tcG9uZW50fSBmcm9tICcuL3BvcHVwLmNvbXBvbmVudCc7XG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtvYnNlcnZlSW4sIHN1YnNjcmliZUlufSBmcm9tICdAc2Npb24vdG9vbGtpdC9vcGVyYXRvcnMnO1xuaW1wb3J0IHvJtVdvcmtiZW5jaFZpZXd9IGZyb20gJy4uL3ZpZXcvybV3b3JrYmVuY2gtdmlldy5tb2RlbCc7XG5pbXBvcnQge0JvdHRvbUxlZnRQb2ludCwgQm90dG9tUmlnaHRQb2ludCwgUG9pbnQsIFBvcHVwT3JpZ2luLCBUb3BMZWZ0UG9pbnQsIFRvcFJpZ2h0UG9pbnR9IGZyb20gJy4vcG9wdXAub3JpZ2luJztcbmltcG9ydCB7dGFrZVVudGlsRGVzdHJveWVkLCB0b09ic2VydmFibGUsIHRvU2lnbmFsfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQge3Byb3ZpZGVWaWV3Q29udGV4dH0gZnJvbSAnLi4vdmlldy92aWV3LWNvbnRleHQtcHJvdmlkZXInO1xuaW1wb3J0IHtVVUlEfSBmcm9tICdAc2Npb24vdG9vbGtpdC91dWlkJztcbmltcG9ydCB7Ym91bmRpbmdDbGllbnRSZWN0fSBmcm9tICdAc2Npb24vY29tcG9uZW50cy9kaW1lbnNpb24nO1xuaW1wb3J0IHtjb2VyY2VFbGVtZW50fSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuXG5jb25zdCBOT1JUSDogQ29ubmVjdGVkUG9zaXRpb24gPSB7b3JpZ2luWDogJ2NlbnRlcicsIG9yaWdpblk6ICd0b3AnLCBvdmVybGF5WDogJ2NlbnRlcicsIG92ZXJsYXlZOiAnYm90dG9tJywgcGFuZWxDbGFzczogJ3diLW5vcnRoJ307XG5jb25zdCBTT1VUSDogQ29ubmVjdGVkUG9zaXRpb24gPSB7b3JpZ2luWDogJ2NlbnRlcicsIG9yaWdpblk6ICdib3R0b20nLCBvdmVybGF5WDogJ2NlbnRlcicsIG92ZXJsYXlZOiAndG9wJywgcGFuZWxDbGFzczogJ3diLXNvdXRoJ307XG5jb25zdCBXRVNUOiBDb25uZWN0ZWRQb3NpdGlvbiA9IHtvcmlnaW5YOiAnc3RhcnQnLCBvcmlnaW5ZOiAnY2VudGVyJywgb3ZlcmxheVg6ICdlbmQnLCBvdmVybGF5WTogJ2NlbnRlcicsIHBhbmVsQ2xhc3M6ICd3Yi13ZXN0J307XG5jb25zdCBFQVNUOiBDb25uZWN0ZWRQb3NpdGlvbiA9IHtvcmlnaW5YOiAnZW5kJywgb3JpZ2luWTogJ2NlbnRlcicsIG92ZXJsYXlYOiAnc3RhcnQnLCBvdmVybGF5WTogJ2NlbnRlcicsIHBhbmVsQ2xhc3M6ICd3Yi1lYXN0J307XG5cbi8qKlxuICogQWxsb3dzIGRpc3BsYXlpbmcgYSBjb21wb25lbnQgaW4gYSB3b3JrYmVuY2ggcG9wdXAuXG4gKlxuICogQSBwb3B1cCBpcyBhIHZpc3VhbCB3b3JrYmVuY2ggY29tcG9uZW50IGZvciBkaXNwbGF5aW5nIGNvbnRlbnQgYWJvdmUgb3RoZXIgY29udGVudC4gSXQgaXMgcG9zaXRpb25lZCByZWxhdGl2ZSB0byBhbiBhbmNob3IsXG4gKiB3aGljaCBjYW4gYmUgZWl0aGVyIGEgY29vcmRpbmF0ZSBvciBhbiBIVE1MIGVsZW1lbnQuIFRoZSBwb3B1cCBtb3ZlcyB3aGVuIHRoZSBhbmNob3IgbW92ZXMuXG4gKlxuICogVW5saWtlIHZpZXdzLCBwb3B1cHMgYXJlIG5vdCBwYXJ0IG9mIHRoZSBwZXJzaXN0ZW50IFdvcmtiZW5jaCBuYXZpZ2F0aW9uLCBtZWFuaW5nIHRoYXQgcG9wdXBzIGRvIG5vdCBzdXJ2aXZlIGEgcGFnZSByZWxvYWQuXG4gKi9cbkBJbmplY3RhYmxlKHtwcm92aWRlZEluOiAncm9vdCd9KVxuZXhwb3J0IGNsYXNzIFBvcHVwU2VydmljZSB7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZW52aXJvbm1lbnRJbmplY3RvciA9IGluamVjdChFbnZpcm9ubWVudEluamVjdG9yKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfb3ZlcmxheSA9IGluamVjdChPdmVybGF5KTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZm9jdXNNYW5hZ2VyID0gaW5qZWN0KEZvY3VzTW9uaXRvcik7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3ZpZXdSZWdpc3RyeSA9IGluamVjdChXT1JLQkVOQ0hfVklFV19SRUdJU1RSWSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3pvbmUgPSBpbmplY3QoTmdab25lKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZG9jdW1lbnQgPSBpbmplY3QoRE9DVU1FTlQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF92aWV3ID0gaW5qZWN0KMm1V29ya2JlbmNoVmlldywge29wdGlvbmFsOiB0cnVlfSk7XG5cbiAgLyoqXG4gICAqIERpc3BsYXlzIHRoZSBzcGVjaWZpZWQgY29tcG9uZW50IGluIGEgcG9wdXAuXG4gICAqXG4gICAqIFRvIHBvc2l0aW9uIHRoZSBwb3B1cCwgcHJvdmlkZSBlaXRoZXIgYSBjb29yZGluYXRlIG9yIGFuIGVsZW1lbnQgdG8gc2VydmUgYXMgdGhlIHBvcHVwIGFuY2hvci5cbiAgICpcbiAgICogSWYgeW91IHVzZSBhbiBlbGVtZW50IGFzIHRoZSBwb3B1cCBhbmNob3IsIHRoZSBwb3B1cCBhbHNvIG1vdmVzIHdoZW4gdGhlIGFuY2hvciBlbGVtZW50IG1vdmVzLiBJZiB5b3UgdXNlIGEgY29vcmRpbmF0ZVxuICAgKiBhbmQgb3BlbiB0aGUgcG9wdXAgaW4gdGhlIGNvbnRleHQgb2YgYSB2aWV3LCB0aGUgcG9wdXAgb3BlbnMgcmVsYXRpdmUgdG8gdGhlIGJvdW5kcyBvZiB0aGF0IHZpZXcuIE90aGVyd2lzZSwgaXRcbiAgICogaXMgcG9zaXRpb25lZCByZWxhdGl2ZSB0byB0aGUgcGFnZSB2aWV3cG9ydC4gSWYgeW91IG1vdmUgb3IgcmVzaXplIHRoZSB2aWV3IG9yIHRoZSBwYWdlLCB0aGUgcG9wdXAgd2lsbCBhbHNvIGJlIG1vdmVkXG4gICAqIGRlcGVuZGluZyBvbiB0aGUgcGFpciBvZiBjb29yZGluYXRlcyB1c2VkLlxuICAgKlxuICAgKiBCeSBzZXR0aW5nIHRoZSBhbGlnbm1lbnQgb2YgdGhlIHBvcHVwLCB5b3UgY2FuIGNvbnRyb2wgdGhlIHJlZ2lvbiB3aGVyZSB0byBvcGVuIHRoZSBwb3B1cCByZWxhdGl2ZSB0byBpdHMgYW5jaG9yLlxuICAgKlxuICAgKiBPcHRpb25hbGx5LCB5b3UgY2FuIHBhc3MgZGF0YSB0byB0aGUgcG9wdXAgY29tcG9uZW50LiBUaGUgY29tcG9uZW50IGNhbiBpbmplY3QgdGhlIHBvcHVwIGhhbmRsZSB7QGxpbmsgUG9wdXB9IHRvXG4gICAqIHJlYWQgaW5wdXQgZGF0YSBvciB0byBjbG9zZSB0aGUgcG9wdXAuXG4gICAqXG4gICAqIEJ5IGRlZmF1bHQsIHRoZSBwb3B1cCB3aWxsIGNsb3NlIG9uIGZvY3VzIGxvc3MsIG9yIHdoZW4gdGhlIHVzZXIgaGl0cyB0aGUgZXNjYXBlIGtleS5cbiAgICpcbiAgICogSWYgb3BlbmluZyB0aGUgcG9wdXAgaW4gdGhlIGNvbnRleHQgb2YgYSB2aWV3LCB0aGUgcG9wdXAgaXMgYm91bmQgdG8gdGhlIGxpZmVjeWNsZSBvZiB0aGUgdmlldywgdGhhdCBpcywgdGhlIHBvcHVwXG4gICAqIGlzIGRpc3BsYXllZCBvbmx5IGlmIHRoZSB2aWV3IGlzIGFjdGl2ZSBhbmQgaXMgY2xvc2VkIHdoZW4gdGhlIHZpZXcgaXMgY2xvc2VkLlxuICAgKlxuICAgKiBAcGFyYW0gICBjb25maWcgLSBDb250cm9scyBwb3B1cCBiZWhhdmlvclxuICAgKiBAcmV0dXJucyBhIHByb21pc2UgdGhhdDpcbiAgICogICAgICAgICAgLSByZXNvbHZlcyB0byB0aGUgcmVzdWx0IGlmIGNsb3NlZCB3aXRoIGEgcmVzdWx0XG4gICAqICAgICAgICAgIC0gcmVzb2x2ZXMgdG8gYHVuZGVmaW5lZGAgaWYgY2xvc2VkIHdpdGhvdXQgYSByZXN1bHRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBvcGVuPFI+KGNvbmZpZzogUG9wdXBDb25maWcpOiBQcm9taXNlPFIgfCB1bmRlZmluZWQ+IHtcbiAgICBhc3NlcnROb3RJblJlYWN0aXZlQ29udGV4dCh0aGlzLm9wZW4sICdDYWxsIFdvcmtiZW5jaFBvcHVwU2VydmljZS5vcGVuKCkgaW4gYSBub24tcmVhY3RpdmUgKG5vbi10cmFja2luZykgY29udGV4dCwgc3VjaCBhcyB3aXRoaW4gdGhlIHVudHJhY2tlZCgpIGZ1bmN0aW9uLicpO1xuXG4gICAgLy8gRW5zdXJlIHRvIHJ1biBpbiBBbmd1bGFyIHpvbmUgdG8gZGlzcGxheSB0aGUgcG9wdXAgZXZlbiB3aGVuIGNhbGxlZCBmcm9tIG91dHNpZGUgb2YgdGhlIEFuZ3VsYXIgem9uZS5cbiAgICBpZiAoIU5nWm9uZS5pc0luQW5ndWxhclpvbmUoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuX3pvbmUucnVuKCgpID0+IHRoaXMub3Blbihjb25maWcpKTtcbiAgICB9XG5cbiAgICBjb25zdCBhbGlnbiA9IGNvbmZpZy5hbGlnbiB8fCAnbm9ydGgnO1xuICAgIGNvbnN0IGNvbnRleHR1YWxWaWV3ID0gdGhpcy5yZXNvbHZlQ29udGV4dHVhbFZpZXcoY29uZmlnKTtcbiAgICBjb25zdCBwb3B1cCA9IHRoaXMuY3JlYXRlUG9wdXAoY29uZmlnLCB7dmlldzogY29udGV4dHVhbFZpZXd9KTtcbiAgICBjb25zdCBwb3B1cERlc3Ryb3lSZWYgPSBwb3B1cC5pbmplY3Rvci5nZXQoRGVzdHJveVJlZik7XG4gICAgY29uc3QgcG9wdXBPcmlnaW4gPSB0aGlzLnRyYWNrUG9wdXBPcmlnaW4oY29uZmlnLCBjb250ZXh0dWFsVmlldywgcG9wdXAuaW5qZWN0b3IpO1xuXG4gICAgLy8gV2FpdCBmb3IgdGhlIGluaXRpYWwgcG9zaXRpb24uXG4gICAgY29uc3QgaW5pdGlhbFBvc2l0aW9uID0gYXdhaXQgZmlyc3RWYWx1ZUZyb20odG9PYnNlcnZhYmxlKHBvcHVwT3JpZ2luLCB7aW5qZWN0b3I6IHBvcHVwLmluamVjdG9yfSkucGlwZShmaWx0ZXIoQm9vbGVhbikpKTtcblxuICAgIGNvbnN0IG92ZXJsYXlQb3NpdGlvblN0cmF0ZWd5ID0gdGhpcy5fb3ZlcmxheS5wb3NpdGlvbigpXG4gICAgICAuZmxleGlibGVDb25uZWN0ZWRUbyhpbml0aWFsUG9zaXRpb24pXG4gICAgICAud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcbiAgICAgIC53aXRoTG9ja2VkUG9zaXRpb24oZmFsc2UpIC8vIElmIGxvY2tlZCwgdGhlIHBvcHVwIHdvbid0IGF0dGVtcHQgdG8gcmVwb3NpdGlvbiBpdHNlbGYgaWYgbm90IGVub3VnaCBzcGFjZSBhdmFpbGFibGUuXG4gICAgICAud2l0aFBvc2l0aW9ucygoKCk6IENvbm5lY3RlZFBvc2l0aW9uW10gPT4ge1xuICAgICAgICBzd2l0Y2ggKGFsaWduKSB7XG4gICAgICAgICAgY2FzZSAnbm9ydGgnOlxuICAgICAgICAgICAgcmV0dXJuIFtOT1JUSCwgU09VVEgsIFdFU1QsIEVBU1RdO1xuICAgICAgICAgIGNhc2UgJ3NvdXRoJzpcbiAgICAgICAgICAgIHJldHVybiBbU09VVEgsIE5PUlRILCBXRVNULCBFQVNUXTtcbiAgICAgICAgICBjYXNlICd3ZXN0JzpcbiAgICAgICAgICAgIHJldHVybiBbV0VTVCwgRUFTVCwgTk9SVEgsIFNPVVRIXTtcbiAgICAgICAgICBjYXNlICdlYXN0JzpcbiAgICAgICAgICAgIHJldHVybiBbRUFTVCwgV0VTVCwgTk9SVEgsIFNPVVRIXTtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1tQb3B1cFBvc2l0aW9uRXJyb3JdIElsbGVnYWwgcG9zaXRpb247IG11c3QgYmUgbm9ydGgsIHNvdXRoLCB3ZXN0IG9yIGVhc3QnKTtcbiAgICAgICAgfVxuICAgICAgfSkoKSk7XG5cbiAgICAvLyBDb25maWd1cmUgdGhlIHBvcHVwIG92ZXJsYXkuXG4gICAgY29uc3Qgb3ZlcmxheUNvbmZpZyA9IG5ldyBPdmVybGF5Q29uZmlnKHtcbiAgICAgIHBhbmVsQ2xhc3M6ICd3Yi1wb3B1cCcsXG4gICAgICBoYXNCYWNrZHJvcDogZmFsc2UsXG4gICAgICBwb3NpdGlvblN0cmF0ZWd5OiBvdmVybGF5UG9zaXRpb25TdHJhdGVneSxcbiAgICAgIHNjcm9sbFN0cmF0ZWd5OiB0aGlzLl9vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMubm9vcCgpLFxuICAgICAgZGlzcG9zZU9uTmF2aWdhdGlvbjogdHJ1ZSxcbiAgICB9KTtcblxuICAgIC8vIENvbnN0cnVjdCB0aGUgcG9wdXAgY29tcG9uZW50IGFuZCBhdHRhY2ggaXQgdG8gdGhlIERPTS5cbiAgICBjb25zdCBvdmVybGF5UmVmID0gdGhpcy5fb3ZlcmxheS5jcmVhdGUob3ZlcmxheUNvbmZpZyk7XG4gICAgY29uc3QgcG9wdXBQb3J0YWwgPSBuZXcgQ29tcG9uZW50UG9ydGFsKFBvcHVwQ29tcG9uZW50LCBudWxsLCBJbmplY3Rvci5jcmVhdGUoe1xuICAgICAgcGFyZW50OiBjb25maWcuY29tcG9uZW50Q29uc3RydWN0T3B0aW9ucz8uaW5qZWN0b3IgfHwgdGhpcy5fZW52aXJvbm1lbnRJbmplY3RvcixcbiAgICAgIHByb3ZpZGVyczogW1xuICAgICAgICB7cHJvdmlkZTogybVQb3B1cCwgdXNlVmFsdWU6IHBvcHVwfSxcbiAgICAgICAge3Byb3ZpZGU6IFBvcHVwLCB1c2VFeGlzdGluZzogybVQb3B1cH0sXG4gICAgICAgIHByb3ZpZGVWaWV3Q29udGV4dChjb250ZXh0dWFsVmlldyksXG4gICAgICAgIC4uLltjb25maWcuY29tcG9uZW50Q29uc3RydWN0T3B0aW9ucz8ucHJvdmlkZXJzIHx8IFtdXSxcbiAgICAgIF0sXG4gICAgfSkpO1xuICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IG92ZXJsYXlSZWYuYXR0YWNoKHBvcHVwUG9ydGFsKTtcbiAgICBjb25zdCBwb3B1cEVsZW1lbnQ6IEhUTUxFbGVtZW50ID0gY29tcG9uZW50UmVmLmxvY2F0aW9uLm5hdGl2ZUVsZW1lbnQ7XG5cbiAgICAvLyBNYWtlIHRoZSBwb3B1cCBmb2N1c2FibGUgYW5kIHJlcXVlc3QgdGhlIGZvY3VzLlxuICAgIHBvcHVwRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJy0xJyk7XG4gICAgdGhpcy5fZm9jdXNNYW5hZ2VyLmZvY3VzVmlhKHBvcHVwRWxlbWVudCwgJ3Byb2dyYW0nKTsgLy8gVG8gbm90IGNsb3NlIHRoZSBwb3B1cCBpbW1lZGlhdGVseSB3aGVuIGl0IG9wZW5zLCBpZiB1c2luZyB0aGUgJ29uRm9jdXNMb3N0JyBzdHJhdGVneS5cblxuICAgIC8vIFJlcG9zaXRpb24gcG9wdXAgd2hlbiB0aGUgYW5jaG9yIGlzIG1vdmVkLlxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBvcmlnaW4gPSBwb3B1cE9yaWdpbigpO1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgaWYgKG9yaWdpbikge1xuICAgICAgICAgIG92ZXJsYXlQb3NpdGlvblN0cmF0ZWd5LnNldE9yaWdpbihvcmlnaW4pO1xuICAgICAgICAgIG92ZXJsYXlSZWYudXBkYXRlUG9zaXRpb24oKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwge2luamVjdG9yOiBwb3B1cC5pbmplY3Rvcn0pO1xuXG4gICAgLy8gUmVwb3NpdGlvbiBwb3B1cCB3aGVuIHJlc2l6ZWQuXG4gICAgZnJvbVJlc2l6ZSQob3ZlcmxheVJlZi5vdmVybGF5RWxlbWVudClcbiAgICAgIC5waXBlKFxuICAgICAgICBvYnNlcnZlSW4oZm4gPT4gdGhpcy5fem9uZS5ydW4oZm4pKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHBvcHVwRGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgb3ZlcmxheVJlZi51cGRhdGVQb3NpdGlvbigpO1xuICAgICAgfSk7XG5cbiAgICAvLyBDbG9zZSB0aGUgcG9wdXAgZGVwZW5kaW5nIG9uIHRoZSBwYXNzZWQgY29uZmlnLlxuICAgIHRoaXMuaW5zdGFsbFBvcHVwQ2xvc2VyKGNvbmZpZywgcG9wdXBFbGVtZW50LCBwb3B1cCwgY29udGV4dHVhbFZpZXcpO1xuXG4gICAgLy8gSGlkZSB0aGUgcG9wdXAgd2hlbiBkZXRhY2hpbmcgdGhlIGNvbnRleHR1YWwgdmlldywgaWYgYW55LlxuICAgIGlmIChjb250ZXh0dWFsVmlldykge1xuICAgICAgdGhpcy5oaWRlUG9wdXBPblZpZXdEZXRhY2gob3ZlcmxheVJlZiwgY29udGV4dHVhbFZpZXcsIHBvcHVwKTtcbiAgICB9XG5cbiAgICAvLyBEaXNwb3NlIHRoZSBwb3B1cCB3aGVuIGNsb3NpbmcgaXQuXG4gICAgcG9wdXBEZXN0cm95UmVmLm9uRGVzdHJveSgoKSA9PiB7XG4gICAgICBvdmVybGF5UmVmLmRpc3Bvc2UoKTtcbiAgICB9KTtcblxuICAgIHJldHVybiBuZXcgUHJvbWlzZTxSIHwgdW5kZWZpbmVkPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICBwb3B1cERlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgICAgcG9wdXAucmVzdWx0IGluc3RhbmNlb2YgRXJyb3IgPyByZWplY3QocG9wdXAucmVzdWx0KSA6IHJlc29sdmUocG9wdXAucmVzdWx0IGFzIFIpO1xuICAgICAgfSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgcG9wdXAgaGFuZGxlLlxuICAgKi9cbiAgcHJpdmF0ZSBjcmVhdGVQb3B1cDxSPihjb25maWc6IFBvcHVwQ29uZmlnLCBjb250ZXh0OiB7dmlldzogybVXb3JrYmVuY2hWaWV3IHwgbnVsbH0pOiDJtVBvcHVwPFI+IHtcbiAgICAvLyBDb25zdHJ1Y3QgdGhlIGhhbmRsZSBpbiBhbiBpbmplY3Rpb24gY29udGV4dCB0aGF0IHNoYXJlcyB0aGUgcG9wdXAncyBsaWZlY3ljbGUsIGFsbG93aW5nIGZvciBhdXRvbWF0aWMgY2xlYW51cCBvZiBlZmZlY3RzIGFuZCBSeEpTIGludGVyb3AgZnVuY3Rpb25zLlxuICAgIGNvbnN0IHBvcHVwSWQgPSBjb25maWcuaWQgPz8gVVVJRC5yYW5kb21VVUlEKCk7XG4gICAgY29uc3QgcG9wdXBFbnZpcm9ubWVudEluamVjdG9yID0gY3JlYXRlRW52aXJvbm1lbnRJbmplY3RvcihbcHJvdmlkZVZpZXdDb250ZXh0KGNvbnRleHQudmlldyldLCB0aGlzLl9lbnZpcm9ubWVudEluamVjdG9yLCBgV29ya2JlbmNoIFBvcHVwICR7cG9wdXBJZH1gKTtcbiAgICByZXR1cm4gcnVuSW5JbmplY3Rpb25Db250ZXh0KHBvcHVwRW52aXJvbm1lbnRJbmplY3RvciwgKCkgPT4gbmV3IMm1UG9wdXA8Uj4ocG9wdXBJZCwgY29uZmlnKSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIHRoZSBwb3B1cCBkZXBlbmRpbmcgb24gdGhlIGNvbmZpZ3VyZWQgcG9wdXAgY2xvc2luZyBzdHJhdGVneS5cbiAgICovXG4gIHByaXZhdGUgaW5zdGFsbFBvcHVwQ2xvc2VyKGNvbmZpZzogUG9wdXBDb25maWcsIHBvcHVwRWxlbWVudDogSFRNTEVsZW1lbnQsIHBvcHVwOiDJtVBvcHVwLCBjb250ZXh0dWFsVmlldzogybVXb3JrYmVuY2hWaWV3IHwgbnVsbCk6IHZvaWQge1xuICAgIGNvbnN0IHBvcHVwRGVzdHJveVJlZiA9IHBvcHVwLmluamVjdG9yLmdldChEZXN0cm95UmVmKTtcblxuICAgIC8vIENsb3NlIHRoZSBwb3B1cCBvbiBlc2NhcGUga2V5c3Ryb2tlLlxuICAgIGlmIChjb25maWcuY2xvc2VTdHJhdGVneT8ub25Fc2NhcGUgPz8gdHJ1ZSkge1xuICAgICAgZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHBvcHVwRWxlbWVudCwgJ2tleWRvd24nKVxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzdWJzY3JpYmVJbihmbiA9PiB0aGlzLl96b25lLnJ1bk91dHNpZGVBbmd1bGFyKGZuKSksXG4gICAgICAgICAgZmlsdGVyKChldmVudDogS2V5Ym9hcmRFdmVudCkgPT4gZXZlbnQua2V5ID09PSAnRXNjYXBlJyksXG4gICAgICAgICAgb2JzZXJ2ZUluKGZuID0+IHRoaXMuX3pvbmUucnVuKGZuKSksXG4gICAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHBvcHVwRGVzdHJveVJlZiksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiBwb3B1cC5jbG9zZSgpKTtcbiAgICB9XG5cbiAgICAvLyBDbG9zZSB0aGUgcG9wdXAgb24gZm9jdXMgbG9zcy5cbiAgICBpZiAoY29uZmlnLmNsb3NlU3RyYXRlZ3k/Lm9uRm9jdXNMb3N0ID8/IHRydWUpIHtcbiAgICAgIHRoaXMuX2ZvY3VzTWFuYWdlci5tb25pdG9yKHBvcHVwRWxlbWVudCwgdHJ1ZSlcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgZmlsdGVyKChmb2N1c09yaWdpbjogRm9jdXNPcmlnaW4pID0+ICFmb2N1c09yaWdpbiksXG4gICAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHBvcHVwRGVzdHJveVJlZiksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgoKSA9PiBwb3B1cC5jbG9zZShwb3B1cC5yZXN1bHQpKTtcbiAgICB9XG5cbiAgICAvLyBDbG9zZSB0aGUgcG9wdXAgd2hlbiBjbG9zaW5nIHRoZSB2aWV3LlxuICAgIGlmIChjb250ZXh0dWFsVmlldykge1xuICAgICAgZWZmZWN0KCgpID0+IHtcbiAgICAgICAgaWYgKCF0aGlzLl92aWV3UmVnaXN0cnkub2JqZWN0cygpLnNvbWUodmlldyA9PiB2aWV3LmlkID09PSBjb250ZXh0dWFsVmlldy5pZCkpIHtcbiAgICAgICAgICB1bnRyYWNrZWQoKCkgPT4gcG9wdXAuY2xvc2UoKSk7XG4gICAgICAgIH1cbiAgICAgIH0sIHtpbmplY3RvcjogcG9wdXAuaW5qZWN0b3J9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGlkZXMgdGhlIHBvcHVwIHdoZW4gaXRzIGNvbnRleHR1YWwgdmlldyBpcyBkZXRhY2hlZCwgYW5kIGRpc3BsYXlzIGl0IHdoZW4gaXQgaXMgcmVhdHRhY2hlZC4gQWxzbyByZXN0b3JlcyB0aGUgZm9jdXMgb24gcmUtYWN0aXZhdGlvbi5cbiAgICogVGhlIGNvbnRleHR1YWwgdmlldyBpcyBkZXRhY2hlZCBpZiBub3QgYWN0aXZlLCBvciBsb2NhdGVkIGluIHRoZSBwZXJpcGhlcmFsIGFyZWEgYW5kIHRoZSBtYWluIGFyZWEgaXMgbWF4aW1pemVkLlxuICAgKi9cbiAgcHJpdmF0ZSBoaWRlUG9wdXBPblZpZXdEZXRhY2gob3ZlcmxheVJlZjogT3ZlcmxheVJlZiwgY29udGV4dHVhbFZpZXc6IMm1V29ya2JlbmNoVmlldywgcG9wdXA6IMm1UG9wdXApOiB2b2lkIHtcbiAgICBvdmVybGF5UmVmLm92ZXJsYXlFbGVtZW50LmNsYXNzTGlzdC5hZGQoJ3diLXZpZXctY29udGV4dCcpO1xuXG4gICAgY29uc3QgcG9wdXBEZXN0cm95UmVmID0gcG9wdXAuaW5qZWN0b3IuZ2V0KERlc3Ryb3lSZWYpO1xuICAgIGxldCBhY3RpdmVFbGVtZW50OiBIVE1MRWxlbWVudCB8IHVuZGVmaW5lZDtcblxuICAgIGVmZmVjdCgoKSA9PiB7XG4gICAgICBjb25zdCBhdHRhY2hlZCA9IGNvbnRleHR1YWxWaWV3LnBvcnRhbC5hdHRhY2hlZCgpO1xuICAgICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgICAgaWYgKGF0dGFjaGVkKSB7XG4gICAgICAgICAgb3ZlcmxheVJlZi5vdmVybGF5RWxlbWVudC5jbGFzc0xpc3QuYWRkKCd3Yi12aWV3LWF0dGFjaGVkJyk7XG4gICAgICAgICAgYWN0aXZlRWxlbWVudD8uZm9jdXMoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICBvdmVybGF5UmVmLm92ZXJsYXlFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoJ3diLXZpZXctYXR0YWNoZWQnKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSwge2luamVjdG9yOiBwb3B1cC5pbmplY3Rvcn0pO1xuXG4gICAgLy8gVHJhY2sgdGhlIGZvY3VzIGluIHRoZSBwb3B1cCB0byByZXN0b3JlIGl0IHdoZW4gYXR0YWNoaW5nIHRoZSBwb3B1cC5cbiAgICBmcm9tRXZlbnQob3ZlcmxheVJlZi5vdmVybGF5RWxlbWVudCwgJ2ZvY3VzaW4nKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN1YnNjcmliZUluKGZuID0+IHRoaXMuX3pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoZm4pKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHBvcHVwRGVzdHJveVJlZiksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgYWN0aXZlRWxlbWVudCA9IHRoaXMuX2RvY3VtZW50LmFjdGl2ZUVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCA/IHRoaXMuX2RvY3VtZW50LmFjdGl2ZUVsZW1lbnQgOiB1bmRlZmluZWQ7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc2lnbmFsIHRoYXQgdHJhY2tzIHRoZSBwb3NpdGlvbiBvZiB0aGUgcG9wdXAgYW5jaG9yLlxuICAgKi9cbiAgcHJpdmF0ZSB0cmFja1BvcHVwT3JpZ2luKGNvbmZpZzogUG9wdXBDb25maWcsIGNvbnRleHR1YWxWaWV3OiDJtVdvcmtiZW5jaFZpZXcgfCBudWxsLCBpbmplY3RvcjogSW5qZWN0b3IpOiBTaWduYWw8RE9NUmVjdCB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IGhvc3RCb3VuZHMgPSBib3VuZGluZ0NsaWVudFJlY3QoY29udGV4dHVhbFZpZXc/LnBvcnRhbC5jb21wb25lbnRSZWYubG9jYXRpb24ubmF0aXZlRWxlbWVudCA/PyBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQsIHtpbmplY3Rvcn0pO1xuXG4gICAgaWYgKGNvbmZpZy5hbmNob3IgaW5zdGFuY2VvZiBFbGVtZW50IHx8IGNvbmZpZy5hbmNob3IgaW5zdGFuY2VvZiBFbGVtZW50UmVmKSB7XG4gICAgICBjb25zdCBhbmNob3IgPSBjb2VyY2VFbGVtZW50KGNvbmZpZy5hbmNob3IpIGFzIEhUTUxFbGVtZW50O1xuICAgICAgY29uc3QgYW5jaG9yQm91bmRzID0gYm91bmRpbmdDbGllbnRSZWN0KGFuY2hvciwge2luamVjdG9yfSk7XG4gICAgICByZXR1cm4gY29tcHV0ZWQoKCkgPT4ge1xuICAgICAgICAvLyBNYWludGFpbiBwb3NpdGlvbiBhbmQgc2l6ZSB3aGVuIGRldGFjaGVkIHRvIHByZXZlbnQgZmxpY2tlcmluZyB3aGVuIGF0dGFjaGVkIGFnYWluIGFuZCB0byBzdXBwb3J0IGZvciB2aXJ0dWFsIHNjcm9sbGluZyBpbiBwb3B1cCBjb250ZW50LlxuICAgICAgICBpZiAoY29udGV4dHVhbFZpZXcgJiYgIWNvbnRleHR1YWxWaWV3LnBvcnRhbC5hdHRhY2hlZCgpKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIElNUE9SVEFOVDogVHJhY2sgYW5jaG9yIGFuZCBob3N0IGJvdW5kcyBvbmx5IGlmIGF0dGFjaGVkIHRvIHByZXZlbnQgZmxpY2tlcmluZy5cblxuICAgICAgICAvLyBUaGUgYGJvdW5kaW5nQ2xpZW50UmVjdGAgc2lnbmFsIGRvZXMgbm90IGRldGVjdCBwb3NpdGlvbiBjaGFuZ2VzIHdoZW4gdGhlIGVsZW1lbnQgaXMgc2Nyb2xsZWQgb3V0IG9mIHZpZXcuXG4gICAgICAgIC8vIENvbnNlcXVlbnRseSwgaWYgdGhlIHBvcHVwIGFuY2hvciBpcyBzY3JvbGxlZCBvdXQgb2YgdmlldyBhbmQgdGhlIHZpZXcgaXMgZW5sYXJnZWQsIHRoZSBwb3B1cCBtYXkgbm90IGFsaWduXG4gICAgICAgIC8vIHdpdGggdGhlIHZpZXcgYm91bmRhcmllcy4gVGhlcmVmb3JlLCB3ZSByZWFkIHRoZSBhbmNob3IncyBib3VuZGluZyBib3ggZGlyZWN0bHkgZnJvbSB0aGUgRE9NLlxuICAgICAgICBhbmNob3JCb3VuZHMoKTtcblxuICAgICAgICByZXR1cm4gY29uc3RyYWluQ2xpZW50UmVjdChhbmNob3IuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIGhvc3RCb3VuZHMoKSk7XG4gICAgICB9LCB7ZXF1YWw6IGlzRXF1YWxEb21SZWN0fSk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgY29uc3QgYW5jaG9yQm91bmRzID0gdG9TaWduYWwoT2JzZXJ2YWJsZXMuY29lcmNlKGNvbmZpZy5hbmNob3IpLCB7aW5qZWN0b3J9KTtcbiAgICAgIHJldHVybiBjb21wdXRlZCgoKSA9PiB7XG4gICAgICAgIC8vIE1haW50YWluIHBvc2l0aW9uIGFuZCBzaXplIHdoZW4gZGV0YWNoZWQgdG8gcHJldmVudCBmbGlja2VyaW5nIHdoZW4gYXR0YWNoZWQgYWdhaW4gYW5kIHRvIHN1cHBvcnQgZm9yIHZpcnR1YWwgc2Nyb2xsaW5nIGluIHBvcHVwIGNvbnRlbnQuXG4gICAgICAgIGlmIChjb250ZXh0dWFsVmlldyAmJiAhY29udGV4dHVhbFZpZXcucG9ydGFsLmF0dGFjaGVkKCkpIHtcbiAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gSU1QT1JUQU5UOiBUcmFjayBhbmNob3IgYW5kIGhvc3QgYm91bmRzIG9ubHkgaWYgYXR0YWNoZWQgdG8gcHJldmVudCBmbGlja2VyaW5nLlxuICAgICAgICBpZiAoIWFuY2hvckJvdW5kcygpKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IHt4LCB5fSA9IG1hcFRvUGFnZUNvb3JkaW5hdGVzKGFuY2hvckJvdW5kcygpISwgaG9zdEJvdW5kcygpKTtcbiAgICAgICAgY29uc3Qge3dpZHRoLCBoZWlnaHR9ID0gYW5jaG9yQm91bmRzKCkhO1xuICAgICAgICByZXR1cm4gY29uc3RyYWluQ2xpZW50UmVjdChuZXcgRE9NUmVjdCh4LCB5LCB3aWR0aCwgaGVpZ2h0KSwgaG9zdEJvdW5kcygpKTtcbiAgICAgIH0sIHtlcXVhbDogaXNFcXVhbERvbVJlY3R9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIGNvbnRleHR1YWwgdmlldyB0byB3aGljaCB0aGUgcG9wdXAgaXMgYm91bmQuXG4gICAqL1xuICBwcml2YXRlIHJlc29sdmVDb250ZXh0dWFsVmlldyhjb25maWc6IFBvcHVwQ29uZmlnKTogybVXb3JrYmVuY2hWaWV3IHwgbnVsbCB7XG4gICAgaWYgKGNvbmZpZy5jb250ZXh0Py52aWV3SWQpIHtcbiAgICAgIHJldHVybiB0aGlzLl92aWV3UmVnaXN0cnkuZ2V0KGNvbmZpZy5jb250ZXh0LnZpZXdJZCk7XG4gICAgfVxuICAgIGlmIChjb25maWcuY29udGV4dD8udmlld0lkID09PSB1bmRlZmluZWQpIHsgLy8gYG51bGxgIG1lYW5zIHRvIG9wZW4gdGhlIHBvcHVwIG91dHNpZGUgdGhlIGNvbnRleHR1YWwgdmlld1xuICAgICAgcmV0dXJuIHRoaXMuX3ZpZXcgPz8gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBNYXBzIGdpdmVuIHZpZXcgY29vcmRpbmF0ZXMgdG8gYWJzb2x1dGUgcGFnZSBjb29yZGluYXRlcy5cbiAqL1xuZnVuY3Rpb24gbWFwVG9QYWdlQ29vcmRpbmF0ZXMob3JpZ2luOiBQb3B1cE9yaWdpbiwgcmVsYXRpdmVUbzogRE9NUmVjdCk6IFBvaW50IHtcbiAgY29uc3QgeHkgPSBvcmlnaW4gYXMgUG9pbnQ7XG4gIGlmICh4eS54ICE9PSB1bmRlZmluZWQgJiYgeHkueSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHJlbGF0aXZlVG8ueCArIHh5LngsXG4gICAgICB5OiByZWxhdGl2ZVRvLnkgKyB4eS55LFxuICAgIH07XG4gIH1cbiAgY29uc3QgdG9wTGVmdCA9IG9yaWdpbiBhcyBUb3BMZWZ0UG9pbnQ7XG4gIGlmICh0b3BMZWZ0LnRvcCAhPT0gdW5kZWZpbmVkICYmIHRvcExlZnQubGVmdCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHg6IHJlbGF0aXZlVG8ueCArIHRvcExlZnQubGVmdCxcbiAgICAgIHk6IHJlbGF0aXZlVG8ueSArIHRvcExlZnQudG9wLFxuICAgIH07XG4gIH1cbiAgY29uc3QgdG9wUmlnaHQgPSBvcmlnaW4gYXMgVG9wUmlnaHRQb2ludDtcbiAgaWYgKHRvcFJpZ2h0LnRvcCAhPT0gdW5kZWZpbmVkICYmIHRvcFJpZ2h0LnJpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogcmVsYXRpdmVUby54ICsgKHJlbGF0aXZlVG8ud2lkdGggLSB0b3BSaWdodC5yaWdodCksXG4gICAgICB5OiByZWxhdGl2ZVRvLnkgKyB0b3BSaWdodC50b3AsXG4gICAgfTtcbiAgfVxuICBjb25zdCBib3R0b21MZWZ0ID0gb3JpZ2luIGFzIEJvdHRvbUxlZnRQb2ludDtcbiAgaWYgKGJvdHRvbUxlZnQuYm90dG9tICE9PSB1bmRlZmluZWQgJiYgYm90dG9tTGVmdC5sZWZ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogcmVsYXRpdmVUby54ICsgYm90dG9tTGVmdC5sZWZ0LFxuICAgICAgeTogcmVsYXRpdmVUby55ICsgKHJlbGF0aXZlVG8uaGVpZ2h0IC0gYm90dG9tTGVmdC5ib3R0b20pLFxuICAgIH07XG4gIH1cbiAgY29uc3QgYm90dG9tUmlnaHQgPSBvcmlnaW4gYXMgQm90dG9tUmlnaHRQb2ludDtcbiAgaWYgKGJvdHRvbVJpZ2h0LmJvdHRvbSAhPT0gdW5kZWZpbmVkICYmIGJvdHRvbVJpZ2h0LnJpZ2h0ICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgeDogcmVsYXRpdmVUby54ICsgKHJlbGF0aXZlVG8ud2lkdGggLSBib3R0b21SaWdodC5yaWdodCksXG4gICAgICB5OiByZWxhdGl2ZVRvLnkgKyAocmVsYXRpdmVUby5oZWlnaHQgLSBib3R0b21SaWdodC5ib3R0b20pLFxuICAgIH07XG4gIH1cbiAgdGhyb3cgRXJyb3IoJ1tQb3B1cE9yaWdpbkVycm9yXSBJbGxlZ2FsIHBvcHVwIG9yaWdpbjsgbXVzdCBiZSBcIlBvaW50XCIsIFwiVG9wTGVmdFBvaW50XCIsIFwiVG9wUmlnaHRQb2ludFwiLCBcIkJvdHRvbUxlZnRQb2ludFwiIG9yIFwiQm90dG9tUmlnaHRQb2ludFwiLicpO1xufVxuXG5mdW5jdGlvbiBjb25zdHJhaW5DbGllbnRSZWN0KGNsaWVudFJlY3Q6IERPTVJlY3QsIGNvbnN0cmFpbnRzOiBET01SZWN0KTogRE9NUmVjdCB7XG4gIGNvbnN0IHRvcCA9IG1pbm1heChjbGllbnRSZWN0LnRvcCwge21pbjogY29uc3RyYWludHMudG9wLCBtYXg6IGNvbnN0cmFpbnRzLmJvdHRvbX0pO1xuICBjb25zdCByaWdodCA9IG1pbm1heChjbGllbnRSZWN0LnJpZ2h0LCB7bWluOiBjb25zdHJhaW50cy5sZWZ0LCBtYXg6IGNvbnN0cmFpbnRzLnJpZ2h0fSk7XG4gIGNvbnN0IGJvdHRvbSA9IG1pbm1heChjbGllbnRSZWN0LmJvdHRvbSwge21pbjogY29uc3RyYWludHMudG9wLCBtYXg6IGNvbnN0cmFpbnRzLmJvdHRvbX0pO1xuICBjb25zdCBsZWZ0ID0gbWlubWF4KGNsaWVudFJlY3QubGVmdCwge21pbjogY29uc3RyYWludHMubGVmdCwgbWF4OiBjb25zdHJhaW50cy5yaWdodH0pO1xuICBjb25zdCB3aWR0aCA9IHJpZ2h0IC0gbGVmdDtcbiAgY29uc3QgaGVpZ2h0ID0gYm90dG9tIC0gdG9wO1xuICByZXR1cm4gbmV3IERPTVJlY3QobGVmdCwgdG9wLCB3aWR0aCwgaGVpZ2h0KTtcbn1cblxuZnVuY3Rpb24gbWlubWF4KHZhbHVlOiBudW1iZXIsIG1pbm1heDoge21pbjogbnVtYmVyOyBtYXg6IG51bWJlcn0pOiBudW1iZXIge1xuICByZXR1cm4gTWF0aC5tYXgobWlubWF4Lm1pbiwgTWF0aC5taW4odmFsdWUsIG1pbm1heC5tYXgpKTtcbn1cblxuZnVuY3Rpb24gaXNFcXVhbERvbVJlY3QoYTogRE9NUmVjdCB8IHVuZGVmaW5lZCwgYjogRE9NUmVjdCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gYT8udG9wID09PSBiPy50b3AgJiYgYT8ucmlnaHQgPT09IGI/LnJpZ2h0ICYmIGE/LmJvdHRvbSA9PT0gYj8uYm90dG9tICYmIGE/LmxlZnQgPT09IGI/LmxlZnQ7XG59XG4iXX0=
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2018-2023 Swiss Federal Railways
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made
|
|
5
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
*/
|
|
10
|
-
export { PopupService } from './popup.service';
|
|
11
|
-
export { Popup, PopupConfig } from './popup.config';
|
|
12
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NjaW9uL3dvcmtiZW5jaC9zcmMvbGliL3BvcHVwL3B1YmxpY19hcGkudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0dBUUc7QUFFSCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0saUJBQWlCLENBQUM7QUFDN0MsT0FBTyxFQUFDLEtBQUssRUFBRSxXQUFXLEVBQTBDLE1BQU0sZ0JBQWdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDE4LTIwMjMgU3dpc3MgRmVkZXJhbCBSYWlsd2F5c1xuICpcbiAqIFRoaXMgcHJvZ3JhbSBhbmQgdGhlIGFjY29tcGFueWluZyBtYXRlcmlhbHMgYXJlIG1hZGVcbiAqIGF2YWlsYWJsZSB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEVjbGlwc2UgUHVibGljIExpY2Vuc2UgMi4wXG4gKiB3aGljaCBpcyBhdmFpbGFibGUgYXQgaHR0cHM6Ly93d3cuZWNsaXBzZS5vcmcvbGVnYWwvZXBsLTIuMC9cbiAqXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogRVBMLTIuMFxuICovXG5cbmV4cG9ydCB7UG9wdXBTZXJ2aWNlfSBmcm9tICcuL3BvcHVwLnNlcnZpY2UnO1xuZXhwb3J0IHtQb3B1cCwgUG9wdXBDb25maWcsIENsb3NlU3RyYXRlZ3ksIFBvcHVwU2l6ZSwgUG9wdXBSZWZlcnJlcn0gZnJvbSAnLi9wb3B1cC5jb25maWcnO1xuZXhwb3J0IHtQb2ludCwgVG9wTGVmdFBvaW50LCBUb3BSaWdodFBvaW50LCBCb3R0b21MZWZ0UG9pbnQsIEJvdHRvbVJpZ2h0UG9pbnQsIFBvcHVwT3JpZ2lufSBmcm9tICcuL3BvcHVwLm9yaWdpbic7XG4iXX0=
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2018-2023 Swiss Federal Railways
|
|
3
|
-
*
|
|
4
|
-
* This program and the accompanying materials are made
|
|
5
|
-
* available under the terms of the Eclipse Public License 2.0
|
|
6
|
-
* which is available at https://www.eclipse.org/legal/epl-2.0/
|
|
7
|
-
*
|
|
8
|
-
* SPDX-License-Identifier: EPL-2.0
|
|
9
|
-
*/
|
|
10
|
-
import { assertNotInReactiveContext, createComponent, EnvironmentInjector, inject, Injector, signal } from '@angular/core';
|
|
11
|
-
import { Logger, LoggerNames } from '../logging';
|
|
12
|
-
/**
|
|
13
|
-
* Like the Angular CDK 'ComponentPortal' but does not destroy the component on detach.
|
|
14
|
-
*
|
|
15
|
-
* IMPORTANT: In order for the component to have the "correct" injection context, construct it the time attaching it to the Angular component tree,
|
|
16
|
-
* or by calling {@link createComponentFromInjectionContext}. The "correct" injection context is crucial, for example, if the portal is displayed
|
|
17
|
-
* in a router outlet, so that child outlets can register with their logical parent outlet. The Angular router uses the logical outlet hierarchy to
|
|
18
|
-
* resolve and activate child routes.
|
|
19
|
-
*
|
|
20
|
-
* @see WbComponentPortal
|
|
21
|
-
*/
|
|
22
|
-
export class WbComponentPortal {
|
|
23
|
-
constructor(_componentType, _options) {
|
|
24
|
-
this._componentType = _componentType;
|
|
25
|
-
this._options = _options;
|
|
26
|
-
this._logger = inject(Logger);
|
|
27
|
-
this._attached = signal(false);
|
|
28
|
-
// Do not construct the component here but the time attaching it to the Angular component tree. See the comment above.
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Constructs the portal's component using given injection context.
|
|
32
|
-
*/
|
|
33
|
-
createComponent(elementInjector) {
|
|
34
|
-
const componentRef = createComponent(this._componentType, {
|
|
35
|
-
elementInjector: Injector.create({
|
|
36
|
-
name: 'WbComponentPortalInjector',
|
|
37
|
-
parent: elementInjector,
|
|
38
|
-
providers: this._options?.providers || [],
|
|
39
|
-
}),
|
|
40
|
-
environmentInjector: elementInjector.get(EnvironmentInjector),
|
|
41
|
-
});
|
|
42
|
-
componentRef.onDestroy(() => this.onDestroy());
|
|
43
|
-
return componentRef;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Constructs the portal's component using the given injection context.
|
|
47
|
-
*/
|
|
48
|
-
createComponentFromInjectionContext(injectionContext) {
|
|
49
|
-
if (this.isConstructed) {
|
|
50
|
-
throw Error(`[PortalConstructError] Component already constructed. [component=${this._componentType}]`);
|
|
51
|
-
}
|
|
52
|
-
this._componentRef = this.createComponent(injectionContext);
|
|
53
|
-
// Trigger change detection to complete the initialization of the component, necessary for components detached from the Angular component tree.
|
|
54
|
-
this._componentRef.changeDetectorRef.detectChanges();
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Attaches this portal to the given {@link ViewContainerRef} according to the following rules:
|
|
58
|
-
*
|
|
59
|
-
* - If the component is not yet constructed, constructs it based on the given view container's injection context.
|
|
60
|
-
* - If already attached to the given view container, does nothing.
|
|
61
|
-
* - If already attached to a different view container, detaches it first.
|
|
62
|
-
*/
|
|
63
|
-
attach(viewContainerRef) {
|
|
64
|
-
assertNotInReactiveContext(this.attach);
|
|
65
|
-
if (this.isAttachedTo(viewContainerRef)) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
if (this.attached()) {
|
|
69
|
-
this.detach();
|
|
70
|
-
}
|
|
71
|
-
this._viewContainerRef = viewContainerRef;
|
|
72
|
-
this._componentRef = this._componentRef || this.createComponent(this._viewContainerRef.injector);
|
|
73
|
-
this._logger.debug(() => 'Attaching portal', LoggerNames.LIFECYCLE, this._componentRef);
|
|
74
|
-
this._componentRef.changeDetectorRef.reattach();
|
|
75
|
-
this._viewContainerRef.insert(this._componentRef.hostView);
|
|
76
|
-
this._attached.set(true);
|
|
77
|
-
this._componentRef.instance?.onAttach();
|
|
78
|
-
}
|
|
79
|
-
/**
|
|
80
|
-
* Detaches this portal from its view container without destroying it. Does nothing if not attached.
|
|
81
|
-
*
|
|
82
|
-
* The portal is removed from the DOM and its change detector detached from the Angular change detector tree,
|
|
83
|
-
* so it will not be checked for changes until it is reattached.
|
|
84
|
-
*/
|
|
85
|
-
detach() {
|
|
86
|
-
assertNotInReactiveContext(this.detach);
|
|
87
|
-
if (!this.attached()) {
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
this._logger.debug(() => 'Detaching portal', LoggerNames.LIFECYCLE, this._componentRef);
|
|
91
|
-
this._componentRef.instance?.onDetach();
|
|
92
|
-
const index = this._viewContainerRef.indexOf(this._componentRef.hostView);
|
|
93
|
-
this._viewContainerRef.detach(index);
|
|
94
|
-
this._componentRef.changeDetectorRef.detach();
|
|
95
|
-
this._attached.set(false);
|
|
96
|
-
}
|
|
97
|
-
get isConstructed() {
|
|
98
|
-
return !!this._componentRef;
|
|
99
|
-
}
|
|
100
|
-
isAttachedTo(viewContainerRef) {
|
|
101
|
-
return this._viewContainerRef === viewContainerRef && this.attached();
|
|
102
|
-
}
|
|
103
|
-
get isDestroyed() {
|
|
104
|
-
return this._componentRef === null;
|
|
105
|
-
}
|
|
106
|
-
get componentRef() {
|
|
107
|
-
if (this._componentRef === null) {
|
|
108
|
-
throw Error('[NullPortalError] Portal destroyed.');
|
|
109
|
-
}
|
|
110
|
-
if (this._componentRef === undefined) {
|
|
111
|
-
throw Error('[NullPortalError] Component not constructed yet.');
|
|
112
|
-
}
|
|
113
|
-
return this._componentRef;
|
|
114
|
-
}
|
|
115
|
-
get attached() {
|
|
116
|
-
return this._attached;
|
|
117
|
-
}
|
|
118
|
-
onDestroy() {
|
|
119
|
-
this._componentRef = null;
|
|
120
|
-
this._viewContainerRef = null;
|
|
121
|
-
this._attached.set(false);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Destroys the component instance and all the data structures associated with it.
|
|
125
|
-
*/
|
|
126
|
-
destroy() {
|
|
127
|
-
this._componentRef?.destroy();
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2ItY29tcG9uZW50LXBvcnRhbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3NjaW9uL3dvcmtiZW5jaC9zcmMvbGliL3BvcnRhbC93Yi1jb21wb25lbnQtcG9ydGFsLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBR0gsT0FBTyxFQUFDLDBCQUEwQixFQUFnQixlQUFlLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxFQUFFLFFBQVEsRUFBb0IsTUFBTSxFQUFtQixNQUFNLGVBQWUsQ0FBQztBQUMzSyxPQUFPLEVBQUMsTUFBTSxFQUFFLFdBQVcsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUUvQzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLE9BQU8saUJBQWlCO0lBTzVCLFlBQW9CLGNBQWdDLEVBQVUsUUFBd0I7UUFBbEUsbUJBQWMsR0FBZCxjQUFjLENBQWtCO1FBQVUsYUFBUSxHQUFSLFFBQVEsQ0FBZ0I7UUFIOUUsWUFBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUN6QixjQUFTLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBR2hDLHNIQUFzSDtJQUN4SCxDQUFDO0lBRUQ7O09BRUc7SUFDSyxlQUFlLENBQUMsZUFBeUI7UUFDL0MsTUFBTSxZQUFZLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUU7WUFDeEQsZUFBZSxFQUFFLFFBQVEsQ0FBQyxNQUFNLENBQUM7Z0JBQy9CLElBQUksRUFBRSwyQkFBMkI7Z0JBQ2pDLE1BQU0sRUFBRSxlQUFlO2dCQUN2QixTQUFTLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxTQUFTLElBQUksRUFBRTthQUMxQyxDQUFDO1lBQ0YsbUJBQW1CLEVBQUUsZUFBZSxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsQ0FBQztTQUM5RCxDQUFDLENBQUM7UUFDSCxZQUFZLENBQUMsU0FBUyxDQUFDLEdBQUcsRUFB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VyxXQUFXO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLGFBQWEsS0FBSyxJQUFJLENBQUM7SUFDckMsQ0FBQztJQUVELElBQVcsWUFBWTtRQUNyQixJQUFJLElBQUksQ0FBQyxhQUFhLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDaEMsTUFBTSxLQUFLLENBQUMscUNBQXFDLENBQUMsQ0FBQztRQUNyRCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsYUFBYSxLQUFLLFNBQVMsRUFBRSxDQUFDO1lBQ3JDLE1BQU0sS0FBSyxDQUFDLGtEQUFrRCxDQUFDLENBQUM7UUFDbEUsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGFBQWEsQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQztJQUN4QixDQUFDO0lBRU8sU0FBUztRQUNmLElBQUksQ0FBQyxhQUFhLEdBQUcsSUFBSSxDQUFDO1FBQzFCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLENBQUM7UUFDOUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDNUIsQ0FBQztJQUVEOztPQUVHO0lBQ0ksT0FBTztRQUNaLElBQUksQ0FBQyxhQUFhLEVBQUUsT0FBTyxFQUFFLENBQUM7SUFDaEMsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAoYykgMjAxOC0yMDIzIFN3aXNzIEZlZGVyYWwgUmFpbHdheXNcbiAqXG4gKiBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBtYWRlXG4gKiBhdmFpbGFibGUgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBFY2xpcHNlIFB1YmxpYyBMaWNlbnNlIDIuMFxuICogd2hpY2ggaXMgYXZhaWxhYmxlIGF0IGh0dHBzOi8vd3d3LmVjbGlwc2Uub3JnL2xlZ2FsL2VwbC0yLjAvXG4gKlxuICogU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEVQTC0yLjBcbiAqL1xuXG5pbXBvcnQge0NvbXBvbmVudFR5cGV9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHthc3NlcnROb3RJblJlYWN0aXZlQ29udGV4dCwgQ29tcG9uZW50UmVmLCBjcmVhdGVDb21wb25lbnQsIEVudmlyb25tZW50SW5qZWN0b3IsIGluamVjdCwgSW5qZWN0b3IsIFByb3ZpZGVyLCBTaWduYWwsIHNpZ25hbCwgVmlld0NvbnRhaW5lclJlZn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge0xvZ2dlciwgTG9nZ2VyTmFtZXN9IGZyb20gJy4uL2xvZ2dpbmcnO1xuXG4vKipcbiAqIExpa2UgdGhlIEFuZ3VsYXIgQ0RLICdDb21wb25lbnRQb3J0YWwnIGJ1dCBkb2VzIG5vdCBkZXN0cm95IHRoZSBjb21wb25lbnQgb24gZGV0YWNoLlxuICpcbiAqIElNUE9SVEFOVDogSW4gb3JkZXIgZm9yIHRoZSBjb21wb25lbnQgdG8gaGF2ZSB0aGUgXCJjb3JyZWN0XCIgaW5qZWN0aW9uIGNvbnRleHQsIGNvbnN0cnVjdCBpdCB0aGUgdGltZSBhdHRhY2hpbmcgaXQgdG8gdGhlIEFuZ3VsYXIgY29tcG9uZW50IHRyZWUsXG4gKiBvciBieSBjYWxsaW5nIHtAbGluayBjcmVhdGVDb21wb25lbnRGcm9tSW5qZWN0aW9uQ29udGV4dH0uIFRoZSBcImNvcnJlY3RcIiBpbmplY3Rpb24gY29udGV4dCBpcyBjcnVjaWFsLCBmb3IgZXhhbXBsZSwgaWYgdGhlIHBvcnRhbCBpcyBkaXNwbGF5ZWRcbiAqIGluIGEgcm91dGVyIG91dGxldCwgc28gdGhhdCBjaGlsZCBvdXRsZXRzIGNhbiByZWdpc3RlciB3aXRoIHRoZWlyIGxvZ2ljYWwgcGFyZW50IG91dGxldC4gVGhlIEFuZ3VsYXIgcm91dGVyIHVzZXMgdGhlIGxvZ2ljYWwgb3V0bGV0IGhpZXJhcmNoeSB0b1xuICogcmVzb2x2ZSBhbmQgYWN0aXZhdGUgY2hpbGQgcm91dGVzLlxuICpcbiAqIEBzZWUgV2JDb21wb25lbnRQb3J0YWxcbiAqL1xuZXhwb3J0IGNsYXNzIFdiQ29tcG9uZW50UG9ydGFsPFQgPSBhbnk+IHtcblxuICBwcml2YXRlIF92aWV3Q29udGFpbmVyUmVmOiBWaWV3Q29udGFpbmVyUmVmIHwgbnVsbCB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBfY29tcG9uZW50UmVmOiBDb21wb25lbnRSZWY8VD4gfCBudWxsIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9sb2dnZXIgPSBpbmplY3QoTG9nZ2VyKTtcbiAgcHJpdmF0ZSBfYXR0YWNoZWQgPSBzaWduYWwoZmFsc2UpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2NvbXBvbmVudFR5cGU6IENvbXBvbmVudFR5cGU8VD4sIHByaXZhdGUgX29wdGlvbnM/OiBQb3J0YWxPcHRpb25zKSB7XG4gICAgLy8gRG8gbm90IGNvbnN0cnVjdCB0aGUgY29tcG9uZW50IGhlcmUgYnV0IHRoZSB0aW1lIGF0dGFjaGluZyBpdCB0byB0aGUgQW5ndWxhciBjb21wb25lbnQgdHJlZS4gU2VlIHRoZSBjb21tZW50IGFib3ZlLlxuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgdGhlIHBvcnRhbCdzIGNvbXBvbmVudCB1c2luZyBnaXZlbiBpbmplY3Rpb24gY29udGV4dC5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlQ29tcG9uZW50KGVsZW1lbnRJbmplY3RvcjogSW5qZWN0b3IpOiBDb21wb25lbnRSZWY8VD4ge1xuICAgIGNvbnN0IGNvbXBvbmVudFJlZiA9IGNyZWF0ZUNvbXBvbmVudCh0aGlzLl9jb21wb25lbnRUeXBlLCB7XG4gICAgICBlbGVtZW50SW5qZWN0b3I6IEluamVjdG9yLmNyZWF0ZSh7XG4gICAgICAgIG5hbWU6ICdXYkNvbXBvbmVudFBvcnRhbEluamVjdG9yJyxcbiAgICAgICAgcGFyZW50OiBlbGVtZW50SW5qZWN0b3IsXG4gICAgICAgIHByb3ZpZGVyczogdGhpcy5fb3B0aW9ucz8ucHJvdmlkZXJzIHx8IFtdLFxuICAgICAgfSksXG4gICAgICBlbnZpcm9ubWVudEluamVjdG9yOiBlbGVtZW50SW5qZWN0b3IuZ2V0KEVudmlyb25tZW50SW5qZWN0b3IpLFxuICAgIH0pO1xuICAgIGNvbXBvbmVudFJlZi5vbkRlc3Ryb3koKCkgPT4gdGhpcy5vbkRlc3Ryb3koKSk7XG4gICAgcmV0dXJuIGNvbXBvbmVudFJlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdHJ1Y3RzIHRoZSBwb3J0YWwncyBjb21wb25lbnQgdXNpbmcgdGhlIGdpdmVuIGluamVjdGlvbiBjb250ZXh0LlxuICAgKi9cbiAgcHVibGljIGNyZWF0ZUNvbXBvbmVudEZyb21JbmplY3Rpb25Db250ZXh0KGluamVjdGlvbkNvbnRleHQ6IEluamVjdG9yKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNDb25zdHJ1Y3RlZCkge1xuICAgICAgdGhyb3cgRXJyb3IoYFtQb3J0YWxDb25zdHJ1Y3RFcnJvcl0gQ29tcG9uZW50IGFscmVhZHkgY29uc3RydWN0ZWQuIFtjb21wb25lbnQ9JHt0aGlzLl9jb21wb25lbnRUeXBlfV1gKTtcbiAgICB9XG4gICAgdGhpcy5fY29tcG9uZW50UmVmID0gdGhpcy5jcmVhdGVDb21wb25lbnQoaW5qZWN0aW9uQ29udGV4dCk7XG4gICAgLy8gVHJpZ2dlciBjaGFuZ2UgZGV0ZWN0aW9uIHRvIGNvbXBsZXRlIHRoZSBpbml0aWFsaXphdGlvbiBvZiB0aGUgY29tcG9uZW50LCBuZWNlc3NhcnkgZm9yIGNvbXBvbmVudHMgZGV0YWNoZWQgZnJvbSB0aGUgQW5ndWxhciBjb21wb25lbnQgdHJlZS5cbiAgICB0aGlzLl9jb21wb25lbnRSZWYuY2hhbmdlRGV0ZWN0b3JSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIHRoaXMgcG9ydGFsIHRvIHRoZSBnaXZlbiB7QGxpbmsgVmlld0NvbnRhaW5lclJlZn0gYWNjb3JkaW5nIHRvIHRoZSBmb2xsb3dpbmcgcnVsZXM6XG4gICAqXG4gICAqIC0gSWYgdGhlIGNvbXBvbmVudCBpcyBub3QgeWV0IGNvbnN0cnVjdGVkLCBjb25zdHJ1Y3RzIGl0IGJhc2VkIG9uIHRoZSBnaXZlbiB2aWV3IGNvbnRhaW5lcidzIGluamVjdGlvbiBjb250ZXh0LlxuICAgKiAtIElmIGFscmVhZHkgYXR0YWNoZWQgdG8gdGhlIGdpdmVuIHZpZXcgY29udGFpbmVyLCBkb2VzIG5vdGhpbmcuXG4gICAqIC0gSWYgYWxyZWFkeSBhdHRhY2hlZCB0byBhIGRpZmZlcmVudCB2aWV3IGNvbnRhaW5lciwgZGV0YWNoZXMgaXQgZmlyc3QuXG4gICAqL1xuICBwdWJsaWMgYXR0YWNoKHZpZXdDb250YWluZXJSZWY6IFZpZXdDb250YWluZXJSZWYpOiB2b2lkIHtcbiAgICBhc3NlcnROb3RJblJlYWN0aXZlQ29udGV4dCh0aGlzLmF0dGFjaCk7XG4gICAgaWYgKHRoaXMuaXNBdHRhY2hlZFRvKHZpZXdDb250YWluZXJSZWYpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmF0dGFjaGVkKCkpIHtcbiAgICAgIHRoaXMuZGV0YWNoKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZiA9IHZpZXdDb250YWluZXJSZWY7XG4gICAgdGhpcy5fY29tcG9uZW50UmVmID0gdGhpcy5fY29tcG9uZW50UmVmIHx8IHRoaXMuY3JlYXRlQ29tcG9uZW50KHRoaXMuX3ZpZXdDb250YWluZXJSZWYuaW5qZWN0b3IpO1xuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygoKSA9PiAnQXR0YWNoaW5nIHBvcnRhbCcsIExvZ2dlck5hbWVzLkxJRkVDWUNMRSwgdGhpcy5fY29tcG9uZW50UmVmKTtcblxuICAgIHRoaXMuX2NvbXBvbmVudFJlZi5jaGFuZ2VEZXRlY3RvclJlZi5yZWF0dGFjaCgpO1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYuaW5zZXJ0KHRoaXMuX2NvbXBvbmVudFJlZi5ob3N0Vmlldyk7XG4gICAgdGhpcy5fYXR0YWNoZWQuc2V0KHRydWUpO1xuICAgICh0aGlzLl9jb21wb25lbnRSZWYuaW5zdGFuY2UgYXMgT25BdHRhY2gpPy5vbkF0dGFjaCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIERldGFjaGVzIHRoaXMgcG9ydGFsIGZyb20gaXRzIHZpZXcgY29udGFpbmVyIHdpdGhvdXQgZGVzdHJveWluZyBpdC4gRG9lcyBub3RoaW5nIGlmIG5vdCBhdHRhY2hlZC5cbiAgICpcbiAgICogVGhlIHBvcnRhbCBpcyByZW1vdmVkIGZyb20gdGhlIERPTSBhbmQgaXRzIGNoYW5nZSBkZXRlY3RvciBkZXRhY2hlZCBmcm9tIHRoZSBBbmd1bGFyIGNoYW5nZSBkZXRlY3RvciB0cmVlLFxuICAgKiBzbyBpdCB3aWxsIG5vdCBiZSBjaGVja2VkIGZvciBjaGFuZ2VzIHVudGlsIGl0IGlzIHJlYXR0YWNoZWQuXG4gICAqL1xuICBwdWJsaWMgZGV0YWNoKCk6IHZvaWQge1xuICAgIGFzc2VydE5vdEluUmVhY3RpdmVDb250ZXh0KHRoaXMuZGV0YWNoKTtcbiAgICBpZiAoIXRoaXMuYXR0YWNoZWQoKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xvZ2dlci5kZWJ1ZygoKSA9PiAnRGV0YWNoaW5nIHBvcnRhbCcsIExvZ2dlck5hbWVzLkxJRkVDWUNMRSwgdGhpcy5fY29tcG9uZW50UmVmKTtcbiAgICAodGhpcy5fY29tcG9uZW50UmVmIS5pbnN0YW5jZSBhcyBPbkRldGFjaCk/Lm9uRGV0YWNoKCk7XG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl92aWV3Q29udGFpbmVyUmVmIS5pbmRleE9mKHRoaXMuX2NvbXBvbmVudFJlZiEuaG9zdFZpZXcpO1xuICAgIHRoaXMuX3ZpZXdDb250YWluZXJSZWYhLmRldGFjaChpbmRleCk7XG4gICAgdGhpcy5fY29tcG9uZW50UmVmIS5jaGFuZ2VEZXRlY3RvclJlZi5kZXRhY2goKTtcbiAgICB0aGlzLl9hdHRhY2hlZC5zZXQoZmFsc2UpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc0NvbnN0cnVjdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMuX2NvbXBvbmVudFJlZjtcbiAgfVxuXG4gIHB1YmxpYyBpc0F0dGFjaGVkVG8odmlld0NvbnRhaW5lclJlZjogVmlld0NvbnRhaW5lclJlZik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl92aWV3Q29udGFpbmVyUmVmID09PSB2aWV3Q29udGFpbmVyUmVmICYmIHRoaXMuYXR0YWNoZWQoKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgaXNEZXN0cm95ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX2NvbXBvbmVudFJlZiA9PT0gbnVsbDtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgY29tcG9uZW50UmVmKCk6IENvbXBvbmVudFJlZjxUPiB7XG4gICAgaWYgKHRoaXMuX2NvbXBvbmVudFJlZiA9PT0gbnVsbCkge1xuICAgICAgdGhyb3cgRXJyb3IoJ1tOdWxsUG9ydGFsRXJyb3JdIFBvcnRhbCBkZXN0cm95ZWQuJyk7XG4gICAgfVxuICAgIGlmICh0aGlzLl9jb21wb25lbnRSZWYgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgRXJyb3IoJ1tOdWxsUG9ydGFsRXJyb3JdIENvbXBvbmVudCBub3QgY29uc3RydWN0ZWQgeWV0LicpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5fY29tcG9uZW50UmVmO1xuICB9XG5cbiAgcHVibGljIGdldCBhdHRhY2hlZCgpOiBTaWduYWw8Ym9vbGVhbj4ge1xuICAgIHJldHVybiB0aGlzLl9hdHRhY2hlZDtcbiAgfVxuXG4gIHByaXZhdGUgb25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuX2NvbXBvbmVudFJlZiA9IG51bGw7XG4gICAgdGhpcy5fdmlld0NvbnRhaW5lclJlZiA9IG51bGw7XG4gICAgdGhpcy5fYXR0YWNoZWQuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZXN0cm95cyB0aGUgY29tcG9uZW50IGluc3RhbmNlIGFuZCBhbGwgdGhlIGRhdGEgc3RydWN0dXJlcyBhc3NvY2lhdGVkIHdpdGggaXQuXG4gICAqL1xuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLl9jb21wb25lbnRSZWY/LmRlc3Ryb3koKTtcbiAgfVxufVxuXG4vKipcbiAqIENvbnRyb2xzIGluc3RhbnRpYXRpb24gb2YgdGhlIGNvbXBvbmVudC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBQb3J0YWxPcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3ZpZGVycyByZWdpc3RlcmVkIHdpdGggdGhlIGluamVjdG9yIGZvciB0aGUgaW5zdGFudGlhdGlvbiBvZiB0aGUgY29tcG9uZW50LlxuICAgKi9cbiAgcHJvdmlkZXJzPzogUHJvdmlkZXJbXTtcbn1cblxuLyoqXG4gKiBMaWZlY3ljbGUgaG9vayBmb3IgY29tcG9uZW50IHJlbmRlcmVkIGJ5IHtAbGluayBXYkNvbXBvbmVudFBvcnRhbH0gd2hlbiBhdHRhY2hpbmcgdG8gdGhlIERPTS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBPbkF0dGFjaCB7XG5cbiAgLyoqXG4gICAqIE1ldGhvZCBpbnZva2VkIGFmdGVyIGF0dGFjaGVkIHRoaXMgY29tcG9uZW50IHRvIHRoZSBET00uXG4gICAqL1xuICBvbkF0dGFjaCgpOiB2b2lkO1xufVxuXG4vKipcbiAqIExpZmVjeWNsZSBob29rIGZvciBjb21wb25lbnQgcmVuZGVyZWQgYnkge0BsaW5rIFdiQ29tcG9uZW50UG9ydGFsfSB3aGVuIGRldGFjaGluZyBmcm9tIHRoZSBET00uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT25EZXRhY2gge1xuXG4gIC8qKlxuICAgKiBNZXRob2QgaW52b2tlZCBiZWZvcmUgZGV0YWNoaW5nIHRoaXMgY29tcG9uZW50IGZyb20gdGhlIERPTS5cbiAgICovXG4gIG9uRGV0YWNoKCk6IHZvaWQ7XG59XG4iXX0=
|