systelab-virtual-keyboard 19.0.0 → 20.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +11 -0
  2. package/fesm2022/systelab-virtual-keyboard.mjs +197 -117
  3. package/fesm2022/systelab-virtual-keyboard.mjs.map +1 -1
  4. package/index.d.ts +182 -6
  5. package/index.d.ts.map +1 -0
  6. package/package.json +6 -8
  7. package/scss/default-theme.scss +102 -0
  8. package/esm2022/lib/constants.mjs +0 -37
  9. package/esm2022/lib/systelab-virtual-keyboard-overlay.service.mjs +0 -177
  10. package/esm2022/lib/systelab-virtual-keyboard.component.mjs +0 -375
  11. package/esm2022/lib/systelab-virtual-keyboard.config.mjs +0 -3
  12. package/esm2022/lib/systelab-virtual-keyboard.directive.mjs +0 -215
  13. package/esm2022/lib/systelab-virtual-keyboard.module.mjs +0 -45
  14. package/esm2022/public-api.mjs +0 -7
  15. package/esm2022/systelab-virtual-keyboard.mjs +0 -5
  16. package/lib/constants.d.ts +0 -25
  17. package/lib/constants.d.ts.map +0 -1
  18. package/lib/systelab-virtual-keyboard-overlay.service.d.ts +0 -38
  19. package/lib/systelab-virtual-keyboard-overlay.service.d.ts.map +0 -1
  20. package/lib/systelab-virtual-keyboard.component.d.ts +0 -43
  21. package/lib/systelab-virtual-keyboard.component.d.ts.map +0 -1
  22. package/lib/systelab-virtual-keyboard.config.d.ts +0 -10
  23. package/lib/systelab-virtual-keyboard.config.d.ts.map +0 -1
  24. package/lib/systelab-virtual-keyboard.directive.d.ts +0 -44
  25. package/lib/systelab-virtual-keyboard.directive.d.ts.map +0 -1
  26. package/lib/systelab-virtual-keyboard.module.d.ts +0 -15
  27. package/lib/systelab-virtual-keyboard.module.d.ts.map +0 -1
  28. package/public-api.d.ts +0 -5
  29. package/public-api.d.ts.map +0 -1
  30. package/systelab-virtual-keyboard.d.ts.map +0 -1
@@ -0,0 +1,102 @@
1
+ @mixin forceWidth($width) {
2
+ min-width: #{$width} !important;
3
+ max-width: #{$width} !important;
4
+ }
5
+
6
+ :root {
7
+ --systelab-virtual-keyboard-font-family: 'SF Mono', 'Menlo', 'Consolas', 'Courier New', monospace;
8
+ --systelab-virtual-keyboard-background-color: #B2B2B2;
9
+ --systelab-virtual-keyboard-button-color: #E5E5E5;
10
+ --systelab-virtual-keyboard-button-font-color: #000000;
11
+ --systelab-virtual-keyboard-active-special-button-color: #4D4D4D;
12
+ --systelab-virtual-keyboard-active-special-button-font-color: #FFFFFF;
13
+ }
14
+
15
+ :host {
16
+ width: 100%;
17
+ }
18
+
19
+ .systelab-virtual-keyboard-theme {
20
+ font-family: var(--systelab-virtual-keyboard-font-family);
21
+ background-color: var(--systelab-virtual-keyboard-background-color);
22
+
23
+ .hg-row {
24
+ .hg-button {
25
+ box-sizing: border-box;
26
+ height: 65px;
27
+ min-width: 75px;
28
+ max-width: 75px !important;
29
+ border-radius: 10px;
30
+ &:not(:last-child) {
31
+ margin-right: 6.8px !important;
32
+ }
33
+ }
34
+ }
35
+
36
+ &.hg-layout-alpha-numeric,
37
+ &.hg-layout-alpha-numeric-shift,
38
+ &.hg-layout-alpha-numeric-uppercase,
39
+ &.hg-layout-alpha-numeric-uppercase-shift {
40
+ .hg-row {
41
+ &:first-child .hg-button {
42
+ height: 50px;
43
+ }
44
+ }
45
+ .hg-button-shift {
46
+ @include forceWidth(182px);
47
+ }
48
+
49
+ .hg-button-bksp {
50
+ @include forceWidth(125px);
51
+ }
52
+
53
+ .hg-button-tab {
54
+ @include forceWidth(126px);
55
+ }
56
+
57
+ .hg-button-enter,
58
+ .hg-button-lock {
59
+ @include forceWidth(141px);
60
+ }
61
+
62
+ .hg-button-space {
63
+ @include forceWidth(100%);
64
+ }
65
+ }
66
+
67
+ .virtual-keyboard-delete-button,
68
+ .virtual-keyboard-enter-button,
69
+ .virtual-keyboard-function-button {
70
+ background-color: var(--systelab-virtual-keyboard-button-color);
71
+ color: var(--systelab-virtual-keyboard-button-font-color);
72
+ &:first-child {
73
+ justify-content: flex-start;
74
+ align-items: flex-end;
75
+ padding-left: 15px;
76
+ padding-bottom: 15px;
77
+ }
78
+ &:last-child {
79
+ justify-content: flex-end;
80
+ align-items: flex-end;
81
+ padding-right: 15px;
82
+ padding-bottom: 15px;
83
+ }
84
+ }
85
+
86
+ .hg-button-tab {
87
+ justify-content: flex-start;
88
+ align-items: flex-end;
89
+ padding-left: 15px;
90
+ padding-bottom: 15px;
91
+ }
92
+
93
+ .virtual-keyboard-lock-active,
94
+ .virtual-keyboard-shift-active {
95
+ background-color: var(--systelab-virtual-keyboard-active-special-button-color);
96
+ color: var(--systelab-virtual-keyboard-active-special-button-font-color);
97
+ }
98
+
99
+ .virtual-keyboard-uppercase {
100
+ text-transform: uppercase;
101
+ }
102
+ }
@@ -1,37 +0,0 @@
1
- /*
2
- * Copyright (c) 2020 - 2024 - Instrumentation Laboratory Company and Systelab Technologies, SA. All rights reserved.
3
- * NOTICE: All information contained herein is and remains the property of Instrumentation Laboratory Company and its
4
- * affiliates, if any. The intellectual and technical concepts contained herein are proprietary to Instrumentation
5
- * Laboratory Company and its affiliates and may be covered by U.S. and foreign patents and patent applications, and/or
6
- * are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is
7
- * strictly forbidden unless prior written permission is Instrumentation Laboratory Company.
8
- */
9
- export var SystelabVirtualKeyboardButton;
10
- (function (SystelabVirtualKeyboardButton) {
11
- SystelabVirtualKeyboardButton["Done"] = "{done}";
12
- SystelabVirtualKeyboardButton["Enter"] = "{enter}";
13
- SystelabVirtualKeyboardButton["Shift"] = "{shift}";
14
- SystelabVirtualKeyboardButton["Lock"] = "{lock}";
15
- SystelabVirtualKeyboardButton["Backspace"] = "{bksp}";
16
- SystelabVirtualKeyboardButton["Language"] = "{language}";
17
- SystelabVirtualKeyboardButton["Space"] = "{space}";
18
- SystelabVirtualKeyboardButton["Tab"] = "{tab}";
19
- })(SystelabVirtualKeyboardButton || (SystelabVirtualKeyboardButton = {}));
20
- export var SystelabVirtualKeyboardLayouts;
21
- (function (SystelabVirtualKeyboardLayouts) {
22
- SystelabVirtualKeyboardLayouts["default"] = "default";
23
- SystelabVirtualKeyboardLayouts["shift"] = "shift";
24
- SystelabVirtualKeyboardLayouts["numeric"] = "numeric";
25
- })(SystelabVirtualKeyboardLayouts || (SystelabVirtualKeyboardLayouts = {}));
26
- export var SystelabVirtualKeyboardInputMethods;
27
- (function (SystelabVirtualKeyboardInputMethods) {
28
- SystelabVirtualKeyboardInputMethods["onlyMouseEvents"] = "onlyMouseEvents";
29
- SystelabVirtualKeyboardInputMethods["onlyTouchEvents"] = "onlyTouchEvents";
30
- })(SystelabVirtualKeyboardInputMethods || (SystelabVirtualKeyboardInputMethods = {}));
31
- export var SystelabVirtualKeyboardInputModes;
32
- (function (SystelabVirtualKeyboardInputModes) {
33
- SystelabVirtualKeyboardInputModes["text"] = "text";
34
- SystelabVirtualKeyboardInputModes["numeric"] = "numeric";
35
- SystelabVirtualKeyboardInputModes["password"] = "password";
36
- })(SystelabVirtualKeyboardInputModes || (SystelabVirtualKeyboardInputModes = {}));
37
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC9zcmMvbGliL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBRUgsTUFBTSxDQUFOLElBQVksNkJBU1g7QUFURCxXQUFZLDZCQUE2QjtJQUNyQyxnREFBZSxDQUFBO0lBQ2Ysa0RBQWlCLENBQUE7SUFDakIsa0RBQWlCLENBQUE7SUFDakIsZ0RBQWUsQ0FBQTtJQUNmLHFEQUFvQixDQUFBO0lBQ3BCLHdEQUF1QixDQUFBO0lBQ3ZCLGtEQUFpQixDQUFBO0lBQ2pCLDhDQUFhLENBQUE7QUFDakIsQ0FBQyxFQVRXLDZCQUE2QixLQUE3Qiw2QkFBNkIsUUFTeEM7QUFFRCxNQUFNLENBQU4sSUFBWSw4QkFJWDtBQUpELFdBQVksOEJBQThCO0lBQ3RDLHFEQUFtQixDQUFBO0lBQ25CLGlEQUFlLENBQUE7SUFDZixxREFBbUIsQ0FBQTtBQUN2QixDQUFDLEVBSlcsOEJBQThCLEtBQTlCLDhCQUE4QixRQUl6QztBQUVELE1BQU0sQ0FBTixJQUFZLG1DQUdYO0FBSEQsV0FBWSxtQ0FBbUM7SUFDM0MsMEVBQW1DLENBQUE7SUFDbkMsMEVBQW1DLENBQUE7QUFDdkMsQ0FBQyxFQUhXLG1DQUFtQyxLQUFuQyxtQ0FBbUMsUUFHOUM7QUFFRCxNQUFNLENBQU4sSUFBWSxpQ0FJWDtBQUpELFdBQVksaUNBQWlDO0lBQ3pDLGtEQUFhLENBQUE7SUFDYix3REFBbUIsQ0FBQTtJQUNuQiwwREFBcUIsQ0FBQTtBQUN6QixDQUFDLEVBSlcsaUNBQWlDLEtBQWpDLGlDQUFpQyxRQUk1QyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gKiBDb3B5cmlnaHQgKGMpIDIwMjAgLSAyMDI0IC0gSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgU3lzdGVsYWIgVGVjaG5vbG9naWVzLCBTQS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIE5PVElDRTogIEFsbCBpbmZvcm1hdGlvbiBjb250YWluZWQgaGVyZWluIGlzIGFuZCByZW1haW5zIHRoZSBwcm9wZXJ0eSBvZiBJbnN0cnVtZW50YXRpb24gTGFib3JhdG9yeSBDb21wYW55IGFuZCBpdHNcbiAqIGFmZmlsaWF0ZXMsIGlmIGFueS4gIFRoZSBpbnRlbGxlY3R1YWwgYW5kIHRlY2huaWNhbCBjb25jZXB0cyBjb250YWluZWQgaGVyZWluIGFyZSBwcm9wcmlldGFyeSB0byBJbnN0cnVtZW50YXRpb25cbiAqIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzIGFmZmlsaWF0ZXMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIGZvcmVpZ24gcGF0ZW50cyBhbmQgcGF0ZW50IGFwcGxpY2F0aW9ucywgYW5kL29yXG4gKiBhcmUgcHJvdGVjdGVkIGJ5IHRyYWRlIHNlY3JldCBvciBjb3B5cmlnaHQgbGF3LiBEaXNzZW1pbmF0aW9uIG9mIHRoaXMgaW5mb3JtYXRpb24gb3IgcmVwcm9kdWN0aW9uIG9mIHRoaXMgbWF0ZXJpYWwgaXNcbiAqIHN0cmljdGx5IGZvcmJpZGRlbiB1bmxlc3MgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uIGlzIEluc3RydW1lbnRhdGlvbiBMYWJvcmF0b3J5IENvbXBhbnkuXG4gKi9cblxuZXhwb3J0IGVudW0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24ge1xuICAgIERvbmUgPSAne2RvbmV9JyxcbiAgICBFbnRlciA9ICd7ZW50ZXJ9JyxcbiAgICBTaGlmdCA9ICd7c2hpZnR9JyxcbiAgICBMb2NrID0gJ3tsb2NrfScsXG4gICAgQmFja3NwYWNlID0gJ3tia3NwfScsXG4gICAgTGFuZ3VhZ2UgPSAne2xhbmd1YWdlfScsXG4gICAgU3BhY2UgPSAne3NwYWNlfScsXG4gICAgVGFiID0gJ3t0YWJ9Jyxcbn1cblxuZXhwb3J0IGVudW0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzIHtcbiAgICBkZWZhdWx0ID0gJ2RlZmF1bHQnLFxuICAgIHNoaWZ0ID0gJ3NoaWZ0JyxcbiAgICBudW1lcmljID0gJ251bWVyaWMnLFxufVxuXG5leHBvcnQgZW51bSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZElucHV0TWV0aG9kcyB7XG4gICAgb25seU1vdXNlRXZlbnRzID0gJ29ubHlNb3VzZUV2ZW50cycsXG4gICAgb25seVRvdWNoRXZlbnRzID0gJ29ubHlUb3VjaEV2ZW50cycsXG59XG5cbmV4cG9ydCBlbnVtIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkSW5wdXRNb2RlcyB7XG4gICAgdGV4dCA9ICd0ZXh0JyxcbiAgICBudW1lcmljID0gJ251bWVyaWMnLFxuICAgIHBhc3N3b3JkID0gJ3Bhc3N3b3JkJyxcbn1cbiJdfQ==
@@ -1,177 +0,0 @@
1
- import { Injectable } from '@angular/core';
2
- import { ComponentPortal } from '@angular/cdk/portal';
3
- import { SystelabVirtualKeyboardLayouts } from './constants';
4
- import { SystelabVirtualKeyboardComponent } from './systelab-virtual-keyboard.component';
5
- import * as i0 from "@angular/core";
6
- import * as i1 from "@angular/cdk/overlay";
7
- export class SystelabVirtualKeyboardOverlayService {
8
- constructor(overlay) {
9
- this.overlay = overlay;
10
- this.clickAlreadyHandled = false;
11
- this.touchEndAlreadyHandled = false;
12
- this.initListener();
13
- }
14
- isCreated() {
15
- return !!this.overlayRef;
16
- }
17
- isOpen() {
18
- return this.open;
19
- }
20
- create(inputOrigin, showKeyboardButtonElement, fixedBottom, layout = SystelabVirtualKeyboardLayouts.default) {
21
- this.inputOrigin = inputOrigin;
22
- this.fixedBottom = fixedBottom;
23
- this.showKeyboardButtonElement = showKeyboardButtonElement;
24
- this.layout = layout;
25
- this.overlayRef = this.overlay.create({
26
- hasBackdrop: false,
27
- scrollStrategy: this.overlay.scrollStrategies.reposition(),
28
- disposeOnNavigation: true,
29
- backdropClass: 'systelab-virtual-keyboard__backdrop',
30
- panelClass: 'systelab-virtual-keyboard__panel',
31
- });
32
- if (fixedBottom) {
33
- this.overlayRef.addPanelClass('systelab-virtual-keyboard__panel--fixed-bottom');
34
- }
35
- this.updatePositionStrategy(inputOrigin, fixedBottom);
36
- this.updateSize();
37
- this.open = true;
38
- return this.overlayRef.attach(new ComponentPortal(SystelabVirtualKeyboardComponent));
39
- }
40
- updatePosition() {
41
- this.updatePositionStrategy(this.inputOrigin, this.fixedBottom);
42
- }
43
- setClickAlreadyHandled() {
44
- this.clickAlreadyHandled = true;
45
- }
46
- setTouchEndAlreadyHandled() {
47
- this.touchEndAlreadyHandled = true;
48
- }
49
- destroy() {
50
- if (this.overlayRef) {
51
- this.overlayRef.dispose();
52
- }
53
- this.overlayRef = null;
54
- this.open = false;
55
- }
56
- initListener() {
57
- document.addEventListener('click', this.handleClick.bind(this));
58
- document.addEventListener('touchend', this.handleTouchEnd.bind(this));
59
- }
60
- handleClick(event) {
61
- if (this.clickAlreadyHandled) {
62
- this.clickAlreadyHandled = false;
63
- return;
64
- }
65
- event.stopPropagation();
66
- this.handleEventTarget(event.target);
67
- }
68
- handleTouchEnd(event) {
69
- if (this.touchEndAlreadyHandled) {
70
- this.touchEndAlreadyHandled = false;
71
- return;
72
- }
73
- event.stopPropagation();
74
- this.handleEventTarget(event.target);
75
- }
76
- handleEventTarget(target) {
77
- const showKeyboardButtonTarget = target?.classList.contains('virtual-keyboard-show-button');
78
- const virtualKeyboardTarget = document.querySelector('.simple-keyboard')?.contains(target);
79
- const inputElementTarget = this.inputOrigin?.contains(target);
80
- const containsShowButton = this.showKeyboardButtonElement?.contains(target);
81
- if (!virtualKeyboardTarget &&
82
- !inputElementTarget &&
83
- !containsShowButton &&
84
- !showKeyboardButtonTarget) {
85
- if (this.isCreated()) {
86
- this.destroy();
87
- }
88
- }
89
- }
90
- hasAttached() {
91
- return this.overlayRef?.hasAttached();
92
- }
93
- updatePositionStrategy(inputOrigin, fixedBottom) {
94
- if (!!this.overlayRef) {
95
- this.overlayRef.updatePositionStrategy(this.getPositionStrategy(inputOrigin, fixedBottom));
96
- }
97
- }
98
- updateSize() {
99
- if (!!this.overlayRef) {
100
- this.overlayRef.updateSize(this.getOverlaySize());
101
- }
102
- }
103
- getPositionStrategy(inputOrigin, fixedBottom) {
104
- if (fixedBottom) {
105
- return this.overlay.position().global().centerHorizontally().bottom('0');
106
- }
107
- const pointWithDimensions = this.computePositionStrategyOrigin(inputOrigin);
108
- return this.overlay
109
- .position()
110
- .flexibleConnectedTo(pointWithDimensions)
111
- .withFlexibleDimensions(false)
112
- .withLockedPosition(true)
113
- .withPush(false)
114
- .withPositions([
115
- {
116
- originX: 'start',
117
- originY: 'bottom',
118
- overlayX: 'start',
119
- overlayY: 'top',
120
- },
121
- {
122
- originX: 'start',
123
- originY: 'top',
124
- overlayX: 'start',
125
- overlayY: 'bottom',
126
- },
127
- {
128
- originX: 'end',
129
- originY: 'bottom',
130
- overlayX: 'end',
131
- overlayY: 'top',
132
- },
133
- {
134
- originX: 'end',
135
- originY: 'top',
136
- overlayX: 'end',
137
- overlayY: 'bottom',
138
- },
139
- ]);
140
- }
141
- getOverlaySize() {
142
- const overlayWidth = this.layout === SystelabVirtualKeyboardLayouts.numeric ? '400px' : '1200px';
143
- return {
144
- width: overlayWidth,
145
- maxWidth: overlayWidth,
146
- minWidth: overlayWidth,
147
- };
148
- }
149
- computePositionStrategyOrigin(inputOrigin) {
150
- const overlayOffsetX = this.computeOverlayOffsetX(inputOrigin);
151
- const { width: overlayWidthString } = this.getOverlaySize();
152
- const overlayWidth = Number(overlayWidthString.replace('px', ''));
153
- const { x, y, width, height } = inputOrigin.getBoundingClientRect();
154
- return {
155
- width,
156
- height,
157
- x: width < overlayWidth ? x - overlayOffsetX : x + overlayOffsetX,
158
- y,
159
- };
160
- }
161
- computeOverlayOffsetX(inputOrigin) {
162
- const { width: overlayWidthString } = this.getOverlaySize();
163
- const overlayWidth = Number(overlayWidthString.replace('px', ''));
164
- const inputWidth = inputOrigin.getBoundingClientRect().width;
165
- const extraWidth = overlayWidth - inputWidth;
166
- return Math.abs(extraWidth) / 2;
167
- }
168
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable }); }
169
- static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, providedIn: 'root' }); }
170
- }
171
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.8", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, decorators: [{
172
- type: Injectable,
173
- args: [{
174
- providedIn: 'root',
175
- }]
176
- }], ctorParameters: () => [{ type: i1.Overlay }] });
177
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC1vdmVybGF5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkL3NyYy9saWIvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC1vdmVybGF5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUEsT0FBTyxFQUFnQixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQzs7O0FBWXpGLE1BQU0sT0FBTyxxQ0FBcUM7SUFVOUMsWUFBNkIsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztRQUhyQyx3QkFBbUIsR0FBWSxLQUFLLENBQUM7UUFDckMsMkJBQXNCLEdBQVksS0FBSyxDQUFDO1FBRzVDLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRU0sU0FBUztRQUNaLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDN0IsQ0FBQztJQUVNLE1BQU07UUFDVCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDckIsQ0FBQztJQUVNLE1BQU0sQ0FDVCxXQUE2QixFQUM3Qix5QkFBc0MsRUFDdEMsV0FBb0IsRUFDcEIsU0FBeUMsOEJBQThCLENBQUMsT0FBTztRQUUvRSxJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQztRQUMvQixJQUFJLENBQUMseUJBQXlCLEdBQUcseUJBQXlCLENBQUM7UUFDM0QsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIs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UUFDNUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFFLGtCQUE2QixDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RSxNQUFNLEVBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFDLEdBQUcsV0FBVyxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDbEUsT0FBTztZQUNILEtBQUs7WUFDTCxNQUFNO1lBQ04sQ0FBQyxFQUFFLEtBQUssR0FBRyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxjQUFjLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxjQUFjO1lBQ2pFLENBQUM7U0FDSixDQUFDO0lBQ04sQ0FBQztJQUVPLHFCQUFxQixDQUFDLFdBQTZCO1FBQ3ZELE1BQU0sRUFBRSxLQUFLLEVBQUUsa0JBQWtCLEVBQUUsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDNUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxDQUFFLGtCQUE2QixDQUFDLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUM5RSxNQUFNLFVBQVUsR0FBRyxXQUFXLENBQUMscUJBQXFCLEVBQUUsQ0FBQyxLQUFLLENBQUM7UUFFN0QsTUFBTSxVQUFVLEdBQUcsWUFBWSxHQUFHLFVBQVUsQ0FBQztRQUU3QyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7OEdBdk1RLHFDQUFxQztrSEFBckMscUNBQXFDLGNBRmxDLE1BQU07OzJGQUVULHFDQUFxQztrQkFIakQsVUFBVTttQkFBQztvQkFDUixVQUFVLEVBQUUsTUFBTTtpQkFDckIiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIC0gMjAyNCAtIEluc3RydW1lbnRhdGlvbiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIFN5c3RlbGFiIFRlY2hub2xvZ2llcywgU0EuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcyBhbmQgcmVtYWlucyB0aGUgcHJvcGVydHkgb2YgSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzXG4gKiBhZmZpbGlhdGVzLCBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gSW5zdHJ1bWVudGF0aW9uXG4gKiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIGl0cyBhZmZpbGlhdGVzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBmb3JlaWduIHBhdGVudHMgYW5kIHBhdGVudCBhcHBsaWNhdGlvbnMsIGFuZC9vclxuICogYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4gRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsIGlzXG4gKiBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBJbnN0cnVtZW50YXRpb24gTGFib3JhdG9yeSBDb21wYW55LlxuICovXG5cbmltcG9ydCB7IE92ZXJsYXksIE92ZXJsYXlSZWYsIE92ZXJsYXlTaXplQ29uZmlnLCBQb3NpdGlvblN0cmF0ZWd5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21wb25lbnRQb3J0YWwgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQ29tcG9uZW50IH0gZnJvbSAnLi9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkLmNvbXBvbmVudCc7XG5cbmludGVyZmFjZSBQb3NpdGlvblN0cmF0ZWd5T3JpZ2luIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHdpZHRoPzogbnVtYmVyO1xuICBoZWlnaHQ/OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgICBwcm92aWRlZEluOiAncm9vdCcsXG59KVxuZXhwb3J0IGNsYXNzIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkT3ZlcmxheVNlcnZpY2Uge1xuICAgIHByaXZhdGUgb3ZlcmxheVJlZiE6IE92ZXJsYXlSZWY7XG4gICAgcHJpdmF0ZSBpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudDtcbiAgICBwcml2YXRlIGZpeGVkQm90dG9tOiBib29sZWFuO1xuICAgIHByaXZhdGUgc2hvd0tleWJvYXJkQnV0dG9uRWxlbWVudDogSFRNTEVsZW1lbnQ7XG4gICAgcHJpdmF0ZSBvcGVuOiBib29sZWFuO1xuICAgIHByaXZhdGUgbGF5b3V0OiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHM7XG4gICAgcHJpdmF0ZSBjbGlja0FscmVhZHlIYW5kbGVkOiBib29sZWFuID0gZmFsc2U7XG4gICAgcHJpdmF0ZSB0b3VjaEVuZEFscmVhZHlIYW5kbGVkOiBib29sZWFuID0gZmFsc2U7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG92ZXJsYXk6IE92ZXJsYXkpIHtcbiAgICAgICAgdGhpcy5pbml0TGlzdGVuZXIoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNDcmVhdGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gISF0aGlzLm92ZXJsYXlSZWY7XG4gICAgfVxuXG4gICAgcHVibGljIGlzT3BlbigpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMub3BlbjtcbiAgICB9XG5cbiAgICBwdWJsaWMgY3JlYXRlKFxuICAgICAgICBpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudCxcbiAgICAgICAgc2hvd0tleWJvYXJkQnV0dG9uRWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgICAgIGZpeGVkQm90dG9tOiBib29sZWFuLFxuICAgICAgICBsYXlvdXQ6IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cyA9IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cy5kZWZhdWx0LFxuICAgICk6IENvbXBvbmVudFJlZjxTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZENvbXBvbmVudD4ge1xuICAgICAgICB0aGlzLmlucHV0T3JpZ2luID0gaW5wdXRPcmlnaW47XG4gICAgICAgIHRoaXMuZml4ZWRCb3R0b20gPSBmaXhlZEJvdHRvbTtcbiAgICAgICAgdGhpcy5zaG93S2V5Ym9hcmRCdXR0b25FbGVtZW50ID0gc2hvd0tleWJvYXJkQnV0dG9uRWxlbWVudDtcbiAgICAgICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgICAgIHRoaXMub3ZlcmxheVJlZiA9IHRoaXMub3ZlcmxheS5jcmVhdGUoe1xuICAgICAgICAgICAgaGFzQmFja2Ryb3A6IGZhbHNlLFxuICAgICAgICAgICAgc2Nyb2xsU3RyYXRlZ3k6IHRoaXMub3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLnJlcG9zaXRpb24oKSxcbiAgICAgICAgICAgIGRpc3Bvc2VPbk5hdmlnYXRpb246IHRydWUsXG4gICAgICAgICAgICBiYWNrZHJvcENsYXNzOiAnc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZF9fYmFja2Ryb3AnLFxuICAgICAgICAgICAgcGFuZWxDbGFzczogJ3N5c3RlbGFiLXZpcnR1YWwta2V5Ym9hcmRfX3BhbmVsJyxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmIChmaXhlZEJvdHRvbSkge1xuICAgICAgICAgICAgdGhpcy5vdmVybGF5UmVmLmFkZFBhbmVsQ2xhc3MoJ3N5c3RlbGFiLXZpcnR1YWwta2V5Ym9hcmRfX3BhbmVsLS1maXhlZC1ib3R0b20nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMudXBkYXRlUG9zaXRpb25TdHJhdGVneShpbnB1dE9yaWdpbiwgZml4ZWRCb3R0b20pO1xuICAgICAgICB0aGlzLnVwZGF0ZVNpemUoKTtcblxuICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICByZXR1cm4gdGhpcy5vdmVybGF5UmVmLmF0dGFjaChuZXcgQ29tcG9uZW50UG9ydGFsKFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQ29tcG9uZW50KSk7XG4gICAgfVxuXG4gICAgcHVibGljIHVwZGF0ZVBvc2l0aW9uKCk6IHZvaWQge1xuICAgICAgICB0aGlzLnVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3kodGhpcy5pbnB1dE9yaWdpbiwgdGhpcy5maXhlZEJvdHRvbSk7XG4gICAgfVxuXG4gICAgcHVibGljIHNldENsaWNrQWxyZWFkeUhhbmRsZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuY2xpY2tBbHJlYWR5SGFuZGxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIHNldFRvdWNoRW5kQWxyZWFkeUhhbmRsZWQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMudG91Y2hFbmRBbHJlYWR5SGFuZGxlZCA9IHRydWU7XG4gICAgfVxuXG4gICAgcHVibGljIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLm92ZXJsYXlSZWYpIHtcbiAgICAgICAgICAgIHRoaXMub3ZlcmxheVJlZi5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5vdmVybGF5UmVmID0gbnVsbDtcbiAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBpbml0TGlzdGVuZXIoKSB7XG4gICAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5oYW5kbGVDbGljay5iaW5kKHRoaXMpKTtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hlbmQnLCB0aGlzLmhhbmRsZVRvdWNoRW5kLmJpbmQodGhpcykpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMuY2xpY2tBbHJlYWR5SGFuZGxlZCkge1xuICAgICAgICAgICAgdGhpcy5jbGlja0FscmVhZHlIYW5kbGVkID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5oYW5kbGVFdmVudFRhcmdldChldmVudC50YXJnZXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlVG91Y2hFbmQoZXZlbnQ6IFRvdWNoRXZlbnQpIHtcbiAgICAgICAgaWYgKHRoaXMudG91Y2hFbmRBbHJlYWR5SGFuZGxlZCkge1xuICAgICAgICAgICAgdGhpcy50b3VjaEVuZEFscmVhZHlIYW5kbGVkID0gZmFsc2U7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgICAgdGhpcy5oYW5kbGVFdmVudFRhcmdldChldmVudC50YXJnZXQpO1xuICAgIH1cblxuICAgIHByaXZhdGUgaGFuZGxlRXZlbnRUYXJnZXQodGFyZ2V0OiBFdmVudFRhcmdldCkge1xuICAgICAgICBjb25zdCBzaG93S2V5Ym9hcmRCdXR0b25UYXJnZXQ6IGJvb2xlYW4gPSAodGFyZ2V0IGFzIEhUTUxFbGVtZW50KT8uY2xhc3NMaXN0LmNvbnRhaW5zKCd2aXJ0dWFsLWtleWJvYXJkLXNob3ctYnV0dG9uJyk7XG4gICAgICAgIGNvbnN0IHZpcnR1YWxLZXlib2FyZFRhcmdldDogYm9vbGVhbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zaW1wbGUta2V5Ym9hcmQnKT8uY29udGFpbnModGFyZ2V0IGFzIE5vZGUpO1xuICAgICAgICBjb25zdCBpbnB1dEVsZW1lbnRUYXJnZXQ6IGJvb2xlYW4gPSB0aGlzLmlucHV0T3JpZ2luPy5jb250YWlucyh0YXJnZXQgYXMgTm9kZSk7XG4gICAgICAgIGNvbnN0IGNvbnRhaW5zU2hvd0J1dHRvbjogYm9vbGVhbiA9IHRoaXMuc2hvd0tleWJvYXJkQnV0dG9uRWxlbWVudD8uY29udGFpbnModGFyZ2V0IGFzIE5vZGUpO1xuXG4gICAgICAgIGlmICghdmlydHVhbEtleWJvYXJkVGFyZ2V0ICYmXG4gICAgICAgICAgICAhaW5wdXRFbGVtZW50VGFyZ2V0ICYmXG4gICAgICAgICAgICAhY29udGFpbnNTaG93QnV0dG9uICYmXG4gICAgICAgICAgICAhc2hvd0tleWJvYXJkQnV0dG9uVGFyZ2V0KSB7XG4gICAgICAgICAgICBpZiAodGhpcy5pc0NyZWF0ZWQoKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZGVzdHJveSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIGhhc0F0dGFjaGVkKCk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5vdmVybGF5UmVmPy5oYXNBdHRhY2hlZCgpO1xuICAgIH1cblxuICAgIHByaXZhdGUgdXBkYXRlUG9zaXRpb25TdHJhdGVneShpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudCwgZml4ZWRCb3R0b206IGJvb2xlYW4pOiB2b2lkIHtcbiAgICAgICAgaWYgKCEhdGhpcy5vdmVybGF5UmVmKSB7XG4gICAgICAgICAgICB0aGlzLm92ZXJsYXlSZWYudXBkYXRlUG9zaXRpb25TdHJhdGVneSh0aGlzLmdldFBvc2l0aW9uU3RyYXRlZ3koaW5wdXRPcmlnaW4sIGZpeGVkQm90dG9tKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHVwZGF0ZVNpemUoKTogdm9pZCB7XG4gICAgICAgIGlmICghIXRoaXMub3ZlcmxheVJlZikge1xuICAgICAgICAgICAgdGhpcy5vdmVybGF5UmVmLnVwZGF0ZVNpemUodGhpcy5nZXRPdmVybGF5U2l6ZSgpKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgZ2V0UG9zaXRpb25TdHJhdGVneShpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudCwgZml4ZWRCb3R0b206IGJvb2xlYW4pOiBQb3NpdGlvblN0cmF0ZWd5IHtcbiAgICAgICAgaWYgKGZpeGVkQm90dG9tKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5vdmVybGF5LnBvc2l0aW9uKCkuZ2xvYmFsKCkuY2VudGVySG9yaXpvbnRhbGx5KCkuYm90dG9tKCcwJyk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwb2ludFdpdGhEaW1lbnNpb25zOiBQb3NpdGlvblN0cmF0ZWd5T3JpZ2luID0gdGhpcy5jb21wdXRlUG9zaXRpb25TdHJhdGVneU9yaWdpbihpbnB1dE9yaWdpbik7XG5cbiAgICAgICAgcmV0dXJuIHRoaXMub3ZlcmxheVxuICAgICAgICAgICAgLnBvc2l0aW9uKClcbiAgICAgICAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHBvaW50V2l0aERpbWVuc2lvbnMpXG4gICAgICAgICAgICAud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcbiAgICAgICAgICAgIC53aXRoTG9ja2VkUG9zaXRpb24odHJ1ZSlcbiAgICAgICAgICAgIC53aXRoUHVzaChmYWxzZSlcbiAgICAgICAgICAgIC53aXRoUG9zaXRpb25zKFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WDogJ3N0YXJ0JyxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBvcmlnaW5YOiAnc3RhcnQnLFxuICAgICAgICAgICAgICAgICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgICAgICAgICAgICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlZOiAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luWDogJ2VuZCcsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlZOiAndG9wJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgb3JpZ2luWDogJ2VuZCcsXG4gICAgICAgICAgICAgICAgICAgIG9yaWdpblk6ICd0b3AnLFxuICAgICAgICAgICAgICAgICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICAgICAgICAgICAgICAgIG92ZXJsYXlZOiAnYm90dG9tJyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBnZXRPdmVybGF5U2l6ZSgpOiBPdmVybGF5U2l6ZUNvbmZpZyB7XG4gICAgICAgIGNvbnN0IG92ZXJsYXlXaWR0aCA9IHRoaXMubGF5b3V0ID09PSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMubnVtZXJpYyA/ICc0MDBweCcgOiAnMTIwMHB4JztcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgd2lkdGg6IG92ZXJsYXlXaWR0aCxcbiAgICAgICAgICAgIG1heFdpZHRoOiBvdmVybGF5V2lkdGgsXG4gICAgICAgICAgICBtaW5XaWR0aDogb3ZlcmxheVdpZHRoLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHByaXZhdGUgY29tcHV0ZVBvc2l0aW9uU3RyYXRlZ3lPcmlnaW4oaW5wdXRPcmlnaW46IEhUTUxJbnB1dEVsZW1lbnQpOiBQb3NpdGlvblN0cmF0ZWd5T3JpZ2luIHtcbiAgICAgICAgY29uc3Qgb3ZlcmxheU9mZnNldFggPSB0aGlzLmNvbXB1dGVPdmVybGF5T2Zmc2V0WChpbnB1dE9yaWdpbik7XG4gICAgICAgIGNvbnN0IHsgd2lkdGg6IG92ZXJsYXlXaWR0aFN0cmluZyB9ID0gdGhpcy5nZXRPdmVybGF5U2l6ZSgpO1xuICAgICAgICBjb25zdCBvdmVybGF5V2lkdGggPSBOdW1iZXIoKG92ZXJsYXlXaWR0aFN0cmluZyBhcyBzdHJpbmcpLnJlcGxhY2UoJ3B4JywgJycpKTtcbiAgICAgICAgY29uc3Qge3gsIHksIHdpZHRoLCBoZWlnaHR9ID0gaW5wdXRPcmlnaW4uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB3aWR0aCxcbiAgICAgICAgICAgIGhlaWdodCxcbiAgICAgICAgICAgIHg6IHdpZHRoIDwgb3ZlcmxheVdpZHRoID8geCAtIG92ZXJsYXlPZmZzZXRYIDogeCArIG92ZXJsYXlPZmZzZXRYLFxuICAgICAgICAgICAgeSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNvbXB1dGVPdmVybGF5T2Zmc2V0WChpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudCk6IG51bWJlciB7XG4gICAgICAgIGNvbnN0IHsgd2lkdGg6IG92ZXJsYXlXaWR0aFN0cmluZyB9ID0gdGhpcy5nZXRPdmVybGF5U2l6ZSgpO1xuICAgICAgICBjb25zdCBvdmVybGF5V2lkdGggPSBOdW1iZXIoKG92ZXJsYXlXaWR0aFN0cmluZyBhcyBzdHJpbmcpLnJlcGxhY2UoJ3B4JywgJycpKTtcbiAgICAgICAgY29uc3QgaW5wdXRXaWR0aCA9IGlucHV0T3JpZ2luLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuXG4gICAgICAgIGNvbnN0IGV4dHJhV2lkdGggPSBvdmVybGF5V2lkdGggLSBpbnB1dFdpZHRoO1xuXG4gICAgICAgIHJldHVybiBNYXRoLmFicyhleHRyYVdpZHRoKSAvIDI7XG4gICAgfVxufVxuIl19