systelab-virtual-keyboard 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,37 @@
1
+ # SystelabVirtualKeyboard
2
+
3
+ Systelab Virtual Keyboard is a on-screen keyboard focused on touch devices.
4
+
5
+ ## Using the directive
6
+
7
+ Before use the directive you have to import the module into your application.
8
+
9
+ ```typescript
10
+ NgModule({
11
+ imports: [
12
+ ...,
13
+ SystelabVirtualKeyboardModule,
14
+ ]
15
+ })
16
+ ```
17
+
18
+ Then the virtual keyboard can be enabled for inputs or textareas. To enable it the attribute *vkEnabled* can be used into the desire HTML element. It can be binding dynamically in the same way *[vkEnabled]="vkEnabledVariable"*
19
+
20
+ ```html
21
+ <input class="input" type="number" placeholder="Numeric input default layout" vkEnabled vkFixedBottom [vkConfig]="vkConfig">
22
+ ```
23
+
24
+ ## Directive options
25
+
26
+ The default behaviour can be overrided trought some attributes:
27
+
28
+ * vkEnabled: enable the virtual keyboard for the element
29
+ * vkFixedBottom: fix the virtual keyboard to the bottom of the page
30
+ * vkConfig: configuration object
31
+
32
+ ### Configuration object
33
+
34
+ The configuration params are describe into the interface *SystelabVirtualKeyboardConfig*
35
+
36
+ * layout: usually the virtual keyboard select the layout between *default* or *numeric* depending on the input type. But with the config object you can override this behaviour and force the desired layout. The available layouts are described in the enum *SystelabVirtualKeyboardLayouts*
37
+
@@ -0,0 +1,32 @@
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 SystelabVirtualKeyboardInputTypes;
27
+ (function (SystelabVirtualKeyboardInputTypes) {
28
+ SystelabVirtualKeyboardInputTypes["text"] = "text";
29
+ SystelabVirtualKeyboardInputTypes["number"] = "number";
30
+ SystelabVirtualKeyboardInputTypes["password"] = "password";
31
+ })(SystelabVirtualKeyboardInputTypes || (SystelabVirtualKeyboardInputTypes = {}));
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC9zcmMvbGliL2NvbnN0YW50cy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztHQU9HO0FBRUgsTUFBTSxDQUFOLElBQVksNkJBU1g7QUFURCxXQUFZLDZCQUE2QjtJQUN2QyxnREFBZSxDQUFBO0lBQ2Ysa0RBQWlCLENBQUE7SUFDakIsa0RBQWlCLENBQUE7SUFDakIsZ0RBQWUsQ0FBQTtJQUNmLHFEQUFvQixDQUFBO0lBQ3BCLHdEQUF1QixDQUFBO0lBQ3ZCLGtEQUFpQixDQUFBO0lBQ2pCLDhDQUFhLENBQUE7QUFDZixDQUFDLEVBVFcsNkJBQTZCLEtBQTdCLDZCQUE2QixRQVN4QztBQUVELE1BQU0sQ0FBTixJQUFZLDhCQUlYO0FBSkQsV0FBWSw4QkFBOEI7SUFDeEMscURBQW1CLENBQUE7SUFDbkIsaURBQWUsQ0FBQTtJQUNmLHFEQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFKVyw4QkFBOEIsS0FBOUIsOEJBQThCLFFBSXpDO0FBRUQsTUFBTSxDQUFOLElBQVksaUNBSVg7QUFKRCxXQUFZLGlDQUFpQztJQUMzQyxrREFBYSxDQUFBO0lBQ2Isc0RBQWlCLENBQUE7SUFDakIsMERBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQUpXLGlDQUFpQyxLQUFqQyxpQ0FBaUMsUUFJNUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogQ29weXJpZ2h0IChjKSAyMDIwIC0gMjAyNCAtIEluc3RydW1lbnRhdGlvbiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIFN5c3RlbGFiIFRlY2hub2xvZ2llcywgU0EuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcyBhbmQgcmVtYWlucyB0aGUgcHJvcGVydHkgb2YgSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzXG4gKiBhZmZpbGlhdGVzLCBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gSW5zdHJ1bWVudGF0aW9uXG4gKiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIGl0cyBhZmZpbGlhdGVzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBmb3JlaWduIHBhdGVudHMgYW5kIHBhdGVudCBhcHBsaWNhdGlvbnMsIGFuZC9vclxuICogYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4gRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsIGlzXG4gKiBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBJbnN0cnVtZW50YXRpb24gTGFib3JhdG9yeSBDb21wYW55LlxuICovXG5cbmV4cG9ydCBlbnVtIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uIHtcbiAgRG9uZSA9ICd7ZG9uZX0nLFxuICBFbnRlciA9ICd7ZW50ZXJ9JyxcbiAgU2hpZnQgPSAne3NoaWZ0fScsXG4gIExvY2sgPSAne2xvY2t9JyxcbiAgQmFja3NwYWNlID0gJ3tia3NwfScsXG4gIExhbmd1YWdlID0gJ3tsYW5ndWFnZX0nLFxuICBTcGFjZSA9ICd7c3BhY2V9JyxcbiAgVGFiID0gJ3t0YWJ9Jyxcbn1cblxuZXhwb3J0IGVudW0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzIHtcbiAgZGVmYXVsdCA9ICdkZWZhdWx0JyxcbiAgc2hpZnQgPSAnc2hpZnQnLFxuICBudW1lcmljID0gJ251bWVyaWMnLFxufVxuXG5leHBvcnQgZW51bSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZElucHV0VHlwZXMge1xuICB0ZXh0ID0gJ3RleHQnLFxuICBudW1iZXIgPSAnbnVtYmVyJyxcbiAgcGFzc3dvcmQgPSAncGFzc3dvcmQnLFxufVxuIl19
@@ -0,0 +1,123 @@
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
+ }
11
+ isCreated() {
12
+ return !!this.overlayRef;
13
+ }
14
+ isOpen() {
15
+ return this.open;
16
+ }
17
+ create(inputOrigin, fixedBottom, layout = SystelabVirtualKeyboardLayouts.default) {
18
+ this.layout = layout;
19
+ this.overlayRef = this.overlay.create({
20
+ hasBackdrop: false,
21
+ scrollStrategy: this.overlay.scrollStrategies.reposition(),
22
+ disposeOnNavigation: true,
23
+ });
24
+ this.overlayRef.addPanelClass('virtual-keyboard-overlay-pane');
25
+ if (fixedBottom) {
26
+ this.overlayRef.addPanelClass('virtual-keyboard-fixed-bottom');
27
+ }
28
+ this.updatePositionStrategy(inputOrigin, fixedBottom);
29
+ this.updateSize();
30
+ this.open = true;
31
+ return this.overlayRef.attach(new ComponentPortal(SystelabVirtualKeyboardComponent));
32
+ }
33
+ destroy() {
34
+ if (this.overlayRef) {
35
+ this.overlayRef.dispose();
36
+ }
37
+ this.overlayRef = null;
38
+ this.open = false;
39
+ }
40
+ hasAttached() {
41
+ return this.overlayRef?.hasAttached();
42
+ }
43
+ updatePositionStrategy(inputOrigin, fixedBottom) {
44
+ this.overlayRef.updatePositionStrategy(this.getPositionStrategy(inputOrigin, fixedBottom));
45
+ }
46
+ updateSize() {
47
+ this.overlayRef.updateSize(this.getOverlaySize());
48
+ }
49
+ getPositionStrategy(inputOrigin, fixedBottom) {
50
+ if (fixedBottom) {
51
+ return this.overlay.position().global().centerHorizontally().bottom('0');
52
+ }
53
+ const pointWithDimensions = this.computePositionStrategyOrigin(inputOrigin);
54
+ return this.overlay
55
+ .position()
56
+ .flexibleConnectedTo(pointWithDimensions)
57
+ .withFlexibleDimensions(false)
58
+ .withLockedPosition(true)
59
+ .withPush(false)
60
+ .withPositions([
61
+ {
62
+ originX: 'start',
63
+ originY: 'bottom',
64
+ overlayX: 'start',
65
+ overlayY: 'top',
66
+ },
67
+ {
68
+ originX: 'start',
69
+ originY: 'top',
70
+ overlayX: 'start',
71
+ overlayY: 'bottom',
72
+ },
73
+ {
74
+ originX: 'end',
75
+ originY: 'bottom',
76
+ overlayX: 'end',
77
+ overlayY: 'top',
78
+ },
79
+ {
80
+ originX: 'end',
81
+ originY: 'top',
82
+ overlayX: 'end',
83
+ overlayY: 'bottom',
84
+ },
85
+ ]);
86
+ }
87
+ getOverlaySize() {
88
+ const overlayWidth = this.layout === SystelabVirtualKeyboardLayouts.numeric ? '400px' : '1200px';
89
+ return {
90
+ width: overlayWidth,
91
+ maxWidth: overlayWidth,
92
+ minWidth: overlayWidth,
93
+ };
94
+ }
95
+ computePositionStrategyOrigin(inputOrigin) {
96
+ const overlayOffsetX = this.computeOverlayOffsetX(inputOrigin);
97
+ const { width: overlayWidthString } = this.getOverlaySize();
98
+ const overlayWidth = Number(overlayWidthString.replace('px', ''));
99
+ const { x, y, width, height } = inputOrigin.getBoundingClientRect();
100
+ return {
101
+ width,
102
+ height,
103
+ x: width < overlayWidth ? x - overlayOffsetX : x + overlayOffsetX,
104
+ y,
105
+ };
106
+ }
107
+ computeOverlayOffsetX(inputOrigin) {
108
+ const { width: overlayWidthString } = this.getOverlaySize();
109
+ const overlayWidth = Number(overlayWidthString.replace('px', ''));
110
+ const inputWidth = inputOrigin.getBoundingClientRect().width;
111
+ const extraWidth = overlayWidth - inputWidth;
112
+ return Math.abs(extraWidth) / 2;
113
+ }
114
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, deps: [{ token: i1.Overlay }], target: i0.ɵɵFactoryTarget.Injectable }); }
115
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, providedIn: 'root' }); }
116
+ }
117
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SystelabVirtualKeyboardOverlayService, decorators: [{
118
+ type: Injectable,
119
+ args: [{
120
+ providedIn: 'root',
121
+ }]
122
+ }], ctorParameters: () => [{ type: i1.Overlay }] });
123
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC1vdmVybGF5LnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkL3NyYy9saWIvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC1vdmVybGF5LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBVUEsT0FBTyxFQUFnQixVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSw4QkFBOEIsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUM3RCxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQzs7O0FBWXpGLE1BQU0sT0FBTyxxQ0FBcUM7SUFLaEQsWUFBNkIsT0FBZ0I7UUFBaEIsWUFBTyxHQUFQLE9BQU8sQ0FBUztJQUFHLENBQUM7SUFFMUMsU0FBUztRQUNkLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDM0IsQ0FBQztJQUVNLE1BQU07UUFDWCxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkIsQ0FBQztJQUVNLE1BQU0sQ0FDWCxXQUE2QixFQUM3QixXQUFvQixFQUNwQixTQUF5Qyw4QkFBOEIsQ0FBQyxPQUFPO1FBRS9FLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO1FBQ3JCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFDcEMsV0FBVyxFQUFFLEtBQUs7WUFDbEIsY0FBYyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxFQUFFO1lBQzFELG1CQUFtQixFQUFFLElBQUk7U0FDMUIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsK0JBQStCLENB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Q29weXJpZ2h0IChjKSAyMDIwIC0gMjAyNCAtIEluc3RydW1lbnRhdGlvbiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIFN5c3RlbGFiIFRlY2hub2xvZ2llcywgU0EuIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcyBhbmQgcmVtYWlucyB0aGUgcHJvcGVydHkgb2YgSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzXG4gKiBhZmZpbGlhdGVzLCBpZiBhbnkuICBUaGUgaW50ZWxsZWN0dWFsIGFuZCB0ZWNobmljYWwgY29uY2VwdHMgY29udGFpbmVkIGhlcmVpbiBhcmUgcHJvcHJpZXRhcnkgdG8gSW5zdHJ1bWVudGF0aW9uXG4gKiBMYWJvcmF0b3J5IENvbXBhbnkgYW5kIGl0cyBhZmZpbGlhdGVzIGFuZCBtYXkgYmUgY292ZXJlZCBieSBVLlMuIGFuZCBmb3JlaWduIHBhdGVudHMgYW5kIHBhdGVudCBhcHBsaWNhdGlvbnMsIGFuZC9vclxuICogYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4gRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsIGlzXG4gKiBzdHJpY3RseSBmb3JiaWRkZW4gdW5sZXNzIHByaW9yIHdyaXR0ZW4gcGVybWlzc2lvbiBpcyBJbnN0cnVtZW50YXRpb24gTGFib3JhdG9yeSBDb21wYW55LlxuICovXG5cbmltcG9ydCB7IE92ZXJsYXksIE92ZXJsYXlSZWYsIE92ZXJsYXlTaXplQ29uZmlnLCBQb3NpdGlvblN0cmF0ZWd5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xuaW1wb3J0IHsgQ29tcG9uZW50UmVmLCBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21wb25lbnRQb3J0YWwgfSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cyB9IGZyb20gJy4vY29uc3RhbnRzJztcbmltcG9ydCB7IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQ29tcG9uZW50IH0gZnJvbSAnLi9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkLmNvbXBvbmVudCc7XG5cbmludGVyZmFjZSBQb3NpdGlvblN0cmF0ZWd5T3JpZ2luIHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG4gIHdpZHRoPzogbnVtYmVyO1xuICBoZWlnaHQ/OiBudW1iZXI7XG59XG5cbkBJbmplY3RhYmxlKHtcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnLFxufSlcbmV4cG9ydCBjbGFzcyBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZE92ZXJsYXlTZXJ2aWNlIHtcbiAgcHJpdmF0ZSBvdmVybGF5UmVmITogT3ZlcmxheVJlZjtcbiAgcHJpdmF0ZSBvcGVuOiBib29sZWFuO1xuICBwcml2YXRlIGxheW91dDogU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgb3ZlcmxheTogT3ZlcmxheSkge31cblxuICBwdWJsaWMgaXNDcmVhdGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMub3ZlcmxheVJlZjtcbiAgfVxuXG4gIHB1YmxpYyBpc09wZW4oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMub3BlbjtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGUoXG4gICAgaW5wdXRPcmlnaW46IEhUTUxJbnB1dEVsZW1lbnQsXG4gICAgZml4ZWRCb3R0b206IGJvb2xlYW4sXG4gICAgbGF5b3V0OiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMgPSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMuZGVmYXVsdCxcbiAgKTogQ29tcG9uZW50UmVmPFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQ29tcG9uZW50PiB7XG4gICAgdGhpcy5sYXlvdXQgPSBsYXlvdXQ7XG4gICAgdGhpcy5vdmVybGF5UmVmID0gdGhpcy5vdmVybGF5LmNyZWF0ZSh7XG4gICAgICBoYXNCYWNrZHJvcDogZmFsc2UsXG4gICAgICBzY3JvbGxTdHJhdGVneTogdGhpcy5vdmVybGF5LnNjcm9sbFN0cmF0ZWdpZXMucmVwb3NpdGlvbigpLFxuICAgICAgZGlzcG9zZU9uTmF2aWdhdGlvbjogdHJ1ZSxcbiAgICB9KTtcbiAgICB0aGlzLm92ZXJsYXlSZWYuYWRkUGFuZWxDbGFzcygndmlydHVhbC1rZXlib2FyZC1vdmVybGF5LXBhbmUnKTtcbiAgICBpZiAoZml4ZWRCb3R0b20pIHtcbiAgICAgIHRoaXMub3ZlcmxheVJlZi5hZGRQYW5lbENsYXNzKCd2aXJ0dWFsLWtleWJvYXJkLWZpeGVkLWJvdHRvbScpO1xuICAgIH1cblxuICAgIHRoaXMudXBkYXRlUG9zaXRpb25TdHJhdGVneShpbnB1dE9yaWdpbiwgZml4ZWRCb3R0b20pO1xuICAgIHRoaXMudXBkYXRlU2l6ZSgpO1xuXG4gICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICByZXR1cm4gdGhpcy5vdmVybGF5UmVmLmF0dGFjaChuZXcgQ29tcG9uZW50UG9ydGFsKFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQ29tcG9uZW50KSk7XG4gIH1cblxuICBwdWJsaWMgZGVzdHJveSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5vdmVybGF5UmVmKSB7XG4gICAgICB0aGlzLm92ZXJsYXlSZWYuZGlzcG9zZSgpO1xuICAgIH1cbiAgICB0aGlzLm92ZXJsYXlSZWYgPSBudWxsO1xuICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGhhc0F0dGFjaGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm92ZXJsYXlSZWY/Lmhhc0F0dGFjaGVkKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3koaW5wdXRPcmlnaW46IEhUTUxJbnB1dEVsZW1lbnQsIGZpeGVkQm90dG9tOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vdmVybGF5UmVmLnVwZGF0ZVBvc2l0aW9uU3RyYXRlZ3kodGhpcy5nZXRQb3NpdGlvblN0cmF0ZWd5KGlucHV0T3JpZ2luLCBmaXhlZEJvdHRvbSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVTaXplKCk6IHZvaWQge1xuICAgIHRoaXMub3ZlcmxheVJlZi51cGRhdGVTaXplKHRoaXMuZ2V0T3ZlcmxheVNpemUoKSk7XG4gIH1cblxuICBwcml2YXRlIGdldFBvc2l0aW9uU3RyYXRlZ3koaW5wdXRPcmlnaW46IEhUTUxJbnB1dEVsZW1lbnQsIGZpeGVkQm90dG9tOiBib29sZWFuKTogUG9zaXRpb25TdHJhdGVneSB7XG4gICAgaWYgKGZpeGVkQm90dG9tKSB7XG4gICAgICByZXR1cm4gdGhpcy5vdmVybGF5LnBvc2l0aW9uKCkuZ2xvYmFsKCkuY2VudGVySG9yaXpvbnRhbGx5KCkuYm90dG9tKCcwJyk7XG4gICAgfVxuXG4gICAgY29uc3QgcG9pbnRXaXRoRGltZW5zaW9uczogUG9zaXRpb25TdHJhdGVneU9yaWdpbiA9IHRoaXMuY29tcHV0ZVBvc2l0aW9uU3RyYXRlZ3lPcmlnaW4oaW5wdXRPcmlnaW4pO1xuXG4gICAgcmV0dXJuIHRoaXMub3ZlcmxheVxuICAgICAgLnBvc2l0aW9uKClcbiAgICAgIC5mbGV4aWJsZUNvbm5lY3RlZFRvKHBvaW50V2l0aERpbWVuc2lvbnMpXG4gICAgICAud2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmYWxzZSlcbiAgICAgIC53aXRoTG9ja2VkUG9zaXRpb24odHJ1ZSlcbiAgICAgIC53aXRoUHVzaChmYWxzZSlcbiAgICAgIC53aXRoUG9zaXRpb25zKFtcbiAgICAgICAge1xuICAgICAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICAgICAgb3JpZ2luWTogJ2JvdHRvbScsXG4gICAgICAgICAgb3ZlcmxheVg6ICdzdGFydCcsXG4gICAgICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgb3JpZ2luWDogJ3N0YXJ0JyxcbiAgICAgICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgICAgICBvdmVybGF5WDogJ3N0YXJ0JyxcbiAgICAgICAgICBvdmVybGF5WTogJ2JvdHRvbScsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBvcmlnaW5YOiAnZW5kJyxcbiAgICAgICAgICBvcmlnaW5ZOiAnYm90dG9tJyxcbiAgICAgICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgb3JpZ2luWDogJ2VuZCcsXG4gICAgICAgICAgb3JpZ2luWTogJ3RvcCcsXG4gICAgICAgICAgb3ZlcmxheVg6ICdlbmQnLFxuICAgICAgICAgIG92ZXJsYXlZOiAnYm90dG9tJyxcbiAgICAgICAgfSxcbiAgICAgIF0pO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRPdmVybGF5U2l6ZSgpOiBPdmVybGF5U2l6ZUNvbmZpZyB7XG4gICAgY29uc3Qgb3ZlcmxheVdpZHRoID0gdGhpcy5sYXlvdXQgPT09IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cy5udW1lcmljID8gJzQwMHB4JyA6ICcxMjAwcHgnO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIHdpZHRoOiBvdmVybGF5V2lkdGgsXG4gICAgICBtYXhXaWR0aDogb3ZlcmxheVdpZHRoLFxuICAgICAgbWluV2lkdGg6IG92ZXJsYXlXaWR0aCxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlUG9zaXRpb25TdHJhdGVneU9yaWdpbihpbnB1dE9yaWdpbjogSFRNTElucHV0RWxlbWVudCk6IFBvc2l0aW9uU3RyYXRlZ3lPcmlnaW4ge1xuICAgIGNvbnN0IG92ZXJsYXlPZmZzZXRYID0gdGhpcy5jb21wdXRlT3ZlcmxheU9mZnNldFgoaW5wdXRPcmlnaW4pO1xuICAgIGNvbnN0IHsgd2lkdGg6IG92ZXJsYXlXaWR0aFN0cmluZyB9ID0gdGhpcy5nZXRPdmVybGF5U2l6ZSgpO1xuICAgIGNvbnN0IG92ZXJsYXlXaWR0aCA9IE51bWJlcigob3ZlcmxheVdpZHRoU3RyaW5nIGFzIHN0cmluZykucmVwbGFjZSgncHgnLCAnJykpO1xuICAgIGNvbnN0IHt4LCB5LCB3aWR0aCwgaGVpZ2h0fSA9IGlucHV0T3JpZ2luLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7XG4gICAgICB3aWR0aCxcbiAgICAgIGhlaWdodCxcbiAgICAgIHg6IHdpZHRoIDwgb3ZlcmxheVdpZHRoID8geCAtIG92ZXJsYXlPZmZzZXRYIDogeCArIG92ZXJsYXlPZmZzZXRYLFxuICAgICAgeSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBjb21wdXRlT3ZlcmxheU9mZnNldFgoaW5wdXRPcmlnaW46IEhUTUxJbnB1dEVsZW1lbnQpOiBudW1iZXIge1xuICAgIGNvbnN0IHsgd2lkdGg6IG92ZXJsYXlXaWR0aFN0cmluZyB9ID0gdGhpcy5nZXRPdmVybGF5U2l6ZSgpO1xuICAgIGNvbnN0IG92ZXJsYXlXaWR0aCA9IE51bWJlcigob3ZlcmxheVdpZHRoU3RyaW5nIGFzIHN0cmluZykucmVwbGFjZSgncHgnLCAnJykpO1xuICAgIGNvbnN0IGlucHV0V2lkdGggPSBpbnB1dE9yaWdpbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDtcblxuICAgIGNvbnN0IGV4dHJhV2lkdGggPSBvdmVybGF5V2lkdGggLSBpbnB1dFdpZHRoO1xuXG4gICAgcmV0dXJuIE1hdGguYWJzKGV4dHJhV2lkdGgpIC8gMjtcbiAgfVxufVxuIl19
@@ -0,0 +1,352 @@
1
+ import { Component, EventEmitter, HostListener, Output } from '@angular/core';
2
+ import SimpleKeyboard from 'simple-keyboard';
3
+ import { SystelabVirtualKeyboardButton, SystelabVirtualKeyboardInputTypes, SystelabVirtualKeyboardLayouts } from './constants';
4
+ import * as i0 from "@angular/core";
5
+ export class SystelabVirtualKeyboardComponent {
6
+ handleKeyUp(event) {
7
+ if (event.isTrusted) {
8
+ this.caretEventHandler(event);
9
+ }
10
+ }
11
+ handleMouseUp(event) {
12
+ this.caretEventHandler(event);
13
+ }
14
+ handleSelect(event) {
15
+ this.caretEventHandler(event);
16
+ }
17
+ handleSelectionChange(event) {
18
+ this.caretEventHandler(event);
19
+ }
20
+ get maxLength() {
21
+ return this.activeInputElement?.maxLength ?? -1;
22
+ }
23
+ get isTextarea() {
24
+ return this.activeInputElement?.type === 'textarea';
25
+ }
26
+ constructor(elementRef) {
27
+ this.elementRef = elementRef;
28
+ this.debug = false;
29
+ this.selectedLayout = SystelabVirtualKeyboardLayouts.default;
30
+ this.caretPosition = null;
31
+ this.caretPositionEnd = null;
32
+ this.closePanel = new EventEmitter();
33
+ }
34
+ ngAfterViewInit() {
35
+ const layout = {
36
+ [SystelabVirtualKeyboardLayouts.default]: [
37
+ '` 1 2 3 4 5 6 7 8 9 0 - = {bksp}',
38
+ '{tab} q w e r t y u i o p [ ] \\',
39
+ "{lock} a s d f g h j k l ; ' {enter}",
40
+ '{shift} z x c v b n m , . / {shift}',
41
+ '{space}',
42
+ ],
43
+ [SystelabVirtualKeyboardLayouts.shift]: [
44
+ '~ ! @ # $ % ^ &amp; * ( ) _ + {bksp}',
45
+ '{tab} Q W E R T Y U I O P { } |',
46
+ '{lock} A S D F G H J K L : " {enter}',
47
+ '{shift} Z X C V B N M &lt; &gt; ? {shift}',
48
+ '{space}',
49
+ ],
50
+ [SystelabVirtualKeyboardLayouts.numeric]: ['7 8 9', '4 5 6', '1 2 3', '0 {bksp}'],
51
+ };
52
+ this.keyboard = new SimpleKeyboard('.simple-keyboard', {
53
+ onKeyPress: (button) => this.handleKeyPress(button),
54
+ mergeDisplay: true,
55
+ display: {
56
+ [SystelabVirtualKeyboardButton.Backspace]: 'delete',
57
+ },
58
+ buttonTheme: [
59
+ {
60
+ class: 'virtual-keyboard-delete-button',
61
+ buttons: `${SystelabVirtualKeyboardButton.Backspace}`,
62
+ },
63
+ ],
64
+ layout,
65
+ });
66
+ this.setLayout(this.selectedLayout);
67
+ if (this.debug) {
68
+ console.log('Layout: ', layout);
69
+ }
70
+ }
71
+ setActiveInput(input) {
72
+ this.activeInputElement = input;
73
+ if (this.debug) {
74
+ const inputType = this.activeInputElement?.type;
75
+ console.log('Layout:', `${inputType}_${this.selectedLayout}`);
76
+ }
77
+ let selectionStart;
78
+ let selectionEnd;
79
+ if (this.isInputNumeric(input)) {
80
+ selectionStart = this.activeInputElement.value.toString().length;
81
+ selectionEnd = this.activeInputElement.value.toString().length;
82
+ }
83
+ else {
84
+ selectionStart = this.activeInputElement.selectionStart;
85
+ selectionEnd = this.activeInputElement.selectionEnd;
86
+ }
87
+ this.setCaretPosition(selectionStart, selectionEnd);
88
+ if (this.debug) {
89
+ console.log('Caret start at:', this.caretPosition, this.caretPositionEnd);
90
+ }
91
+ this.focusActiveInput();
92
+ }
93
+ setLayout(layout) {
94
+ this.selectedLayout = layout;
95
+ if (this.keyboard) {
96
+ this.keyboard.setOptions({
97
+ layoutName: layout,
98
+ });
99
+ }
100
+ }
101
+ isInputAlphabetic(activeInputElement) {
102
+ const inputType = activeInputElement?.type;
103
+ return inputType && [SystelabVirtualKeyboardInputTypes.text, SystelabVirtualKeyboardInputTypes.password].some((i) => i === inputType);
104
+ }
105
+ isInputNumeric(activeInputElement) {
106
+ const inputType = activeInputElement?.type;
107
+ return inputType && [SystelabVirtualKeyboardInputTypes.number].some((i) => i === inputType);
108
+ }
109
+ handleKeyPress(button, e) {
110
+ if (this.debug) {
111
+ console.log('Key press:', button);
112
+ }
113
+ if (button === SystelabVirtualKeyboardButton.Shift || button === SystelabVirtualKeyboardButton.Lock) {
114
+ this.toggleShift();
115
+ }
116
+ else if (button === SystelabVirtualKeyboardButton.Done) {
117
+ this.closePanel.emit();
118
+ return;
119
+ }
120
+ if (!this.isAcceptedNonStandardButton(button) && !this.isStandardButton(button)) {
121
+ return;
122
+ }
123
+ const output = this.handleButtonOutput(button);
124
+ if (this.activeInputElement) {
125
+ this.activeInputElement.value = output;
126
+ if (this.debug) {
127
+ console.log('Caret at:', this.caretPosition, this.caretPositionEnd, 'Button', e);
128
+ }
129
+ }
130
+ this.dispatchEvents(button);
131
+ }
132
+ handleButtonOutput(button) {
133
+ const commonParams = this.getCommonParams();
134
+ let output = this.activeInputElement?.value || '';
135
+ if (!this.isStandardButton(button)) {
136
+ if (button === SystelabVirtualKeyboardButton.Backspace) {
137
+ output = this.removeAt(output, ...commonParams);
138
+ }
139
+ else if (button === SystelabVirtualKeyboardButton.Space) {
140
+ output = this.addStringAt(output, ' ', ...commonParams);
141
+ }
142
+ else if (button === SystelabVirtualKeyboardButton.Tab) {
143
+ output = this.addStringAt(output, '\t', ...commonParams);
144
+ }
145
+ else if (button === SystelabVirtualKeyboardButton.Enter) {
146
+ if (this.isTextarea) {
147
+ output = this.addStringAt(output, '\n', ...commonParams);
148
+ }
149
+ }
150
+ else {
151
+ return;
152
+ }
153
+ }
154
+ else {
155
+ output = this.addStringAt(output, button, ...commonParams);
156
+ }
157
+ return output;
158
+ }
159
+ getCommonParams() {
160
+ return [this.caretPosition || 0, this.caretPositionEnd || 0, true];
161
+ }
162
+ isAcceptedNonStandardButton(button) {
163
+ return [
164
+ SystelabVirtualKeyboardButton.Backspace.toString(),
165
+ SystelabVirtualKeyboardButton.Space.toString(),
166
+ SystelabVirtualKeyboardButton.Tab.toString(),
167
+ SystelabVirtualKeyboardButton.Enter.toString(),
168
+ ].includes(button);
169
+ }
170
+ dispatchEvents(button) {
171
+ const { key, code } = this.convertFromButtonToCode(button);
172
+ const eventInit = {
173
+ bubbles: true,
174
+ cancelable: true,
175
+ shiftKey: this.selectedLayout === SystelabVirtualKeyboardLayouts.shift,
176
+ key: key,
177
+ code: code,
178
+ location: 0,
179
+ };
180
+ // Simulate all needed events on base element
181
+ this.activeInputElement?.dispatchEvent(new KeyboardEvent('keydown', eventInit));
182
+ this.activeInputElement?.dispatchEvent(new KeyboardEvent('keypress', eventInit));
183
+ this.activeInputElement?.dispatchEvent(new Event('input', { bubbles: true }));
184
+ this.activeInputElement?.dispatchEvent(new KeyboardEvent('keyup', eventInit));
185
+ // And set focus to input
186
+ this.focusActiveInput();
187
+ }
188
+ /*
189
+ * AUXILIARY METHODS
190
+ * */
191
+ convertFromButtonToCode(button) {
192
+ let key;
193
+ let code;
194
+ if (button.includes('{') && button.includes('}')) {
195
+ // Capitalize name
196
+ key = button.slice(1, button.length - 1).toLowerCase();
197
+ key = key.charAt(0).toUpperCase() + key.slice(1);
198
+ code = key;
199
+ // Fix to standard key code
200
+ if (code.toLowerCase() === SystelabVirtualKeyboardButton.Backspace.slice(1, SystelabVirtualKeyboardButton.Backspace.length - 1).toLowerCase()) {
201
+ code = 'Backspace';
202
+ }
203
+ }
204
+ else {
205
+ key = button;
206
+ code = Number.isInteger(Number(button)) ? `Digit${button}` : `Key${button.toUpperCase()}`;
207
+ }
208
+ return { key, code };
209
+ }
210
+ focusActiveInput() {
211
+ this.activeInputElement?.focus();
212
+ if (!this.isInputNumeric(this.activeInputElement)) {
213
+ this.activeInputElement?.setSelectionRange(this.caretPosition, this.caretPositionEnd);
214
+ }
215
+ }
216
+ toggleShift() {
217
+ let currentLayout = this.keyboard.options.layoutName;
218
+ let selectedLayout = currentLayout === SystelabVirtualKeyboardLayouts.default ? SystelabVirtualKeyboardLayouts.shift : SystelabVirtualKeyboardLayouts.default;
219
+ this.setLayout(selectedLayout);
220
+ }
221
+ isStandardButton(button) {
222
+ return button && !(button[0] === '{' && button[button.length - 1] === '}');
223
+ }
224
+ /*
225
+ * OUTPUT STRING METHODS
226
+ * */
227
+ removeAt(source, position = source.length, positionEnd = source.length, moveCaret = false) {
228
+ if (position === 0 && positionEnd === 0) {
229
+ return source;
230
+ }
231
+ let output;
232
+ if (position === positionEnd) {
233
+ if (position && position >= 0) {
234
+ output = source.slice(0, position - 1) + source.slice(position);
235
+ if (moveCaret) {
236
+ this.updateCaretPosition(1, true);
237
+ }
238
+ }
239
+ else {
240
+ output = source.slice(0, -1);
241
+ if (moveCaret) {
242
+ this.updateCaretPosition(1, true);
243
+ }
244
+ }
245
+ }
246
+ else {
247
+ output = source.slice(0, position) + source.slice(positionEnd);
248
+ if (moveCaret) {
249
+ this.setCaretPosition(position);
250
+ }
251
+ }
252
+ return output;
253
+ }
254
+ addStringAt(source, str, position = source.length, positionEnd = source.length, moveCaret = false) {
255
+ if (this.maxLength !== -1 && source.length >= this.maxLength) {
256
+ return source;
257
+ }
258
+ let output;
259
+ if (!position && position !== 0) {
260
+ output = source + str;
261
+ }
262
+ else {
263
+ output = [source.slice(0, position), str, source.slice(positionEnd)].join('');
264
+ if (moveCaret) {
265
+ this.updateCaretPosition(str.length, false);
266
+ }
267
+ }
268
+ return output;
269
+ }
270
+ /*
271
+ * CARET METHODS
272
+ * */
273
+ caretEventHandler(event) {
274
+ let targetTagName = '';
275
+ if (event.target.tagName) {
276
+ targetTagName = event.target.tagName.toLowerCase();
277
+ }
278
+ const isTextInput = targetTagName === 'textarea' ||
279
+ (targetTagName === 'input' && ['text', 'search', 'email', 'password', 'url', 'tel'].includes(event.target.type));
280
+ const isKeyboard = event.target === this.elementRef.nativeElement || (event.target && this.elementRef.nativeElement.contains(event.target));
281
+ if (isTextInput && this.activeInputElement == event.target) {
282
+ /**
283
+ * Tracks current cursor position
284
+ * As keys are pressed, text will be added/removed at that position within the input.
285
+ */
286
+ this.setCaretPosition(event.target.selectionStart, event.target.selectionEnd);
287
+ if (this.debug) {
288
+ console.log('Caret at:', this.caretPosition, this.caretPositionEnd, event && event.target.tagName.toLowerCase(), event);
289
+ }
290
+ }
291
+ else if (event.type === 'pointerup' && this.activeInputElement === document.activeElement) {
292
+ return;
293
+ }
294
+ else if (!isKeyboard && event?.type !== 'selectionchange') {
295
+ /**
296
+ * we must ensure caretPosition doesn't persist once reactivated.
297
+ */
298
+ this.setCaretPosition(null);
299
+ if (this.debug) {
300
+ console.log(`Caret position reset due to "${event?.type}" event`, event);
301
+ }
302
+ }
303
+ }
304
+ updateCaretPosition(length, minus = false) {
305
+ const newCaretPos = this.computeNewCaretPosition(length, minus);
306
+ this.setCaretPosition(newCaretPos);
307
+ // Scroll to bottom
308
+ setTimeout(() => {
309
+ this.activeInputElement?.scrollTo({
310
+ top: this.activeInputElement.scrollHeight,
311
+ });
312
+ });
313
+ }
314
+ computeNewCaretPosition(length, minus = false) {
315
+ let caretPosition = this.caretPosition;
316
+ if (caretPosition != null) {
317
+ if (minus) {
318
+ if (caretPosition > 0)
319
+ caretPosition = caretPosition - length;
320
+ }
321
+ else {
322
+ caretPosition = caretPosition + length;
323
+ }
324
+ }
325
+ return caretPosition;
326
+ }
327
+ setCaretPosition(position, endPosition = position) {
328
+ this.caretPosition = position;
329
+ this.caretPositionEnd = endPosition;
330
+ }
331
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SystelabVirtualKeyboardComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
332
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.9", type: SystelabVirtualKeyboardComponent, isStandalone: true, selector: "systelab-virtual-keyboard.component", outputs: { closePanel: "closePanel" }, host: { listeners: { "window:keyup": "handleKeyUp($event)", "window:pointerup": "handleMouseUp($event)", "window:select": "handleSelect($event)", "window:selectionchange": "handleSelectionChange($event)" } }, ngImport: i0, template: "<!--\n ~ Copyright (c) 2020 - 2024 - Instrumentation Laboratory Company and Systelab Technologies, SA. All rights reserved.\n ~ NOTICE: All information contained herein is and remains the property of Instrumentation Laboratory Company and its\n ~ affiliates, if any. The intellectual and technical concepts contained herein are proprietary to Instrumentation\n ~ Laboratory Company and its affiliates and may be covered by U.S. and foreign patents and patent applications, and/or\n ~ are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is\n ~ strictly forbidden unless prior written permission is Instrumentation Laboratory Company.\n -->\n\n<div class=\"simple-keyboard\"></div>\n", styles: [":host{width:100%}\n"] }); }
333
+ }
334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.9", ngImport: i0, type: SystelabVirtualKeyboardComponent, decorators: [{
335
+ type: Component,
336
+ args: [{ selector: 'systelab-virtual-keyboard.component', standalone: true, imports: [], template: "<!--\n ~ Copyright (c) 2020 - 2024 - Instrumentation Laboratory Company and Systelab Technologies, SA. All rights reserved.\n ~ NOTICE: All information contained herein is and remains the property of Instrumentation Laboratory Company and its\n ~ affiliates, if any. The intellectual and technical concepts contained herein are proprietary to Instrumentation\n ~ Laboratory Company and its affiliates and may be covered by U.S. and foreign patents and patent applications, and/or\n ~ are protected by trade secret or copyright law. Dissemination of this information or reproduction of this material is\n ~ strictly forbidden unless prior written permission is Instrumentation Laboratory Company.\n -->\n\n<div class=\"simple-keyboard\"></div>\n", styles: [":host{width:100%}\n"] }]
337
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { handleKeyUp: [{
338
+ type: HostListener,
339
+ args: ['window:keyup', ['$event']]
340
+ }], handleMouseUp: [{
341
+ type: HostListener,
342
+ args: ['window:pointerup', ['$event']]
343
+ }], handleSelect: [{
344
+ type: HostListener,
345
+ args: ['window:select', ['$event']]
346
+ }], handleSelectionChange: [{
347
+ type: HostListener,
348
+ args: ['window:selectionchange', ['$event']]
349
+ }], closePanel: [{
350
+ type: Output
351
+ }] } });
352
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkL3NyYy9saWIvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkL3NyYy9saWIvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQWlCLFNBQVMsRUFBYyxZQUFZLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN6RyxPQUFPLGNBQWMsTUFBTSxpQkFBaUIsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsNkJBQTZCLEVBQzdCLGlDQUFpQyxFQUNqQyw4QkFBOEIsRUFDL0IsTUFBTSxhQUFhLENBQUM7O0FBU3JCLE1BQU0sT0FBTyxnQ0FBZ0M7SUFFM0MsV0FBVyxDQUFDLEtBQW9CO1FBQzlCLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtZQUNuQixJQUFJLENBQUMsaUJBQWlCLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDL0I7SUFDSCxDQUFDO0lBR0QsYUFBYSxDQUFDLEtBQW1CO1FBQy9CLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBR0QsWUFBWSxDQUFDLEtBQVk7UUFDdkIsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFHRCxxQkFBcUIsQ0FBQyxLQUFZO1FBQ2hDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBSSxTQUFTO1FBQ1gsT0FBTyxJQUFJLENBQUMsa0JBQWtCLEVBQUUsU0FBUyxJQUFJLENB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Z0IsQ0FBQyxRQUF1QixFQUFFLFdBQVcsR0FBRyxRQUFRO1FBQ3RFLElBQUksQ0FBQyxhQUFhLEdBQUcsUUFBUSxDQUFDO1FBQzlCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxXQUFXLENBQUM7SUFDdEMsQ0FBQzs4R0F0WFUsZ0NBQWdDO2tHQUFoQyxnQ0FBZ0MsdVZDZjdDLG12QkFVQTs7MkZES2EsZ0NBQWdDO2tCQVA1QyxTQUFTOytCQUNFLHFDQUFxQyxjQUNuQyxJQUFJLFdBQ1AsRUFBRTsrRUFNWCxXQUFXO3NCQURWLFlBQVk7dUJBQUMsY0FBYyxFQUFFLENBQUMsUUFBUSxDQUFDO2dCQVF4QyxhQUFhO3NCQURaLFlBQVk7dUJBQUMsa0JBQWtCLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBTTVDLFlBQVk7c0JBRFgsWUFBWTt1QkFBQyxlQUFlLEVBQUUsQ0FBQyxRQUFRLENBQUM7Z0JBTXpDLHFCQUFxQjtzQkFEcEIsWUFBWTt1QkFBQyx3QkFBd0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFvQnhDLFVBQVU7c0JBQW5CLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSG9zdExpc3RlbmVyLCBPdXRwdXQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCBTaW1wbGVLZXlib2FyZCBmcm9tICdzaW1wbGUta2V5Ym9hcmQnO1xuaW1wb3J0IHtcbiAgU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24sXG4gIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkSW5wdXRUeXBlcyxcbiAgU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzXG59IGZyb20gJy4vY29uc3RhbnRzJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb21wb25lbnQnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3N5c3RlbGFiLXZpcnR1YWwta2V5Ym9hcmQuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJ3N5c3RlbGFiLXZpcnR1YWwta2V5Ym9hcmQuY29tcG9uZW50LnNjc3MnLFxufSlcbmV4cG9ydCBjbGFzcyBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZENvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQge1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6a2V5dXAnLCBbJyRldmVudCddKVxuICBoYW5kbGVLZXlVcChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC5pc1RydXN0ZWQpIHtcbiAgICAgIHRoaXMuY2FyZXRFdmVudEhhbmRsZXIoZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpwb2ludGVydXAnLCBbJyRldmVudCddKVxuICBoYW5kbGVNb3VzZVVwKGV2ZW50OiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmNhcmV0RXZlbnRIYW5kbGVyKGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpzZWxlY3QnLCBbJyRldmVudCddKVxuICBoYW5kbGVTZWxlY3QoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5jYXJldEV2ZW50SGFuZGxlcihldmVudCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6c2VsZWN0aW9uY2hhbmdlJywgWyckZXZlbnQnXSlcbiAgaGFuZGxlU2VsZWN0aW9uQ2hhbmdlKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIHRoaXMuY2FyZXRFdmVudEhhbmRsZXIoZXZlbnQpO1xuICB9XG5cbiAgZ2V0IG1heExlbmd0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8ubWF4TGVuZ3RoID8/IC0xO1xuICB9XG5cbiAgZ2V0IGlzVGV4dGFyZWEoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50Py50eXBlID09PSAndGV4dGFyZWEnO1xuICB9XG5cbiAgcHVibGljIGRlYnVnID0gZmFsc2U7XG4gIHByaXZhdGUgc2VsZWN0ZWRMYXlvdXQ6IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cyA9IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkTGF5b3V0cy5kZWZhdWx0O1xuICBwcml2YXRlIGtleWJvYXJkOiBTaW1wbGVLZXlib2FyZDtcbiAgcHJpdmF0ZSBjYXJldFBvc2l0aW9uOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBjYXJldFBvc2l0aW9uRW5kOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBhY3RpdmVJbnB1dEVsZW1lbnQhOiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCB8IG51bGw7XG5cbiAgQE91dHB1dCgpIGNsb3NlUGFuZWwgPSBuZXcgRXZlbnRFbWl0dGVyPHZvaWQ+KCk7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBlbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+KSB7fVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICBjb25zdCBsYXlvdXQgPSB7XG4gICAgICBbU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzLmRlZmF1bHRdOiBbXG4gICAgICAgICdgIDEgMiAzIDQgNSA2IDcgOCA5IDAgLSA9IHtia3NwfScsXG4gICAgICAgICd7dGFifSBxIHcgZSByIHQgeSB1IGkgbyBwIFsgXSBcXFxcJyxcbiAgICAgICAgXCJ7bG9ja30gYSBzIGQgZiBnIGggaiBrIGwgOyAnIHtlbnRlcn1cIixcbiAgICAgICAgJ3tzaGlmdH0geiB4IGMgdiBiIG4gbSAsIC4gLyB7c2hpZnR9JyxcbiAgICAgICAgJ3tzcGFjZX0nLFxuICAgICAgXSxcbiAgICAgIFtTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMuc2hpZnRdOiBbXG4gICAgICAgICd+ICEgQCAjICQgJSBeICZhbXA7ICogKCApIF8gKyB7YmtzcH0nLFxuICAgICAgICAne3RhYn0gUSBXIEUgUiBUIFkgVSBJIE8gUCB7IH0gfCcsXG4gICAgICAgICd7bG9ja30gQSBTIEQgRiBHIEggSiBLIEwgOiBcIiB7ZW50ZXJ9JyxcbiAgICAgICAgJ3tzaGlmdH0gWiBYIEMgViBCIE4gTSAmbHQ7ICZndDsgPyB7c2hpZnR9JyxcbiAgICAgICAgJ3tzcGFjZX0nLFxuICAgICAgXSxcbiAgICAgIFtTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMubnVtZXJpY106IFsnNyA4IDknLCAnNCA1IDYnLCAnMSAyIDMnLCAnMCB7YmtzcH0nXSxcbiAgICB9O1xuICAgIHRoaXMua2V5Ym9hcmQgPSBuZXcgU2ltcGxlS2V5Ym9hcmQoJy5zaW1wbGUta2V5Ym9hcmQnLCB7XG4gICAgICBvbktleVByZXNzOiAoYnV0dG9uKSA9PiB0aGlzLmhhbmRsZUtleVByZXNzKGJ1dHRvbiksXG4gICAgICBtZXJnZURpc3BsYXk6IHRydWUsXG4gICAgICBkaXNwbGF5OiB7XG4gICAgICAgIFtTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZEJ1dHRvbi5CYWNrc3BhY2VdOiAnZGVsZXRlJyxcbiAgICAgIH0sXG4gICAgICBidXR0b25UaGVtZTogW1xuICAgICAgICB7XG4gICAgICAgICAgY2xhc3M6ICd2aXJ0dWFsLWtleWJvYXJkLWRlbGV0ZS1idXR0b24nLFxuICAgICAgICAgIGJ1dHRvbnM6IGAke1N5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLkJhY2tzcGFjZX1gLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICAgIGxheW91dCxcbiAgICB9KTtcbiAgICB0aGlzLnNldExheW91dCh0aGlzLnNlbGVjdGVkTGF5b3V0KTtcbiAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgY29uc29sZS5sb2coJ0xheW91dDogJywgbGF5b3V0KTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgc2V0QWN0aXZlSW5wdXQoaW5wdXQ6IEhUTUxJbnB1dEVsZW1lbnQgfCBIVE1MVGV4dEFyZWFFbGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQgPSBpbnB1dDtcblxuICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICBjb25zdCBpbnB1dFR5cGUgPSB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8udHlwZTtcbiAgICAgIGNvbnNvbGUubG9nKCdMYXlvdXQ6JywgYCR7aW5wdXRUeXBlfV8ke3RoaXMuc2VsZWN0ZWRMYXlvdXR9YCk7XG4gICAgfVxuXG4gICAgbGV0IHNlbGVjdGlvblN0YXJ0OiBudW1iZXI7XG4gICAgbGV0IHNlbGVjdGlvbkVuZDogbnVtYmVyO1xuICAgIGlmICh0aGlzLmlzSW5wdXROdW1lcmljKGlucHV0KSkge1xuICAgICAgc2VsZWN0aW9uU3RhcnQgPSB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudC52YWx1ZS50b1N0cmluZygpLmxlbmd0aDtcbiAgICAgIHNlbGVjdGlvbkVuZCA9IHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50LnZhbHVlLnRvU3RyaW5nKCkubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZWxlY3Rpb25TdGFydCA9IHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50LnNlbGVjdGlvblN0YXJ0O1xuICAgICAgc2VsZWN0aW9uRW5kID0gdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQuc2VsZWN0aW9uRW5kO1xuICAgIH1cblxuICAgIHRoaXMuc2V0Q2FyZXRQb3NpdGlvbihzZWxlY3Rpb25TdGFydCwgc2VsZWN0aW9uRW5kKTtcblxuICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICBjb25zb2xlLmxvZygnQ2FyZXQgc3RhcnQgYXQ6JywgdGhpcy5jYXJldFBvc2l0aW9uLCB0aGlzLmNhcmV0UG9zaXRpb25FbmQpO1xuICAgIH1cbiAgICB0aGlzLmZvY3VzQWN0aXZlSW5wdXQoKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRMYXlvdXQobGF5b3V0OiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkTGF5b3V0ID0gbGF5b3V0O1xuICAgIGlmICh0aGlzLmtleWJvYXJkKSB7XG4gICAgICB0aGlzLmtleWJvYXJkLnNldE9wdGlvbnMoe1xuICAgICAgICBsYXlvdXROYW1lOiBsYXlvdXQsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGlzSW5wdXRBbHBoYWJldGljKGFjdGl2ZUlucHV0RWxlbWVudDogSFRNTElucHV0RWxlbWVudCB8IEhUTUxUZXh0QXJlYUVsZW1lbnQpOiBib29sZWFuIHtcbiAgICBjb25zdCBpbnB1dFR5cGUgPSBhY3RpdmVJbnB1dEVsZW1lbnQ/LnR5cGU7XG4gICAgcmV0dXJuIGlucHV0VHlwZSAmJiBbU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRJbnB1dFR5cGVzLnRleHQsIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkSW5wdXRUeXBlcy5wYXNzd29yZF0uc29tZSgoaSkgPT4gaSA9PT0gaW5wdXRUeXBlKTtcbiAgfVxuXG4gIHByaXZhdGUgaXNJbnB1dE51bWVyaWMoYWN0aXZlSW5wdXRFbGVtZW50OiBIVE1MSW5wdXRFbGVtZW50IHwgSFRNTFRleHRBcmVhRWxlbWVudCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGlucHV0VHlwZSA9IGFjdGl2ZUlucHV0RWxlbWVudD8udHlwZTtcbiAgICByZXR1cm4gaW5wdXRUeXBlICYmIFtTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZElucHV0VHlwZXMubnVtYmVyXS5zb21lKChpKSA9PiBpID09PSBpbnB1dFR5cGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBoYW5kbGVLZXlQcmVzcyhidXR0b246IHN0cmluZywgZT86IEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZGVidWcpIHtcbiAgICAgIGNvbnNvbGUubG9nKCdLZXkgcHJlc3M6JywgYnV0dG9uKTtcbiAgICB9XG5cbiAgICBpZiAoYnV0dG9uID09PSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZEJ1dHRvbi5TaGlmdCB8fCBidXR0b24gPT09IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLkxvY2spIHtcbiAgICAgIHRoaXMudG9nZ2xlU2hpZnQoKTtcbiAgICB9IGVsc2UgaWYgKGJ1dHRvbiA9PT0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uRG9uZSkge1xuICAgICAgdGhpcy5jbG9zZVBhbmVsLmVtaXQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuaXNBY2NlcHRlZE5vblN0YW5kYXJkQnV0dG9uKGJ1dHRvbikgJiYgIXRoaXMuaXNTdGFuZGFyZEJ1dHRvbihidXR0b24pKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5oYW5kbGVCdXR0b25PdXRwdXQoYnV0dG9uKTtcblxuICAgIGlmICh0aGlzLmFjdGl2ZUlucHV0RWxlbWVudCkge1xuICAgICAgdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQudmFsdWUgPSBvdXRwdXQ7XG5cbiAgICAgIGlmICh0aGlzLmRlYnVnKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKCdDYXJldCBhdDonLCB0aGlzLmNhcmV0UG9zaXRpb24sIHRoaXMuY2FyZXRQb3NpdGlvbkVuZCwgJ0J1dHRvbicsIGUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuZGlzcGF0Y2hFdmVudHMoYnV0dG9uKTtcbiAgfVxuXG4gIHByaXZhdGUgaGFuZGxlQnV0dG9uT3V0cHV0KGJ1dHRvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb21tb25QYXJhbXM6IFtudW1iZXIsIG51bWJlciwgYm9vbGVhbl0gPSB0aGlzLmdldENvbW1vblBhcmFtcygpO1xuICAgIGxldCBvdXRwdXQgPSB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8udmFsdWUgfHwgJyc7XG4gICAgaWYgKCF0aGlzLmlzU3RhbmRhcmRCdXR0b24oYnV0dG9uKSkge1xuICAgICAgaWYgKGJ1dHRvbiA9PT0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uQmFja3NwYWNlKSB7XG4gICAgICAgIG91dHB1dCA9IHRoaXMucmVtb3ZlQXQob3V0cHV0LCAuLi5jb21tb25QYXJhbXMpO1xuICAgICAgfSBlbHNlIGlmIChidXR0b24gPT09IFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLlNwYWNlKSB7XG4gICAgICAgIG91dHB1dCA9IHRoaXMuYWRkU3RyaW5nQXQob3V0cHV0LCAnICcsIC4uLmNvbW1vblBhcmFtcyk7XG4gICAgICB9IGVsc2UgaWYgKGJ1dHRvbiA9PT0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uVGFiKSB7XG4gICAgICAgIG91dHB1dCA9IHRoaXMuYWRkU3RyaW5nQXQob3V0cHV0LCAnXFx0JywgLi4uY29tbW9uUGFyYW1zKTtcbiAgICAgIH0gZWxzZSBpZiAoYnV0dG9uID09PSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZEJ1dHRvbi5FbnRlcikge1xuICAgICAgICBpZiAodGhpcy5pc1RleHRhcmVhKSB7XG4gICAgICAgICAgb3V0cHV0ID0gdGhpcy5hZGRTdHJpbmdBdChvdXRwdXQsICdcXG4nLCAuLi5jb21tb25QYXJhbXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dCA9IHRoaXMuYWRkU3RyaW5nQXQob3V0cHV0LCBidXR0b24sIC4uLmNvbW1vblBhcmFtcyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29tbW9uUGFyYW1zKCk6IFtudW1iZXIsIG51bWJlciwgYm9vbGVhbl0ge1xuICAgIHJldHVybiBbdGhpcy5jYXJldFBvc2l0aW9uIHx8IDAsIHRoaXMuY2FyZXRQb3NpdGlvbkVuZCB8fCAwLCB0cnVlXTtcbiAgfVxuXG4gIHByaXZhdGUgaXNBY2NlcHRlZE5vblN0YW5kYXJkQnV0dG9uKGJ1dHRvbjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIFtcbiAgICAgIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLkJhY2tzcGFjZS50b1N0cmluZygpLFxuICAgICAgU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uU3BhY2UudG9TdHJpbmcoKSxcbiAgICAgIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLlRhYi50b1N0cmluZygpLFxuICAgICAgU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uRW50ZXIudG9TdHJpbmcoKSxcbiAgICBdLmluY2x1ZGVzKGJ1dHRvbik7XG4gIH1cblxuICBwcml2YXRlIGRpc3BhdGNoRXZlbnRzKGJ1dHRvbjogc3RyaW5nKSB7XG4gICAgY29uc3QgeyBrZXksIGNvZGUgfSA9IHRoaXMuY29udmVydEZyb21CdXR0b25Ub0NvZGUoYnV0dG9uKTtcblxuICAgIGNvbnN0IGV2ZW50SW5pdDogS2V5Ym9hcmRFdmVudEluaXQgPSB7XG4gICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgY2FuY2VsYWJsZTogdHJ1ZSxcbiAgICAgIHNoaWZ0S2V5OiB0aGlzLnNlbGVjdGVkTGF5b3V0ID09PSBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMuc2hpZnQsXG4gICAgICBrZXk6IGtleSxcbiAgICAgIGNvZGU6IGNvZGUsXG4gICAgICBsb2NhdGlvbjogMCxcbiAgICB9O1xuXG4gICAgLy8gU2ltdWxhdGUgYWxsIG5lZWRlZCBldmVudHMgb24gYmFzZSBlbGVtZW50XG4gICAgdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQ/LmRpc3BhdGNoRXZlbnQobmV3IEtleWJvYXJkRXZlbnQoJ2tleWRvd24nLCBldmVudEluaXQpKTtcbiAgICB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8uZGlzcGF0Y2hFdmVudChuZXcgS2V5Ym9hcmRFdmVudCgna2V5cHJlc3MnLCBldmVudEluaXQpKTtcbiAgICB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8uZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2lucHV0JywgeyBidWJibGVzOiB0cnVlIH0pKTtcbiAgICB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8uZGlzcGF0Y2hFdmVudChuZXcgS2V5Ym9hcmRFdmVudCgna2V5dXAnLCBldmVudEluaXQpKTtcblxuICAgIC8vIEFuZCBzZXQgZm9jdXMgdG8gaW5wdXRcbiAgICB0aGlzLmZvY3VzQWN0aXZlSW5wdXQoKTtcbiAgfVxuXG4gIC8qXG4gICAqIEFVWElMSUFSWSBNRVRIT0RTXG4gICAqICovXG4gIHByaXZhdGUgY29udmVydEZyb21CdXR0b25Ub0NvZGUoYnV0dG9uOiBzdHJpbmcpOiB7IGtleTogc3RyaW5nOyBjb2RlOiBzdHJpbmcgfSB7XG4gICAgbGV0IGtleTogc3RyaW5nO1xuICAgIGxldCBjb2RlOiBzdHJpbmc7XG4gICAgaWYgKGJ1dHRvbi5pbmNsdWRlcygneycpICYmIGJ1dHRvbi5pbmNsdWRlcygnfScpKSB7XG4gICAgICAvLyBDYXBpdGFsaXplIG5hbWVcbiAgICAgIGtleSA9IGJ1dHRvbi5zbGljZSgxLCBidXR0b24ubGVuZ3RoIC0gMSkudG9Mb3dlckNhc2UoKTtcbiAgICAgIGtleSA9IGtleS5jaGFyQXQoMCkudG9VcHBlckNhc2UoKSArIGtleS5zbGljZSgxKTtcbiAgICAgIGNvZGUgPSBrZXk7XG5cbiAgICAgIC8vIEZpeCB0byBzdGFuZGFyZCBrZXkgY29kZVxuICAgICAgaWYgKGNvZGUudG9Mb3dlckNhc2UoKSA9PT0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRCdXR0b24uQmFja3NwYWNlLnNsaWNlKDEsIFN5c3RlbGFiVmlydHVhbEtleWJvYXJkQnV0dG9uLkJhY2tzcGFjZS5sZW5ndGggLSAxKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgICAgIGNvZGUgPSAnQmFja3NwYWNlJztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAga2V5ID0gYnV0dG9uO1xuICAgICAgY29kZSA9IE51bWJlci5pc0ludGVnZXIoTnVtYmVyKGJ1dHRvbikpID8gYERpZ2l0JHtidXR0b259YCA6IGBLZXkke2J1dHRvbi50b1VwcGVyQ2FzZSgpfWA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsga2V5LCBjb2RlIH07XG4gIH1cblxuICBwcml2YXRlIGZvY3VzQWN0aXZlSW5wdXQoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQ/LmZvY3VzKCk7XG4gICAgaWYgKCF0aGlzLmlzSW5wdXROdW1lcmljKHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50KSkge1xuICAgICAgdGhpcy5hY3RpdmVJbnB1dEVsZW1lbnQ/LnNldFNlbGVjdGlvblJhbmdlKHRoaXMuY2FyZXRQb3NpdGlvbiwgdGhpcy5jYXJldFBvc2l0aW9uRW5kKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvZ2dsZVNoaWZ0KCkge1xuICAgIGxldCBjdXJyZW50TGF5b3V0ID0gdGhpcy5rZXlib2FyZC5vcHRpb25zLmxheW91dE5hbWU7XG4gICAgbGV0IHNlbGVjdGVkTGF5b3V0OiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMgPVxuICAgICAgY3VycmVudExheW91dCA9PT0gU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRMYXlvdXRzLmRlZmF1bHQgPyBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMuc2hpZnQgOiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMuZGVmYXVsdDtcblxuICAgIHRoaXMuc2V0TGF5b3V0KHNlbGVjdGVkTGF5b3V0KTtcbiAgfVxuXG4gIHByaXZhdGUgaXNTdGFuZGFyZEJ1dHRvbihidXR0b246IHN0cmluZykge1xuICAgIHJldHVybiBidXR0b24gJiYgIShidXR0b25bMF0gPT09ICd7JyAmJiBidXR0b25bYnV0dG9uLmxlbmd0aCAtIDFdID09PSAnfScpO1xuICB9XG5cbiAgLypcbiAgICogT1VUUFVUIFNUUklORyBNRVRIT0RTXG4gICAqICovXG4gIHByaXZhdGUgcmVtb3ZlQXQoc291cmNlOiBzdHJpbmcsIHBvc2l0aW9uID0gc291cmNlLmxlbmd0aCwgcG9zaXRpb25FbmQgPSBzb3VyY2UubGVuZ3RoLCBtb3ZlQ2FyZXQgPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgaWYgKHBvc2l0aW9uID09PSAwICYmIHBvc2l0aW9uRW5kID09PSAwKSB7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH1cblxuICAgIGxldCBvdXRwdXQ6IHN0cmluZztcblxuICAgIGlmIChwb3NpdGlvbiA9PT0gcG9zaXRpb25FbmQpIHtcbiAgICAgIGlmIChwb3NpdGlvbiAmJiBwb3NpdGlvbiA+PSAwKSB7XG4gICAgICAgIG91dHB1dCA9IHNvdXJjZS5zbGljZSgwLCBwb3NpdGlvbiAtIDEpICsgc291cmNlLnNsaWNlKHBvc2l0aW9uKTtcbiAgICAgICAgaWYgKG1vdmVDYXJldCkge1xuICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZXRQb3NpdGlvbigxLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0cHV0ID0gc291cmNlLnNsaWNlKDAsIC0xKTtcbiAgICAgICAgaWYgKG1vdmVDYXJldCkge1xuICAgICAgICAgIHRoaXMudXBkYXRlQ2FyZXRQb3NpdGlvbigxLCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQgPSBzb3VyY2Uuc2xpY2UoMCwgcG9zaXRpb24pICsgc291cmNlLnNsaWNlKHBvc2l0aW9uRW5kKTtcbiAgICAgIGlmIChtb3ZlQ2FyZXQpIHtcbiAgICAgICAgdGhpcy5zZXRDYXJldFBvc2l0aW9uKHBvc2l0aW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gb3V0cHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRTdHJpbmdBdChzb3VyY2U6IHN0cmluZywgc3RyOiBzdHJpbmcsIHBvc2l0aW9uID0gc291cmNlLmxlbmd0aCwgcG9zaXRpb25FbmQgPSBzb3VyY2UubGVuZ3RoLCBtb3ZlQ2FyZXQgPSBmYWxzZSk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMubWF4TGVuZ3RoICE9PSAtMSAmJiBzb3VyY2UubGVuZ3RoID49IHRoaXMubWF4TGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc291cmNlO1xuICAgIH1cblxuICAgIGxldCBvdXRwdXQ6IHN0cmluZztcblxuICAgIGlmICghcG9zaXRpb24gJiYgcG9zaXRpb24gIT09IDApIHtcbiAgICAgIG91dHB1dCA9IHNvdXJjZSArIHN0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0ID0gW3NvdXJjZS5zbGljZSgwLCBwb3NpdGlvbiksIHN0ciwgc291cmNlLnNsaWNlKHBvc2l0aW9uRW5kKV0uam9pbignJyk7XG4gICAgICBpZiAobW92ZUNhcmV0KSB7XG4gICAgICAgIHRoaXMudXBkYXRlQ2FyZXRQb3NpdGlvbihzdHIubGVuZ3RoLCBmYWxzZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG91dHB1dDtcbiAgfVxuXG4gIC8qXG4gICAqIENBUkVUIE1FVEhPRFNcbiAgICogKi9cbiAgcHJpdmF0ZSBjYXJldEV2ZW50SGFuZGxlcihldmVudDogYW55KSB7XG4gICAgbGV0IHRhcmdldFRhZ05hbWUgPSAnJztcbiAgICBpZiAoZXZlbnQudGFyZ2V0LnRhZ05hbWUpIHtcbiAgICAgIHRhcmdldFRhZ05hbWUgPSBldmVudC50YXJnZXQudGFnTmFtZS50b0xvd2VyQ2FzZSgpO1xuICAgIH1cblxuICAgIGNvbnN0IGlzVGV4dElucHV0ID1cbiAgICAgIHRhcmdldFRhZ05hbWUgPT09ICd0ZXh0YXJlYScgfHxcbiAgICAgICh0YXJnZXRUYWdOYW1lID09PSAnaW5wdXQnICYmIFsndGV4dCcsICdzZWFyY2gnLCAnZW1haWwnLCAncGFzc3dvcmQnLCAndXJsJywgJ3RlbCddLmluY2x1ZGVzKGV2ZW50LnRhcmdldC50eXBlKSk7XG5cbiAgICBjb25zdCBpc0tleWJvYXJkID1cbiAgICAgIGV2ZW50LnRhcmdldCA9PT0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQgfHwgKGV2ZW50LnRhcmdldCAmJiB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jb250YWlucyhldmVudC50YXJnZXQpKTtcblxuICAgIGlmIChpc1RleHRJbnB1dCAmJiB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudCA9PSBldmVudC50YXJnZXQpIHtcbiAgICAgIC8qKlxuICAgICAgICogVHJhY2tzIGN1cnJlbnQgY3Vyc29yIHBvc2l0aW9uXG4gICAgICAgKiBBcyBrZXlzIGFyZSBwcmVzc2VkLCB0ZXh0IHdpbGwgYmUgYWRkZWQvcmVtb3ZlZCBhdCB0aGF0IHBvc2l0aW9uIHdpdGhpbiB0aGUgaW5wdXQuXG4gICAgICAgKi9cbiAgICAgIHRoaXMuc2V0Q2FyZXRQb3NpdGlvbihldmVudC50YXJnZXQuc2VsZWN0aW9uU3RhcnQsIGV2ZW50LnRhcmdldC5zZWxlY3Rpb25FbmQpO1xuXG4gICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICBjb25zb2xlLmxvZygnQ2FyZXQgYXQ6JywgdGhpcy5jYXJldFBvc2l0aW9uLCB0aGlzLmNhcmV0UG9zaXRpb25FbmQsIGV2ZW50ICYmIGV2ZW50LnRhcmdldC50YWdOYW1lLnRvTG93ZXJDYXNlKCksIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGV2ZW50LnR5cGUgPT09ICdwb2ludGVydXAnICYmIHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50ID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfSBlbHNlIGlmICghaXNLZXlib2FyZCAmJiBldmVudD8udHlwZSAhPT0gJ3NlbGVjdGlvbmNoYW5nZScpIHtcbiAgICAgIC8qKlxuICAgICAgICogd2UgbXVzdCBlbnN1cmUgY2FyZXRQb3NpdGlvbiBkb2Vzbid0IHBlcnNpc3Qgb25jZSByZWFjdGl2YXRlZC5cbiAgICAgICAqL1xuICAgICAgdGhpcy5zZXRDYXJldFBvc2l0aW9uKG51bGwpO1xuXG4gICAgICBpZiAodGhpcy5kZWJ1Zykge1xuICAgICAgICBjb25zb2xlLmxvZyhgQ2FyZXQgcG9zaXRpb24gcmVzZXQgZHVlIHRvIFwiJHtldmVudD8udHlwZX1cIiBldmVudGAsIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZUNhcmV0UG9zaXRpb24obGVuZ3RoOiBudW1iZXIsIG1pbnVzID0gZmFsc2UpIHtcbiAgICBjb25zdCBuZXdDYXJldFBvcyA9IHRoaXMuY29tcHV0ZU5ld0NhcmV0UG9zaXRpb24obGVuZ3RoLCBtaW51cyk7XG4gICAgdGhpcy5zZXRDYXJldFBvc2l0aW9uKG5ld0NhcmV0UG9zKTtcbiAgICAvLyBTY3JvbGwgdG8gYm90dG9tXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmFjdGl2ZUlucHV0RWxlbWVudD8uc2Nyb2xsVG8oe1xuICAgICAgICB0b3A6IHRoaXMuYWN0aXZlSW5wdXRFbGVtZW50LnNjcm9sbEhlaWdodCxcbiAgICAgIH0gYXMgU2Nyb2xsVG9PcHRpb25zKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZU5ld0NhcmV0UG9zaXRpb24obGVuZ3RoOiBudW1iZXIsIG1pbnVzID0gZmFsc2UpIHtcbiAgICBsZXQgY2FyZXRQb3NpdGlvbiA9IHRoaXMuY2FyZXRQb3NpdGlvbjtcblxuICAgIGlmIChjYXJldFBvc2l0aW9uICE9IG51bGwpIHtcbiAgICAgIGlmIChtaW51cykge1xuICAgICAgICBpZiAoY2FyZXRQb3NpdGlvbiA+IDApIGNhcmV0UG9zaXRpb24gPSBjYXJldFBvc2l0aW9uIC0gbGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FyZXRQb3NpdGlvbiA9IGNhcmV0UG9zaXRpb24gKyBsZW5ndGg7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjYXJldFBvc2l0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRDYXJldFBvc2l0aW9uKHBvc2l0aW9uOiBudW1iZXIgfCBudWxsLCBlbmRQb3NpdGlvbiA9IHBvc2l0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5jYXJldFBvc2l0aW9uID0gcG9zaXRpb247XG4gICAgdGhpcy5jYXJldFBvc2l0aW9uRW5kID0gZW5kUG9zaXRpb247XG4gIH1cbn1cbiIsIjwhLS1cbiAgfiBDb3B5cmlnaHQgKGMpIDIwMjAgLSAyMDI0IC0gSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgU3lzdGVsYWIgVGVjaG5vbG9naWVzLCBTQS4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAgfiBOT1RJQ0U6ICBBbGwgaW5mb3JtYXRpb24gY29udGFpbmVkIGhlcmVpbiBpcyBhbmQgcmVtYWlucyB0aGUgcHJvcGVydHkgb2YgSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzXG4gIH4gYWZmaWxpYXRlcywgaWYgYW55LiAgVGhlIGludGVsbGVjdHVhbCBhbmQgdGVjaG5pY2FsIGNvbmNlcHRzIGNvbnRhaW5lZCBoZXJlaW4gYXJlIHByb3ByaWV0YXJ5IHRvIEluc3RydW1lbnRhdGlvblxuICB+IExhYm9yYXRvcnkgQ29tcGFueSBhbmQgaXRzIGFmZmlsaWF0ZXMgYW5kIG1heSBiZSBjb3ZlcmVkIGJ5IFUuUy4gYW5kIGZvcmVpZ24gcGF0ZW50cyBhbmQgcGF0ZW50IGFwcGxpY2F0aW9ucywgYW5kL29yXG4gIH4gYXJlIHByb3RlY3RlZCBieSB0cmFkZSBzZWNyZXQgb3IgY29weXJpZ2h0IGxhdy4gRGlzc2VtaW5hdGlvbiBvZiB0aGlzIGluZm9ybWF0aW9uIG9yIHJlcHJvZHVjdGlvbiBvZiB0aGlzIG1hdGVyaWFsIGlzXG4gIH4gc3RyaWN0bHkgZm9yYmlkZGVuIHVubGVzcyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24gaXMgSW5zdHJ1bWVudGF0aW9uIExhYm9yYXRvcnkgQ29tcGFueS5cbiAgLS0+XG5cbjxkaXYgY2xhc3M9XCJzaW1wbGUta2V5Ym9hcmRcIj48L2Rpdj5cbiJdfQ==
@@ -0,0 +1,3 @@
1
+ import { InjectionToken } from '@angular/core';
2
+ export const VIRTUAL_KEYBOARD_CONFIG = new InjectionToken('VIRTUAL_KEYBOARD_CONFIG');
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9zeXN0ZWxhYi12aXJ0dWFsLWtleWJvYXJkL3NyYy9saWIvc3lzdGVsYWItdmlydHVhbC1rZXlib2FyZC5jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUcvQyxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLGNBQWMsQ0FBZ0MseUJBQXlCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5cbmV4cG9ydCBjb25zdCBWSVJUVUFMX0tFWUJPQVJEX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZENvbmZpZz4oJ1ZJUlRVQUxfS0VZQk9BUkRfQ09ORklHJyk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3lzdGVsYWJWaXJ0dWFsS2V5Ym9hcmRDb25maWcge1xuICBsYXlvdXQ/OiBTeXN0ZWxhYlZpcnR1YWxLZXlib2FyZExheW91dHM7XG59XG4iXX0=