@flogeez/angular-tiptap-editor 3.1.3 → 3.1.4
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/CHANGELOG.md +18 -0
- package/README.md +2 -2
- package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
- package/esm2022/lib/ate-editor.provider.mjs +38 -0
- package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
- package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +137 -0
- package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
- package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +309 -0
- package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
- package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +126 -0
- package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +271 -0
- package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +272 -0
- package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +123 -0
- package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
- package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +1031 -0
- package/esm2022/lib/components/editor/ate-block-controls.component.mjs +256 -0
- package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +328 -0
- package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
- package/esm2022/lib/components/ui/ate-button.component.mjs +91 -0
- package/esm2022/lib/components/ui/ate-separator.component.mjs +11 -0
- package/esm2022/lib/config/ate-editor.config.mjs +133 -0
- package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
- package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
- package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
- package/esm2022/lib/directives/ate-tooltip.directive.mjs +138 -0
- package/esm2022/lib/extensions/ate-block-controls.extension.mjs +156 -0
- package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
- package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +277 -0
- package/esm2022/lib/extensions/ate-table.extension.mjs +27 -0
- package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
- package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
- package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
- package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
- package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
- package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
- package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
- package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
- package/esm2022/lib/models/ate-bubble-menu.model.mjs +53 -0
- package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
- package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
- package/esm2022/lib/models/ate-image.model.mjs +2 -0
- package/esm2022/lib/models/ate-slash-command.model.mjs +2 -0
- package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
- package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
- package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
- package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
- package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
- package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
- package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
- package/esm2022/lib/services/ate-color-picker.service.mjs +194 -0
- package/esm2022/lib/services/ate-editor-commands.service.mjs +474 -0
- package/esm2022/lib/services/ate-i18n.service.mjs +422 -0
- package/esm2022/lib/services/ate-image.service.mjs +459 -0
- package/esm2022/lib/services/ate-link.service.mjs +99 -0
- package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
- package/esm2022/public-api.mjs +40 -0
- package/fesm2022/flogeez-angular-tiptap-editor.mjs +319 -352
- package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
- package/index.d.ts +3 -1734
- package/lib/ate-editor.provider.d.ts +21 -0
- package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
- package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
- package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
- package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +49 -0
- package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
- package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +16 -0
- package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +25 -0
- package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
- package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
- package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
- package/lib/components/editor/angular-tiptap-editor.component.d.ts +242 -0
- package/lib/components/editor/ate-block-controls.component.d.ts +44 -0
- package/lib/components/slash-commands/ate-slash-commands.component.d.ts +34 -0
- package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
- package/lib/components/ui/ate-button.component.d.ts +25 -0
- package/lib/components/ui/ate-separator.component.d.ts +5 -0
- package/lib/config/ate-editor.config.d.ts +19 -0
- package/lib/config/ate-global-config.token.d.ts +6 -0
- package/lib/config/ate-slash-commands.config.d.ts +41 -0
- package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
- package/lib/directives/ate-tooltip.directive.d.ts +30 -0
- package/lib/extensions/ate-block-controls.extension.d.ts +10 -0
- package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
- package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
- package/lib/extensions/ate-table.extension.d.ts +2 -0
- package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
- package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
- package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
- package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
- package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
- package/lib/models/ate-bubble-menu.model.d.ts +33 -0
- package/lib/models/ate-editor-config.model.d.ts +113 -0
- package/lib/models/ate-editor-state.model.d.ts +109 -0
- package/lib/models/ate-image.model.d.ts +104 -0
- package/lib/models/ate-slash-command.model.d.ts +17 -0
- package/lib/models/ate-toolbar.model.d.ts +18 -0
- package/lib/node-view/ate-angular-node-view.d.ts +115 -0
- package/lib/node-view/ate-injector.registry.d.ts +3 -0
- package/lib/node-view/ate-node-view.factory.d.ts +10 -0
- package/lib/node-view/ate-node-view.models.d.ts +138 -0
- package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
- package/lib/node-view/ate-register-angular-component.d.ts +35 -0
- package/lib/services/ate-color-picker.service.d.ts +65 -0
- package/lib/services/ate-editor-commands.service.d.ts +75 -0
- package/lib/services/ate-i18n.service.d.ts +406 -0
- package/lib/services/ate-image.service.d.ts +82 -0
- package/lib/services/ate-link.service.d.ts +42 -0
- package/lib/utils/ate-color.utils.d.ts +12 -0
- package/package.json +3 -1
- package/public-api.d.ts +31 -0
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
import { Component, ChangeDetectionStrategy, signal, inject, computed, viewChild, } from "@angular/core";
|
|
2
|
+
import { CommonModule } from "@angular/common";
|
|
3
|
+
import { FormsModule } from "@angular/forms";
|
|
4
|
+
import { AteColorPickerService } from "../../../services/ate-color-picker.service";
|
|
5
|
+
import { AteButtonComponent } from "../../ui/ate-button.component";
|
|
6
|
+
import { AteSeparatorComponent } from "../../ui/ate-separator.component";
|
|
7
|
+
import { AteBaseSubBubbleMenu } from "../base/ate-base-sub-bubble-menu";
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
const PRESET_COLORS = [
|
|
10
|
+
"#000000",
|
|
11
|
+
"#666666",
|
|
12
|
+
"#CCCCCC",
|
|
13
|
+
"#FFFFFF",
|
|
14
|
+
"#F44336",
|
|
15
|
+
"#FF9800",
|
|
16
|
+
"#FFEB3B",
|
|
17
|
+
"#4CAF50",
|
|
18
|
+
"#00BCD4",
|
|
19
|
+
"#2196F3",
|
|
20
|
+
"#9C27B0",
|
|
21
|
+
"#E91E63",
|
|
22
|
+
];
|
|
23
|
+
export class AteColorBubbleMenuComponent extends AteBaseSubBubbleMenu {
|
|
24
|
+
constructor() {
|
|
25
|
+
super(...arguments);
|
|
26
|
+
this.colorPickerSvc = inject(AteColorPickerService);
|
|
27
|
+
this.t = this.i18nService.toolbar;
|
|
28
|
+
this.common = this.i18nService.common;
|
|
29
|
+
this.presets = PRESET_COLORS;
|
|
30
|
+
this.colorInputRef = viewChild("colorInput");
|
|
31
|
+
/**
|
|
32
|
+
* LOCAL MODE: We lock the mode when the menu is shown to avoid race conditions
|
|
33
|
+
* where the parent (bubble menu) clears the global signal before we apply the color.
|
|
34
|
+
*/
|
|
35
|
+
this.activeMode = signal("text");
|
|
36
|
+
this.currentColor = computed(() => {
|
|
37
|
+
const marks = this.state().marks;
|
|
38
|
+
const color = this.activeMode() === "text" ? marks.computedColor : marks.computedBackground;
|
|
39
|
+
return color || (this.activeMode() === "text" ? "#000000" : "#ffff00");
|
|
40
|
+
});
|
|
41
|
+
this.hexValue = computed(() => {
|
|
42
|
+
const color = this.currentColor();
|
|
43
|
+
return color.replace("#", "").toUpperCase();
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
onStateChange() {
|
|
47
|
+
this.colorPickerSvc.editMode();
|
|
48
|
+
this.colorPickerSvc.menuTrigger();
|
|
49
|
+
this.colorPickerSvc.isInteracting();
|
|
50
|
+
}
|
|
51
|
+
shouldShow() {
|
|
52
|
+
const { isEditable } = this.state();
|
|
53
|
+
if (!isEditable) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (this.colorPickerSvc.editMode() !== null || this.colorPickerSvc.isInteracting()) {
|
|
57
|
+
return true;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
getSelectionRect() {
|
|
62
|
+
const trigger = this.colorPickerSvc.menuTrigger();
|
|
63
|
+
const ed = this.editor();
|
|
64
|
+
if (!ed) {
|
|
65
|
+
return new DOMRect(0, 0, 0, 0);
|
|
66
|
+
}
|
|
67
|
+
// 1. If we have a stable trigger from service (toolbar or parent menu), anchor to it
|
|
68
|
+
if (trigger) {
|
|
69
|
+
const rect = trigger.getBoundingClientRect();
|
|
70
|
+
// Only use if it's still visible/in DOM (width > 0)
|
|
71
|
+
if (rect.width > 0) {
|
|
72
|
+
return rect;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 2. Otherwise (bubble menu / relay), anchor to text selection
|
|
76
|
+
const { from } = ed.state.selection;
|
|
77
|
+
try {
|
|
78
|
+
const { node } = ed.view.domAtPos(from);
|
|
79
|
+
const element = node instanceof Element ? node : node.parentElement;
|
|
80
|
+
const colorElement = element?.closest('[style*="color"], [style*="background"], mark');
|
|
81
|
+
if (colorElement) {
|
|
82
|
+
return colorElement.getBoundingClientRect();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch (_e) {
|
|
86
|
+
/* ignore */
|
|
87
|
+
}
|
|
88
|
+
// Use native selection for multi-line accuracy
|
|
89
|
+
const selection = window.getSelection();
|
|
90
|
+
if (selection && selection.rangeCount > 0) {
|
|
91
|
+
const range = selection.getRangeAt(0);
|
|
92
|
+
const rect = range.getBoundingClientRect();
|
|
93
|
+
if (rect.width > 0 && rect.height > 0) {
|
|
94
|
+
return rect;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// Final fallback to coordinates at cursor
|
|
98
|
+
const { top, bottom, left, right } = ed.view.coordsAtPos(from);
|
|
99
|
+
return new DOMRect(left, top, right - left, bottom - top);
|
|
100
|
+
}
|
|
101
|
+
onTippyShow(_instance) {
|
|
102
|
+
// 1. Lock the mode immediately to be immune to external signal changes
|
|
103
|
+
const currentMode = this.colorPickerSvc.editMode() || "text";
|
|
104
|
+
this.activeMode.set(currentMode);
|
|
105
|
+
// 2. Capture selection for the command fallback
|
|
106
|
+
this.colorPickerSvc.captureSelection(this.editor());
|
|
107
|
+
}
|
|
108
|
+
onTippyHide(_instance) {
|
|
109
|
+
// Clear trigger only AFTER the menu is hidden to maintain anchor stability during animation
|
|
110
|
+
this.colorPickerSvc.done();
|
|
111
|
+
this.colorPickerSvc.close();
|
|
112
|
+
}
|
|
113
|
+
isColorActive(color) {
|
|
114
|
+
return (this.colorPickerSvc.normalizeColor(this.currentColor()) ===
|
|
115
|
+
this.colorPickerSvc.normalizeColor(color));
|
|
116
|
+
}
|
|
117
|
+
applyColor(color, addToHistory = true, event) {
|
|
118
|
+
if (event) {
|
|
119
|
+
event.preventDefault();
|
|
120
|
+
event.stopPropagation();
|
|
121
|
+
}
|
|
122
|
+
const editor = this.editor();
|
|
123
|
+
// Use our LOCKED mode instead of the global signal
|
|
124
|
+
// Determine if we should focus back to the editor.
|
|
125
|
+
const shouldFocus = !this.colorPickerSvc.isInteracting();
|
|
126
|
+
if (this.activeMode() === "text") {
|
|
127
|
+
this.colorPickerSvc.applyColor(editor, color, addToHistory, shouldFocus);
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
this.colorPickerSvc.applyHighlight(editor, color, addToHistory, shouldFocus);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
onApply(event) {
|
|
134
|
+
if (event) {
|
|
135
|
+
event.preventDefault();
|
|
136
|
+
event.stopPropagation();
|
|
137
|
+
}
|
|
138
|
+
this.colorPickerSvc.close();
|
|
139
|
+
}
|
|
140
|
+
onHexInput(event) {
|
|
141
|
+
const input = event.target;
|
|
142
|
+
let value = input.value.trim();
|
|
143
|
+
if (!value.startsWith("#")) {
|
|
144
|
+
value = "#" + value;
|
|
145
|
+
}
|
|
146
|
+
if (/^#?[0-9A-Fa-f]{3,6}$/.test(value)) {
|
|
147
|
+
this.applyColor(value, false);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
onHexChange(event) {
|
|
151
|
+
const input = event.target;
|
|
152
|
+
let value = input.value.trim();
|
|
153
|
+
if (!value.startsWith("#")) {
|
|
154
|
+
value = "#" + value;
|
|
155
|
+
}
|
|
156
|
+
if (/^#?[0-9A-Fa-f]{3,6}$/.test(value)) {
|
|
157
|
+
this.applyColor(value, true, event);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
triggerNativePicker(event) {
|
|
161
|
+
if (event) {
|
|
162
|
+
event.preventDefault();
|
|
163
|
+
event.stopPropagation();
|
|
164
|
+
}
|
|
165
|
+
this.colorInputRef()?.nativeElement.click();
|
|
166
|
+
}
|
|
167
|
+
onNativeInput(event) {
|
|
168
|
+
this.applyColor(event.target.value, false);
|
|
169
|
+
}
|
|
170
|
+
onNativeChange(event) {
|
|
171
|
+
this.applyColor(event.target.value, true, event);
|
|
172
|
+
}
|
|
173
|
+
onClearColor(event) {
|
|
174
|
+
if (event) {
|
|
175
|
+
event.preventDefault();
|
|
176
|
+
event.stopPropagation();
|
|
177
|
+
}
|
|
178
|
+
const editor = this.editor();
|
|
179
|
+
if (this.activeMode() === "text") {
|
|
180
|
+
this.colorPickerSvc.unsetColor(editor);
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
this.colorPickerSvc.unsetHighlight(editor);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
onMouseDown(event) {
|
|
187
|
+
event.stopPropagation();
|
|
188
|
+
const target = event.target;
|
|
189
|
+
if (target.tagName !== "INPUT") {
|
|
190
|
+
event.preventDefault();
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
onFocus() {
|
|
194
|
+
this.colorPickerSvc.setInteracting(true);
|
|
195
|
+
}
|
|
196
|
+
onBlur() {
|
|
197
|
+
setTimeout(() => {
|
|
198
|
+
this.colorPickerSvc.setInteracting(false);
|
|
199
|
+
this.updateMenu();
|
|
200
|
+
}, 150);
|
|
201
|
+
}
|
|
202
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteColorBubbleMenuComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
203
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: AteColorBubbleMenuComponent, isStandalone: true, selector: "ate-color-bubble-menu", viewQueries: [{ propertyName: "colorInputRef", first: true, predicate: ["colorInput"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: `
|
|
204
|
+
<div
|
|
205
|
+
#menuRef
|
|
206
|
+
class="bubble-menu color-bubble-menu"
|
|
207
|
+
(mousedown)="onMouseDown($event)"
|
|
208
|
+
(click)="$event.stopPropagation()"
|
|
209
|
+
(keydown)="$event.stopPropagation()"
|
|
210
|
+
(keydown.escape)="onApply($event)"
|
|
211
|
+
tabindex="-1"
|
|
212
|
+
role="dialog">
|
|
213
|
+
<div class="color-picker-container">
|
|
214
|
+
<div class="dropdown-row presets">
|
|
215
|
+
<div class="color-grid">
|
|
216
|
+
@for (color of presets; track color) {
|
|
217
|
+
<ate-button
|
|
218
|
+
class="color-swatch-btn"
|
|
219
|
+
size="small"
|
|
220
|
+
[title]="color"
|
|
221
|
+
[active]="isColorActive(color)"
|
|
222
|
+
[backgroundColor]="color"
|
|
223
|
+
(buttonClick)="applyColor(color, true, $event)"></ate-button>
|
|
224
|
+
}
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<div class="dropdown-row controls">
|
|
229
|
+
<div class="hex-input-wrapper">
|
|
230
|
+
<span class="hex-hash">#</span>
|
|
231
|
+
<input
|
|
232
|
+
#hexInput
|
|
233
|
+
type="text"
|
|
234
|
+
class="hex-input"
|
|
235
|
+
[value]="hexValue()"
|
|
236
|
+
[attr.aria-label]="t().customColor"
|
|
237
|
+
(input)="onHexInput($event)"
|
|
238
|
+
(change)="onHexChange($event)"
|
|
239
|
+
(keydown.enter)="onApply($event)"
|
|
240
|
+
(focus)="onFocus()"
|
|
241
|
+
(blur)="onBlur()"
|
|
242
|
+
maxlength="6"
|
|
243
|
+
placeholder="000000" />
|
|
244
|
+
</div>
|
|
245
|
+
|
|
246
|
+
<div class="native-trigger-wrapper">
|
|
247
|
+
<ate-button
|
|
248
|
+
class="btn-native-picker-trigger"
|
|
249
|
+
icon="colorize"
|
|
250
|
+
[title]="t().customColor"
|
|
251
|
+
[backgroundColor]="currentColor()"
|
|
252
|
+
(buttonClick)="triggerNativePicker($event)"></ate-button>
|
|
253
|
+
<input
|
|
254
|
+
#colorInput
|
|
255
|
+
type="color"
|
|
256
|
+
class="hidden-native-input"
|
|
257
|
+
[value]="currentColor()"
|
|
258
|
+
[attr.aria-label]="t().customColor"
|
|
259
|
+
(input)="onNativeInput($event)"
|
|
260
|
+
(change)="onNativeChange($event)"
|
|
261
|
+
(focus)="onFocus()"
|
|
262
|
+
(blur)="onBlur()" />
|
|
263
|
+
</div>
|
|
264
|
+
|
|
265
|
+
<ate-button
|
|
266
|
+
icon="check"
|
|
267
|
+
[title]="common().apply"
|
|
268
|
+
color="var(--ate-primary)"
|
|
269
|
+
(buttonClick)="onApply($event)"></ate-button>
|
|
270
|
+
|
|
271
|
+
<ate-separator />
|
|
272
|
+
|
|
273
|
+
<ate-button
|
|
274
|
+
icon="format_color_reset"
|
|
275
|
+
[title]="t().clear"
|
|
276
|
+
variant="danger"
|
|
277
|
+
(buttonClick)="onClearColor($event)"></ate-button>
|
|
278
|
+
</div>
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
`, isInline: true, styles: [".color-picker-container{display:flex;flex-direction:column;gap:8px}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}:host ::ng-deep .color-swatch-btn .ate-button{width:100%;aspect-ratio:1;height:auto;border-radius:4px;border:1px solid rgba(0,0,0,.1);padding:0}:host ::ng-deep .color-swatch-btn .ate-button.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}:host ::ng-deep .btn-native-picker-trigger .ate-button{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: AteButtonComponent, selector: "ate-button", inputs: ["icon", "title", "active", "disabled", "color", "backgroundColor", "variant", "size", "iconSize"], outputs: ["buttonClick"] }, { kind: "component", type: AteSeparatorComponent, selector: "ate-separator" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
282
|
+
}
|
|
283
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteColorBubbleMenuComponent, decorators: [{
|
|
284
|
+
type: Component,
|
|
285
|
+
args: [{ selector: "ate-color-bubble-menu", standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [CommonModule, FormsModule, AteButtonComponent, AteSeparatorComponent], template: `
|
|
286
|
+
<div
|
|
287
|
+
#menuRef
|
|
288
|
+
class="bubble-menu color-bubble-menu"
|
|
289
|
+
(mousedown)="onMouseDown($event)"
|
|
290
|
+
(click)="$event.stopPropagation()"
|
|
291
|
+
(keydown)="$event.stopPropagation()"
|
|
292
|
+
(keydown.escape)="onApply($event)"
|
|
293
|
+
tabindex="-1"
|
|
294
|
+
role="dialog">
|
|
295
|
+
<div class="color-picker-container">
|
|
296
|
+
<div class="dropdown-row presets">
|
|
297
|
+
<div class="color-grid">
|
|
298
|
+
@for (color of presets; track color) {
|
|
299
|
+
<ate-button
|
|
300
|
+
class="color-swatch-btn"
|
|
301
|
+
size="small"
|
|
302
|
+
[title]="color"
|
|
303
|
+
[active]="isColorActive(color)"
|
|
304
|
+
[backgroundColor]="color"
|
|
305
|
+
(buttonClick)="applyColor(color, true, $event)"></ate-button>
|
|
306
|
+
}
|
|
307
|
+
</div>
|
|
308
|
+
</div>
|
|
309
|
+
|
|
310
|
+
<div class="dropdown-row controls">
|
|
311
|
+
<div class="hex-input-wrapper">
|
|
312
|
+
<span class="hex-hash">#</span>
|
|
313
|
+
<input
|
|
314
|
+
#hexInput
|
|
315
|
+
type="text"
|
|
316
|
+
class="hex-input"
|
|
317
|
+
[value]="hexValue()"
|
|
318
|
+
[attr.aria-label]="t().customColor"
|
|
319
|
+
(input)="onHexInput($event)"
|
|
320
|
+
(change)="onHexChange($event)"
|
|
321
|
+
(keydown.enter)="onApply($event)"
|
|
322
|
+
(focus)="onFocus()"
|
|
323
|
+
(blur)="onBlur()"
|
|
324
|
+
maxlength="6"
|
|
325
|
+
placeholder="000000" />
|
|
326
|
+
</div>
|
|
327
|
+
|
|
328
|
+
<div class="native-trigger-wrapper">
|
|
329
|
+
<ate-button
|
|
330
|
+
class="btn-native-picker-trigger"
|
|
331
|
+
icon="colorize"
|
|
332
|
+
[title]="t().customColor"
|
|
333
|
+
[backgroundColor]="currentColor()"
|
|
334
|
+
(buttonClick)="triggerNativePicker($event)"></ate-button>
|
|
335
|
+
<input
|
|
336
|
+
#colorInput
|
|
337
|
+
type="color"
|
|
338
|
+
class="hidden-native-input"
|
|
339
|
+
[value]="currentColor()"
|
|
340
|
+
[attr.aria-label]="t().customColor"
|
|
341
|
+
(input)="onNativeInput($event)"
|
|
342
|
+
(change)="onNativeChange($event)"
|
|
343
|
+
(focus)="onFocus()"
|
|
344
|
+
(blur)="onBlur()" />
|
|
345
|
+
</div>
|
|
346
|
+
|
|
347
|
+
<ate-button
|
|
348
|
+
icon="check"
|
|
349
|
+
[title]="common().apply"
|
|
350
|
+
color="var(--ate-primary)"
|
|
351
|
+
(buttonClick)="onApply($event)"></ate-button>
|
|
352
|
+
|
|
353
|
+
<ate-separator />
|
|
354
|
+
|
|
355
|
+
<ate-button
|
|
356
|
+
icon="format_color_reset"
|
|
357
|
+
[title]="t().clear"
|
|
358
|
+
variant="danger"
|
|
359
|
+
(buttonClick)="onClearColor($event)"></ate-button>
|
|
360
|
+
</div>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
`, styles: [".color-picker-container{display:flex;flex-direction:column;gap:8px}.dropdown-row{display:flex;align-items:center;width:100%}.dropdown-row.presets{justify-content:center}.dropdown-row.controls{gap:8px;justify-content:space-between;padding-top:4px;border-top:1px solid var(--ate-border, #e2e8f0)}.color-grid{display:grid;grid-template-columns:repeat(12,1fr);gap:4px;width:100%}:host ::ng-deep .color-swatch-btn .ate-button{width:100%;aspect-ratio:1;height:auto;border-radius:4px;border:1px solid rgba(0,0,0,.1);padding:0}:host ::ng-deep .color-swatch-btn .ate-button.is-active{border-color:var(--ate-primary, #3b82f6);box-shadow:0 0 0 2px #3b82f64d}:host ::ng-deep .btn-native-picker-trigger .ate-button{color:#fff;text-shadow:0 1px 2px rgba(0,0,0,.2)}.divider-v{width:1px;height:24px;background:var(--ate-border, #e2e8f0)}.hex-input-wrapper{flex:1;display:flex;align-items:center;background:var(--ate-surface-secondary, #f8fafc);border:1px solid var(--ate-border, #e2e8f0);border-radius:8px;padding:0 10px;height:32px;transition:border-color .15s ease}.hex-input-wrapper:focus-within{border-color:var(--ate-primary, #3b82f6);background:var(--ate-menu-bg, #ffffff)}.hex-hash{color:var(--ate-text-muted, #94a3b8);font-family:monospace;font-size:.875rem}.hex-input{background:transparent;border:none;outline:none;color:var(--ate-text, #1e293b);font-family:monospace;font-size:.875rem;width:100%;padding-left:4px}.native-trigger-wrapper{position:relative;width:32px;height:32px}.hidden-native-input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}\n"] }]
|
|
364
|
+
}] });
|
|
365
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWNvbG9yLWJ1YmJsZS1tZW51LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvYnViYmxlLW1lbnVzL2NvbG9yL2F0ZS1jb2xvci1idWJibGUtbWVudS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCx1QkFBdUIsRUFFdkIsTUFBTSxFQUNOLE1BQU0sRUFDTixRQUFRLEVBQ1IsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sNENBQTRDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDbkUsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUFDekUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sa0NBQWtDLENBQUM7O0FBRXhFLE1BQU0sYUFBYSxHQUFHO0lBQ3BCLFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztJQUNULFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztJQUNULFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztJQUNULFNBQVM7SUFDVCxTQUFTO0lBQ1QsU0FBUztDQUNWLENBQUM7QUFrTUYsTUFBTSxPQUFPLDJCQUE0QixTQUFRLG9CQUFvQjtJQWhNckU7O1FBaU1tQixtQkFBYyxHQUFHLE1BQU0sQ0FBQyxxQkFBcUIsQ0FBQyxDQUFDO1FBRXZELE1BQUMsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQztRQUM3QixXQUFNLEdBQUcsSUFB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LE9BQU87UUFDTCxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsTUFBTTtRQUNKLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsY0FBYyxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMxQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDcEIsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ1YsQ0FBQzsrR0FqTlUsMkJBQTJCO21HQUEzQiwyQkFBMkIscU9BM0w1Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEVULDJtREEvRVMsWUFBWSw4QkFBRSxXQUFXLCtCQUFFLGtCQUFrQiw2TEFBRSxxQkFBcUI7OzRGQTRMbkUsMkJBQTJCO2tCQWhNdkMsU0FBUzsrQkFDRSx1QkFBdUIsY0FDckIsSUFBSSxtQkFDQyx1QkFBdUIsQ0FBQyxNQUFNLFdBQ3RDLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsQ0FBQyxZQUNyRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBOEVUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgRWxlbWVudFJlZixcbiAgc2lnbmFsLFxuICBpbmplY3QsXG4gIGNvbXB1dGVkLFxuICB2aWV3Q2hpbGQsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gXCJAYW5ndWxhci9mb3Jtc1wiO1xuaW1wb3J0IHsgSW5zdGFuY2UgYXMgVGlwcHlJbnN0YW5jZSB9IGZyb20gXCJ0aXBweS5qc1wiO1xuaW1wb3J0IHsgQXRlQ29sb3JQaWNrZXJTZXJ2aWNlIH0gZnJvbSBcIi4uLy4uLy4uL3NlcnZpY2VzL2F0ZS1jb2xvci1waWNrZXIuc2VydmljZVwiO1xuaW1wb3J0IHsgQXRlQnV0dG9uQ29tcG9uZW50IH0gZnJvbSBcIi4uLy4uL3VpL2F0ZS1idXR0b24uY29tcG9uZW50XCI7XG5pbXBvcnQgeyBBdGVTZXBhcmF0b3JDb21wb25lbnQgfSBmcm9tIFwiLi4vLi4vdWkvYXRlLXNlcGFyYXRvci5jb21wb25lbnRcIjtcbmltcG9ydCB7IEF0ZUJhc2VTdWJCdWJibGVNZW51IH0gZnJvbSBcIi4uL2Jhc2UvYXRlLWJhc2Utc3ViLWJ1YmJsZS1tZW51XCI7XG5cbmNvbnN0IFBSRVNFVF9DT0xPUlMgPSBbXG4gIFwiIzAwMDAwMFwiLFxuICBcIiM2NjY2NjZcIixcbiAgXCIjQ0NDQ0NDXCIsXG4gIFwiI0ZGRkZGRlwiLFxuICBcIiNGNDQzMzZcIixcbiAgXCIjRkY5ODAwXCIsXG4gIFwiI0ZGRUIzQlwiLFxuICBcIiM0Q0FGNTBcIixcbiAgXCIjMDBCQ0Q0XCIsXG4gIFwiIzIxOTZGM1wiLFxuICBcIiM5QzI3QjBcIixcbiAgXCIjRTkxRTYzXCIsXG5dO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiYXRlLWNvbG9yLWJ1YmJsZS1tZW51XCIsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgQXRlQnV0dG9uQ29tcG9uZW50LCBBdGVTZXBhcmF0b3JDb21wb25lbnRdLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXZcbiAgICAgICNtZW51UmVmXG4gICAgICBjbGFzcz1cImJ1YmJsZS1tZW51IGNvbG9yLWJ1YmJsZS1tZW51XCJcbiAgICAgIChtb3VzZWRvd24pPVwib25Nb3VzZURvd24oJGV2ZW50KVwiXG4gICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgIChrZXlkb3duKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAoa2V5ZG93bi5lc2NhcGUpPVwib25BcHBseSgkZXZlbnQpXCJcbiAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgcm9sZT1cImRpYWxvZ1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLXBpY2tlci1jb250YWluZXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImRyb3Bkb3duLXJvdyBwcmVzZXRzXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNvbG9yLWdyaWRcIj5cbiAgICAgICAgICAgIEBmb3IgKGNvbG9yIG9mIHByZXNldHM7IHRyYWNrIGNvbG9yKSB7XG4gICAgICAgICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjb2xvci1zd2F0Y2gtYnRuXCJcbiAgICAgICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgICAgIFt0aXRsZV09XCJjb2xvclwiXG4gICAgICAgICAgICAgICAgW2FjdGl2ZV09XCJpc0NvbG9yQWN0aXZlKGNvbG9yKVwiXG4gICAgICAgICAgICAgICAgW2JhY2tncm91bmRDb2xvcl09XCJjb2xvclwiXG4gICAgICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cImFwcGx5Q29sb3IoY29sb3IsIHRydWUsICRldmVudClcIj48L2F0ZS1idXR0b24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkcm9wZG93bi1yb3cgY29udHJvbHNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiaGV4LWlucHV0LXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaGV4LWhhc2hcIj4jPC9zcGFuPlxuICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICNoZXhJbnB1dFxuICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiaGV4LWlucHV0XCJcbiAgICAgICAgICAgICAgW3ZhbHVlXT1cImhleFZhbHVlKClcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInQoKS5jdXN0b21Db2xvclwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJvbkhleElucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uSGV4Q2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkFwcGx5KCRldmVudClcIlxuICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIlxuICAgICAgICAgICAgICBtYXhsZW5ndGg9XCI2XCJcbiAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCIwMDAwMDBcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm5hdGl2ZS10cmlnZ2VyLXdyYXBwZXJcIj5cbiAgICAgICAgICAgIDxhdGUtYnV0dG9uXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuLW5hdGl2ZS1waWNrZXItdHJpZ2dlclwiXG4gICAgICAgICAgICAgIGljb249XCJjb2xvcml6ZVwiXG4gICAgICAgICAgICAgIFt0aXRsZV09XCJ0KCkuY3VzdG9tQ29sb3JcIlxuICAgICAgICAgICAgICBbYmFja2dyb3VuZENvbG9yXT1cImN1cnJlbnRDb2xvcigpXCJcbiAgICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cInRyaWdnZXJOYXRpdmVQaWNrZXIoJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cbiAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAjY29sb3JJbnB1dFxuICAgICAgICAgICAgICB0eXBlPVwiY29sb3JcIlxuICAgICAgICAgICAgICBjbGFzcz1cImhpZGRlbi1uYXRpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICBbdmFsdWVdPVwiY3VycmVudENvbG9yKClcIlxuICAgICAgICAgICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cInQoKS5jdXN0b21Db2xvclwiXG4gICAgICAgICAgICAgIChpbnB1dCk9XCJvbk5hdGl2ZUlucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAoY2hhbmdlKT1cIm9uTmF0aXZlQ2hhbmdlKCRldmVudClcIlxuICAgICAgICAgICAgICAoZm9jdXMpPVwib25Gb2N1cygpXCJcbiAgICAgICAgICAgICAgKGJsdXIpPVwib25CbHVyKClcIiAvPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPGF0ZS1idXR0b25cbiAgICAgICAgICAgIGljb249XCJjaGVja1wiXG4gICAgICAgICAgICBbdGl0bGVdPVwiY29tbW9uKCkuYXBwbHlcIlxuICAgICAgICAgICAgY29sb3I9XCJ2YXIoLS1hdGUtcHJpbWFyeSlcIlxuICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQXBwbHkoJGV2ZW50KVwiPjwvYXRlLWJ1dHRvbj5cblxuICAgICAgICAgIDxhdGUtc2VwYXJhdG9yIC8+XG5cbiAgICAgICAgICA8YXRlLWJ1dHRvblxuICAgICAgICAgICAgaWNvbj1cImZvcm1hdF9jb2xvcl9yZXNldFwiXG4gICAgICAgICAgICBbdGl0bGVdPVwidCgpLmNsZWFyXCJcbiAgICAgICAgICAgIHZhcmlhbnQ9XCJkYW5nZXJcIlxuICAgICAgICAgICAgKGJ1dHRvbkNsaWNrKT1cIm9uQ2xlYXJDb2xvcigkZXZlbnQpXCI+PC9hdGUtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICBgLFxuICBzdHlsZXM6IFtcbiAgICBgXG4gICAgICAuY29sb3ItcGlja2VyLWNvbnRhaW5lciB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGdhcDogOHB4O1xuICAgICAgfVxuXG4gICAgICAuZHJvcGRvd24tcm93IHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICB9XG5cbiAgICAgIC5kcm9wZG93bi1yb3cucHJlc2V0cyB7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgfVxuXG4gICAgICAuZHJvcGRvd24tcm93LmNvbnRyb2xzIHtcbiAgICAgICAgZ2FwOiA4cHg7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICAgICAgcGFkZGluZy10b3A6IDRweDtcbiAgICAgICAgYm9yZGVyLXRvcDogMXB4IHNvbGlkIHZhcigtLWF0ZS1ib3JkZXIsICNlMmU4ZjApO1xuICAgICAgfVxuXG4gICAgICAuY29sb3ItZ3JpZCB7XG4gICAgICAgIGRpc3BsYXk6IGdyaWQ7XG4gICAgICAgIGdyaWQtdGVtcGxhdGUtY29sdW1uczogcmVwZWF0KDEyLCAxZnIpO1xuICAgICAgICBnYXA6IDRweDtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICB9XG5cbiAgICAgIDpob3N0IDo6bmctZGVlcCAuY29sb3Itc3dhdGNoLWJ0biAuYXRlLWJ1dHRvbiB7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICBhc3BlY3QtcmF0aW86IDE7XG4gICAgICAgIGhlaWdodDogYXV0bztcbiAgICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCByZ2JhKDAsIDAsIDAsIDAuMSk7XG4gICAgICAgIHBhZGRpbmc6IDA7XG4gICAgICB9XG5cbiAgICAgIDpob3N0IDo6bmctZGVlcCAuY29sb3Itc3dhdGNoLWJ0biAuYXRlLWJ1dHRvbi5pcy1hY3RpdmUge1xuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLWF0ZS1wcmltYXJ5LCAjM2I4MmY2KTtcbiAgICAgICAgYm94LXNoYWRvdzogMCAwIDAgMnB4IHJnYmEoNTksIDEzMCwgMjQ2LCAwLjMpO1xuICAgICAgfVxuXG4gICAgICA6aG9zdCA6Om5nLWRlZXAgLmJ0bi1uYXRpdmUtcGlja2VyLXRyaWdnZXIgLmF0ZS1idXR0b24ge1xuICAgICAgICBjb2xvcjogI2ZmZmZmZjtcbiAgICAgICAgdGV4dC1zaGFkb3c6IDAgMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMik7XG4gICAgICB9XG5cbiAgICAgIC5kaXZpZGVyLXYge1xuICAgICAgICB3aWR0aDogMXB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWF0ZS1ib3JkZXIsICNlMmU4ZjApO1xuICAgICAgfVxuXG4gICAgICAuaGV4LWlucHV0LXdyYXBwZXIge1xuICAgICAgICBmbGV4OiAxO1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1hdGUtc3VyZmFjZS1zZWNvbmRhcnksICNmOGZhZmMpO1xuICAgICAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1hdGUtYm9yZGVyLCAjZTJlOGYwKTtcbiAgICAgICAgYm9yZGVyLXJhZGl1czogOHB4O1xuICAgICAgICBwYWRkaW5nOiAwIDEwcHg7XG4gICAgICAgIGhlaWdodDogMzJweDtcbiAgICAgICAgdHJhbnNpdGlvbjogYm9yZGVyLWNvbG9yIDE1MG1zIGVhc2U7XG4gICAgICB9XG5cbiAgICAgIC5oZXgtaW5wdXQtd3JhcHBlcjpmb2N1cy13aXRoaW4ge1xuICAgICAgICBib3JkZXItY29sb3I6IHZhcigtLWF0ZS1wcmltYXJ5LCAjM2I4MmY2KTtcbiAgICAgICAgYmFja2dyb3VuZDogdmFyKC0tYXRlLW1lbnUtYmcsICNmZmZmZmYpO1xuICAgICAgfVxuXG4gICAgICAuaGV4LWhhc2gge1xuICAgICAgICBjb2xvcjogdmFyKC0tYXRlLXRleHQtbXV0ZWQsICM5NGEzYjgpO1xuICAgICAgICBmb250LWZhbWlseTogbW9ub3NwYWNlO1xuICAgICAgICBmb250LXNpemU6IDAuODc1cmVtO1xuICAgICAgfVxuXG4gICAgICAuaGV4LWlucHV0IHtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgb3V0bGluZTogbm9uZTtcbiAgICAgICAgY29sb3I6IHZhcigtLWF0ZS10ZXh0LCAjMWUyOTNiKTtcbiAgICAgICAgZm9udC1mYW1pbHk6IG1vbm9zcGFjZTtcbiAgICAgICAgZm9udC1zaXplOiAwLjg3NXJlbTtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG4gICAgICAgIHBhZGRpbmctbGVmdDogNHB4O1xuICAgICAgfVxuXG4gICAgICAubmF0aXZlLXRyaWdnZXItd3JhcHBlciB7XG4gICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgd2lkdGg6IDMycHg7XG4gICAgICAgIGhlaWdodDogMzJweDtcbiAgICAgIH1cblxuICAgICAgLmhpZGRlbi1uYXRpdmUtaW5wdXQge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgIGluc2V0OiAwO1xuICAgICAgICBvcGFjaXR5OiAwO1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB9XG4gICAgYCxcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgQXRlQ29sb3JCdWJibGVNZW51Q29tcG9uZW50IGV4dGVuZHMgQXRlQmFzZVN1YkJ1YmJsZU1lbnUge1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbG9yUGlja2VyU3ZjID0gaW5qZWN0KEF0ZUNvbG9yUGlja2VyU2VydmljZSk7XG5cbiAgcmVhZG9ubHkgdCA9IHRoaXMuaTE4blNlcnZpY2UudG9vbGJhcjtcbiAgcmVhZG9ubHkgY29tbW9uID0gdGhpcy5pMThuU2VydmljZS5jb21tb247XG4gIHJlYWRvbmx5IHByZXNldHMgPSBQUkVTRVRfQ09MT1JTO1xuXG4gIHByaXZhdGUgY29sb3JJbnB1dFJlZiA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+PihcImNvbG9ySW5wdXRcIik7XG5cbiAgLyoqXG4gICAqIExPQ0FMIE1PREU6IFdlIGxvY2sgdGhlIG1vZGUgd2hlbiB0aGUgbWVudSBpcyBzaG93biB0byBhdm9pZCByYWNlIGNvbmRpdGlvbnNcbiAgICogd2hlcmUgdGhlIHBhcmVudCAoYnViYmxlIG1lbnUpIGNsZWFycyB0aGUgZ2xvYmFsIHNpZ25hbCBiZWZvcmUgd2UgYXBwbHkgdGhlIGNvbG9yLlxuICAgKi9cbiAgYWN0aXZlTW9kZSA9IHNpZ25hbDxcInRleHRcIiB8IFwiaGlnaGxpZ2h0XCI+KFwidGV4dFwiKTtcblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25TdGF0ZUNoYW5nZSgpIHtcbiAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmVkaXRNb2RlKCk7XG4gICAgdGhpcy5jb2xvclBpY2tlclN2Yy5tZW51VHJpZ2dlcigpO1xuICAgIHRoaXMuY29sb3JQaWNrZXJTdmMuaXNJbnRlcmFjdGluZygpO1xuICB9XG5cbiAgb3ZlcnJpZGUgc2hvdWxkU2hvdygpOiBib29sZWFuIHtcbiAgICBjb25zdCB7IGlzRWRpdGFibGUgfSA9IHRoaXMuc3RhdGUoKTtcbiAgICBpZiAoIWlzRWRpdGFibGUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb2xvclBpY2tlclN2Yy5lZGl0TW9kZSgpICE9PSBudWxsIHx8IHRoaXMuY29sb3JQaWNrZXJTdmMuaXNJbnRlcmFjdGluZygpKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBvdmVycmlkZSBnZXRTZWxlY3Rpb25SZWN0KCk6IERPTVJlY3Qge1xuICAgIGNvbnN0IHRyaWdnZXIgPSB0aGlzLmNvbG9yUGlja2VyU3ZjLm1lbnVUcmlnZ2VyKCk7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGlmICghZWQpIHtcbiAgICAgIHJldHVybiBuZXcgRE9NUmVjdCgwLCAwLCAwLCAwKTtcbiAgICB9XG5cbiAgICAvLyAxLiBJZiB3ZSBoYXZlIGEgc3RhYmxlIHRyaWdnZXIgZnJvbSBzZXJ2aWNlICh0b29sYmFyIG9yIHBhcmVudCBtZW51KSwgYW5jaG9yIHRvIGl0XG4gICAgaWYgKHRyaWdnZXIpIHtcbiAgICAgIGNvbnN0IHJlY3QgPSB0cmlnZ2VyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgLy8gT25seSB1c2UgaWYgaXQncyBzdGlsbCB2aXNpYmxlL2luIERPTSAod2lkdGggPiAwKVxuICAgICAgaWYgKHJlY3Qud2lkdGggPiAwKSB7XG4gICAgICAgIHJldHVybiByZWN0O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIDIuIE90aGVyd2lzZSAoYnViYmxlIG1lbnUgLyByZWxheSksIGFuY2hvciB0byB0ZXh0IHNlbGVjdGlvblxuICAgIGNvbnN0IHsgZnJvbSB9ID0gZWQuc3RhdGUuc2VsZWN0aW9uO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHsgbm9kZSB9ID0gZWQudmlldy5kb21BdFBvcyhmcm9tKTtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSBub2RlIGluc3RhbmNlb2YgRWxlbWVudCA/IG5vZGUgOiBub2RlLnBhcmVudEVsZW1lbnQ7XG4gICAgICBjb25zdCBjb2xvckVsZW1lbnQgPSAoZWxlbWVudCBhcyBFbGVtZW50KT8uY2xvc2VzdChcbiAgICAgICAgJ1tzdHlsZSo9XCJjb2xvclwiXSwgW3N0eWxlKj1cImJhY2tncm91bmRcIl0sIG1hcmsnXG4gICAgICApO1xuICAgICAgaWYgKGNvbG9yRWxlbWVudCkge1xuICAgICAgICByZXR1cm4gY29sb3JFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKF9lKSB7XG4gICAgICAvKiBpZ25vcmUgKi9cbiAgICB9XG5cbiAgICAvLyBVc2UgbmF0aXZlIHNlbGVjdGlvbiBmb3IgbXVsdGktbGluZSBhY2N1cmFjeVxuICAgIGNvbnN0IHNlbGVjdGlvbiA9IHdpbmRvdy5nZXRTZWxlY3Rpb24oKTtcbiAgICBpZiAoc2VsZWN0aW9uICYmIHNlbGVjdGlvbi5yYW5nZUNvdW50ID4gMCkge1xuICAgICAgY29uc3QgcmFuZ2UgPSBzZWxlY3Rpb24uZ2V0UmFuZ2VBdCgwKTtcbiAgICAgIGNvbnN0IHJlY3QgPSByYW5nZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmIChyZWN0LndpZHRoID4gMCAmJiByZWN0LmhlaWdodCA+IDApIHtcbiAgICAgICAgcmV0dXJuIHJlY3Q7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmluYWwgZmFsbGJhY2sgdG8gY29vcmRpbmF0ZXMgYXQgY3Vyc29yXG4gICAgY29uc3QgeyB0b3AsIGJvdHRvbSwgbGVmdCwgcmlnaHQgfSA9IGVkLnZpZXcuY29vcmRzQXRQb3MoZnJvbSk7XG4gICAgcmV0dXJuIG5ldyBET01SZWN0KGxlZnQsIHRvcCwgcmlnaHQgLSBsZWZ0LCBib3R0b20gLSB0b3ApO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIG9uVGlwcHlTaG93KF9pbnN0YW5jZTogVGlwcHlJbnN0YW5jZSkge1xuICAgIC8vIDEuIExvY2sgdGhlIG1vZGUgaW1tZWRpYXRlbHkgdG8gYmUgaW1tdW5lIHRvIGV4dGVybmFsIHNpZ25hbCBjaGFuZ2VzXG4gICAgY29uc3QgY3VycmVudE1vZGUgPSB0aGlzLmNvbG9yUGlja2VyU3ZjLmVkaXRNb2RlKCkgfHwgXCJ0ZXh0XCI7XG4gICAgdGhpcy5hY3RpdmVNb2RlLnNldChjdXJyZW50TW9kZSk7XG5cbiAgICAvLyAyLiBDYXB0dXJlIHNlbGVjdGlvbiBmb3IgdGhlIGNvbW1hbmQgZmFsbGJhY2tcbiAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmNhcHR1cmVTZWxlY3Rpb24odGhpcy5lZGl0b3IoKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgb25UaXBweUhpZGUoX2luc3RhbmNlOiBUaXBweUluc3RhbmNlKSB7XG4gICAgLy8gQ2xlYXIgdHJpZ2dlciBvbmx5IEFGVEVSIHRoZSBtZW51IGlzIGhpZGRlbiB0byBtYWludGFpbiBhbmNob3Igc3RhYmlsaXR5IGR1cmluZyBhbmltYXRpb25cbiAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmRvbmUoKTtcbiAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmNsb3NlKCk7XG4gIH1cblxuICByZWFkb25seSBjdXJyZW50Q29sb3IgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgbWFya3MgPSB0aGlzLnN0YXRlKCkubWFya3M7XG4gICAgY29uc3QgY29sb3IgPSB0aGlzLmFjdGl2ZU1vZGUoKSA9PT0gXCJ0ZXh0XCIgPyBtYXJrcy5jb21wdXRlZENvbG9yIDogbWFya3MuY29tcHV0ZWRCYWNrZ3JvdW5kO1xuICAgIHJldHVybiBjb2xvciB8fCAodGhpcy5hY3RpdmVNb2RlKCkgPT09IFwidGV4dFwiID8gXCIjMDAwMDAwXCIgOiBcIiNmZmZmMDBcIik7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGhleFZhbHVlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGNvbG9yID0gdGhpcy5jdXJyZW50Q29sb3IoKTtcbiAgICByZXR1cm4gY29sb3IucmVwbGFjZShcIiNcIiwgXCJcIikudG9VcHBlckNhc2UoKTtcbiAgfSk7XG5cbiAgaXNDb2xvckFjdGl2ZShjb2xvcjogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY29sb3JQaWNrZXJTdmMubm9ybWFsaXplQ29sb3IodGhpcy5jdXJyZW50Q29sb3IoKSkgPT09XG4gICAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLm5vcm1hbGl6ZUNvbG9yKGNvbG9yKVxuICAgICk7XG4gIH1cblxuICBhcHBseUNvbG9yKGNvbG9yOiBzdHJpbmcsIGFkZFRvSGlzdG9yeSA9IHRydWUsIGV2ZW50PzogRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG5cbiAgICBjb25zdCBlZGl0b3IgPSB0aGlzLmVkaXRvcigpO1xuICAgIC8vIFVzZSBvdXIgTE9DS0VEIG1vZGUgaW5zdGVhZCBvZiB0aGUgZ2xvYmFsIHNpZ25hbFxuICAgIC8vIERldGVybWluZSBpZiB3ZSBzaG91bGQgZm9jdXMgYmFjayB0byB0aGUgZWRpdG9yLlxuICAgIGNvbnN0IHNob3VsZEZvY3VzID0gIXRoaXMuY29sb3JQaWNrZXJTdmMuaXNJbnRlcmFjdGluZygpO1xuXG4gICAgaWYgKHRoaXMuYWN0aXZlTW9kZSgpID09PSBcInRleHRcIikge1xuICAgICAgdGhpcy5jb2xvclBpY2tlclN2Yy5hcHBseUNvbG9yKGVkaXRvciwgY29sb3IsIGFkZFRvSGlzdG9yeSwgc2hvdWxkRm9jdXMpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmFwcGx5SGlnaGxpZ2h0KGVkaXRvciwgY29sb3IsIGFkZFRvSGlzdG9yeSwgc2hvdWxkRm9jdXMpO1xuICAgIH1cbiAgfVxuXG4gIG9uQXBwbHkoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLmNsb3NlKCk7XG4gIH1cblxuICBvbkhleElucHV0KGV2ZW50OiBFdmVudCkge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgbGV0IHZhbHVlID0gaW5wdXQudmFsdWUudHJpbSgpO1xuICAgIGlmICghdmFsdWUuc3RhcnRzV2l0aChcIiNcIikpIHtcbiAgICAgIHZhbHVlID0gXCIjXCIgKyB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKC9eIz9bMC05QS1GYS1mXXszLDZ9JC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHRoaXMuYXBwbHlDb2xvcih2YWx1ZSwgZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIG9uSGV4Q2hhbmdlKGV2ZW50OiBFdmVudCkge1xuICAgIGNvbnN0IGlucHV0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxJbnB1dEVsZW1lbnQ7XG4gICAgbGV0IHZhbHVlID0gaW5wdXQudmFsdWUudHJpbSgpO1xuICAgIGlmICghdmFsdWUuc3RhcnRzV2l0aChcIiNcIikpIHtcbiAgICAgIHZhbHVlID0gXCIjXCIgKyB2YWx1ZTtcbiAgICB9XG4gICAgaWYgKC9eIz9bMC05QS1GYS1mXXszLDZ9JC8udGVzdCh2YWx1ZSkpIHtcbiAgICAgIHRoaXMuYXBwbHlDb2xvcih2YWx1ZSwgdHJ1ZSwgZXZlbnQpO1xuICAgIH1cbiAgfVxuXG4gIHRyaWdnZXJOYXRpdmVQaWNrZXIoZXZlbnQ/OiBFdmVudCkge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICB0aGlzLmNvbG9ySW5wdXRSZWYoKT8ubmF0aXZlRWxlbWVudC5jbGljaygpO1xuICB9XG5cbiAgb25OYXRpdmVJbnB1dChldmVudDogRXZlbnQpIHtcbiAgICB0aGlzLmFwcGx5Q29sb3IoKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZSwgZmFsc2UpO1xuICB9XG5cbiAgb25OYXRpdmVDaGFuZ2UoZXZlbnQ6IEV2ZW50KSB7XG4gICAgdGhpcy5hcHBseUNvbG9yKChldmVudC50YXJnZXQgYXMgSFRNTElucHV0RWxlbWVudCkudmFsdWUsIHRydWUsIGV2ZW50KTtcbiAgfVxuXG4gIG9uQ2xlYXJDb2xvcihldmVudD86IEV2ZW50KSB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3IoKTtcbiAgICBpZiAodGhpcy5hY3RpdmVNb2RlKCkgPT09IFwidGV4dFwiKSB7XG4gICAgICB0aGlzLmNvbG9yUGlja2VyU3ZjLnVuc2V0Q29sb3IoZWRpdG9yKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5jb2xvclBpY2tlclN2Yy51bnNldEhpZ2hsaWdodChlZGl0b3IpO1xuICAgIH1cbiAgfVxuXG4gIG9uTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgdGFyZ2V0ID0gZXZlbnQudGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICh0YXJnZXQudGFnTmFtZSAhPT0gXCJJTlBVVFwiKSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIG9uRm9jdXMoKSB7XG4gICAgdGhpcy5jb2xvclBpY2tlclN2Yy5zZXRJbnRlcmFjdGluZyh0cnVlKTtcbiAgfVxuXG4gIG9uQmx1cigpIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuY29sb3JQaWNrZXJTdmMuc2V0SW50ZXJhY3RpbmcoZmFsc2UpO1xuICAgICAgdGhpcy51cGRhdGVNZW51KCk7XG4gICAgfSwgMTUwKTtcbiAgfVxufVxuIl19
|