@angular/cdk 19.0.0-next.1 → 19.0.0-next.2
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/a11y/index.d.ts +5 -1
- package/fesm2022/a11y.mjs +21 -11
- package/fesm2022/a11y.mjs.map +1 -1
- package/fesm2022/cdk.mjs +1 -1
- package/fesm2022/cdk.mjs.map +1 -1
- package/fesm2022/drag-drop.mjs +2 -1
- package/fesm2022/drag-drop.mjs.map +1 -1
- package/fesm2022/overlay.mjs +20 -1
- package/fesm2022/overlay.mjs.map +1 -1
- package/fesm2022/private.mjs +9 -7
- package/fesm2022/private.mjs.map +1 -1
- package/fesm2022/text-field.mjs +17 -2
- package/fesm2022/text-field.mjs.map +1 -1
- package/fesm2022/tree.mjs +13 -7
- package/fesm2022/tree.mjs.map +1 -1
- package/overlay/_index.scss +15 -13
- package/overlay/index.d.ts +5 -0
- package/overlay-prebuilt.css +1 -1
- package/package.json +1 -57
- package/private/index.d.ts +1 -0
- package/schematics/ng-add/index.js +1 -1
- package/schematics/ng-add/index.mjs +1 -1
- package/text-field/index.d.ts +1 -0
- package/tree/index.d.ts +3 -1
- package/esm2022/a11y/a11y-module.mjs +0 -31
- package/esm2022/a11y/a11y_public_index.mjs +0 -5
- package/esm2022/a11y/aria-describer/aria-describer.mjs +0 -232
- package/esm2022/a11y/aria-describer/aria-reference.mjs +0 -47
- package/esm2022/a11y/fake-event-detection.mjs +0 -29
- package/esm2022/a11y/focus-monitor/focus-monitor.mjs +0 -468
- package/esm2022/a11y/focus-trap/configurable-focus-trap-config.mjs +0 -9
- package/esm2022/a11y/focus-trap/configurable-focus-trap-factory.mjs +0 -54
- package/esm2022/a11y/focus-trap/configurable-focus-trap.mjs +0 -51
- package/esm2022/a11y/focus-trap/event-listener-inert-strategy.mjs +0 -61
- package/esm2022/a11y/focus-trap/focus-trap-inert-strategy.mjs +0 -11
- package/esm2022/a11y/focus-trap/focus-trap-manager.mjs +0 -53
- package/esm2022/a11y/focus-trap/focus-trap.mjs +0 -396
- package/esm2022/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +0 -116
- package/esm2022/a11y/index.mjs +0 -9
- package/esm2022/a11y/input-modality/input-modality-detector.mjs +0 -176
- package/esm2022/a11y/interactivity-checker/interactivity-checker.mjs +0 -238
- package/esm2022/a11y/key-manager/activedescendant-key-manager.mjs +0 -20
- package/esm2022/a11y/key-manager/focus-key-manager.mjs +0 -29
- package/esm2022/a11y/key-manager/list-key-manager.mjs +0 -357
- package/esm2022/a11y/key-manager/noop-tree-key-manager.mjs +0 -94
- package/esm2022/a11y/key-manager/tree-key-manager-strategy.mjs +0 -9
- package/esm2022/a11y/key-manager/tree-key-manager.mjs +0 -345
- package/esm2022/a11y/key-manager/typeahead.mjs +0 -91
- package/esm2022/a11y/live-announcer/live-announcer-tokens.mjs +0 -19
- package/esm2022/a11y/live-announcer/live-announcer.mjs +0 -210
- package/esm2022/a11y/public-api.mjs +0 -30
- package/esm2022/accordion/accordion-item.mjs +0 -162
- package/esm2022/accordion/accordion-module.mjs +0 -24
- package/esm2022/accordion/accordion.mjs +0 -65
- package/esm2022/accordion/accordion_public_index.mjs +0 -5
- package/esm2022/accordion/index.mjs +0 -9
- package/esm2022/accordion/public-api.mjs +0 -11
- package/esm2022/bidi/bidi-module.mjs +0 -23
- package/esm2022/bidi/bidi_public_index.mjs +0 -5
- package/esm2022/bidi/dir-document-token.mjs +0 -33
- package/esm2022/bidi/dir.mjs +0 -70
- package/esm2022/bidi/directionality.mjs +0 -52
- package/esm2022/bidi/index.mjs +0 -9
- package/esm2022/bidi/public-api.mjs +0 -12
- package/esm2022/clipboard/clipboard-module.mjs +0 -23
- package/esm2022/clipboard/clipboard.mjs +0 -53
- package/esm2022/clipboard/clipboard_public_index.mjs +0 -5
- package/esm2022/clipboard/copy-to-clipboard.mjs +0 -100
- package/esm2022/clipboard/index.mjs +0 -9
- package/esm2022/clipboard/pending-copy.mjs +0 -71
- package/esm2022/clipboard/public-api.mjs +0 -12
- package/esm2022/coercion/array.mjs +0 -11
- package/esm2022/coercion/boolean-property.mjs +0 -12
- package/esm2022/coercion/css-pixel-value.mjs +0 -15
- package/esm2022/coercion/element.mjs +0 -16
- package/esm2022/coercion/index.mjs +0 -9
- package/esm2022/coercion/number-property.mjs +0 -24
- package/esm2022/coercion/private/index.mjs +0 -9
- package/esm2022/coercion/private/observable.mjs +0 -19
- package/esm2022/coercion/private/private_public_index.mjs +0 -5
- package/esm2022/coercion/public-api.mjs +0 -14
- package/esm2022/coercion/string-array.mjs +0 -38
- package/esm2022/collections/array-data-source.mjs +0 -21
- package/esm2022/collections/collection-viewer.mjs +0 -9
- package/esm2022/collections/collections_public_index.mjs +0 -5
- package/esm2022/collections/data-source.mjs +0 -19
- package/esm2022/collections/dispose-view-repeater-strategy.mjs +0 -48
- package/esm2022/collections/index.mjs +0 -9
- package/esm2022/collections/public-api.mjs +0 -17
- package/esm2022/collections/recycle-view-repeater-strategy.mjs +0 -129
- package/esm2022/collections/selection-model.mjs +0 -225
- package/esm2022/collections/tree-adapter.mjs +0 -9
- package/esm2022/collections/unique-selection-dispatcher.mjs +0 -55
- package/esm2022/collections/view-repeater.mjs +0 -26
- package/esm2022/dialog/dialog-config.mjs +0 -70
- package/esm2022/dialog/dialog-container.mjs +0 -308
- package/esm2022/dialog/dialog-injectors.mjs +0 -40
- package/esm2022/dialog/dialog-module.mjs +0 -40
- package/esm2022/dialog/dialog-ref.mjs +0 -85
- package/esm2022/dialog/dialog.mjs +0 -303
- package/esm2022/dialog/dialog_public_index.mjs +0 -5
- package/esm2022/dialog/index.mjs +0 -9
- package/esm2022/dialog/public-api.mjs +0 -14
- package/esm2022/drag-drop/directives/assertions.mjs +0 -18
- package/esm2022/drag-drop/directives/config.mjs +0 -14
- package/esm2022/drag-drop/directives/drag-handle.mjs +0 -68
- package/esm2022/drag-drop/directives/drag-placeholder.mjs +0 -43
- package/esm2022/drag-drop/directives/drag-preview.mjs +0 -48
- package/esm2022/drag-drop/directives/drag.mjs +0 -520
- package/esm2022/drag-drop/directives/drop-list-group.mjs +0 -47
- package/esm2022/drag-drop/directives/drop-list.mjs +0 -352
- package/esm2022/drag-drop/dom/clone-node.mjs +0 -65
- package/esm2022/drag-drop/dom/dom-rect.mjs +0 -64
- package/esm2022/drag-drop/dom/parent-position-tracker.mjs +0 -76
- package/esm2022/drag-drop/dom/root-node.mjs +0 -21
- package/esm2022/drag-drop/dom/styling.mjs +0 -89
- package/esm2022/drag-drop/dom/transition-duration.mjs +0 -36
- package/esm2022/drag-drop/drag-drop-module.mjs +0 -49
- package/esm2022/drag-drop/drag-drop-registry.mjs +0 -248
- package/esm2022/drag-drop/drag-drop.mjs +0 -57
- package/esm2022/drag-drop/drag-drop_public_index.mjs +0 -5
- package/esm2022/drag-drop/drag-events.mjs +0 -9
- package/esm2022/drag-drop/drag-parent.mjs +0 -16
- package/esm2022/drag-drop/drag-ref.mjs +0 -1097
- package/esm2022/drag-drop/drag-utils.mjs +0 -60
- package/esm2022/drag-drop/drop-list-ref.mjs +0 -672
- package/esm2022/drag-drop/index.mjs +0 -9
- package/esm2022/drag-drop/preview-ref.mjs +0 -125
- package/esm2022/drag-drop/public-api.mjs +0 -23
- package/esm2022/drag-drop/sorting/drop-list-sort-strategy.mjs +0 -9
- package/esm2022/drag-drop/sorting/mixed-sort-strategy.mjs +0 -246
- package/esm2022/drag-drop/sorting/single-axis-sort-strategy.mjs +0 -343
- package/esm2022/index.mjs +0 -9
- package/esm2022/keycodes/index.mjs +0 -9
- package/esm2022/keycodes/keycodes.mjs +0 -127
- package/esm2022/keycodes/keycodes_public_index.mjs +0 -5
- package/esm2022/keycodes/modifiers.mjs +0 -18
- package/esm2022/keycodes/public-api.mjs +0 -10
- package/esm2022/layout/breakpoints-observer.mjs +0 -105
- package/esm2022/layout/breakpoints.mjs +0 -29
- package/esm2022/layout/index.mjs +0 -9
- package/esm2022/layout/layout-module.mjs +0 -19
- package/esm2022/layout/layout_public_index.mjs +0 -5
- package/esm2022/layout/media-matcher.mjs +0 -94
- package/esm2022/layout/public-api.mjs +0 -12
- package/esm2022/listbox/index.mjs +0 -9
- package/esm2022/listbox/listbox-module.mjs +0 -24
- package/esm2022/listbox/listbox.mjs +0 -888
- package/esm2022/listbox/listbox_public_index.mjs +0 -5
- package/esm2022/listbox/public-api.mjs +0 -10
- package/esm2022/menu/context-menu-trigger.mjs +0 -221
- package/esm2022/menu/event-detection.mjs +0 -28
- package/esm2022/menu/index.mjs +0 -9
- package/esm2022/menu/menu-aim.mjs +0 -204
- package/esm2022/menu/menu-bar.mjs +0 -134
- package/esm2022/menu/menu-base.mjs +0 -192
- package/esm2022/menu/menu-errors.mjs +0 -22
- package/esm2022/menu/menu-group.mjs +0 -31
- package/esm2022/menu/menu-interface.mjs +0 -11
- package/esm2022/menu/menu-item-checkbox.mjs +0 -50
- package/esm2022/menu/menu-item-radio.mjs +0 -72
- package/esm2022/menu/menu-item-selectable.mjs +0 -36
- package/esm2022/menu/menu-item.mjs +0 -270
- package/esm2022/menu/menu-module.mjs +0 -60
- package/esm2022/menu/menu-stack.mjs +0 -163
- package/esm2022/menu/menu-trigger-base.mjs +0 -119
- package/esm2022/menu/menu-trigger.mjs +0 -313
- package/esm2022/menu/menu.mjs +0 -135
- package/esm2022/menu/menu_public_index.mjs +0 -5
- package/esm2022/menu/pointer-focus-tracker.mjs +0 -51
- package/esm2022/menu/public-api.mjs +0 -24
- package/esm2022/observers/index.mjs +0 -9
- package/esm2022/observers/observe-content.mjs +0 -216
- package/esm2022/observers/observers_public_index.mjs +0 -5
- package/esm2022/observers/private/index.mjs +0 -9
- package/esm2022/observers/private/private_public_index.mjs +0 -5
- package/esm2022/observers/private/shared-resize-observer.mjs +0 -125
- package/esm2022/observers/public-api.mjs +0 -9
- package/esm2022/overlay/dispatchers/base-overlay-dispatcher.mjs +0 -52
- package/esm2022/overlay/dispatchers/index.mjs +0 -10
- package/esm2022/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +0 -81
- package/esm2022/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +0 -151
- package/esm2022/overlay/fullscreen-overlay-container.mjs +0 -94
- package/esm2022/overlay/index.mjs +0 -9
- package/esm2022/overlay/overlay-config.mjs +0 -45
- package/esm2022/overlay/overlay-container.mjs +0 -81
- package/esm2022/overlay/overlay-directives.mjs +0 -432
- package/esm2022/overlay/overlay-module.mjs +0 -28
- package/esm2022/overlay/overlay-ref.mjs +0 -437
- package/esm2022/overlay/overlay.mjs +0 -126
- package/esm2022/overlay/overlay_public_index.mjs +0 -5
- package/esm2022/overlay/position/connected-position.mjs +0 -88
- package/esm2022/overlay/position/flexible-connected-position-strategy.mjs +0 -1002
- package/esm2022/overlay/position/global-position-strategy.mjs +0 -237
- package/esm2022/overlay/position/overlay-position-builder.mjs +0 -50
- package/esm2022/overlay/position/position-strategy.mjs +0 -9
- package/esm2022/overlay/position/scroll-clip.mjs +0 -40
- package/esm2022/overlay/public-api.mjs +0 -22
- package/esm2022/overlay/scroll/block-scroll-strategy.mjs +0 -80
- package/esm2022/overlay/scroll/close-scroll-strategy.mjs +0 -65
- package/esm2022/overlay/scroll/index.mjs +0 -14
- package/esm2022/overlay/scroll/noop-scroll-strategy.mjs +0 -17
- package/esm2022/overlay/scroll/reposition-scroll-strategy.mjs +0 -61
- package/esm2022/overlay/scroll/scroll-strategy-options.mjs +0 -55
- package/esm2022/overlay/scroll/scroll-strategy.mjs +0 -14
- package/esm2022/platform/features/input-types.mjs +0 -59
- package/esm2022/platform/features/passive-listeners.mjs +0 -36
- package/esm2022/platform/features/scrolling.mjs +0 -104
- package/esm2022/platform/features/shadow-dom.mjs +0 -54
- package/esm2022/platform/features/test-environment.mjs +0 -24
- package/esm2022/platform/index.mjs +0 -9
- package/esm2022/platform/platform-module.mjs +0 -19
- package/esm2022/platform/platform.mjs +0 -82
- package/esm2022/platform/platform_public_index.mjs +0 -5
- package/esm2022/platform/public-api.mjs +0 -15
- package/esm2022/portal/dom-portal-outlet.mjs +0 -158
- package/esm2022/portal/index.mjs +0 -9
- package/esm2022/portal/portal-directives.mjs +0 -251
- package/esm2022/portal/portal-errors.mjs +0 -51
- package/esm2022/portal/portal-injector.mjs +0 -28
- package/esm2022/portal/portal.mjs +0 -189
- package/esm2022/portal/portal_public_index.mjs +0 -5
- package/esm2022/portal/public-api.mjs +0 -12
- package/esm2022/private/index.mjs +0 -9
- package/esm2022/private/private_public_index.mjs +0 -5
- package/esm2022/private/public-api.mjs +0 -9
- package/esm2022/private/style-loader.mjs +0 -50
- package/esm2022/public-api.mjs +0 -9
- package/esm2022/scrolling/fixed-size-virtual-scroll.mjs +0 -218
- package/esm2022/scrolling/index.mjs +0 -9
- package/esm2022/scrolling/public-api.mjs +0 -20
- package/esm2022/scrolling/scroll-dispatcher.mjs +0 -163
- package/esm2022/scrolling/scrollable.mjs +0 -177
- package/esm2022/scrolling/scrolling-module.mjs +0 -69
- package/esm2022/scrolling/scrolling_public_index.mjs +0 -5
- package/esm2022/scrolling/viewport-ruler.mjs +0 -146
- package/esm2022/scrolling/virtual-for-of.mjs +0 -299
- package/esm2022/scrolling/virtual-scroll-repeater.mjs +0 -9
- package/esm2022/scrolling/virtual-scroll-strategy.mjs +0 -11
- package/esm2022/scrolling/virtual-scroll-viewport.mjs +0 -445
- package/esm2022/scrolling/virtual-scrollable-element.mjs +0 -42
- package/esm2022/scrolling/virtual-scrollable-window.mjs +0 -41
- package/esm2022/scrolling/virtual-scrollable.mjs +0 -40
- package/esm2022/stepper/index.mjs +0 -9
- package/esm2022/stepper/public-api.mjs +0 -13
- package/esm2022/stepper/step-header.mjs +0 -31
- package/esm2022/stepper/step-label.mjs +0 -24
- package/esm2022/stepper/stepper-button.mjs +0 -58
- package/esm2022/stepper/stepper-module.mjs +0 -41
- package/esm2022/stepper/stepper.mjs +0 -452
- package/esm2022/stepper/stepper_public_index.mjs +0 -5
- package/esm2022/table/can-stick.mjs +0 -46
- package/esm2022/table/cell.mjs +0 -245
- package/esm2022/table/coalesced-style-scheduler.mjs +0 -79
- package/esm2022/table/index.mjs +0 -9
- package/esm2022/table/public-api.mjs +0 -20
- package/esm2022/table/row.mjs +0 -317
- package/esm2022/table/sticky-position-listener.mjs +0 -11
- package/esm2022/table/sticky-styler.mjs +0 -347
- package/esm2022/table/table-errors.mjs +0 -67
- package/esm2022/table/table-module.mjs +0 -93
- package/esm2022/table/table.mjs +0 -1148
- package/esm2022/table/table_public_index.mjs +0 -5
- package/esm2022/table/text-column.mjs +0 -154
- package/esm2022/table/tokens.mjs +0 -16
- package/esm2022/testing/change-detection.mjs +0 -102
- package/esm2022/testing/component-harness.mjs +0 -328
- package/esm2022/testing/element-dimensions.mjs +0 -9
- package/esm2022/testing/harness-environment.mjs +0 -220
- package/esm2022/testing/index.mjs +0 -9
- package/esm2022/testing/public-api.mjs +0 -15
- package/esm2022/testing/selenium-webdriver/index.mjs +0 -9
- package/esm2022/testing/selenium-webdriver/public-api.mjs +0 -10
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-element.mjs +0 -216
- package/esm2022/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +0 -88
- package/esm2022/testing/selenium-webdriver/selenium-webdriver-keys.mjs +0 -64
- package/esm2022/testing/test-element-errors.mjs +0 -15
- package/esm2022/testing/test-element.mjs +0 -49
- package/esm2022/testing/testbed/fake-events/dispatch-events.mjs +0 -53
- package/esm2022/testing/testbed/fake-events/element-focus.mjs +0 -39
- package/esm2022/testing/testbed/fake-events/event-objects.mjs +0 -127
- package/esm2022/testing/testbed/fake-events/index.mjs +0 -14
- package/esm2022/testing/testbed/fake-events/type-in-element.mjs +0 -97
- package/esm2022/testing/testbed/index.mjs +0 -9
- package/esm2022/testing/testbed/public-api.mjs +0 -10
- package/esm2022/testing/testbed/task-state-zone-interceptor.mjs +0 -83
- package/esm2022/testing/testbed/testbed-harness-environment.mjs +0 -165
- package/esm2022/testing/testbed/unit-test-element.mjs +0 -258
- package/esm2022/testing/text-filtering.mjs +0 -21
- package/esm2022/text-field/autofill.mjs +0 -114
- package/esm2022/text-field/autosize.mjs +0 -309
- package/esm2022/text-field/index.mjs +0 -9
- package/esm2022/text-field/public-api.mjs +0 -11
- package/esm2022/text-field/text-field-module.mjs +0 -24
- package/esm2022/text-field/text-field_public_index.mjs +0 -5
- package/esm2022/tree/control/base-tree-control.mjs +0 -62
- package/esm2022/tree/control/flat-tree-control.mjs +0 -57
- package/esm2022/tree/control/nested-tree-control.mjs +0 -67
- package/esm2022/tree/control/tree-control.mjs +0 -2
- package/esm2022/tree/index.mjs +0 -9
- package/esm2022/tree/nested-node.mjs +0 -103
- package/esm2022/tree/node.mjs +0 -36
- package/esm2022/tree/outlet.mjs +0 -40
- package/esm2022/tree/padding.mjs +0 -129
- package/esm2022/tree/public-api.mjs +0 -20
- package/esm2022/tree/toggle.mjs +0 -51
- package/esm2022/tree/tree-errors.mjs +0 -44
- package/esm2022/tree/tree-module.mjs +0 -49
- package/esm2022/tree/tree.mjs +0 -1123
- package/esm2022/tree/tree_public_index.mjs +0 -5
- package/esm2022/version.mjs +0 -11
|
@@ -1,328 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
import { parallel } from './change-detection';
|
|
9
|
-
/**
|
|
10
|
-
* Base class for component harnesses that all component harness authors should extend. This base
|
|
11
|
-
* component harness provides the basic ability to locate element and sub-component harness. It
|
|
12
|
-
* should be inherited when defining user's own harness.
|
|
13
|
-
*/
|
|
14
|
-
export class ComponentHarness {
|
|
15
|
-
constructor(locatorFactory) {
|
|
16
|
-
this.locatorFactory = locatorFactory;
|
|
17
|
-
}
|
|
18
|
-
/** Gets a `Promise` for the `TestElement` representing the host element of the component. */
|
|
19
|
-
async host() {
|
|
20
|
-
return this.locatorFactory.rootElement;
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* Gets a `LocatorFactory` for the document root element. This factory can be used to create
|
|
24
|
-
* locators for elements that a component creates outside of its own root element. (e.g. by
|
|
25
|
-
* appending to document.body).
|
|
26
|
-
*/
|
|
27
|
-
documentRootLocatorFactory() {
|
|
28
|
-
return this.locatorFactory.documentRootLocatorFactory();
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance
|
|
32
|
-
* or element under the host element of this `ComponentHarness`.
|
|
33
|
-
* @param queries A list of queries specifying which harnesses and elements to search for:
|
|
34
|
-
* - A `string` searches for elements matching the CSS selector specified by the string.
|
|
35
|
-
* - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the
|
|
36
|
-
* given class.
|
|
37
|
-
* - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given
|
|
38
|
-
* predicate.
|
|
39
|
-
* @return An asynchronous locator function that searches for and returns a `Promise` for the
|
|
40
|
-
* first element or harness matching the given search criteria. Matches are ordered first by
|
|
41
|
-
* order in the DOM, and second by order in the queries list. If no matches are found, the
|
|
42
|
-
* `Promise` rejects. The type that the `Promise` resolves to is a union of all result types for
|
|
43
|
-
* each query.
|
|
44
|
-
*
|
|
45
|
-
* e.g. Given the following DOM: `<div id="d1" /><div id="d2" />`, and assuming
|
|
46
|
-
* `DivHarness.hostSelector === 'div'`:
|
|
47
|
-
* - `await ch.locatorFor(DivHarness, 'div')()` gets a `DivHarness` instance for `#d1`
|
|
48
|
-
* - `await ch.locatorFor('div', DivHarness)()` gets a `TestElement` instance for `#d1`
|
|
49
|
-
* - `await ch.locatorFor('span')()` throws because the `Promise` rejects.
|
|
50
|
-
*/
|
|
51
|
-
locatorFor(...queries) {
|
|
52
|
-
return this.locatorFactory.locatorFor(...queries);
|
|
53
|
-
}
|
|
54
|
-
/**
|
|
55
|
-
* Creates an asynchronous locator function that can be used to find a `ComponentHarness` instance
|
|
56
|
-
* or element under the host element of this `ComponentHarness`.
|
|
57
|
-
* @param queries A list of queries specifying which harnesses and elements to search for:
|
|
58
|
-
* - A `string` searches for elements matching the CSS selector specified by the string.
|
|
59
|
-
* - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the
|
|
60
|
-
* given class.
|
|
61
|
-
* - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given
|
|
62
|
-
* predicate.
|
|
63
|
-
* @return An asynchronous locator function that searches for and returns a `Promise` for the
|
|
64
|
-
* first element or harness matching the given search criteria. Matches are ordered first by
|
|
65
|
-
* order in the DOM, and second by order in the queries list. If no matches are found, the
|
|
66
|
-
* `Promise` is resolved with `null`. The type that the `Promise` resolves to is a union of all
|
|
67
|
-
* result types for each query or null.
|
|
68
|
-
*
|
|
69
|
-
* e.g. Given the following DOM: `<div id="d1" /><div id="d2" />`, and assuming
|
|
70
|
-
* `DivHarness.hostSelector === 'div'`:
|
|
71
|
-
* - `await ch.locatorForOptional(DivHarness, 'div')()` gets a `DivHarness` instance for `#d1`
|
|
72
|
-
* - `await ch.locatorForOptional('div', DivHarness)()` gets a `TestElement` instance for `#d1`
|
|
73
|
-
* - `await ch.locatorForOptional('span')()` gets `null`.
|
|
74
|
-
*/
|
|
75
|
-
locatorForOptional(...queries) {
|
|
76
|
-
return this.locatorFactory.locatorForOptional(...queries);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Creates an asynchronous locator function that can be used to find `ComponentHarness` instances
|
|
80
|
-
* or elements under the host element of this `ComponentHarness`.
|
|
81
|
-
* @param queries A list of queries specifying which harnesses and elements to search for:
|
|
82
|
-
* - A `string` searches for elements matching the CSS selector specified by the string.
|
|
83
|
-
* - A `ComponentHarness` constructor searches for `ComponentHarness` instances matching the
|
|
84
|
-
* given class.
|
|
85
|
-
* - A `HarnessPredicate` searches for `ComponentHarness` instances matching the given
|
|
86
|
-
* predicate.
|
|
87
|
-
* @return An asynchronous locator function that searches for and returns a `Promise` for all
|
|
88
|
-
* elements and harnesses matching the given search criteria. Matches are ordered first by
|
|
89
|
-
* order in the DOM, and second by order in the queries list. If an element matches more than
|
|
90
|
-
* one `ComponentHarness` class, the locator gets an instance of each for the same element. If
|
|
91
|
-
* an element matches multiple `string` selectors, only one `TestElement` instance is returned
|
|
92
|
-
* for that element. The type that the `Promise` resolves to is an array where each element is
|
|
93
|
-
* the union of all result types for each query.
|
|
94
|
-
*
|
|
95
|
-
* e.g. Given the following DOM: `<div id="d1" /><div id="d2" />`, and assuming
|
|
96
|
-
* `DivHarness.hostSelector === 'div'` and `IdIsD1Harness.hostSelector === '#d1'`:
|
|
97
|
-
* - `await ch.locatorForAll(DivHarness, 'div')()` gets `[
|
|
98
|
-
* DivHarness, // for #d1
|
|
99
|
-
* TestElement, // for #d1
|
|
100
|
-
* DivHarness, // for #d2
|
|
101
|
-
* TestElement // for #d2
|
|
102
|
-
* ]`
|
|
103
|
-
* - `await ch.locatorForAll('div', '#d1')()` gets `[
|
|
104
|
-
* TestElement, // for #d1
|
|
105
|
-
* TestElement // for #d2
|
|
106
|
-
* ]`
|
|
107
|
-
* - `await ch.locatorForAll(DivHarness, IdIsD1Harness)()` gets `[
|
|
108
|
-
* DivHarness, // for #d1
|
|
109
|
-
* IdIsD1Harness, // for #d1
|
|
110
|
-
* DivHarness // for #d2
|
|
111
|
-
* ]`
|
|
112
|
-
* - `await ch.locatorForAll('span')()` gets `[]`.
|
|
113
|
-
*/
|
|
114
|
-
locatorForAll(...queries) {
|
|
115
|
-
return this.locatorFactory.locatorForAll(...queries);
|
|
116
|
-
}
|
|
117
|
-
/**
|
|
118
|
-
* Flushes change detection and async tasks in the Angular zone.
|
|
119
|
-
* In most cases it should not be necessary to call this manually. However, there may be some edge
|
|
120
|
-
* cases where it is needed to fully flush animation events.
|
|
121
|
-
*/
|
|
122
|
-
async forceStabilize() {
|
|
123
|
-
return this.locatorFactory.forceStabilize();
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Waits for all scheduled or running async tasks to complete. This allows harness
|
|
127
|
-
* authors to wait for async tasks outside of the Angular zone.
|
|
128
|
-
*/
|
|
129
|
-
async waitForTasksOutsideAngular() {
|
|
130
|
-
return this.locatorFactory.waitForTasksOutsideAngular();
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Base class for component harnesses that authors should extend if they anticipate that consumers
|
|
135
|
-
* of the harness may want to access other harnesses within the `<ng-content>` of the component.
|
|
136
|
-
*/
|
|
137
|
-
export class ContentContainerComponentHarness extends ComponentHarness {
|
|
138
|
-
async getChildLoader(selector) {
|
|
139
|
-
return (await this.getRootHarnessLoader()).getChildLoader(selector);
|
|
140
|
-
}
|
|
141
|
-
async getAllChildLoaders(selector) {
|
|
142
|
-
return (await this.getRootHarnessLoader()).getAllChildLoaders(selector);
|
|
143
|
-
}
|
|
144
|
-
async getHarness(query) {
|
|
145
|
-
return (await this.getRootHarnessLoader()).getHarness(query);
|
|
146
|
-
}
|
|
147
|
-
async getHarnessOrNull(query) {
|
|
148
|
-
return (await this.getRootHarnessLoader()).getHarnessOrNull(query);
|
|
149
|
-
}
|
|
150
|
-
async getAllHarnesses(query) {
|
|
151
|
-
return (await this.getRootHarnessLoader()).getAllHarnesses(query);
|
|
152
|
-
}
|
|
153
|
-
async hasHarness(query) {
|
|
154
|
-
return (await this.getRootHarnessLoader()).hasHarness(query);
|
|
155
|
-
}
|
|
156
|
-
/**
|
|
157
|
-
* Gets the root harness loader from which to start
|
|
158
|
-
* searching for content contained by this harness.
|
|
159
|
-
*/
|
|
160
|
-
async getRootHarnessLoader() {
|
|
161
|
-
return this.locatorFactory.rootHarnessLoader();
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* A class used to associate a ComponentHarness class with predicates functions that can be used to
|
|
166
|
-
* filter instances of the class.
|
|
167
|
-
*/
|
|
168
|
-
export class HarnessPredicate {
|
|
169
|
-
constructor(harnessType, options) {
|
|
170
|
-
this.harnessType = harnessType;
|
|
171
|
-
this._predicates = [];
|
|
172
|
-
this._descriptions = [];
|
|
173
|
-
this._addBaseOptions(options);
|
|
174
|
-
}
|
|
175
|
-
/**
|
|
176
|
-
* Checks if the specified nullable string value matches the given pattern.
|
|
177
|
-
* @param value The nullable string value to check, or a Promise resolving to the
|
|
178
|
-
* nullable string value.
|
|
179
|
-
* @param pattern The pattern the value is expected to match. If `pattern` is a string,
|
|
180
|
-
* `value` is expected to match exactly. If `pattern` is a regex, a partial match is
|
|
181
|
-
* allowed. If `pattern` is `null`, the value is expected to be `null`.
|
|
182
|
-
* @return Whether the value matches the pattern.
|
|
183
|
-
*/
|
|
184
|
-
static async stringMatches(value, pattern) {
|
|
185
|
-
value = await value;
|
|
186
|
-
if (pattern === null) {
|
|
187
|
-
return value === null;
|
|
188
|
-
}
|
|
189
|
-
else if (value === null) {
|
|
190
|
-
return false;
|
|
191
|
-
}
|
|
192
|
-
return typeof pattern === 'string' ? value === pattern : pattern.test(value);
|
|
193
|
-
}
|
|
194
|
-
/**
|
|
195
|
-
* Adds a predicate function to be run against candidate harnesses.
|
|
196
|
-
* @param description A description of this predicate that may be used in error messages.
|
|
197
|
-
* @param predicate An async predicate function.
|
|
198
|
-
* @return this (for method chaining).
|
|
199
|
-
*/
|
|
200
|
-
add(description, predicate) {
|
|
201
|
-
this._descriptions.push(description);
|
|
202
|
-
this._predicates.push(predicate);
|
|
203
|
-
return this;
|
|
204
|
-
}
|
|
205
|
-
/**
|
|
206
|
-
* Adds a predicate function that depends on an option value to be run against candidate
|
|
207
|
-
* harnesses. If the option value is undefined, the predicate will be ignored.
|
|
208
|
-
* @param name The name of the option (may be used in error messages).
|
|
209
|
-
* @param option The option value.
|
|
210
|
-
* @param predicate The predicate function to run if the option value is not undefined.
|
|
211
|
-
* @return this (for method chaining).
|
|
212
|
-
*/
|
|
213
|
-
addOption(name, option, predicate) {
|
|
214
|
-
if (option !== undefined) {
|
|
215
|
-
this.add(`${name} = ${_valueAsString(option)}`, item => predicate(item, option));
|
|
216
|
-
}
|
|
217
|
-
return this;
|
|
218
|
-
}
|
|
219
|
-
/**
|
|
220
|
-
* Filters a list of harnesses on this predicate.
|
|
221
|
-
* @param harnesses The list of harnesses to filter.
|
|
222
|
-
* @return A list of harnesses that satisfy this predicate.
|
|
223
|
-
*/
|
|
224
|
-
async filter(harnesses) {
|
|
225
|
-
if (harnesses.length === 0) {
|
|
226
|
-
return [];
|
|
227
|
-
}
|
|
228
|
-
const results = await parallel(() => harnesses.map(h => this.evaluate(h)));
|
|
229
|
-
return harnesses.filter((_, i) => results[i]);
|
|
230
|
-
}
|
|
231
|
-
/**
|
|
232
|
-
* Evaluates whether the given harness satisfies this predicate.
|
|
233
|
-
* @param harness The harness to check
|
|
234
|
-
* @return A promise that resolves to true if the harness satisfies this predicate,
|
|
235
|
-
* and resolves to false otherwise.
|
|
236
|
-
*/
|
|
237
|
-
async evaluate(harness) {
|
|
238
|
-
const results = await parallel(() => this._predicates.map(p => p(harness)));
|
|
239
|
-
return results.reduce((combined, current) => combined && current, true);
|
|
240
|
-
}
|
|
241
|
-
/** Gets a description of this predicate for use in error messages. */
|
|
242
|
-
getDescription() {
|
|
243
|
-
return this._descriptions.join(', ');
|
|
244
|
-
}
|
|
245
|
-
/** Gets the selector used to find candidate elements. */
|
|
246
|
-
getSelector() {
|
|
247
|
-
// We don't have to go through the extra trouble if there are no ancestors.
|
|
248
|
-
if (!this._ancestor) {
|
|
249
|
-
return (this.harnessType.hostSelector || '').trim();
|
|
250
|
-
}
|
|
251
|
-
const [ancestors, ancestorPlaceholders] = _splitAndEscapeSelector(this._ancestor);
|
|
252
|
-
const [selectors, selectorPlaceholders] = _splitAndEscapeSelector(this.harnessType.hostSelector || '');
|
|
253
|
-
const result = [];
|
|
254
|
-
// We have to add the ancestor to each part of the host compound selector, otherwise we can get
|
|
255
|
-
// incorrect results. E.g. `.ancestor .a, .ancestor .b` vs `.ancestor .a, .b`.
|
|
256
|
-
ancestors.forEach(escapedAncestor => {
|
|
257
|
-
const ancestor = _restoreSelector(escapedAncestor, ancestorPlaceholders);
|
|
258
|
-
return selectors.forEach(escapedSelector => result.push(`${ancestor} ${_restoreSelector(escapedSelector, selectorPlaceholders)}`));
|
|
259
|
-
});
|
|
260
|
-
return result.join(', ');
|
|
261
|
-
}
|
|
262
|
-
/** Adds base options common to all harness types. */
|
|
263
|
-
_addBaseOptions(options) {
|
|
264
|
-
this._ancestor = options.ancestor || '';
|
|
265
|
-
if (this._ancestor) {
|
|
266
|
-
this._descriptions.push(`has ancestor matching selector "${this._ancestor}"`);
|
|
267
|
-
}
|
|
268
|
-
const selector = options.selector;
|
|
269
|
-
if (selector !== undefined) {
|
|
270
|
-
this.add(`host matches selector "${selector}"`, async (item) => {
|
|
271
|
-
return (await item.host()).matchesSelector(selector);
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
/** Represent a value as a string for the purpose of logging. */
|
|
277
|
-
function _valueAsString(value) {
|
|
278
|
-
if (value === undefined) {
|
|
279
|
-
return 'undefined';
|
|
280
|
-
}
|
|
281
|
-
try {
|
|
282
|
-
// `JSON.stringify` doesn't handle RegExp properly, so we need a custom replacer.
|
|
283
|
-
// Use a character that is unlikely to appear in real strings to denote the start and end of
|
|
284
|
-
// the regex. This allows us to strip out the extra quotes around the value added by
|
|
285
|
-
// `JSON.stringify`. Also do custom escaping on `"` characters to prevent `JSON.stringify`
|
|
286
|
-
// from escaping them as if they were part of a string.
|
|
287
|
-
const stringifiedValue = JSON.stringify(value, (_, v) => v instanceof RegExp
|
|
288
|
-
? `◬MAT_RE_ESCAPE◬${v.toString().replace(/"/g, '◬MAT_RE_ESCAPE◬')}◬MAT_RE_ESCAPE◬`
|
|
289
|
-
: v);
|
|
290
|
-
// Strip out the extra quotes around regexes and put back the manually escaped `"` characters.
|
|
291
|
-
return stringifiedValue
|
|
292
|
-
.replace(/"◬MAT_RE_ESCAPE◬|◬MAT_RE_ESCAPE◬"/g, '')
|
|
293
|
-
.replace(/◬MAT_RE_ESCAPE◬/g, '"');
|
|
294
|
-
}
|
|
295
|
-
catch {
|
|
296
|
-
// `JSON.stringify` will throw if the object is cyclical,
|
|
297
|
-
// in this case the best we can do is report the value as `{...}`.
|
|
298
|
-
return '{...}';
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
/**
|
|
302
|
-
* Splits up a compound selector into its parts and escapes any quoted content. The quoted content
|
|
303
|
-
* has to be escaped, because it can contain commas which will throw throw us off when trying to
|
|
304
|
-
* split it.
|
|
305
|
-
* @param selector Selector to be split.
|
|
306
|
-
* @returns The escaped string where any quoted content is replaced with a placeholder. E.g.
|
|
307
|
-
* `[foo="bar"]` turns into `[foo=__cdkPlaceholder-0__]`. Use `_restoreSelector` to restore
|
|
308
|
-
* the placeholders.
|
|
309
|
-
*/
|
|
310
|
-
function _splitAndEscapeSelector(selector) {
|
|
311
|
-
const placeholders = [];
|
|
312
|
-
// Note that the regex doesn't account for nested quotes so something like `"ab'cd'e"` will be
|
|
313
|
-
// considered as two blocks. It's a bit of an edge case, but if we find that it's a problem,
|
|
314
|
-
// we can make it a bit smarter using a loop. Use this for now since it's more readable and
|
|
315
|
-
// compact. More complete implementation:
|
|
316
|
-
// https://github.com/angular/angular/blob/bd34bc9e89f18a/packages/compiler/src/shadow_css.ts#L655
|
|
317
|
-
const result = selector.replace(/(["'][^["']*["'])/g, (_, keep) => {
|
|
318
|
-
const replaceBy = `__cdkPlaceholder-${placeholders.length}__`;
|
|
319
|
-
placeholders.push(keep);
|
|
320
|
-
return replaceBy;
|
|
321
|
-
});
|
|
322
|
-
return [result.split(',').map(part => part.trim()), placeholders];
|
|
323
|
-
}
|
|
324
|
-
/** Restores a selector whose content was escaped in `_splitAndEscapeSelector`. */
|
|
325
|
-
function _restoreSelector(selector, placeholders) {
|
|
326
|
-
return selector.replace(/__cdkPlaceholder-(\d+)__/g, (_, index) => placeholders[+index]);
|
|
327
|
-
}
|
|
328
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LWhhcm5lc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL3Rlc3RpbmcvY29tcG9uZW50LWhhcm5lc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUFDLFFBQVEsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBbVE1Qzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFnQixnQkFBZ0I7SUFDcEMsWUFBK0IsY0FBOEI7UUFBOUIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO0lBQUcsQ0FBQztJQUVqRSw2RkFBNkY7SUFDN0YsS0FBSyxDQUFDLElBQUk7UUFDUixPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsV0FBVyxDQUFDO0lBQ3pDLENBQUM7SUFFRDs7OztPQUlHO0lBQ08sMEJBQTBCO1FBQ2xDLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQywwQkFBMEIsRUFBRSxDQUFDO0lBQzFELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FvQkc7SUFDTyxVQUFVLENBQ2xCLEdBQUcsT0FBVTtRQUViLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxVQUFVLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O09Bb0JHO0lBQ08sa0JBQWtCLENBQzFCLEdBQUcsT0FBVTtRQUViLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxrQkFBa0IsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0lBQzVELENBQUM7SUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0FtQ0c7SUFDTyxhQUFhLENBQ3JCLEdBQUcsT0FBVTtRQUViLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxhQUFhLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNPLEtBQUssQ0FBQyxj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QUMsQ0FBQztJQUN0QyxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AseURBQXlEO1FBQ3pELGtFQUFrRTtRQUNsRSxPQUFPLE9BQU8sQ0FBQztJQUNqQixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyx1QkFBdUIsQ0FBQyxRQUFnQjtJQUMvQyxNQUFNLFlBQVksR0FBYSxFQUFFLENBQUM7SUFFbEMsOEZBQThGO0lBQzlGLDRGQUE0RjtJQUM1RiwyRkFBMkY7SUFDM0YseUNBQXlDO0lBQ3pDLGtHQUFrRztJQUNsRyxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLG9CQUFvQixFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxFQUFFO1FBQ2hFLE1BQU0sU0FBUyxHQUFHLG9CQUFvQixZQUFZLENBQUMsTUFBTSxJQUFJLENBQUM7UUFDOUQsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QixPQUFPLFNBQVMsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztJQUVILE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQ3BFLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsU0FBUyxnQkFBZ0IsQ0FBQyxRQUFnQixFQUFFLFlBQXNCO0lBQ2hFLE9BQU8sUUFBUSxDQUFDLE9BQU8sQ0FBQywyQkFBMkIsRUFBRSxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFlBQVksQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge3BhcmFsbGVsfSBmcm9tICcuL2NoYW5nZS1kZXRlY3Rpb24nO1xuaW1wb3J0IHtUZXN0RWxlbWVudH0gZnJvbSAnLi90ZXN0LWVsZW1lbnQnO1xuXG4vKiogQW4gYXN5bmMgZnVuY3Rpb24gdGhhdCByZXR1cm5zIGEgcHJvbWlzZSB3aGVuIGNhbGxlZC4gKi9cbmV4cG9ydCB0eXBlIEFzeW5jRmFjdG9yeUZuPFQ+ID0gKCkgPT4gUHJvbWlzZTxUPjtcblxuLyoqIEFuIGFzeW5jIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4gaXRlbSBhbmQgcmV0dXJucyBhIGJvb2xlYW4gcHJvbWlzZSAqL1xuZXhwb3J0IHR5cGUgQXN5bmNQcmVkaWNhdGU8VD4gPSAoaXRlbTogVCkgPT4gUHJvbWlzZTxib29sZWFuPjtcblxuLyoqIEFuIGFzeW5jIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4gaXRlbSBhbmQgYW4gb3B0aW9uIHZhbHVlIGFuZCByZXR1cm5zIGEgYm9vbGVhbiBwcm9taXNlLiAqL1xuZXhwb3J0IHR5cGUgQXN5bmNPcHRpb25QcmVkaWNhdGU8VCwgTz4gPSAoaXRlbTogVCwgb3B0aW9uOiBPKSA9PiBQcm9taXNlPGJvb2xlYW4+O1xuXG4vKipcbiAqIEEgcXVlcnkgZm9yIGEgYENvbXBvbmVudEhhcm5lc3NgLCB3aGljaCBpcyBleHByZXNzZWQgYXMgZWl0aGVyIGEgYENvbXBvbmVudEhhcm5lc3NDb25zdHJ1Y3RvcmAgb3JcbiAqIGEgYEhhcm5lc3NQcmVkaWNhdGVgLlxuICovXG5leHBvcnQgdHlwZSBIYXJuZXNzUXVlcnk8VCBleHRlbmRzIENvbXBvbmVudEhhcm5lc3M+ID1cbiAgfCBDb21wb25lbnRIYXJuZXNzQ29uc3RydWN0b3I8VD5cbiAgfCBIYXJuZXNzUHJlZGljYXRlPFQ+O1xuXG4vKipcbiAqIFRoZSByZXN1bHQgdHlwZSBvYnRhaW5lZCB3aGVuIHNlYXJjaGluZyB1c2luZyBhIHBhcnRpY3VsYXIgbGlzdCBvZiBxdWVyaWVzLiBUaGlzIHR5cGUgZGVwZW5kcyBvblxuICogdGhlIHBhcnRpY3VsYXIgaXRlbXMgYmVpbmcgcXVlcmllZC5cbiAqIC0gSWYgb25lIG9mIHRoZSBxdWVyaWVzIGlzIGZvciBhIGBDb21wb25lbnRIYXJuZXNzQ29uc3RydWN0b3I8QzE+YCwgaXQgbWVhbnMgdGhhdCB0aGUgcmVzdWx0XG4gKiAgIG1pZ2h0IGJlIGEgaGFybmVzcyBvZiB0eXBlIGBDMWBcbiAqIC0gSWYgb25lIG9mIHRoZSBxdWVyaWVzIGlzIGZvciBhIGBIYXJuZXNzUHJlZGljYXRlPEMyPmAsIGl0IG1lYW5zIHRoYXQgdGhlIHJlc3VsdCBtaWdodCBiZSBhXG4gKiAgIGhhcm5lc3Mgb2YgdHlwZSBgQzJgXG4gKiAtIElmIG9uZSBvZiB0aGUgcXVlcmllcyBpcyBmb3IgYSBgc3RyaW5nYCwgaXQgbWVhbnMgdGhhdCB0aGUgcmVzdWx0IG1pZ2h0IGJlIGEgYFRlc3RFbGVtZW50YC5cbiAqXG4gKiBTaW5jZSB3ZSBkb24ndCBrbm93IGZvciBzdXJlIHdoaWNoIHF1ZXJ5IHdpbGwgbWF0Y2gsIHRoZSByZXN1bHQgdHlwZSBpZiB0aGUgdW5pb24gb2YgdGhlIHR5cGVzXG4gKiBmb3IgYWxsIHBvc3NpYmxlIHJlc3VsdHMuXG4gKlxuICogZS5nLlxuICogVGhlIHR5cGU6XG4gKiBgTG9jYXRvckZuUmVzdWx0Jmx0O1tcbiAqICAgQ29tcG9uZW50SGFybmVzc0NvbnN0cnVjdG9yJmx0O015SGFybmVzcyZndDssXG4gKiAgIEhhcm5lc3NQcmVkaWNhdGUmbHQ7TXlPdGhlckhhcm5lc3MmZ3Q7LFxuICogICBzdHJpbmdcbiAqIF0mZ3Q7YFxuICogaXMgZXF1aXZhbGVudCB0bzpcbiAqIGBNeUhhcm5lc3MgfCBNeU90aGVySGFybmVzcyB8IFRlc3RFbGVtZW50YC5cbiAqL1xuZXhwb3J0IHR5cGUgTG9jYXRvckZuUmVzdWx0PFQgZXh0ZW5kcyAoSGFybmVzc1F1ZXJ5PGFueT4gfCBzdHJpbmcpW10+ID0ge1xuICBbSSBpbiBrZXlvZiBUXTogVFtJXSBleHRlbmRzIG5ldyAoLi4uYXJnczogYW55W10pID0+IGluZmVyIEMgLy8gTWFwIGBDb21wb25lbnRIYXJuZXNzQ29uc3RydWN0b3I8Qz5gIHRvIGBDYC5cbiAgICA/IENcbiAgICA6IC8vIE1hcCBgSGFybmVzc1ByZWRpY2F0ZTxDPmAgdG8gYENgLlxuICAgIFRbSV0gZXh0ZW5kcyB7aGFybmVzc1R5cGU6IG5ldyAoLi4uYXJnczogYW55W10pID0+IGluZmVyIEN9XG4gICAgPyBDXG4gICAgOiAvLyBNYXAgYHN0cmluZ2AgdG8gYFRlc3RFbGVtZW50YC5cbiAgICBUW0ldIGV4dGVuZHMgc3RyaW5nXG4gICAgPyBUZXN0RWxlbWVudFxuICAgIDogLy8gTWFwIGV2ZXJ5dGhpbmcgZWxzZSB0byBgbmV2ZXJgIChzaG91bGQgbm90IGhhcHBlbiBkdWUgdG8gdGhlIHR5cGUgY29uc3RyYWludCBvbiBgVGApLlxuICAgICAgbmV2ZXI7XG59W251bWJlcl07XG5cbi8qKlxuICogSW50ZXJmYWNlIHVzZWQgdG8gbG9hZCBDb21wb25lbnRIYXJuZXNzIG9iamVjdHMuIFRoaXMgaW50ZXJmYWNlIGlzIHVzZWQgYnkgdGVzdCBhdXRob3JzIHRvXG4gKiBpbnN0YW50aWF0ZSBgQ29tcG9uZW50SGFybmVzc2Blcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBIYXJuZXNzTG9hZGVyIHtcbiAgLyoqXG4gICAqIFNlYXJjaGVzIGZvciBhbiBlbGVtZW50IHdpdGggdGhlIGdpdmVuIHNlbGVjdG9yIHVuZGVyIHRoZSBjdXJyZW50IGluc3RhbmNlcydzIHJvb3QgZWxlbWVudCxcbiAgICogYW5kIHJldHVybnMgYSBgSGFybmVzc0xvYWRlcmAgcm9vdGVkIGF0IHRoZSBtYXRjaGluZyBlbGVtZW50LiBJZiBtdWx0aXBsZSBlbGVtZW50cyBtYXRjaCB0aGVcbiAgICogc2VsZWN0b3IsIHRoZSBmaXJzdCBpcyB1c2VkLiBJZiBubyBlbGVtZW50cyBtYXRjaCwgYW4gZXJyb3IgaXMgdGhyb3duLlxuICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIGZvciB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBuZXcgYEhhcm5lc3NMb2FkZXJgXG4gICAqIEByZXR1cm4gQSBgSGFybmVzc0xvYWRlcmAgcm9vdGVkIGF0IHRoZSBlbGVtZW50IG1hdGNoaW5nIHRoZSBnaXZlbiBzZWxlY3Rvci5cbiAgICogQHRocm93cyBJZiBhIG1hdGNoaW5nIGVsZW1lbnQgY2FuJ3QgYmUgZm91bmQuXG4gICAqL1xuICBnZXRDaGlsZExvYWRlcihzZWxlY3Rvcjogc3RyaW5nKTogUHJvbWlzZTxIYXJuZXNzTG9hZGVyPjtcblxuICAvKipcbiAgICogU2VhcmNoZXMgZm9yIGFsbCBlbGVtZW50cyB3aXRoIHRoZSBnaXZlbiBzZWxlY3RvciB1bmRlciB0aGUgY3VycmVudCBpbnN0YW5jZXMncyByb290IGVsZW1lbnQsXG4gICAqIGFuZCByZXR1cm5zIGFuIGFycmF5IG9mIGBIYXJuZXNzTG9hZGVyYHMsIG9uZSBmb3IgZWFjaCBtYXRjaGluZyBlbGVtZW50LCByb290ZWQgYXQgdGhhdFxuICAgKiBlbGVtZW50LlxuICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIGZvciB0aGUgcm9vdCBlbGVtZW50IG9mIHRoZSBuZXcgYEhhcm5lc3NMb2FkZXJgXG4gICAqIEByZXR1cm4gQSBsaXN0IG9mIGBIYXJuZXNzTG9hZGVyYHMsIG9uZSBmb3IgZWFjaCBtYXRjaGluZyBlbGVtZW50LCByb290ZWQgYXQgdGhhdCBlbGVtZW50LlxuICAgKi9cbiAgZ2V0QWxsQ2hpbGRMb2FkZXJzKHNlbGVjdG9yOiBzdHJpbmcpOiBQcm9taXNlPEhhcm5lc3NMb2FkZXJbXT47XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIGZvciBhbiBpbnN0YW5jZSBvZiB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGhhcm5lc3MgdHlwZSB1bmRlciB0aGVcbiAgICogYEhhcm5lc3NMb2FkZXJgJ3Mgcm9vdCBlbGVtZW50LCBhbmQgcmV0dXJucyBhIGBDb21wb25lbnRIYXJuZXNzYCBmb3IgdGhhdCBpbnN0YW5jZS4gSWYgbXVsdGlwbGVcbiAgICogbWF0Y2hpbmcgY29tcG9uZW50cyBhcmUgZm91bmQsIGEgaGFybmVzcyBmb3IgdGhlIGZpcnN0IG9uZSBpcyByZXR1cm5lZC4gSWYgbm8gbWF0Y2hpbmdcbiAgICogY29tcG9uZW50IGlzIGZvdW5kLCBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqIEBwYXJhbSBxdWVyeSBBIHF1ZXJ5IGZvciBhIGhhcm5lc3MgdG8gY3JlYXRlXG4gICAqIEByZXR1cm4gQW4gaW5zdGFuY2Ugb2YgdGhlIGdpdmVuIGhhcm5lc3MgdHlwZVxuICAgKiBAdGhyb3dzIElmIGEgbWF0Y2hpbmcgY29tcG9uZW50IGluc3RhbmNlIGNhbid0IGJlIGZvdW5kLlxuICAgKi9cbiAgZ2V0SGFybmVzczxUIGV4dGVuZHMgQ29tcG9uZW50SGFybmVzcz4ocXVlcnk6IEhhcm5lc3NRdWVyeTxUPik6IFByb21pc2U8VD47XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIGZvciBhbiBpbnN0YW5jZSBvZiB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGhhcm5lc3MgdHlwZSB1bmRlciB0aGVcbiAgICogYEhhcm5lc3NMb2FkZXJgJ3Mgcm9vdCBlbGVtZW50LCBhbmQgcmV0dXJucyBhIGBDb21wb25lbnRIYXJuZXNzYCBmb3IgdGhhdCBpbnN0YW5jZS4gSWYgbXVsdGlwbGVcbiAgICogbWF0Y2hpbmcgY29tcG9uZW50cyBhcmUgZm91bmQsIGEgaGFybmVzcyBmb3IgdGhlIGZpcnN0IG9uZSBpcyByZXR1cm5lZC4gSWYgbm8gbWF0Y2hpbmdcbiAgICogY29tcG9uZW50IGlzIGZvdW5kLCBudWxsIGlzIHJldHVybmVkLlxuICAgKiBAcGFyYW0gcXVlcnkgQSBxdWVyeSBmb3IgYSBoYXJuZXNzIHRvIGNyZWF0ZVxuICAgKiBAcmV0dXJuIEFuIGluc3RhbmNlIG9mIHRoZSBnaXZlbiBoYXJuZXNzIHR5cGUgKG9yIG51bGwgaWYgbm90IGZvdW5kKS5cbiAgICovXG4gIGdldEhhcm5lc3NPck51bGw8VCBleHRlbmRzIENvbXBvbmVudEhhcm5lc3M+KHF1ZXJ5OiBIYXJuZXNzUXVlcnk8VD4pOiBQcm9taXNlPFQgfCBudWxsPjtcblxuICAvKipcbiAgICogU2VhcmNoZXMgZm9yIGFsbCBpbnN0YW5jZXMgb2YgdGhlIGNvbXBvbmVudCBjb3JyZXNwb25kaW5nIHRvIHRoZSBnaXZlbiBoYXJuZXNzIHR5cGUgdW5kZXIgdGhlXG4gICAqIGBIYXJuZXNzTG9hZGVyYCdzIHJvb3QgZWxlbWVudCwgYW5kIHJldHVybnMgYSBsaXN0IGBDb21wb25lbnRIYXJuZXNzYCBmb3IgZWFjaCBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHF1ZXJ5IEEgcXVlcnkgZm9yIGEgaGFybmVzcyB0byBjcmVhdGVcbiAgICogQHJldHVybiBBIGxpc3QgaW5zdGFuY2VzIG9mIHRoZSBnaXZlbiBoYXJuZXNzIHR5cGUuXG4gICAqL1xuICBnZXRBbGxIYXJuZXNzZXM8VCBleHRlbmRzIENvbXBvbmVudEhhcm5lc3M+KHF1ZXJ5OiBIYXJuZXNzUXVlcnk8VD4pOiBQcm9taXNlPFRbXT47XG5cbiAgLyoqXG4gICAqIFNlYXJjaGVzIGZvciBhbiBpbnN0YW5jZSBvZiB0aGUgY29tcG9uZW50IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGhhcm5lc3MgdHlwZSB1bmRlciB0aGVcbiAgICogYEhhcm5lc3NMb2FkZXJgJ3Mgcm9vdCBlbGVtZW50LCBhbmQgcmV0dXJucyBhIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBhbnkgd2VyZSBmb3VuZC5cbiAgICogQHBhcmFtIHF1ZXJ5IEEgcXVlcnkgZm9yIGEgaGFybmVzcyB0byBjcmVhdGVcbiAgICogQHJldHVybiBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiBhbiBpbnN0YW5jZSB3YXMgZm91bmQuXG4gICAqL1xuICBoYXNIYXJuZXNzPFQgZXh0ZW5kcyBDb21wb25lbnRIYXJuZXNzPihxdWVyeTogSGFybmVzc1F1ZXJ5PFQ+KTogUHJvbWlzZTxib29sZWFuPjtcbn1cblxuLyoqXG4gKiBJbnRlcmZhY2UgdXNlZCB0byBjcmVhdGUgYXN5bmNocm9ub3VzIGxvY2F0b3IgZnVuY3Rpb25zIHVzZWQgZmluZCBlbGVtZW50cyBhbmQgY29tcG9uZW50XG4gKiBoYXJuZXNzZXMuIFRoaXMgaW50ZXJmYWNlIGlzIHVzZWQgYnkgYENvbXBvbmVudEhhcm5lc3NgIGF1dGhvcnMgdG8gY3JlYXRlIGxvY2F0b3IgZnVuY3Rpb25zIGZvclxuICogdGhlaXIgYENvbXBvbmVudEhhcm5lc3NgIHN1YmNsYXNzLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIExvY2F0b3JGYWN0b3J5IHtcbiAgLyoqIEdldHMgYSBsb2NhdG9yIGZhY3Rvcnkgcm9vdGVkIGF0IHRoZSBkb2N1bWVudCByb290LiAqL1xuICBkb2N1bWVudFJvb3RMb2NhdG9yRmFjdG9yeSgpOiBMb2NhdG9yRmFjdG9yeTtcblxuICAvKiogVGhlIHJvb3QgZWxlbWVudCBvZiB0aGlzIGBMb2NhdG9yRmFjdG9yeWAgYXMgYSBgVGVzdEVsZW1lbnRgLiAqL1xuICByb290RWxlbWVudDogVGVzdEVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYXN5bmNocm9ub3VzIGxvY2F0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaW5kIGEgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlXG4gICAqIG9yIGVsZW1lbnQgdW5kZXIgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGlzIGBMb2NhdG9yRmFjdG9yeWAuXG4gICAqIEBwYXJhbSBxdWVyaWVzIEEgbGlzdCBvZiBxdWVyaWVzIHNwZWNpZnlpbmcgd2hpY2ggaGFybmVzc2VzIGFuZCBlbGVtZW50cyB0byBzZWFyY2ggZm9yOlxuICAgKiAgIC0gQSBgc3RyaW5nYCBzZWFyY2hlcyBmb3IgZWxlbWVudHMgbWF0Y2hpbmcgdGhlIENTUyBzZWxlY3RvciBzcGVjaWZpZWQgYnkgdGhlIHN0cmluZy5cbiAgICogICAtIEEgYENvbXBvbmVudEhhcm5lc3NgIGNvbnN0cnVjdG9yIHNlYXJjaGVzIGZvciBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZVxuICAgKiAgICAgZ2l2ZW4gY2xhc3MuXG4gICAqICAgLSBBIGBIYXJuZXNzUHJlZGljYXRlYCBzZWFyY2hlcyBmb3IgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcyBtYXRjaGluZyB0aGUgZ2l2ZW5cbiAgICogICAgIHByZWRpY2F0ZS5cbiAgICogQHJldHVybiBBbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IHNlYXJjaGVzIGZvciBhbmQgcmV0dXJucyBhIGBQcm9taXNlYCBmb3IgdGhlXG4gICAqICAgZmlyc3QgZWxlbWVudCBvciBoYXJuZXNzIG1hdGNoaW5nIHRoZSBnaXZlbiBzZWFyY2ggY3JpdGVyaWEuIE1hdGNoZXMgYXJlIG9yZGVyZWQgZmlyc3QgYnlcbiAgICogICBvcmRlciBpbiB0aGUgRE9NLCBhbmQgc2Vjb25kIGJ5IG9yZGVyIGluIHRoZSBxdWVyaWVzIGxpc3QuIElmIG5vIG1hdGNoZXMgYXJlIGZvdW5kLCB0aGVcbiAgICogICBgUHJvbWlzZWAgcmVqZWN0cy4gVGhlIHR5cGUgdGhhdCB0aGUgYFByb21pc2VgIHJlc29sdmVzIHRvIGlzIGEgdW5pb24gb2YgYWxsIHJlc3VsdCB0eXBlcyBmb3JcbiAgICogICBlYWNoIHF1ZXJ5LlxuICAgKlxuICAgKiBlLmcuIEdpdmVuIHRoZSBmb2xsb3dpbmcgRE9NOiBgPGRpdiBpZD1cImQxXCIgLz48ZGl2IGlkPVwiZDJcIiAvPmAsIGFuZCBhc3N1bWluZ1xuICAgKiBgRGl2SGFybmVzcy5ob3N0U2VsZWN0b3IgPT09ICdkaXYnYDpcbiAgICogLSBgYXdhaXQgbGYubG9jYXRvckZvcihEaXZIYXJuZXNzLCAnZGl2JykoKWAgZ2V0cyBhIGBEaXZIYXJuZXNzYCBpbnN0YW5jZSBmb3IgYCNkMWBcbiAgICogLSBgYXdhaXQgbGYubG9jYXRvckZvcignZGl2JywgRGl2SGFybmVzcykoKWAgZ2V0cyBhIGBUZXN0RWxlbWVudGAgaW5zdGFuY2UgZm9yIGAjZDFgXG4gICAqIC0gYGF3YWl0IGxmLmxvY2F0b3JGb3IoJ3NwYW4nKSgpYCB0aHJvd3MgYmVjYXVzZSB0aGUgYFByb21pc2VgIHJlamVjdHMuXG4gICAqL1xuICBsb2NhdG9yRm9yPFQgZXh0ZW5kcyAoSGFybmVzc1F1ZXJ5PGFueT4gfCBzdHJpbmcpW10+KFxuICAgIC4uLnF1ZXJpZXM6IFRcbiAgKTogQXN5bmNGYWN0b3J5Rm48TG9jYXRvckZuUmVzdWx0PFQ+PjtcblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIHRvIGZpbmQgYSBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VcbiAgICogb3IgZWxlbWVudCB1bmRlciB0aGUgcm9vdCBlbGVtZW50IG9mIHRoaXMgYExvY2F0b3JGYWN0b3J5YC5cbiAgICogQHBhcmFtIHF1ZXJpZXMgQSBsaXN0IG9mIHF1ZXJpZXMgc3BlY2lmeWluZyB3aGljaCBoYXJuZXNzZXMgYW5kIGVsZW1lbnRzIHRvIHNlYXJjaCBmb3I6XG4gICAqICAgLSBBIGBzdHJpbmdgIHNlYXJjaGVzIGZvciBlbGVtZW50cyBtYXRjaGluZyB0aGUgQ1NTIHNlbGVjdG9yIHNwZWNpZmllZCBieSB0aGUgc3RyaW5nLlxuICAgKiAgIC0gQSBgQ29tcG9uZW50SGFybmVzc2AgY29uc3RydWN0b3Igc2VhcmNoZXMgZm9yIGBDb21wb25lbnRIYXJuZXNzYCBpbnN0YW5jZXMgbWF0Y2hpbmcgdGhlXG4gICAqICAgICBnaXZlbiBjbGFzcy5cbiAgICogICAtIEEgYEhhcm5lc3NQcmVkaWNhdGVgIHNlYXJjaGVzIGZvciBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZSBnaXZlblxuICAgKiAgICAgcHJlZGljYXRlLlxuICAgKiBAcmV0dXJuIEFuIGFzeW5jaHJvbm91cyBsb2NhdG9yIGZ1bmN0aW9uIHRoYXQgc2VhcmNoZXMgZm9yIGFuZCByZXR1cm5zIGEgYFByb21pc2VgIGZvciB0aGVcbiAgICogICBmaXJzdCBlbGVtZW50IG9yIGhhcm5lc3MgbWF0Y2hpbmcgdGhlIGdpdmVuIHNlYXJjaCBjcml0ZXJpYS4gTWF0Y2hlcyBhcmUgb3JkZXJlZCBmaXJzdCBieVxuICAgKiAgIG9yZGVyIGluIHRoZSBET00sIGFuZCBzZWNvbmQgYnkgb3JkZXIgaW4gdGhlIHF1ZXJpZXMgbGlzdC4gSWYgbm8gbWF0Y2hlcyBhcmUgZm91bmQsIHRoZVxuICAgKiAgIGBQcm9taXNlYCBpcyByZXNvbHZlZCB3aXRoIGBudWxsYC4gVGhlIHR5cGUgdGhhdCB0aGUgYFByb21pc2VgIHJlc29sdmVzIHRvIGlzIGEgdW5pb24gb2YgYWxsXG4gICAqICAgcmVzdWx0IHR5cGVzIGZvciBlYWNoIHF1ZXJ5IG9yIG51bGwuXG4gICAqXG4gICAqIGUuZy4gR2l2ZW4gdGhlIGZvbGxvd2luZyBET006IGA8ZGl2IGlkPVwiZDFcIiAvPjxkaXYgaWQ9XCJkMlwiIC8+YCwgYW5kIGFzc3VtaW5nXG4gICAqIGBEaXZIYXJuZXNzLmhvc3RTZWxlY3RvciA9PT0gJ2RpdidgOlxuICAgKiAtIGBhd2FpdCBsZi5sb2NhdG9yRm9yT3B0aW9uYWwoRGl2SGFybmVzcywgJ2RpdicpKClgIGdldHMgYSBgRGl2SGFybmVzc2AgaW5zdGFuY2UgZm9yIGAjZDFgXG4gICAqIC0gYGF3YWl0IGxmLmxvY2F0b3JGb3JPcHRpb25hbCgnZGl2JywgRGl2SGFybmVzcykoKWAgZ2V0cyBhIGBUZXN0RWxlbWVudGAgaW5zdGFuY2UgZm9yIGAjZDFgXG4gICAqIC0gYGF3YWl0IGxmLmxvY2F0b3JGb3JPcHRpb25hbCgnc3BhbicpKClgIGdldHMgYG51bGxgLlxuICAgKi9cbiAgbG9jYXRvckZvck9wdGlvbmFsPFQgZXh0ZW5kcyAoSGFybmVzc1F1ZXJ5PGFueT4gfCBzdHJpbmcpW10+KFxuICAgIC4uLnF1ZXJpZXM6IFRcbiAgKTogQXN5bmNGYWN0b3J5Rm48TG9jYXRvckZuUmVzdWx0PFQ+IHwgbnVsbD47XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYXN5bmNocm9ub3VzIGxvY2F0b3IgZnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBmaW5kIGBDb21wb25lbnRIYXJuZXNzYCBpbnN0YW5jZXNcbiAgICogb3IgZWxlbWVudHMgdW5kZXIgdGhlIHJvb3QgZWxlbWVudCBvZiB0aGlzIGBMb2NhdG9yRmFjdG9yeWAuXG4gICAqIEBwYXJhbSBxdWVyaWVzIEEgbGlzdCBvZiBxdWVyaWVzIHNwZWNpZnlpbmcgd2hpY2ggaGFybmVzc2VzIGFuZCBlbGVtZW50cyB0byBzZWFyY2ggZm9yOlxuICAgKiAgIC0gQSBgc3RyaW5nYCBzZWFyY2hlcyBmb3IgZWxlbWVudHMgbWF0Y2hpbmcgdGhlIENTUyBzZWxlY3RvciBzcGVjaWZpZWQgYnkgdGhlIHN0cmluZy5cbiAgICogICAtIEEgYENvbXBvbmVudEhhcm5lc3NgIGNvbnN0cnVjdG9yIHNlYXJjaGVzIGZvciBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZVxuICAgKiAgICAgZ2l2ZW4gY2xhc3MuXG4gICAqICAgLSBBIGBIYXJuZXNzUHJlZGljYXRlYCBzZWFyY2hlcyBmb3IgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcyBtYXRjaGluZyB0aGUgZ2l2ZW5cbiAgICogICAgIHByZWRpY2F0ZS5cbiAgICogQHJldHVybiBBbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IHNlYXJjaGVzIGZvciBhbmQgcmV0dXJucyBhIGBQcm9taXNlYCBmb3IgYWxsXG4gICAqICAgZWxlbWVudHMgYW5kIGhhcm5lc3NlcyBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VhcmNoIGNyaXRlcmlhLiBNYXRjaGVzIGFyZSBvcmRlcmVkIGZpcnN0IGJ5XG4gICAqICAgb3JkZXIgaW4gdGhlIERPTSwgYW5kIHNlY29uZCBieSBvcmRlciBpbiB0aGUgcXVlcmllcyBsaXN0LiBJZiBhbiBlbGVtZW50IG1hdGNoZXMgbW9yZSB0aGFuXG4gICAqICAgb25lIGBDb21wb25lbnRIYXJuZXNzYCBjbGFzcywgdGhlIGxvY2F0b3IgZ2V0cyBhbiBpbnN0YW5jZSBvZiBlYWNoIGZvciB0aGUgc2FtZSBlbGVtZW50LiBJZlxuICAgKiAgIGFuIGVsZW1lbnQgbWF0Y2hlcyBtdWx0aXBsZSBgc3RyaW5nYCBzZWxlY3RvcnMsIG9ubHkgb25lIGBUZXN0RWxlbWVudGAgaW5zdGFuY2UgaXMgcmV0dXJuZWRcbiAgICogICBmb3IgdGhhdCBlbGVtZW50LiBUaGUgdHlwZSB0aGF0IHRoZSBgUHJvbWlzZWAgcmVzb2x2ZXMgdG8gaXMgYW4gYXJyYXkgd2hlcmUgZWFjaCBlbGVtZW50IGlzXG4gICAqICAgdGhlIHVuaW9uIG9mIGFsbCByZXN1bHQgdHlwZXMgZm9yIGVhY2ggcXVlcnkuXG4gICAqXG4gICAqIGUuZy4gR2l2ZW4gdGhlIGZvbGxvd2luZyBET006IGA8ZGl2IGlkPVwiZDFcIiAvPjxkaXYgaWQ9XCJkMlwiIC8+YCwgYW5kIGFzc3VtaW5nXG4gICAqIGBEaXZIYXJuZXNzLmhvc3RTZWxlY3RvciA9PT0gJ2RpdidgIGFuZCBgSWRJc0QxSGFybmVzcy5ob3N0U2VsZWN0b3IgPT09ICcjZDEnYDpcbiAgICogLSBgYXdhaXQgbGYubG9jYXRvckZvckFsbChEaXZIYXJuZXNzLCAnZGl2JykoKWAgZ2V0cyBgW1xuICAgKiAgICAgRGl2SGFybmVzcywgLy8gZm9yICNkMVxuICAgKiAgICAgVGVzdEVsZW1lbnQsIC8vIGZvciAjZDFcbiAgICogICAgIERpdkhhcm5lc3MsIC8vIGZvciAjZDJcbiAgICogICAgIFRlc3RFbGVtZW50IC8vIGZvciAjZDJcbiAgICogICBdYFxuICAgKiAtIGBhd2FpdCBsZi5sb2NhdG9yRm9yQWxsKCdkaXYnLCAnI2QxJykoKWAgZ2V0cyBgW1xuICAgKiAgICAgVGVzdEVsZW1lbnQsIC8vIGZvciAjZDFcbiAgICogICAgIFRlc3RFbGVtZW50IC8vIGZvciAjZDJcbiAgICogICBdYFxuICAgKiAtIGBhd2FpdCBsZi5sb2NhdG9yRm9yQWxsKERpdkhhcm5lc3MsIElkSXNEMUhhcm5lc3MpKClgIGdldHMgYFtcbiAgICogICAgIERpdkhhcm5lc3MsIC8vIGZvciAjZDFcbiAgICogICAgIElkSXNEMUhhcm5lc3MsIC8vIGZvciAjZDFcbiAgICogICAgIERpdkhhcm5lc3MgLy8gZm9yICNkMlxuICAgKiAgIF1gXG4gICAqIC0gYGF3YWl0IGxmLmxvY2F0b3JGb3JBbGwoJ3NwYW4nKSgpYCBnZXRzIGBbXWAuXG4gICAqL1xuICBsb2NhdG9yRm9yQWxsPFQgZXh0ZW5kcyAoSGFybmVzc1F1ZXJ5PGFueT4gfCBzdHJpbmcpW10+KFxuICAgIC4uLnF1ZXJpZXM6IFRcbiAgKTogQXN5bmNGYWN0b3J5Rm48TG9jYXRvckZuUmVzdWx0PFQ+W10+O1xuXG4gIC8qKiBAcmV0dXJuIEEgYEhhcm5lc3NMb2FkZXJgIHJvb3RlZCBhdCB0aGUgcm9vdCBlbGVtZW50IG9mIHRoaXMgYExvY2F0b3JGYWN0b3J5YC4gKi9cbiAgcm9vdEhhcm5lc3NMb2FkZXIoKTogUHJvbWlzZTxIYXJuZXNzTG9hZGVyPjtcblxuICAvKipcbiAgICogR2V0cyBhIGBIYXJuZXNzTG9hZGVyYCBpbnN0YW5jZSBmb3IgYW4gZWxlbWVudCB1bmRlciB0aGUgcm9vdCBvZiB0aGlzIGBMb2NhdG9yRmFjdG9yeWAuXG4gICAqIEBwYXJhbSBzZWxlY3RvciBUaGUgc2VsZWN0b3IgZm9yIHRoZSByb290IGVsZW1lbnQuXG4gICAqIEByZXR1cm4gQSBgSGFybmVzc0xvYWRlcmAgcm9vdGVkIGF0IHRoZSBmaXJzdCBlbGVtZW50IG1hdGNoaW5nIHRoZSBnaXZlbiBzZWxlY3Rvci5cbiAgICogQHRocm93cyBJZiBubyBtYXRjaGluZyBlbGVtZW50IGlzIGZvdW5kIGZvciB0aGUgZ2l2ZW4gc2VsZWN0b3IuXG4gICAqL1xuICBoYXJuZXNzTG9hZGVyRm9yKHNlbGVjdG9yOiBzdHJpbmcpOiBQcm9taXNlPEhhcm5lc3NMb2FkZXI+O1xuXG4gIC8qKlxuICAgKiBHZXRzIGEgYEhhcm5lc3NMb2FkZXJgIGluc3RhbmNlIGZvciBhbiBlbGVtZW50IHVuZGVyIHRoZSByb290IG9mIHRoaXMgYExvY2F0b3JGYWN0b3J5YFxuICAgKiBAcGFyYW0gc2VsZWN0b3IgVGhlIHNlbGVjdG9yIGZvciB0aGUgcm9vdCBlbGVtZW50LlxuICAgKiBAcmV0dXJuIEEgYEhhcm5lc3NMb2FkZXJgIHJvb3RlZCBhdCB0aGUgZmlyc3QgZWxlbWVudCBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VsZWN0b3IsIG9yIG51bGwgaWZcbiAgICogICAgIG5vIG1hdGNoaW5nIGVsZW1lbnQgaXMgZm91bmQuXG4gICAqL1xuICBoYXJuZXNzTG9hZGVyRm9yT3B0aW9uYWwoc2VsZWN0b3I6IHN0cmluZyk6IFByb21pc2U8SGFybmVzc0xvYWRlciB8IG51bGw+O1xuXG4gIC8qKlxuICAgKiBHZXRzIGEgbGlzdCBvZiBgSGFybmVzc0xvYWRlcmAgaW5zdGFuY2VzLCBvbmUgZm9yIGVhY2ggbWF0Y2hpbmcgZWxlbWVudC5cbiAgICogQHBhcmFtIHNlbGVjdG9yIFRoZSBzZWxlY3RvciBmb3IgdGhlIHJvb3QgZWxlbWVudC5cbiAgICogQHJldHVybiBBIGxpc3Qgb2YgYEhhcm5lc3NMb2FkZXJgLCBvbmUgcm9vdGVkIGF0IGVhY2ggZWxlbWVudCBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VsZWN0b3IuXG4gICAqL1xuICBoYXJuZXNzTG9hZGVyRm9yQWxsKHNlbGVjdG9yOiBzdHJpbmcpOiBQcm9taXNlPEhhcm5lc3NMb2FkZXJbXT47XG5cbiAgLyoqXG4gICAqIEZsdXNoZXMgY2hhbmdlIGRldGVjdGlvbiBhbmQgYXN5bmMgdGFza3MgY2FwdHVyZWQgaW4gdGhlIEFuZ3VsYXIgem9uZS5cbiAgICogSW4gbW9zdCBjYXNlcyBpdCBzaG91bGQgbm90IGJlIG5lY2Vzc2FyeSB0byBjYWxsIHRoaXMgbWFudWFsbHkuIEhvd2V2ZXIsIHRoZXJlIG1heSBiZSBzb21lIGVkZ2VcbiAgICogY2FzZXMgd2hlcmUgaXQgaXMgbmVlZGVkIHRvIGZ1bGx5IGZsdXNoIGFuaW1hdGlvbiBldmVudHMuXG4gICAqL1xuICBmb3JjZVN0YWJpbGl6ZSgpOiBQcm9taXNlPHZvaWQ+O1xuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgYWxsIHNjaGVkdWxlZCBvciBydW5uaW5nIGFzeW5jIHRhc2tzIHRvIGNvbXBsZXRlLiBUaGlzIGFsbG93cyBoYXJuZXNzXG4gICAqIGF1dGhvcnMgdG8gd2FpdCBmb3IgYXN5bmMgdGFza3Mgb3V0c2lkZSBvZiB0aGUgQW5ndWxhciB6b25lLlxuICAgKi9cbiAgd2FpdEZvclRhc2tzT3V0c2lkZUFuZ3VsYXIoKTogUHJvbWlzZTx2b2lkPjtcbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciBjb21wb25lbnQgaGFybmVzc2VzIHRoYXQgYWxsIGNvbXBvbmVudCBoYXJuZXNzIGF1dGhvcnMgc2hvdWxkIGV4dGVuZC4gVGhpcyBiYXNlXG4gKiBjb21wb25lbnQgaGFybmVzcyBwcm92aWRlcyB0aGUgYmFzaWMgYWJpbGl0eSB0byBsb2NhdGUgZWxlbWVudCBhbmQgc3ViLWNvbXBvbmVudCBoYXJuZXNzLiBJdFxuICogc2hvdWxkIGJlIGluaGVyaXRlZCB3aGVuIGRlZmluaW5nIHVzZXIncyBvd24gaGFybmVzcy5cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIENvbXBvbmVudEhhcm5lc3Mge1xuICBjb25zdHJ1Y3Rvcihwcm90ZWN0ZWQgcmVhZG9ubHkgbG9jYXRvckZhY3Rvcnk6IExvY2F0b3JGYWN0b3J5KSB7fVxuXG4gIC8qKiBHZXRzIGEgYFByb21pc2VgIGZvciB0aGUgYFRlc3RFbGVtZW50YCByZXByZXNlbnRpbmcgdGhlIGhvc3QgZWxlbWVudCBvZiB0aGUgY29tcG9uZW50LiAqL1xuICBhc3luYyBob3N0KCk6IFByb21pc2U8VGVzdEVsZW1lbnQ+IHtcbiAgICByZXR1cm4gdGhpcy5sb2NhdG9yRmFjdG9yeS5yb290RWxlbWVudDtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIGEgYExvY2F0b3JGYWN0b3J5YCBmb3IgdGhlIGRvY3VtZW50IHJvb3QgZWxlbWVudC4gVGhpcyBmYWN0b3J5IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZVxuICAgKiBsb2NhdG9ycyBmb3IgZWxlbWVudHMgdGhhdCBhIGNvbXBvbmVudCBjcmVhdGVzIG91dHNpZGUgb2YgaXRzIG93biByb290IGVsZW1lbnQuIChlLmcuIGJ5XG4gICAqIGFwcGVuZGluZyB0byBkb2N1bWVudC5ib2R5KS5cbiAgICovXG4gIHByb3RlY3RlZCBkb2N1bWVudFJvb3RMb2NhdG9yRmFjdG9yeSgpOiBMb2NhdG9yRmFjdG9yeSB7XG4gICAgcmV0dXJuIHRoaXMubG9jYXRvckZhY3RvcnkuZG9jdW1lbnRSb290TG9jYXRvckZhY3RvcnkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGFzeW5jaHJvbm91cyBsb2NhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZmluZCBhIGBDb21wb25lbnRIYXJuZXNzYCBpbnN0YW5jZVxuICAgKiBvciBlbGVtZW50IHVuZGVyIHRoZSBob3N0IGVsZW1lbnQgb2YgdGhpcyBgQ29tcG9uZW50SGFybmVzc2AuXG4gICAqIEBwYXJhbSBxdWVyaWVzIEEgbGlzdCBvZiBxdWVyaWVzIHNwZWNpZnlpbmcgd2hpY2ggaGFybmVzc2VzIGFuZCBlbGVtZW50cyB0byBzZWFyY2ggZm9yOlxuICAgKiAgIC0gQSBgc3RyaW5nYCBzZWFyY2hlcyBmb3IgZWxlbWVudHMgbWF0Y2hpbmcgdGhlIENTUyBzZWxlY3RvciBzcGVjaWZpZWQgYnkgdGhlIHN0cmluZy5cbiAgICogICAtIEEgYENvbXBvbmVudEhhcm5lc3NgIGNvbnN0cnVjdG9yIHNlYXJjaGVzIGZvciBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZVxuICAgKiAgICAgZ2l2ZW4gY2xhc3MuXG4gICAqICAgLSBBIGBIYXJuZXNzUHJlZGljYXRlYCBzZWFyY2hlcyBmb3IgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcyBtYXRjaGluZyB0aGUgZ2l2ZW5cbiAgICogICAgIHByZWRpY2F0ZS5cbiAgICogQHJldHVybiBBbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IHNlYXJjaGVzIGZvciBhbmQgcmV0dXJucyBhIGBQcm9taXNlYCBmb3IgdGhlXG4gICAqICAgZmlyc3QgZWxlbWVudCBvciBoYXJuZXNzIG1hdGNoaW5nIHRoZSBnaXZlbiBzZWFyY2ggY3JpdGVyaWEuIE1hdGNoZXMgYXJlIG9yZGVyZWQgZmlyc3QgYnlcbiAgICogICBvcmRlciBpbiB0aGUgRE9NLCBhbmQgc2Vjb25kIGJ5IG9yZGVyIGluIHRoZSBxdWVyaWVzIGxpc3QuIElmIG5vIG1hdGNoZXMgYXJlIGZvdW5kLCB0aGVcbiAgICogICBgUHJvbWlzZWAgcmVqZWN0cy4gVGhlIHR5cGUgdGhhdCB0aGUgYFByb21pc2VgIHJlc29sdmVzIHRvIGlzIGEgdW5pb24gb2YgYWxsIHJlc3VsdCB0eXBlcyBmb3JcbiAgICogICBlYWNoIHF1ZXJ5LlxuICAgKlxuICAgKiBlLmcuIEdpdmVuIHRoZSBmb2xsb3dpbmcgRE9NOiBgPGRpdiBpZD1cImQxXCIgLz48ZGl2IGlkPVwiZDJcIiAvPmAsIGFuZCBhc3N1bWluZ1xuICAgKiBgRGl2SGFybmVzcy5ob3N0U2VsZWN0b3IgPT09ICdkaXYnYDpcbiAgICogLSBgYXdhaXQgY2gubG9jYXRvckZvcihEaXZIYXJuZXNzLCAnZGl2JykoKWAgZ2V0cyBhIGBEaXZIYXJuZXNzYCBpbnN0YW5jZSBmb3IgYCNkMWBcbiAgICogLSBgYXdhaXQgY2gubG9jYXRvckZvcignZGl2JywgRGl2SGFybmVzcykoKWAgZ2V0cyBhIGBUZXN0RWxlbWVudGAgaW5zdGFuY2UgZm9yIGAjZDFgXG4gICAqIC0gYGF3YWl0IGNoLmxvY2F0b3JGb3IoJ3NwYW4nKSgpYCB0aHJvd3MgYmVjYXVzZSB0aGUgYFByb21pc2VgIHJlamVjdHMuXG4gICAqL1xuICBwcm90ZWN0ZWQgbG9jYXRvckZvcjxUIGV4dGVuZHMgKEhhcm5lc3NRdWVyeTxhbnk+IHwgc3RyaW5nKVtdPihcbiAgICAuLi5xdWVyaWVzOiBUXG4gICk6IEFzeW5jRmFjdG9yeUZuPExvY2F0b3JGblJlc3VsdDxUPj4ge1xuICAgIHJldHVybiB0aGlzLmxvY2F0b3JGYWN0b3J5LmxvY2F0b3JGb3IoLi4ucXVlcmllcyk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyBhbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IGNhbiBiZSB1c2VkIHRvIGZpbmQgYSBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VcbiAgICogb3IgZWxlbWVudCB1bmRlciB0aGUgaG9zdCBlbGVtZW50IG9mIHRoaXMgYENvbXBvbmVudEhhcm5lc3NgLlxuICAgKiBAcGFyYW0gcXVlcmllcyBBIGxpc3Qgb2YgcXVlcmllcyBzcGVjaWZ5aW5nIHdoaWNoIGhhcm5lc3NlcyBhbmQgZWxlbWVudHMgdG8gc2VhcmNoIGZvcjpcbiAgICogICAtIEEgYHN0cmluZ2Agc2VhcmNoZXMgZm9yIGVsZW1lbnRzIG1hdGNoaW5nIHRoZSBDU1Mgc2VsZWN0b3Igc3BlY2lmaWVkIGJ5IHRoZSBzdHJpbmcuXG4gICAqICAgLSBBIGBDb21wb25lbnRIYXJuZXNzYCBjb25zdHJ1Y3RvciBzZWFyY2hlcyBmb3IgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcyBtYXRjaGluZyB0aGVcbiAgICogICAgIGdpdmVuIGNsYXNzLlxuICAgKiAgIC0gQSBgSGFybmVzc1ByZWRpY2F0ZWAgc2VhcmNoZXMgZm9yIGBDb21wb25lbnRIYXJuZXNzYCBpbnN0YW5jZXMgbWF0Y2hpbmcgdGhlIGdpdmVuXG4gICAqICAgICBwcmVkaWNhdGUuXG4gICAqIEByZXR1cm4gQW4gYXN5bmNocm9ub3VzIGxvY2F0b3IgZnVuY3Rpb24gdGhhdCBzZWFyY2hlcyBmb3IgYW5kIHJldHVybnMgYSBgUHJvbWlzZWAgZm9yIHRoZVxuICAgKiAgIGZpcnN0IGVsZW1lbnQgb3IgaGFybmVzcyBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VhcmNoIGNyaXRlcmlhLiBNYXRjaGVzIGFyZSBvcmRlcmVkIGZpcnN0IGJ5XG4gICAqICAgb3JkZXIgaW4gdGhlIERPTSwgYW5kIHNlY29uZCBieSBvcmRlciBpbiB0aGUgcXVlcmllcyBsaXN0LiBJZiBubyBtYXRjaGVzIGFyZSBmb3VuZCwgdGhlXG4gICAqICAgYFByb21pc2VgIGlzIHJlc29sdmVkIHdpdGggYG51bGxgLiBUaGUgdHlwZSB0aGF0IHRoZSBgUHJvbWlzZWAgcmVzb2x2ZXMgdG8gaXMgYSB1bmlvbiBvZiBhbGxcbiAgICogICByZXN1bHQgdHlwZXMgZm9yIGVhY2ggcXVlcnkgb3IgbnVsbC5cbiAgICpcbiAgICogZS5nLiBHaXZlbiB0aGUgZm9sbG93aW5nIERPTTogYDxkaXYgaWQ9XCJkMVwiIC8+PGRpdiBpZD1cImQyXCIgLz5gLCBhbmQgYXNzdW1pbmdcbiAgICogYERpdkhhcm5lc3MuaG9zdFNlbGVjdG9yID09PSAnZGl2J2A6XG4gICAqIC0gYGF3YWl0IGNoLmxvY2F0b3JGb3JPcHRpb25hbChEaXZIYXJuZXNzLCAnZGl2JykoKWAgZ2V0cyBhIGBEaXZIYXJuZXNzYCBpbnN0YW5jZSBmb3IgYCNkMWBcbiAgICogLSBgYXdhaXQgY2gubG9jYXRvckZvck9wdGlvbmFsKCdkaXYnLCBEaXZIYXJuZXNzKSgpYCBnZXRzIGEgYFRlc3RFbGVtZW50YCBpbnN0YW5jZSBmb3IgYCNkMWBcbiAgICogLSBgYXdhaXQgY2gubG9jYXRvckZvck9wdGlvbmFsKCdzcGFuJykoKWAgZ2V0cyBgbnVsbGAuXG4gICAqL1xuICBwcm90ZWN0ZWQgbG9jYXRvckZvck9wdGlvbmFsPFQgZXh0ZW5kcyAoSGFybmVzc1F1ZXJ5PGFueT4gfCBzdHJpbmcpW10+KFxuICAgIC4uLnF1ZXJpZXM6IFRcbiAgKTogQXN5bmNGYWN0b3J5Rm48TG9jYXRvckZuUmVzdWx0PFQ+IHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLmxvY2F0b3JGYWN0b3J5LmxvY2F0b3JGb3JPcHRpb25hbCguLi5xdWVyaWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGFuIGFzeW5jaHJvbm91cyBsb2NhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gZmluZCBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzXG4gICAqIG9yIGVsZW1lbnRzIHVuZGVyIHRoZSBob3N0IGVsZW1lbnQgb2YgdGhpcyBgQ29tcG9uZW50SGFybmVzc2AuXG4gICAqIEBwYXJhbSBxdWVyaWVzIEEgbGlzdCBvZiBxdWVyaWVzIHNwZWNpZnlpbmcgd2hpY2ggaGFybmVzc2VzIGFuZCBlbGVtZW50cyB0byBzZWFyY2ggZm9yOlxuICAgKiAgIC0gQSBgc3RyaW5nYCBzZWFyY2hlcyBmb3IgZWxlbWVudHMgbWF0Y2hpbmcgdGhlIENTUyBzZWxlY3RvciBzcGVjaWZpZWQgYnkgdGhlIHN0cmluZy5cbiAgICogICAtIEEgYENvbXBvbmVudEhhcm5lc3NgIGNvbnN0cnVjdG9yIHNlYXJjaGVzIGZvciBgQ29tcG9uZW50SGFybmVzc2AgaW5zdGFuY2VzIG1hdGNoaW5nIHRoZVxuICAgKiAgICAgZ2l2ZW4gY2xhc3MuXG4gICAqICAgLSBBIGBIYXJuZXNzUHJlZGljYXRlYCBzZWFyY2hlcyBmb3IgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcyBtYXRjaGluZyB0aGUgZ2l2ZW5cbiAgICogICAgIHByZWRpY2F0ZS5cbiAgICogQHJldHVybiBBbiBhc3luY2hyb25vdXMgbG9jYXRvciBmdW5jdGlvbiB0aGF0IHNlYXJjaGVzIGZvciBhbmQgcmV0dXJucyBhIGBQcm9taXNlYCBmb3IgYWxsXG4gICAqICAgZWxlbWVudHMgYW5kIGhhcm5lc3NlcyBtYXRjaGluZyB0aGUgZ2l2ZW4gc2VhcmNoIGNyaXRlcmlhLiBNYXRjaGVzIGFyZSBvcmRlcmVkIGZpcnN0IGJ5XG4gICAqICAgb3JkZXIgaW4gdGhlIERPTSwgYW5kIHNlY29uZCBieSBvcmRlciBpbiB0aGUgcXVlcmllcyBsaXN0LiBJZiBhbiBlbGVtZW50IG1hdGNoZXMgbW9yZSB0aGFuXG4gICAqICAgb25lIGBDb21wb25lbnRIYXJuZXNzYCBjbGFzcywgdGhlIGxvY2F0b3IgZ2V0cyBhbiBpbnN0YW5jZSBvZiBlYWNoIGZvciB0aGUgc2FtZSBlbGVtZW50LiBJZlxuICAgKiAgIGFuIGVsZW1lbnQgbWF0Y2hlcyBtdWx0aXBsZSBgc3RyaW5nYCBzZWxlY3RvcnMsIG9ubHkgb25lIGBUZXN0RWxlbWVudGAgaW5zdGFuY2UgaXMgcmV0dXJuZWRcbiAgICogICBmb3IgdGhhdCBlbGVtZW50LiBUaGUgdHlwZSB0aGF0IHRoZSBgUHJvbWlzZWAgcmVzb2x2ZXMgdG8gaXMgYW4gYXJyYXkgd2hlcmUgZWFjaCBlbGVtZW50IGlzXG4gICAqICAgdGhlIHVuaW9uIG9mIGFsbCByZXN1bHQgdHlwZXMgZm9yIGVhY2ggcXVlcnkuXG4gICAqXG4gICAqIGUuZy4gR2l2ZW4gdGhlIGZvbGxvd2luZyBET006IGA8ZGl2IGlkPVwiZDFcIiAvPjxkaXYgaWQ9XCJkMlwiIC8+YCwgYW5kIGFzc3VtaW5nXG4gICAqIGBEaXZIYXJuZXNzLmhvc3RTZWxlY3RvciA9PT0gJ2RpdidgIGFuZCBgSWRJc0QxSGFybmVzcy5ob3N0U2VsZWN0b3IgPT09ICcjZDEnYDpcbiAgICogLSBgYXdhaXQgY2gubG9jYXRvckZvckFsbChEaXZIYXJuZXNzLCAnZGl2JykoKWAgZ2V0cyBgW1xuICAgKiAgICAgRGl2SGFybmVzcywgLy8gZm9yICNkMVxuICAgKiAgICAgVGVzdEVsZW1lbnQsIC8vIGZvciAjZDFcbiAgICogICAgIERpdkhhcm5lc3MsIC8vIGZvciAjZDJcbiAgICogICAgIFRlc3RFbGVtZW50IC8vIGZvciAjZDJcbiAgICogICBdYFxuICAgKiAtIGBhd2FpdCBjaC5sb2NhdG9yRm9yQWxsKCdkaXYnLCAnI2QxJykoKWAgZ2V0cyBgW1xuICAgKiAgICAgVGVzdEVsZW1lbnQsIC8vIGZvciAjZDFcbiAgICogICAgIFRlc3RFbGVtZW50IC8vIGZvciAjZDJcbiAgICogICBdYFxuICAgKiAtIGBhd2FpdCBjaC5sb2NhdG9yRm9yQWxsKERpdkhhcm5lc3MsIElkSXNEMUhhcm5lc3MpKClgIGdldHMgYFtcbiAgICogICAgIERpdkhhcm5lc3MsIC8vIGZvciAjZDFcbiAgICogICAgIElkSXNEMUhhcm5lc3MsIC8vIGZvciAjZDFcbiAgICogICAgIERpdkhhcm5lc3MgLy8gZm9yICNkMlxuICAgKiAgIF1gXG4gICAqIC0gYGF3YWl0IGNoLmxvY2F0b3JGb3JBbGwoJ3NwYW4nKSgpYCBnZXRzIGBbXWAuXG4gICAqL1xuICBwcm90ZWN0ZWQgbG9jYXRvckZvckFsbDxUIGV4dGVuZHMgKEhhcm5lc3NRdWVyeTxhbnk+IHwgc3RyaW5nKVtdPihcbiAgICAuLi5xdWVyaWVzOiBUXG4gICk6IEFzeW5jRmFjdG9yeUZuPExvY2F0b3JGblJlc3VsdDxUPltdPiB7XG4gICAgcmV0dXJuIHRoaXMubG9jYXRvckZhY3RvcnkubG9jYXRvckZvckFsbCguLi5xdWVyaWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbHVzaGVzIGNoYW5nZSBkZXRlY3Rpb24gYW5kIGFzeW5jIHRhc2tzIGluIHRoZSBBbmd1bGFyIHpvbmUuXG4gICAqIEluIG1vc3QgY2FzZXMgaXQgc2hvdWxkIG5vdCBiZSBuZWNlc3NhcnkgdG8gY2FsbCB0aGlzIG1hbnVhbGx5LiBIb3dldmVyLCB0aGVyZSBtYXkgYmUgc29tZSBlZGdlXG4gICAqIGNhc2VzIHdoZXJlIGl0IGlzIG5lZWRlZCB0byBmdWxseSBmbHVzaCBhbmltYXRpb24gZXZlbnRzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGZvcmNlU3RhYmlsaXplKCkge1xuICAgIHJldHVybiB0aGlzLmxvY2F0b3JGYWN0b3J5LmZvcmNlU3RhYmlsaXplKCk7XG4gIH1cblxuICAvKipcbiAgICogV2FpdHMgZm9yIGFsbCBzY2hlZHVsZWQgb3IgcnVubmluZyBhc3luYyB0YXNrcyB0byBjb21wbGV0ZS4gVGhpcyBhbGxvd3MgaGFybmVzc1xuICAgKiBhdXRob3JzIHRvIHdhaXQgZm9yIGFzeW5jIHRhc2tzIG91dHNpZGUgb2YgdGhlIEFuZ3VsYXIgem9uZS5cbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyB3YWl0Rm9yVGFza3NPdXRzaWRlQW5ndWxhcigpIHtcbiAgICByZXR1cm4gdGhpcy5sb2NhdG9yRmFjdG9yeS53YWl0Rm9yVGFza3NPdXRzaWRlQW5ndWxhcigpO1xuICB9XG59XG5cbi8qKlxuICogQmFzZSBjbGFzcyBmb3IgY29tcG9uZW50IGhhcm5lc3NlcyB0aGF0IGF1dGhvcnMgc2hvdWxkIGV4dGVuZCBpZiB0aGV5IGFudGljaXBhdGUgdGhhdCBjb25zdW1lcnNcbiAqIG9mIHRoZSBoYXJuZXNzIG1heSB3YW50IHRvIGFjY2VzcyBvdGhlciBoYXJuZXNzZXMgd2l0aGluIHRoZSBgPG5nLWNvbnRlbnQ+YCBvZiB0aGUgY29tcG9uZW50LlxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQ29udGVudENvbnRhaW5lckNvbXBvbmVudEhhcm5lc3M8UyBleHRlbmRzIHN0cmluZyA9IHN0cmluZz5cbiAgZXh0ZW5kcyBDb21wb25lbnRIYXJuZXNzXG4gIGltcGxlbWVudHMgSGFybmVzc0xvYWRlclxue1xuICBhc3luYyBnZXRDaGlsZExvYWRlcihzZWxlY3RvcjogUyk6IFByb21pc2U8SGFybmVzc0xvYWRlcj4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5nZXRSb290SGFybmVzc0xvYWRlcigpKS5nZXRDaGlsZExvYWRlcihzZWxlY3Rvcik7XG4gIH1cblxuICBhc3luYyBnZXRBbGxDaGlsZExvYWRlcnMoc2VsZWN0b3I6IFMpOiBQcm9taXNlPEhhcm5lc3NMb2FkZXJbXT4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5nZXRSb290SGFybmVzc0xvYWRlcigpKS5nZXRBbGxDaGlsZExvYWRlcnMoc2VsZWN0b3IpO1xuICB9XG5cbiAgYXN5bmMgZ2V0SGFybmVzczxUIGV4dGVuZHMgQ29tcG9uZW50SGFybmVzcz4ocXVlcnk6IEhhcm5lc3NRdWVyeTxUPik6IFByb21pc2U8VD4ge1xuICAgIHJldHVybiAoYXdhaXQgdGhpcy5nZXRSb290SGFybmVzc0xvYWRlcigpKS5nZXRIYXJuZXNzKHF1ZXJ5KTtcbiAgfVxuXG4gIGFzeW5jIGdldEhhcm5lc3NPck51bGw8VCBleHRlbmRzIENvbXBvbmVudEhhcm5lc3M+KHF1ZXJ5OiBIYXJuZXNzUXVlcnk8VD4pOiBQcm9taXNlPFQgfCBudWxsPiB7XG4gICAgcmV0dXJuIChhd2FpdCB0aGlzLmdldFJvb3RIYXJuZXNzTG9hZGVyKCkpLmdldEhhcm5lc3NPck51bGwocXVlcnkpO1xuICB9XG5cbiAgYXN5bmMgZ2V0QWxsSGFybmVzc2VzPFQgZXh0ZW5kcyBDb21wb25lbnRIYXJuZXNzPihxdWVyeTogSGFybmVzc1F1ZXJ5PFQ+KTogUHJvbWlzZTxUW10+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0Um9vdEhhcm5lc3NMb2FkZXIoKSkuZ2V0QWxsSGFybmVzc2VzKHF1ZXJ5KTtcbiAgfVxuXG4gIGFzeW5jIGhhc0hhcm5lc3M8VCBleHRlbmRzIENvbXBvbmVudEhhcm5lc3M+KHF1ZXJ5OiBIYXJuZXNzUXVlcnk8VD4pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICByZXR1cm4gKGF3YWl0IHRoaXMuZ2V0Um9vdEhhcm5lc3NMb2FkZXIoKSkuaGFzSGFybmVzcyhxdWVyeSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcm9vdCBoYXJuZXNzIGxvYWRlciBmcm9tIHdoaWNoIHRvIHN0YXJ0XG4gICAqIHNlYXJjaGluZyBmb3IgY29udGVudCBjb250YWluZWQgYnkgdGhpcyBoYXJuZXNzLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGdldFJvb3RIYXJuZXNzTG9hZGVyKCk6IFByb21pc2U8SGFybmVzc0xvYWRlcj4ge1xuICAgIHJldHVybiB0aGlzLmxvY2F0b3JGYWN0b3J5LnJvb3RIYXJuZXNzTG9hZGVyKCk7XG4gIH1cbn1cblxuLyoqIENvbnN0cnVjdG9yIGZvciBhIENvbXBvbmVudEhhcm5lc3Mgc3ViY2xhc3MuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudEhhcm5lc3NDb25zdHJ1Y3RvcjxUIGV4dGVuZHMgQ29tcG9uZW50SGFybmVzcz4ge1xuICBuZXcgKGxvY2F0b3JGYWN0b3J5OiBMb2NhdG9yRmFjdG9yeSk6IFQ7XG5cbiAgLyoqXG4gICAqIGBDb21wb25lbnRIYXJuZXNzYCBzdWJjbGFzc2VzIG11c3Qgc3BlY2lmeSBhIHN0YXRpYyBgaG9zdFNlbGVjdG9yYCBwcm9wZXJ0eSB0aGF0IGlzIHVzZWQgdG9cbiAgICogZmluZCB0aGUgaG9zdCBlbGVtZW50IGZvciB0aGUgY29ycmVzcG9uZGluZyBjb21wb25lbnQuIFRoaXMgcHJvcGVydHkgc2hvdWxkIG1hdGNoIHRoZSBzZWxlY3RvclxuICAgKiBmb3IgdGhlIEFuZ3VsYXIgY29tcG9uZW50LlxuICAgKi9cbiAgaG9zdFNlbGVjdG9yOiBzdHJpbmc7XG59XG5cbi8qKiBBIHNldCBvZiBjcml0ZXJpYSB0aGF0IGNhbiBiZSB1c2VkIHRvIGZpbHRlciBhIGxpc3Qgb2YgYENvbXBvbmVudEhhcm5lc3NgIGluc3RhbmNlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQmFzZUhhcm5lc3NGaWx0ZXJzIHtcbiAgLyoqIE9ubHkgZmluZCBpbnN0YW5jZXMgd2hvc2UgaG9zdCBlbGVtZW50IG1hdGNoZXMgdGhlIGdpdmVuIHNlbGVjdG9yLiAqL1xuICBzZWxlY3Rvcj86IHN0cmluZztcbiAgLyoqIE9ubHkgZmluZCBpbnN0YW5jZXMgdGhhdCBhcmUgbmVzdGVkIHVuZGVyIGFuIGVsZW1lbnQgd2l0aCB0aGUgZ2l2ZW4gc2VsZWN0b3IuICovXG4gIGFuY2VzdG9yPzogc3RyaW5nO1xufVxuXG4vKipcbiAqIEEgY2xhc3MgdXNlZCB0byBhc3NvY2lhdGUgYSBDb21wb25lbnRIYXJuZXNzIGNsYXNzIHdpdGggcHJlZGljYXRlcyBmdW5jdGlvbnMgdGhhdCBjYW4gYmUgdXNlZCB0b1xuICogZmlsdGVyIGluc3RhbmNlcyBvZiB0aGUgY2xhc3MuXG4gKi9cbmV4cG9ydCBjbGFzcyBIYXJuZXNzUHJlZGljYXRlPFQgZXh0ZW5kcyBDb21wb25lbnRIYXJuZXNzPiB7XG4gIHByaXZhdGUgX3ByZWRpY2F0ZXM6IEFzeW5jUHJlZGljYXRlPFQ+W10gPSBbXTtcbiAgcHJpdmF0ZSBfZGVzY3JpcHRpb25zOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIF9hbmNlc3Rvcjogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBoYXJuZXNzVHlwZTogQ29tcG9uZW50SGFybmVzc0NvbnN0cnVjdG9yPFQ+LCBvcHRpb25zOiBCYXNlSGFybmVzc0ZpbHRlcnMpIHtcbiAgICB0aGlzLl9hZGRCYXNlT3B0aW9ucyhvcHRpb25zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBudWxsYWJsZSBzdHJpbmcgdmFsdWUgbWF0Y2hlcyB0aGUgZ2l2ZW4gcGF0dGVybi5cbiAgICogQHBhcmFtIHZhbHVlIFRoZSBudWxsYWJsZSBzdHJpbmcgdmFsdWUgdG8gY2hlY2ssIG9yIGEgUHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlXG4gICAqICAgbnVsbGFibGUgc3RyaW5nIHZhbHVlLlxuICAgKiBAcGFyYW0gcGF0dGVybiBUaGUgcGF0dGVybiB0aGUgdmFsdWUgaXMgZXhwZWN0ZWQgdG8gbWF0Y2guIElmIGBwYXR0ZXJuYCBpcyBhIHN0cmluZyxcbiAgICogICBgdmFsdWVgIGlzIGV4cGVjdGVkIHRvIG1hdGNoIGV4YWN0bHkuIElmIGBwYXR0ZXJuYCBpcyBhIHJlZ2V4LCBhIHBhcnRpYWwgbWF0Y2ggaXNcbiAgICogICBhbGxvd2VkLiBJZiBgcGF0dGVybmAgaXMgYG51bGxgLCB0aGUgdmFsdWUgaXMgZXhwZWN0ZWQgdG8gYmUgYG51bGxgLlxuICAgKiBAcmV0dXJuIFdoZXRoZXIgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIHBhdHRlcm4uXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgc3RyaW5nTWF0Y2hlcyhcbiAgICB2YWx1ZTogc3RyaW5nIHwgbnVsbCB8IFByb21pc2U8c3RyaW5nIHwgbnVsbD4sXG4gICAgcGF0dGVybjogc3RyaW5nIHwgUmVnRXhwIHwgbnVsbCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgdmFsdWUgPSBhd2FpdCB2YWx1ZTtcbiAgICBpZiAocGF0dGVybiA9PT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHZhbHVlID09PSBudWxsO1xuICAgIH0gZWxzZSBpZiAodmFsdWUgPT09IG51bGwpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGVvZiBwYXR0ZXJuID09PSAnc3RyaW5nJyA/IHZhbHVlID09PSBwYXR0ZXJuIDogcGF0dGVybi50ZXN0KHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIGJlIHJ1biBhZ2FpbnN0IGNhbmRpZGF0ZSBoYXJuZXNzZXMuXG4gICAqIEBwYXJhbSBkZXNjcmlwdGlvbiBBIGRlc2NyaXB0aW9uIG9mIHRoaXMgcHJlZGljYXRlIHRoYXQgbWF5IGJlIHVzZWQgaW4gZXJyb3IgbWVzc2FnZXMuXG4gICAqIEBwYXJhbSBwcmVkaWNhdGUgQW4gYXN5bmMgcHJlZGljYXRlIGZ1bmN0aW9uLlxuICAgKiBAcmV0dXJuIHRoaXMgKGZvciBtZXRob2QgY2hhaW5pbmcpLlxuICAgKi9cbiAgYWRkKGRlc2NyaXB0aW9uOiBzdHJpbmcsIHByZWRpY2F0ZTogQXN5bmNQcmVkaWNhdGU8VD4pIHtcbiAgICB0aGlzLl9kZXNjcmlwdGlvbnMucHVzaChkZXNjcmlwdGlvbik7XG4gICAgdGhpcy5fcHJlZGljYXRlcy5wdXNoKHByZWRpY2F0ZSk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHByZWRpY2F0ZSBmdW5jdGlvbiB0aGF0IGRlcGVuZHMgb24gYW4gb3B0aW9uIHZhbHVlIHRvIGJlIHJ1biBhZ2FpbnN0IGNhbmRpZGF0ZVxuICAgKiBoYXJuZXNzZXMuIElmIHRoZSBvcHRpb24gdmFsdWUgaXMgdW5kZWZpbmVkLCB0aGUgcHJlZGljYXRlIHdpbGwgYmUgaWdub3JlZC5cbiAgICogQHBhcmFtIG5hbWUgVGhlIG5hbWUgb2YgdGhlIG9wdGlvbiAobWF5IGJlIHVzZWQgaW4gZXJyb3IgbWVzc2FnZXMpLlxuICAgKiBAcGFyYW0gb3B0aW9uIFRoZSBvcHRpb24gdmFsdWUuXG4gICAqIEBwYXJhbSBwcmVkaWNhdGUgVGhlIHByZWRpY2F0ZSBmdW5jdGlvbiB0byBydW4gaWYgdGhlIG9wdGlvbiB2YWx1ZSBpcyBub3QgdW5kZWZpbmVkLlxuICAgKiBAcmV0dXJuIHRoaXMgKGZvciBtZXRob2QgY2hhaW5pbmcpLlxuICAgKi9cbiAgYWRkT3B0aW9uPE8+KG5hbWU6IHN0cmluZywgb3B0aW9uOiBPIHwgdW5kZWZpbmVkLCBwcmVkaWNhdGU6IEFzeW5jT3B0aW9uUHJlZGljYXRlPFQsIE8+KSB7XG4gICAgaWYgKG9wdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmFkZChgJHtuYW1lfSA9ICR7X3ZhbHVlQXNTdHJpbmcob3B0aW9uKX1gLCBpdGVtID0+IHByZWRpY2F0ZShpdGVtLCBvcHRpb24pKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhIGxpc3Qgb2YgaGFybmVzc2VzIG9uIHRoaXMgcHJlZGljYXRlLlxuICAgKiBAcGFyYW0gaGFybmVzc2VzIFRoZSBsaXN0IG9mIGhhcm5lc3NlcyB0byBmaWx0ZXIuXG4gICAqIEByZXR1cm4gQSBsaXN0IG9mIGhhcm5lc3NlcyB0aGF0IHNhdGlzZnkgdGhpcyBwcmVkaWNhdGUuXG4gICAqL1xuICBhc3luYyBmaWx0ZXIoaGFybmVzc2VzOiBUW10pOiBQcm9taXNlPFRbXT4ge1xuICAgIGlmIChoYXJuZXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBwYXJhbGxlbCgoKSA9PiBoYXJuZXNzZXMubWFwKGggPT4gdGhpcy5ldmFsdWF0ZShoKSkpO1xuICAgIHJldHVybiBoYXJuZXNzZXMuZmlsdGVyKChfLCBpKSA9PiByZXN1bHRzW2ldKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFdmFsdWF0ZXMgd2hldGhlciB0aGUgZ2l2ZW4gaGFybmVzcyBzYXRpc2ZpZXMgdGhpcyBwcmVkaWNhdGUuXG4gICAqIEBwYXJhbSBoYXJuZXNzIFRoZSBoYXJuZXNzIHRvIGNoZWNrXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdHJ1ZSBpZiB0aGUgaGFybmVzcyBzYXRpc2ZpZXMgdGhpcyBwcmVkaWNhdGUsXG4gICAqICAgYW5kIHJlc29sdmVzIHRvIGZhbHNlIG90aGVyd2lzZS5cbiAgICovXG4gIGFzeW5jIGV2YWx1YXRlKGhhcm5lc3M6IFQpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgcGFyYWxsZWwoKCkgPT4gdGhpcy5fcHJlZGljYXRlcy5tYXAocCA9PiBwKGhhcm5lc3MpKSk7XG4gICAgcmV0dXJuIHJlc3VsdHMucmVkdWNlKChjb21iaW5lZCwgY3VycmVudCkgPT4gY29tYmluZWQgJiYgY3VycmVudCwgdHJ1ZSk7XG4gIH1cblxuICAvKiogR2V0cyBhIGRlc2NyaXB0aW9uIG9mIHRoaXMgcHJlZGljYXRlIGZvciB1c2UgaW4gZXJyb3IgbWVzc2FnZXMuICovXG4gIGdldERlc2NyaXB0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9kZXNjcmlwdGlvbnMuam9pbignLCAnKTtcbiAgfVxuXG4gIC8qKiBHZXRzIHRoZSBzZWxlY3RvciB1c2VkIHRvIGZpbmQgY2FuZGlkYXRlIGVsZW1lbnRzLiAqL1xuICBnZXRTZWxlY3RvcigpIHtcbiAgICAvLyBXZSBkb24ndCBoYXZlIHRvIGdvIHRocm91Z2ggdGhlIGV4dHJhIHRyb3VibGUgaWYgdGhlcmUgYXJlIG5vIGFuY2VzdG9ycy5cbiAgICBpZiAoIXRoaXMuX2FuY2VzdG9yKSB7XG4gICAgICByZXR1cm4gKHRoaXMuaGFybmVzc1R5cGUuaG9zdFNlbGVjdG9yIHx8ICcnKS50cmltKCk7XG4gICAgfVxuXG4gICAgY29uc3QgW2FuY2VzdG9ycywgYW5jZXN0b3JQbGFjZWhvbGRlcnNdID0gX3NwbGl0QW5kRXNjYXBlU2VsZWN0b3IodGhpcy5fYW5jZXN0b3IpO1xuICAgIGNvbnN0IFtzZWxlY3RvcnMsIHNlbGVjdG9yUGxhY2Vob2xkZXJzXSA9IF9zcGxpdEFuZEVzY2FwZVNlbGVjdG9yKFxuICAgICAgdGhpcy5oYXJuZXNzVHlwZS5ob3N0U2VsZWN0b3IgfHwgJycsXG4gICAgKTtcbiAgICBjb25zdCByZXN1bHQ6IHN0cmluZ1tdID0gW107XG5cbiAgICAvLyBXZSBoYXZlIHRvIGFkZCB0aGUgYW5jZXN0b3IgdG8gZWFjaCBwYXJ0IG9mIHRoZSBob3N0IGNvbXBvdW5kIHNlbGVjdG9yLCBvdGhlcndpc2Ugd2UgY2FuIGdldFxuICAgIC8vIGluY29ycmVjdCByZXN1bHRzLiBFLmcuIGAuYW5jZXN0b3IgLmEsIC5hbmNlc3RvciAuYmAgdnMgYC5hbmNlc3RvciAuYSwgLmJgLlxuICAgIGFuY2VzdG9ycy5mb3JFYWNoKGVzY2FwZWRBbmNlc3RvciA9PiB7XG4gICAgICBjb25zdCBhbmNlc3RvciA9IF9yZXN0b3JlU2VsZWN0b3IoZXNjYXBlZEFuY2VzdG9yLCBhbmNlc3RvclBsYWNlaG9sZGVycyk7XG4gICAgICByZXR1cm4gc2VsZWN0b3JzLmZvckVhY2goZXNjYXBlZFNlbGVjdG9yID0+XG4gICAgICAgIHJlc3VsdC5wdXNoKGAke2FuY2VzdG9yfSAke19yZXN0b3JlU2VsZWN0b3IoZXNjYXBlZFNlbGVjdG9yLCBzZWxlY3RvclBsYWNlaG9sZGVycyl9YCksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdC5qb2luKCcsICcpO1xuICB9XG5cbiAgLyoqIEFkZHMgYmFzZSBvcHRpb25zIGNvbW1vbiB0byBhbGwgaGFybmVzcyB0eXBlcy4gKi9cbiAgcHJpdmF0ZSBfYWRkQmFzZU9wdGlvbnMob3B0aW9uczogQmFzZUhhcm5lc3NGaWx0ZXJzKSB7XG4gICAgdGhpcy5fYW5jZXN0b3IgPSBvcHRpb25zLmFuY2VzdG9yIHx8ICcnO1xuICAgIGlmICh0aGlzLl9hbmNlc3Rvcikge1xuICAgICAgdGhpcy5fZGVzY3JpcHRpb25zLnB1c2goYGhhcyBhbmNlc3RvciBtYXRjaGluZyBzZWxlY3RvciBcIiR7dGhpcy5fYW5jZXN0b3J9XCJgKTtcbiAgICB9XG4gICAgY29uc3Qgc2VsZWN0b3IgPSBvcHRpb25zLnNlbGVjdG9yO1xuICAgIGlmIChzZWxlY3RvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLmFkZChgaG9zdCBtYXRjaGVzIHNlbGVjdG9yIFwiJHtzZWxlY3Rvcn1cImAsIGFzeW5jIGl0ZW0gPT4ge1xuICAgICAgICByZXR1cm4gKGF3YWl0IGl0ZW0uaG9zdCgpKS5tYXRjaGVzU2VsZWN0b3Ioc2VsZWN0b3IpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59XG5cbi8qKiBSZXByZXNlbnQgYSB2YWx1ZSBhcyBhIHN0cmluZyBmb3IgdGhlIHB1cnBvc2Ugb2YgbG9nZ2luZy4gKi9cbmZ1bmN0aW9uIF92YWx1ZUFzU3RyaW5nKHZhbHVlOiB1bmtub3duKSB7XG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuICd1bmRlZmluZWQnO1xuICB9XG4gIHRyeSB7XG4gICAgLy8gYEpTT04uc3RyaW5naWZ5YCBkb2Vzbid0IGhhbmRsZSBSZWdFeHAgcHJvcGVybHksIHNvIHdlIG5lZWQgYSBjdXN0b20gcmVwbGFjZXIuXG4gICAgLy8gVXNlIGEgY2hhcmFjdGVyIHRoYXQgaXMgdW5saWtlbHkgdG8gYXBwZWFyIGluIHJlYWwgc3RyaW5ncyB0byBkZW5vdGUgdGhlIHN0YXJ0IGFuZCBlbmQgb2ZcbiAgICAvLyB0aGUgcmVnZXguIFRoaXMgYWxsb3dzIHVzIHRvIHN0cmlwIG91dCB0aGUgZXh0cmEgcXVvdGVzIGFyb3VuZCB0aGUgdmFsdWUgYWRkZWQgYnlcbiAgICAvLyBgSlNPTi5zdHJpbmdpZnlgLiBBbHNvIGRvIGN1c3RvbSBlc2NhcGluZyBvbiBgXCJgIGNoYXJhY3RlcnMgdG8gcHJldmVudCBgSlNPTi5zdHJpbmdpZnlgXG4gICAgLy8gZnJvbSBlc2NhcGluZyB0aGVtIGFzIGlmIHRoZXkgd2VyZSBwYXJ0IG9mIGEgc3RyaW5nLlxuICAgIGNvbnN0IHN0cmluZ2lmaWVkVmFsdWUgPSBKU09OLnN0cmluZ2lmeSh2YWx1ZSwgKF8sIHYpID0+XG4gICAgICB2IGluc3RhbmNlb2YgUmVnRXhwXG4gICAgICAgID8gYOKXrE1BVF9SRV9FU0NBUEXil6wke3YudG9TdHJpbmcoKS5yZXBsYWNlKC9cIi9nLCAn4pesTUFUX1JFX0VTQ0FQReKXrCcpfeKXrE1BVF9SRV9FU0NBUEXil6xgXG4gICAgICAgIDogdixcbiAgICApO1xuICAgIC8vIFN0cmlwIG91dCB0aGUgZXh0cmEgcXVvdGVzIGFyb3VuZCByZWdleGVzIGFuZCBwdXQgYmFjayB0aGUgbWFudWFsbHkgZXNjYXBlZCBgXCJgIGNoYXJhY3RlcnMuXG4gICAgcmV0dXJuIHN0cmluZ2lmaWVkVmFsdWVcbiAgICAgIC5yZXBsYWNlKC9cIuKXrE1BVF9SRV9FU0NBUEXil6x84pesTUFUX1JFX0VTQ0FQReKXrFwiL2csICcnKVxuICAgICAgLnJlcGxhY2UoL+KXrE1BVF9SRV9FU0NBUEXil6wvZywgJ1wiJyk7XG4gIH0gY2F0Y2gge1xuICAgIC8vIGBKU09OLnN0cmluZ2lmeWAgd2lsbCB0aHJvdyBpZiB0aGUgb2JqZWN0IGlzIGN5Y2xpY2FsLFxuICAgIC8vIGluIHRoaXMgY2FzZSB0aGUgYmVzdCB3ZSBjYW4gZG8gaXMgcmVwb3J0IHRoZSB2YWx1ZSBhcyBgey4uLn1gLlxuICAgIHJldHVybiAney4uLn0nO1xuICB9XG59XG5cbi8qKlxuICogU3BsaXRzIHVwIGEgY29tcG91bmQgc2VsZWN0b3IgaW50byBpdHMgcGFydHMgYW5kIGVzY2FwZXMgYW55IHF1b3RlZCBjb250ZW50LiBUaGUgcXVvdGVkIGNvbnRlbnRcbiAqIGhhcyB0byBiZSBlc2NhcGVkLCBiZWNhdXNlIGl0IGNhbiBjb250YWluIGNvbW1hcyB3aGljaCB3aWxsIHRocm93IHRocm93IHVzIG9mZiB3aGVuIHRyeWluZyB0b1xuICogc3BsaXQgaXQuXG4gKiBAcGFyYW0gc2VsZWN0b3IgU2VsZWN0b3IgdG8gYmUgc3BsaXQuXG4gKiBAcmV0dXJucyBUaGUgZXNjYXBlZCBzdHJpbmcgd2hlcmUgYW55IHF1b3RlZCBjb250ZW50IGlzIHJlcGxhY2VkIHdpdGggYSBwbGFjZWhvbGRlci4gRS5nLlxuICogYFtmb289XCJiYXJcIl1gIHR1cm5zIGludG8gYFtmb289X19jZGtQbGFjZWhvbGRlci0wX19dYC4gVXNlIGBfcmVzdG9yZVNlbGVjdG9yYCB0byByZXN0b3JlXG4gKiB0aGUgcGxhY2Vob2xkZXJzLlxuICovXG5mdW5jdGlvbiBfc3BsaXRBbmRFc2NhcGVTZWxlY3RvcihzZWxlY3Rvcjogc3RyaW5nKTogW3BhcnRzOiBzdHJpbmdbXSwgcGxhY2Vob2xkZXJzOiBzdHJpbmdbXV0ge1xuICBjb25zdCBwbGFjZWhvbGRlcnM6IHN0cmluZ1tdID0gW107XG5cbiAgLy8gTm90ZSB0aGF0IHRoZSByZWdleCBkb2Vzbid0IGFjY291bnQgZm9yIG5lc3RlZCBxdW90ZXMgc28gc29tZXRoaW5nIGxpa2UgYFwiYWInY2QnZVwiYCB3aWxsIGJlXG4gIC8vIGNvbnNpZGVyZWQgYXMgdHdvIGJsb2Nrcy4gSXQncyBhIGJpdCBvZiBhbiBlZGdlIGNhc2UsIGJ1dCBpZiB3ZSBmaW5kIHRoYXQgaXQncyBhIHByb2JsZW0sXG4gIC8vIHdlIGNhbiBtYWtlIGl0IGEgYml0IHNtYXJ0ZXIgdXNpbmcgYSBsb29wLiBVc2UgdGhpcyBmb3Igbm93IHNpbmNlIGl0J3MgbW9yZSByZWFkYWJsZSBhbmRcbiAgLy8gY29tcGFjdC4gTW9yZSBjb21wbGV0ZSBpbXBsZW1lbnRhdGlvbjpcbiAgLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9ibG9iL2JkMzRiYzllODlmMThhL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9zaGFkb3dfY3NzLnRzI0w2NTVcbiAgY29uc3QgcmVzdWx0ID0gc2VsZWN0b3IucmVwbGFjZSgvKFtcIiddW15bXCInXSpbXCInXSkvZywgKF8sIGtlZXApID0+IHtcbiAgICBjb25zdCByZXBsYWNlQnkgPSBgX19jZGtQbGFjZWhvbGRlci0ke3BsYWNlaG9sZGVycy5sZW5ndGh9X19gO1xuICAgIHBsYWNlaG9sZGVycy5wdXNoKGtlZXApO1xuICAgIHJldHVybiByZXBsYWNlQnk7XG4gIH0pO1xuXG4gIHJldHVybiBbcmVzdWx0LnNwbGl0KCcsJykubWFwKHBhcnQgPT4gcGFydC50cmltKCkpLCBwbGFjZWhvbGRlcnNdO1xufVxuXG4vKiogUmVzdG9yZXMgYSBzZWxlY3RvciB3aG9zZSBjb250ZW50IHdhcyBlc2NhcGVkIGluIGBfc3BsaXRBbmRFc2NhcGVTZWxlY3RvcmAuICovXG5mdW5jdGlvbiBfcmVzdG9yZVNlbGVjdG9yKHNlbGVjdG9yOiBzdHJpbmcsIHBsYWNlaG9sZGVyczogc3RyaW5nW10pOiBzdHJpbmcge1xuICByZXR1cm4gc2VsZWN0b3IucmVwbGFjZSgvX19jZGtQbGFjZWhvbGRlci0oXFxkKylfXy9nLCAoXywgaW5kZXgpID0+IHBsYWNlaG9sZGVyc1sraW5kZXhdKTtcbn1cbiJdfQ==
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @license
|
|
3
|
-
* Copyright Google LLC All Rights Reserved.
|
|
4
|
-
*
|
|
5
|
-
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
-
* found in the LICENSE file at https://angular.io/license
|
|
7
|
-
*/
|
|
8
|
-
export {};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWxlbWVudC1kaW1lbnNpb25zLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Nkay90ZXN0aW5nL2VsZW1lbnQtZGltZW5zaW9ucy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUciLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuLyoqXG4gKiBEaW1lbnNpb25zIGZvciBlbGVtZW50IHNpemUgYW5kIGl0cyBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgdmlld3BvcnQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRWxlbWVudERpbWVuc2lvbnMge1xuICB0b3A6IG51bWJlcjtcbiAgbGVmdDogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbn1cbiJdfQ==
|