@flogeez/angular-tiptap-editor 3.8.1 → 3.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,23 @@ All notable changes to `@flogeez/angular-tiptap-editor` will be documented in th
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html), with the exception that the major version is specifically aligned with the major version of [Tiptap](https://tiptap.dev).
7
7
 
8
+ ## [3.9.0] - 2026-10-27
9
+
10
+ ### Added
11
+
12
+ - **Multi-Block Drag**: When the selection spans several blocks and the handle of one of them is dragged, all the selected blocks now move together and keep their order (previously only the grabbed block moved and the selection collapsed to it). (#84)
13
+ - **Block Drop Indicator**: Dragging a block shows a line (`.ate-block-drop-before` / `.ate-block-drop-after`) at the top-level block boundary where it will land, and the native drop cursor is hidden during the drag. (#84)
14
+
15
+ ### Changed
16
+
17
+ - **Smoother Block Controls**: The drag handle and plus button glide from block to block in 200 ms with a strong ease-out, so they keep up with the pointer. They now appear in place next to the hovered block instead of gliding in from wherever they were last shown (Tippy only skipped the glide on the very first show), and they stay on their block while scrolling instead of trailing behind it. The glide is skipped when the system asks for reduced motion. Their hover feedback is a 120 ms background and color change, only on devices with a fine pointer. (#84)
18
+
19
+ ### Fixed
20
+
21
+ - **Block Dropped Inside Another Block**: The drag handle used to drop a block wherever the pointer was, so it could end up inside a list item, blockquote or table cell. Drops now always resolve to the nearest top-level boundary, chosen by the upper or lower half of the hovered top-level block. (#84)
22
+ - **Leftover Drag State**: A drag started from the handle that ended without a drop on the editor (Escape, drop outside the editor) left the editor in a "dragging" state, so the next external drop (text from another window, for example) was handled as a move of the stale block instead of inserting the dropped content. The state is now cleared on `dragend`, drop and when a foreign drag enters the editor. (#84)
23
+ - **Block Controls After an Edit**: When an edit removed or moved the hovered block while the pointer stayed still (e.g. deleting a paragraph above it), the controls measured the detached element and jumped to the editor's top-left corner, and kept the block's old position for the plus button and the drag. They now follow the block under the pointer after every document change. (#84)
24
+
8
25
  ## [3.8.1] - 2026-10-27
9
26
 
10
27
  ### Fixed
@@ -3,7 +3,13 @@ import tippy, { sticky } from "tippy.js";
3
3
  import { AteEditorI18n } from "../../services/ate-editor-i18n.service";
4
4
  import { AteTooltipDirective } from "../../directives/ate-tooltip.directive";
5
5
  import { AteIconComponent } from "../ui/ate-icon.component";
6
+ import { ATE_BLOCK_DRAG_MIME, ateMultiBlockSelection, endAteBlockDrag, } from "../../extensions/ate-block-controls.extension";
6
7
  import * as i0 from "@angular/core";
8
+ // Glides from block to block; the strong ease-out covers most of the way at once, so it never trails the pointer
9
+ const BLOCK_CONTROLS_MOVE_TRANSITION = "transform 200ms cubic-bezier(0.23, 1, 0.32, 1)";
10
+ function prefersReducedMotion() {
11
+ return typeof matchMedia === "function" && matchMedia("(prefers-reduced-motion: reduce)").matches;
12
+ }
7
13
  /**
8
14
  * Component providing Notion-like block controls (Plus button and Drag Handle).
9
15
  */
@@ -18,23 +24,37 @@ export class AteBlockControlsComponent {
18
24
  this.lastValidRect = null;
19
25
  this.tippyInstance = null;
20
26
  this.updateTimeout = null;
27
+ this.glideFrame = null;
28
+ /** While scrolling, the controls follow their block every frame: a glide would make them trail behind it */
29
+ this.onScroll = () => {
30
+ if (this.tippyInstance?.state.isVisible) {
31
+ this.withoutGlide();
32
+ }
33
+ };
21
34
  effect(() => {
22
35
  const data = this.hoveredData();
23
36
  const interacting = this.isInteracting();
24
37
  if (data) {
25
38
  this.lastValidData = data;
26
- this.lastValidRect = data.element.getBoundingClientRect();
39
+ if (data.element.isConnected) {
40
+ this.lastValidRect = data.element.getBoundingClientRect();
41
+ }
27
42
  }
28
43
  this.updateMenu(!!data || interacting);
29
44
  });
30
45
  }
31
46
  ngAfterViewInit() {
32
47
  this.initTippy();
48
+ window.addEventListener("scroll", this.onScroll, { capture: true, passive: true });
33
49
  }
34
50
  ngOnDestroy() {
51
+ window.removeEventListener("scroll", this.onScroll, { capture: true });
35
52
  if (this.updateTimeout) {
36
53
  clearTimeout(this.updateTimeout);
37
54
  }
55
+ if (this.glideFrame !== null) {
56
+ cancelAnimationFrame(this.glideFrame);
57
+ }
38
58
  if (this.tippyInstance) {
39
59
  this.tippyInstance.destroy();
40
60
  this.tippyInstance = null;
@@ -58,7 +78,8 @@ export class AteBlockControlsComponent {
58
78
  zIndex: 99,
59
79
  plugins: [sticky],
60
80
  sticky: "reference",
61
- moveTransition: "transform 0.2s ease-out",
81
+ // The glide keeps the handle visibly the same one moving with the pointer (see withoutGlide for when it is skipped)
82
+ moveTransition: prefersReducedMotion() ? "" : BLOCK_CONTROLS_MOVE_TRANSITION,
62
83
  getReferenceClientRect: () => this.getSelectionRect(),
63
84
  popperOptions: {
64
85
  modifiers: [
@@ -87,8 +108,33 @@ export class AteBlockControlsComponent {
87
108
  }
88
109
  }, delay);
89
110
  }
111
+ /**
112
+ * Moves the controls without gliding until the position settles (two frames after the last call).
113
+ * Tippy only skips the move transition on its very first show: the controls are never unmounted
114
+ * afterwards, so they would otherwise glide in from wherever they were last shown.
115
+ */
116
+ withoutGlide() {
117
+ const popper = this.tippyInstance?.popper;
118
+ if (!popper) {
119
+ return;
120
+ }
121
+ popper.style.transition = "none";
122
+ if (this.glideFrame !== null) {
123
+ cancelAnimationFrame(this.glideFrame);
124
+ }
125
+ this.glideFrame = requestAnimationFrame(() => {
126
+ this.glideFrame = requestAnimationFrame(() => {
127
+ this.glideFrame = null;
128
+ popper.style.transition = this.tippyInstance?.props.moveTransition ?? "";
129
+ });
130
+ });
131
+ }
90
132
  showTippy() {
91
133
  if (this.tippyInstance) {
134
+ // Appearing: show the controls in place, the glide is only for moving between blocks
135
+ if (!this.tippyInstance.state.isVisible) {
136
+ this.withoutGlide();
137
+ }
92
138
  this.tippyInstance.setProps({
93
139
  getReferenceClientRect: () => this.getSelectionRect(),
94
140
  });
@@ -102,8 +148,10 @@ export class AteBlockControlsComponent {
102
148
  }
103
149
  getSelectionRect() {
104
150
  const data = this.hoveredData();
105
- if (data && data.element) {
106
- return data.element.getBoundingClientRect();
151
+ // A block removed by an edit is detached: its rect is (0, 0), which would send the controls to the editor's corner
152
+ if (data?.element?.isConnected) {
153
+ this.lastValidRect = data.element.getBoundingClientRect();
154
+ return this.lastValidRect;
107
155
  }
108
156
  return this.lastValidRect || new DOMRect(-9999, -9999, 0, 0);
109
157
  }
@@ -128,7 +176,7 @@ export class AteBlockControlsComponent {
128
176
  event.stopPropagation();
129
177
  const ed = this.editor();
130
178
  const data = this.hoveredData() || this.lastValidData;
131
- if (ed && data) {
179
+ if (ed && data && !ateMultiBlockSelection(ed.state, data.pos)) {
132
180
  // Force whole-node selection. This is crucial for atomic nodes like tables and images.
133
181
  ed.commands.setNodeSelection(data.pos);
134
182
  }
@@ -167,32 +215,33 @@ export class AteBlockControlsComponent {
167
215
  }
168
216
  const { element, pos } = data;
169
217
  const view = ed.view;
170
- // 1. Force the editor to focus and select the ENTIRE node
218
+ // 1. Select the grabbed block, unless it belongs to a multi-block selection that is dragged as a whole
171
219
  view.focus();
172
- ed.commands.setNodeSelection(pos);
220
+ if (!ateMultiBlockSelection(ed.state, pos)) {
221
+ ed.commands.setNodeSelection(pos);
222
+ }
173
223
  // 2. Browser Drag Image & metadata
174
224
  event.dataTransfer.setDragImage(element, 0, 10);
175
225
  event.dataTransfer.effectAllowed = "move";
176
- event.dataTransfer.setData("text/plain", "");
177
- // 3. PRO-HACK: Indicate this is a move of the current selection (the whole node)
178
- view.dragging = {
179
- slice: ed.state.selection.content(),
180
- move: true,
181
- };
182
- // 4. Dispatch virtual dragstart
226
+ event.dataTransfer.setData(ATE_BLOCK_DRAG_MIME, "1");
227
+ // 3. Dispatch virtual dragstart, handled by the block drag plugin of AteBlockControlsExtension
183
228
  const pmEvent = new DragEvent("dragstart", {
184
229
  dataTransfer: event.dataTransfer,
185
230
  bubbles: true,
186
231
  cancelable: true,
187
232
  });
188
233
  element.dispatchEvent(pmEvent);
189
- // 5. Cleanup UI
234
+ // 4. Cleanup UI
190
235
  setTimeout(() => {
191
236
  this.hideTippy();
192
237
  this.isInteracting.set(false);
193
238
  }, 0);
194
239
  }
195
240
  onDragEnd() {
241
+ const ed = this.editor();
242
+ if (!ed.isDestroyed) {
243
+ endAteBlockDrag(ed.view);
244
+ }
196
245
  this.isInteracting.set(false);
197
246
  }
198
247
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteBlockControlsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
@@ -222,7 +271,7 @@ export class AteBlockControlsComponent {
222
271
  <ate-icon name="blockDrag" />
223
272
  </div>
224
273
  </div>
225
- `, isInline: true, styles: [".ate-block-controls{display:flex;align-items:center;gap:2px;padding:4px;pointer-events:auto;will-change:transform}.ate-control-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;border:none;background:transparent;color:var(--ate-text-secondary);cursor:pointer;transition:all .15s ease}.ate-control-btn:hover{background:var(--ate-surface-tertiary);color:var(--ate-text)}.ate-control-btn .ate-icon{font-size:18px}@media (max-width: 768px){:host{display:none!important}}\n"], dependencies: [{ kind: "directive", type: AteTooltipDirective, selector: "[ateTooltip]", inputs: ["ateTooltip", "ateTooltipPlacement", "ateTooltipDelay", "ateTooltipDisabled"] }, { kind: "component", type: AteIconComponent, selector: "ate-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
274
+ `, isInline: true, styles: [".ate-block-controls{display:flex;align-items:center;gap:2px;padding:4px;pointer-events:auto;will-change:transform}.ate-control-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;border:none;background:transparent;color:var(--ate-text-secondary);cursor:pointer}@media (hover: hover) and (pointer: fine){.ate-control-btn{transition:background-color .12s ease-out,color .12s ease-out}.ate-control-btn:hover{background:var(--ate-surface-tertiary);color:var(--ate-text)}}.ate-control-btn .ate-icon{font-size:18px}@media (max-width: 768px){:host{display:none!important}}\n"], dependencies: [{ kind: "directive", type: AteTooltipDirective, selector: "[ateTooltip]", inputs: ["ateTooltip", "ateTooltipPlacement", "ateTooltipDelay", "ateTooltipDisabled"] }, { kind: "component", type: AteIconComponent, selector: "ate-icon", inputs: ["name"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
226
275
  }
227
276
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteBlockControlsComponent, decorators: [{
228
277
  type: Component,
@@ -252,6 +301,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
252
301
  <ate-icon name="blockDrag" />
253
302
  </div>
254
303
  </div>
255
- `, styles: [".ate-block-controls{display:flex;align-items:center;gap:2px;padding:4px;pointer-events:auto;will-change:transform}.ate-control-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;border:none;background:transparent;color:var(--ate-text-secondary);cursor:pointer;transition:all .15s ease}.ate-control-btn:hover{background:var(--ate-surface-tertiary);color:var(--ate-text)}.ate-control-btn .ate-icon{font-size:18px}@media (max-width: 768px){:host{display:none!important}}\n"] }]
304
+ `, styles: [".ate-block-controls{display:flex;align-items:center;gap:2px;padding:4px;pointer-events:auto;will-change:transform}.ate-control-btn{display:flex;align-items:center;justify-content:center;width:24px;height:24px;border-radius:4px;border:none;background:transparent;color:var(--ate-text-secondary);cursor:pointer}@media (hover: hover) and (pointer: fine){.ate-control-btn{transition:background-color .12s ease-out,color .12s ease-out}.ate-control-btn:hover{background:var(--ate-surface-tertiary);color:var(--ate-text)}}.ate-control-btn .ate-icon{font-size:18px}@media (max-width: 768px){:host{display:none!important}}\n"] }]
256
305
  }], ctorParameters: () => [] });
257
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWJsb2NrLWNvbnRyb2xzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvZWRpdG9yL2F0ZS1ibG9jay1jb250cm9scy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBUyxFQUdULE1BQU0sRUFDTixNQUFNLEVBQ04sTUFBTSxFQUNOLHVCQUF1QixHQUV4QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEtBQUssRUFBRSxFQUE2QixNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFHcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDOztBQUU1RDs7R0FFRztBQTJFSCxNQUFNLE9BQU8seUJBQXlCO0lBY3BDO1FBYm1CLFNBQUksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFaEQsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUNsQyxnQkFBVyxHQUFHLEtBQUssQ0FBNkQsSUFBSSxDQUFDLENBQUM7UUFFdEYsWUFBTyxHQUFHLFNBQVMsQ0FBQyxRQUFRLENBQTZCLFNBQVMsQ0FBQyxDQUFDO1FBRTFELGtCQUFhLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLGtCQUFhLEdBQStELElBQUksQ0FBQztRQUNqRixrQkFBYSxHQUFtQixJQUFJLENBQUM7UUFDckMsa0JBQWEsR0FBeUIsSUFBSSxDQUFDO1FBQzNDLGtCQUFhLEdBQXlDLElBQUksQ0FBQztRQUdqRSxNQUFNLENBQUMsR0FBRyxFQUFF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WUFBWSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTdDLGlGQUFpRjtRQUNoRixJQUF5QyxDQUFDLFFBQVEsR0FBRztZQUNwRCxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsT0FBTyxFQUFFO1lBQ25DLElBQUksRUFBRSxJQUFJO1NBQ1gsQ0FBQztRQUVGLGdDQUFnQztRQUNoQyxNQUFNLE9BQU8sR0FBRyxJQUFJLFNBQVMsQ0FBQyxXQUFXLEVBQUU7WUFDekMsWUFBWSxFQUFFLEtBQUssQ0FBQyxZQUFZO1lBQ2hDLE9BQU8sRUFBRSxJQUFJO1lBQ2IsVUFBVSxFQUFFLElBQUk7U0FDakIsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxDQUFDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUUvQixnQkFBZ0I7UUFDaEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNqQixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDO0lBRUQsU0FBUztRQUNQLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7K0dBdk5VLHlCQUF5QjttR0FBekIseUJBQXlCLGtkQXJFMUI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJULGdsQkE1QlMsbUJBQW1CLGlKQUFFLGdCQUFnQjs7NEZBdUVwQyx5QkFBeUI7a0JBMUVyQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1AsQ0FBQyxtQkFBbUIsRUFBRSxnQkFBZ0IsQ0FBQyxtQkFDL0IsdUJBQXVCLENBQUMsTUFBTSxZQUNyQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQlQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDb21wb25lbnQsXG4gIGlucHV0LFxuICB2aWV3Q2hpbGQsXG4gIEVsZW1lbnRSZWYsXG4gIE9uRGVzdHJveSxcbiAgZWZmZWN0LFxuICBzaWduYWwsXG4gIGluamVjdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIEFmdGVyVmlld0luaXQsXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgdGlwcHksIHsgSW5zdGFuY2UgYXMgVGlwcHlJbnN0YW5jZSwgc3RpY2t5IH0gZnJvbSBcInRpcHB5LmpzXCI7XG5pbXBvcnQgeyBFZGl0b3IgfSBmcm9tIFwiQHRpcHRhcC9jb3JlXCI7XG5pbXBvcnQgeyBOb2RlIGFzIFBNTm9kZSB9IGZyb20gXCJAdGlwdGFwL3BtL21vZGVsXCI7XG5pbXBvcnQgeyBBdGVFZGl0b3JJMThuIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL2F0ZS1lZGl0b3ItaTE4bi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBBdGVUb29sdGlwRGlyZWN0aXZlIH0gZnJvbSBcIi4uLy4uL2RpcmVjdGl2ZXMvYXRlLXRvb2x0aXAuZGlyZWN0aXZlXCI7XG5pbXBvcnQgeyBBdGVJY29uQ29tcG9uZW50IH0gZnJvbSBcIi4uL3VpL2F0ZS1pY29uLmNvbXBvbmVudFwiO1xuXG4vKipcbiAqIENvbXBvbmVudCBwcm92aWRpbmcgTm90aW9uLWxpa2UgYmxvY2sgY29udHJvbHMgKFBsdXMgYnV0dG9uIGFuZCBEcmFnIEhhbmRsZSkuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogXCJhdGUtYmxvY2stY29udHJvbHNcIixcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0F0ZVRvb2x0aXBEaXJlY3RpdmUsIEF0ZUljb25Db21wb25lbnRdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2XG4gICAgICAjbWVudVJlZlxuICAgICAgY2xhc3M9XCJhdGUtYmxvY2stY29udHJvbHNcIlxuICAgICAgKG1vdXNlZW50ZXIpPVwib25Nb3VzZUVudGVyKClcIlxuICAgICAgKG1vdXNlbGVhdmUpPVwib25Nb3VzZUxlYXZlKClcIlxuICAgICAgKG1vdXNlZG93bik9XCJvbkNvbnRhaW5lck1vdXNlRG93bigkZXZlbnQpXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIGNsYXNzPVwiYXRlLWNvbnRyb2wtYnRuIGF0ZS1ibG9jay1hZGRcIlxuICAgICAgICAobW91c2Vkb3duKT1cIm9uQnV0dG9uTW91c2VEb3duKCRldmVudClcIlxuICAgICAgICAoY2xpY2spPVwiYWRkQmxvY2soJGV2ZW50KVwiXG4gICAgICAgIFthdGVUb29sdGlwXT1cImkxOG4uZWRpdG9yKCkuYmxvY2tBZGRcIlxuICAgICAgICBhdGVUb29sdGlwUGxhY2VtZW50PVwidG9wXCI+XG4gICAgICAgIDxhdGUtaWNvbiBuYW1lPVwiYmxvY2tBZGRcIiAvPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8ZGl2XG4gICAgICAgIGNsYXNzPVwiYXRlLWNvbnRyb2wtYnRuIGF0ZS1ibG9jay1kcmFnXCJcbiAgICAgICAgZHJhZ2dhYmxlPVwidHJ1ZVwiXG4gICAgICAgIChtb3VzZWRvd24pPVwib25EcmFnSGFuZGxlTW91c2VEb3duKCRldmVudClcIlxuICAgICAgICAoZHJhZ3N0YXJ0KT1cIm9uRHJhZ1N0YXJ0KCRldmVudClcIlxuICAgICAgICAoZHJhZ2VuZCk9XCJvbkRyYWdFbmQoKVwiXG4gICAgICAgIFthdGVUb29sdGlwXT1cImkxOG4uZWRpdG9yKCkuYmxvY2tEcmFnXCJcbiAgICAgICAgYXRlVG9vbHRpcFBsYWNlbWVudD1cInRvcFwiPlxuICAgICAgICA8YXRlLWljb24gbmFtZT1cImJsb2NrRHJhZ1wiIC8+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYCxcbiAgc3R5bGVzOiBbXG4gICAgYFxuICAgICAgLmF0ZS1ibG9jay1jb250cm9scyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGdhcDogMnB4O1xuICAgICAgICBwYWRkaW5nOiA0cHg7XG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBhdXRvO1xuICAgICAgICB3aWxsLWNoYW5nZTogdHJhbnNmb3JtO1xuICAgICAgfVxuXG4gICAgICAuYXRlLWNvbnRyb2wtYnRuIHtcbiAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgICBoZWlnaHQ6IDI0cHg7XG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgICAgY29sb3I6IHZhcigtLWF0ZS10ZXh0LXNlY29uZGFyeSk7XG4gICAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgICAgdHJhbnNpdGlvbjogYWxsIDAuMTVzIGVhc2U7XG4gICAgICB9XG5cbiAgICAgIC5hdGUtY29udHJvbC1idG46aG92ZXIge1xuICAgICAgICBiYWNrZ3JvdW5kOiB2YXIoLS1hdGUtc3VyZmFjZS10ZXJ0aWFyeSk7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1hdGUtdGV4dCk7XG4gICAgICB9XG5cbiAgICAgIC5hdGUtY29udHJvbC1idG4gLmF0ZS1pY29uIHtcbiAgICAgICAgZm9udC1zaXplOiAxOHB4O1xuICAgICAgfVxuXG4gICAgICBAbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHtcbiAgICAgICAgOmhvc3Qge1xuICAgICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIGAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEF0ZUJsb2NrQ29udHJvbHNDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaTE4biA9IGluamVjdChBdGVFZGl0b3JJMThuKTtcblxuICBlZGl0b3IgPSBpbnB1dC5yZXF1aXJlZDxFZGl0b3I+KCk7XG4gIGhvdmVyZWREYXRhID0gaW5wdXQ8eyBub2RlOiBQTU5vZGU7IGVsZW1lbnQ6IEhUTUxFbGVtZW50OyBwb3M6IG51bWJlciB9IHwgbnVsbD4obnVsbCk7XG5cbiAgbWVudVJlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pj4oXCJtZW51UmVmXCIpO1xuXG4gIHByb3RlY3RlZCBpc0ludGVyYWN0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJpdmF0ZSBsYXN0VmFsaWREYXRhOiB7IG5vZGU6IFBNTm9kZTsgZWxlbWVudDogSFRNTEVsZW1lbnQ7IHBvczogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0VmFsaWRSZWN0OiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdGlwcHlJbnN0YW5jZTogVGlwcHlJbnN0YW5jZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVwZGF0ZVRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmhvdmVyZWREYXRhKCk7XG4gICAgICBjb25zdCBpbnRlcmFjdGluZyA9IHRoaXMuaXNJbnRlcmFjdGluZygpO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICB0aGlzLmxhc3RWYWxpZERhdGEgPSBkYXRhO1xuICAgICAgICB0aGlzLmxhc3RWYWxpZFJlY3QgPSBkYXRhLmVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMudXBkYXRlTWVudSghIWRhdGEgfHwgaW50ZXJhY3RpbmcpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaW5pdFRpcHB5KCk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICBpZiAodGhpcy51cGRhdGVUaW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy51cGRhdGVUaW1lb3V0KTtcbiAgICB9XG4gICAgaWYgKHRoaXMudGlwcHlJbnN0YW5jZSkge1xuICAgICAgdGhpcy50aXBweUluc3RhbmNlLmRlc3Ryb3koKTtcbiAgICAgIHRoaXMudGlwcHlJbnN0YW5jZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0VGlwcHkoKSB7XG4gICAgY29uc3QgbmF0aXZlRWxlbWVudCA9IHRoaXMubWVudVJlZigpLm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFuYXRpdmVFbGVtZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy50aXBweUluc3RhbmNlID0gdGlwcHkoZG9jdW1lbnQuYm9keSwge1xuICAgICAgY29udGVudDogbmF0aXZlRWxlbWVudCxcbiAgICAgIHRyaWdnZXI6IFwibWFudWFsXCIsXG4gICAgICBwbGFjZW1lbnQ6IFwibGVmdFwiLFxuICAgICAgdGhlbWU6IFwiYXRlLWJsb2NrLWNvbnRyb2xzXCIsXG4gICAgICBhcHBlbmRUbzogKCkgPT4gKHRoaXMuZWRpdG9yKCk/Lm9wdGlvbnM/LmVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpIHx8IGRvY3VtZW50LmJvZHksXG4gICAgICBpbnRlcmFjdGl2ZTogdHJ1ZSxcbiAgICAgIGhpZGVPbkNsaWNrOiBmYWxzZSxcbiAgICAgIGFycm93OiBmYWxzZSxcbiAgICAgIG9mZnNldDogWzAsIDhdLFxuICAgICAgekluZGV4OiA5OSxcbiAgICAgIHBsdWdpbnM6IFtzdGlja3ldLFxuICAgICAgc3RpY2t5OiBcInJlZmVyZW5jZVwiLFxuICAgICAgbW92ZVRyYW5zaXRpb246IFwidHJhbnNmb3JtIDAuMnMgZWFzZS1vdXRcIixcbiAgICAgIGdldFJlZmVyZW5jZUNsaWVudFJlY3Q6ICgpID0+IHRoaXMuZ2V0U2VsZWN0aW9uUmVjdCgpLFxuICAgICAgcG9wcGVyT3B0aW9uczoge1xuICAgICAgICBtb2RpZmllcnM6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICBuYW1lOiBcInByZXZlbnRPdmVyZmxvd1wiLFxuICAgICAgICAgICAgb3B0aW9uczoge1xuICAgICAgICAgICAgICBib3VuZGFyeTogKHRoaXMuZWRpdG9yKCk/Lm9wdGlvbnM/LmVsZW1lbnQgYXMgSFRNTEVsZW1lbnQpIHx8IGRvY3VtZW50LmJvZHksXG4gICAgICAgICAgICAgIHBhZGRpbmc6IDgsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVNZW51KHNob3c6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy51cGRhdGVUaW1lb3V0KSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy51cGRhdGVUaW1lb3V0KTtcbiAgICB9XG4gICAgY29uc3QgZGVsYXkgPSBzaG93ID8gMCA6IDQwMDtcbiAgICB0aGlzLnVwZGF0ZVRpbWVvdXQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmIChzaG93KSB7XG4gICAgICAgIHRoaXMuc2hvd1RpcHB5KCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmhpZGVUaXBweSgpO1xuICAgICAgfVxuICAgIH0sIGRlbGF5KTtcbiAgfVxuXG4gIHByaXZhdGUgc2hvd1RpcHB5KCkge1xuICAgIGlmICh0aGlzLnRpcHB5SW5zdGFuY2UpIHtcbiAgICAgIHRoaXMudGlwcHlJbnN0YW5jZS5zZXRQcm9wcyh7XG4gICAgICAgIGdldFJlZmVyZW5jZUNsaWVudFJlY3Q6ICgpID0+IHRoaXMuZ2V0U2VsZWN0aW9uUmVjdCgpLFxuICAgICAgfSk7XG4gICAgICB0aGlzLnRpcHB5SW5zdGFuY2Uuc2hvdygpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaGlkZVRpcHB5KCkge1xuICAgIGlmICh0aGlzLnRpcHB5SW5zdGFuY2UpIHtcbiAgICAgIHRoaXMudGlwcHlJbnN0YW5jZS5oaWRlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRTZWxlY3Rpb25SZWN0KCk6IERPTVJlY3Qge1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmhvdmVyZWREYXRhKCk7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5lbGVtZW50KSB7XG4gICAgICByZXR1cm4gZGF0YS5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5sYXN0VmFsaWRSZWN0IHx8IG5ldyBET01SZWN0KC05OTk5LCAtOTk5OSwgMCwgMCk7XG4gIH1cblxuICBvbk1vdXNlRW50ZXIoKSB7XG4gICAgdGhpcy5pc0ludGVyYWN0aW5nLnNldCh0cnVlKTtcbiAgfVxuXG4gIG9uTW91c2VMZWF2ZSgpIHtcbiAgICB0aGlzLmlzSW50ZXJhY3Rpbmcuc2V0KGZhbHNlKTtcbiAgfVxuXG4gIG9uQ29udGFpbmVyTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgaWYgKGV2ZW50LnRhcmdldCA9PT0gZXZlbnQuY3VycmVudFRhcmdldCkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gIH1cblxuICBvbkJ1dHRvbk1vdXNlRG93bihldmVudDogTW91c2VFdmVudCkge1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0aW9uIHN0cmF0ZWd5IHRvIGF2b2lkIHBhcnRpYWwgbm9kZSBkcmFnZ2luZyAoZ2hvc3QgdGFibGUgaXNzdWUpLlxuICAgKi9cbiAgb25EcmFnSGFuZGxlTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmhvdmVyZWREYXRhKCkgfHwgdGhpcy5sYXN0VmFsaWREYXRhO1xuICAgIGlmIChlZCAmJiBkYXRhKSB7XG4gICAgICAvLyBGb3JjZSB3aG9sZS1ub2RlIHNlbGVjdGlvbi4gVGhpcyBpcyBjcnVjaWFsIGZvciBhdG9taWMgbm9kZXMgbGlrZSB0YWJsZXMgYW5kIGltYWdlcy5cbiAgICAgIGVkLmNvbW1hbmRzLnNldE5vZGVTZWxlY3Rpb24oZGF0YS5wb3MpO1xuICAgIH1cbiAgfVxuXG4gIGFkZEJsb2NrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZWQgPSB0aGlzLmVkaXRvcigpO1xuICAgIGNvbnN0IGRhdGEgPSB0aGlzLmhvdmVyZWREYXRhKCkgfHwgdGhpcy5sYXN0VmFsaWREYXRhO1xuICAgIGlmICghZWQgfHwgIWRhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IHBvcywgbm9kZSB9ID0gZGF0YTtcbiAgICBpZiAobm9kZS5jb250ZW50LnNpemUgPT09IDApIHtcbiAgICAgIGVkLmNoYWluKClcbiAgICAgICAgLmZvY3VzKClcbiAgICAgICAgLnNldFRleHRTZWxlY3Rpb24ocG9zICsgMSlcbiAgICAgICAgLmluc2VydENvbnRlbnQoXCIvXCIpXG4gICAgICAgIC5ydW4oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbmV4dFBvcyA9IHBvcyArIG5vZGUubm9kZVNpemU7XG4gICAgICBlZC5jaGFpbigpXG4gICAgICAgIC5mb2N1cygpXG4gICAgICAgIC5pbnNlcnRDb250ZW50QXQobmV4dFBvcywgeyB0eXBlOiBcInBhcmFncmFwaFwiLCBjb250ZW50OiBbeyB0eXBlOiBcInRleHRcIiwgdGV4dDogXCIvXCIgfV0gfSlcbiAgICAgICAgLnNldFRleHRTZWxlY3Rpb24obmV4dFBvcyArIDIpXG4gICAgICAgIC5ydW4oKTtcbiAgICB9XG5cbiAgICB0aGlzLmlzSW50ZXJhY3Rpbmcuc2V0KGZhbHNlKTtcbiAgICB0aGlzLmhpZGVUaXBweSgpO1xuICB9XG5cbiAgb25EcmFnU3RhcnQoZXZlbnQ6IERyYWdFdmVudCkge1xuICAgIGNvbnN0IGVkID0gdGhpcy5lZGl0b3IoKTtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5ob3ZlcmVkRGF0YSgpIHx8IHRoaXMubGFzdFZhbGlkRGF0YTtcbiAgICBpZiAoIWVkIHx8ICFkYXRhIHx8ICFldmVudC5kYXRhVHJhbnNmZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB7IGVsZW1lbnQsIHBvcyB9ID0gZGF0YTtcbiAgICBjb25zdCB2aWV3ID0gZWQudmlldztcblxuICAgIC8vIDEuIEZvcmNlIHRoZSBlZGl0b3IgdG8gZm9jdXMgYW5kIHNlbGVjdCB0aGUgRU5USVJFIG5vZGVcbiAgICB2aWV3LmZvY3VzKCk7XG4gICAgZWQuY29tbWFuZHMuc2V0Tm9kZVNlbGVjdGlvbihwb3MpO1xuXG4gICAgLy8gMi4gQnJvd3NlciBEcmFnIEltYWdlICYgbWV0YWRhdGFcbiAgICBldmVudC5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKGVsZW1lbnQsIDAsIDEwKTtcbiAgICBldmVudC5kYXRhVHJhbnNmZXIuZWZmZWN0QWxsb3dlZCA9IFwibW92ZVwiO1xuICAgIGV2ZW50LmRhdGFUcmFuc2Zlci5zZXREYXRhKFwidGV4dC9wbGFpblwiLCBcIlwiKTtcblxuICAgIC8vIDMuIFBSTy1IQUNLOiBJbmRpY2F0ZSB0aGlzIGlzIGEgbW92ZSBvZiB0aGUgY3VycmVudCBzZWxlY3Rpb24gKHRoZSB3aG9sZSBub2RlKVxuICAgICh2aWV3IGFzIHVua25vd24gYXMgeyBkcmFnZ2luZzogdW5rbm93biB9KS5kcmFnZ2luZyA9IHtcbiAgICAgIHNsaWNlOiBlZC5zdGF0ZS5zZWxlY3Rpb24uY29udGVudCgpLFxuICAgICAgbW92ZTogdHJ1ZSxcbiAgICB9O1xuXG4gICAgLy8gNC4gRGlzcGF0Y2ggdmlydHVhbCBkcmFnc3RhcnRcbiAgICBjb25zdCBwbUV2ZW50ID0gbmV3IERyYWdFdmVudChcImRyYWdzdGFydFwiLCB7XG4gICAgICBkYXRhVHJhbnNmZXI6IGV2ZW50LmRhdGFUcmFuc2ZlcixcbiAgICAgIGJ1YmJsZXM6IHRydWUsXG4gICAgICBjYW5jZWxhYmxlOiB0cnVlLFxuICAgIH0pO1xuICAgIGVsZW1lbnQuZGlzcGF0Y2hFdmVudChwbUV2ZW50KTtcblxuICAgIC8vIDUuIENsZWFudXAgVUlcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaGlkZVRpcHB5KCk7XG4gICAgICB0aGlzLmlzSW50ZXJhY3Rpbmcuc2V0KGZhbHNlKTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIG9uRHJhZ0VuZCgpIHtcbiAgICB0aGlzLmlzSW50ZXJhY3Rpbmcuc2V0KGZhbHNlKTtcbiAgfVxufVxuIl19
306
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWJsb2NrLWNvbnRyb2xzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2NvbXBvbmVudHMvZWRpdG9yL2F0ZS1ibG9jay1jb250cm9scy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFDVCxLQUFLLEVBQ0wsU0FBUyxFQUdULE1BQU0sRUFDTixNQUFNLEVBQ04sTUFBTSxFQUNOLHVCQUF1QixHQUV4QixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEtBQUssRUFBRSxFQUE2QixNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFHcEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ3ZFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzVELE9BQU8sRUFDTCxtQkFBbUIsRUFDbkIsc0JBQXNCLEVBQ3RCLGVBQWUsR0FDaEIsTUFBTSwrQ0FBK0MsQ0FBQzs7QUFFdkQsaUhBQWlIO0FBQ2pILE1BQU0sOEJBQThCLEdBQUcsZ0RBQWdELENBQUM7QUFFeEYsU0FBUyxvQkFBb0I7SUFDM0IsT0FBTyxPQUFPLFVBQVUsS0FBSyxVQUFVLElBQUksVUFBVSxDQUFDLGtDQUFrQyxDQUFDLENBQUMsT0FBTyxDQUFDO0FBQ3BHLENBQUM7QUFFRDs7R0FFRztBQW1GSCxNQUFNLE9BQU8seUJBQXlCO0lBZXBDO1FBZG1CLFNBQUksR0FBRyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUM7UUFFaEQsV0FBTSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQVUsQ0FBQztRQUNsQyxnQkFBVyxHQUFHLEtBQUssQ0FBNkQsSUFBSSxDQUFDLENBQUM7UUFFdEYsWUFBTyxH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QyxPQUFPLEVBQUUsSUFBSTtZQUNiLFVBQVUsRUFBRSxJQUFJO1NBQ2pCLENBQUMsQ0FBQztRQUNILE9BQU8sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFL0IsZ0JBQWdCO1FBQ2hCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUVELFNBQVM7UUFDUCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNwQixlQUFlLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFDRCxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDOytHQW5RVSx5QkFBeUI7bUdBQXpCLHlCQUF5QixrZEE3RTFCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTBCVCxpckJBNUJTLG1CQUFtQixpSkFBRSxnQkFBZ0I7OzRGQStFcEMseUJBQXlCO2tCQWxGckMsU0FBUzsrQkFDRSxvQkFBb0IsY0FDbEIsSUFBSSxXQUNQLENBQUMsbUJBQW1CLEVBQUUsZ0JBQWdCLENBQUMsbUJBQy9CLHVCQUF1QixDQUFDLE1BQU0sWUFDckM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBMEJUIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBpbnB1dCxcbiAgdmlld0NoaWxkLFxuICBFbGVtZW50UmVmLFxuICBPbkRlc3Ryb3ksXG4gIGVmZmVjdCxcbiAgc2lnbmFsLFxuICBpbmplY3QsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBBZnRlclZpZXdJbml0LFxufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHRpcHB5LCB7IEluc3RhbmNlIGFzIFRpcHB5SW5zdGFuY2UsIHN0aWNreSB9IGZyb20gXCJ0aXBweS5qc1wiO1xuaW1wb3J0IHsgRWRpdG9yIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IHsgTm9kZSBhcyBQTU5vZGUgfSBmcm9tIFwiQHRpcHRhcC9wbS9tb2RlbFwiO1xuaW1wb3J0IHsgQXRlRWRpdG9ySTE4biB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9hdGUtZWRpdG9yLWkxOG4uc2VydmljZVwiO1xuaW1wb3J0IHsgQXRlVG9vbHRpcERpcmVjdGl2ZSB9IGZyb20gXCIuLi8uLi9kaXJlY3RpdmVzL2F0ZS10b29sdGlwLmRpcmVjdGl2ZVwiO1xuaW1wb3J0IHsgQXRlSWNvbkNvbXBvbmVudCB9IGZyb20gXCIuLi91aS9hdGUtaWNvbi5jb21wb25lbnRcIjtcbmltcG9ydCB7XG4gIEFURV9CTE9DS19EUkFHX01JTUUsXG4gIGF0ZU11bHRpQmxvY2tTZWxlY3Rpb24sXG4gIGVuZEF0ZUJsb2NrRHJhZyxcbn0gZnJvbSBcIi4uLy4uL2V4dGVuc2lvbnMvYXRlLWJsb2NrLWNvbnRyb2xzLmV4dGVuc2lvblwiO1xuXG4vLyBHbGlkZXMgZnJvbSBibG9jayB0byBibG9jazsgdGhlIHN0cm9uZyBlYXNlLW91dCBjb3ZlcnMgbW9zdCBvZiB0aGUgd2F5IGF0IG9uY2UsIHNvIGl0IG5ldmVyIHRyYWlscyB0aGUgcG9pbnRlclxuY29uc3QgQkxPQ0tfQ09OVFJPTFNfTU9WRV9UUkFOU0lUSU9OID0gXCJ0cmFuc2Zvcm0gMjAwbXMgY3ViaWMtYmV6aWVyKDAuMjMsIDEsIDAuMzIsIDEpXCI7XG5cbmZ1bmN0aW9uIHByZWZlcnNSZWR1Y2VkTW90aW9uKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdHlwZW9mIG1hdGNoTWVkaWEgPT09IFwiZnVuY3Rpb25cIiAmJiBtYXRjaE1lZGlhKFwiKHByZWZlcnMtcmVkdWNlZC1tb3Rpb246IHJlZHVjZSlcIikubWF0Y2hlcztcbn1cblxuLyoqXG4gKiBDb21wb25lbnQgcHJvdmlkaW5nIE5vdGlvbi1saWtlIGJsb2NrIGNvbnRyb2xzIChQbHVzIGJ1dHRvbiBhbmQgRHJhZyBIYW5kbGUpLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwiYXRlLWJsb2NrLWNvbnRyb2xzXCIsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtBdGVUb29sdGlwRGlyZWN0aXZlLCBBdGVJY29uQ29tcG9uZW50XSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdlxuICAgICAgI21lbnVSZWZcbiAgICAgIGNsYXNzPVwiYXRlLWJsb2NrLWNvbnRyb2xzXCJcbiAgICAgIChtb3VzZWVudGVyKT1cIm9uTW91c2VFbnRlcigpXCJcbiAgICAgIChtb3VzZWxlYXZlKT1cIm9uTW91c2VMZWF2ZSgpXCJcbiAgICAgIChtb3VzZWRvd24pPVwib25Db250YWluZXJNb3VzZURvd24oJGV2ZW50KVwiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBjbGFzcz1cImF0ZS1jb250cm9sLWJ0biBhdGUtYmxvY2stYWRkXCJcbiAgICAgICAgKG1vdXNlZG93bik9XCJvbkJ1dHRvbk1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAgICAgKGNsaWNrKT1cImFkZEJsb2NrKCRldmVudClcIlxuICAgICAgICBbYXRlVG9vbHRpcF09XCJpMThuLmVkaXRvcigpLmJsb2NrQWRkXCJcbiAgICAgICAgYXRlVG9vbHRpcFBsYWNlbWVudD1cInRvcFwiPlxuICAgICAgICA8YXRlLWljb24gbmFtZT1cImJsb2NrQWRkXCIgLz5cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGRpdlxuICAgICAgICBjbGFzcz1cImF0ZS1jb250cm9sLWJ0biBhdGUtYmxvY2stZHJhZ1wiXG4gICAgICAgIGRyYWdnYWJsZT1cInRydWVcIlxuICAgICAgICAobW91c2Vkb3duKT1cIm9uRHJhZ0hhbmRsZU1vdXNlRG93bigkZXZlbnQpXCJcbiAgICAgICAgKGRyYWdzdGFydCk9XCJvbkRyYWdTdGFydCgkZXZlbnQpXCJcbiAgICAgICAgKGRyYWdlbmQpPVwib25EcmFnRW5kKClcIlxuICAgICAgICBbYXRlVG9vbHRpcF09XCJpMThuLmVkaXRvcigpLmJsb2NrRHJhZ1wiXG4gICAgICAgIGF0ZVRvb2x0aXBQbGFjZW1lbnQ9XCJ0b3BcIj5cbiAgICAgICAgPGF0ZS1pY29uIG5hbWU9XCJibG9ja0RyYWdcIiAvPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW1xuICAgIGBcbiAgICAgIC5hdGUtYmxvY2stY29udHJvbHMge1xuICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICBnYXA6IDJweDtcbiAgICAgICAgcGFkZGluZzogNHB4O1xuICAgICAgICBwb2ludGVyLWV2ZW50czogYXV0bztcbiAgICAgICAgd2lsbC1jaGFuZ2U6IHRyYW5zZm9ybTtcbiAgICAgIH1cblxuICAgICAgLmF0ZS1jb250cm9sLWJ0biB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgICB3aWR0aDogMjRweDtcbiAgICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICAgIGNvbG9yOiB2YXIoLS1hdGUtdGV4dC1zZWNvbmRhcnkpO1xuICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB9XG5cbiAgICAgIC8qIEhvdmVyZWQgZG96ZW5zIG9mIHRpbWVzIGEgbWludXRlOiBhIGZsYXNoIGF0IG1vc3QsIGFuZCBvbmx5IHdpdGggYSByZWFsIHBvaW50ZXIgKi9cbiAgICAgIEBtZWRpYSAoaG92ZXI6IGhvdmVyKSBhbmQgKHBvaW50ZXI6IGZpbmUpIHtcbiAgICAgICAgLmF0ZS1jb250cm9sLWJ0biB7XG4gICAgICAgICAgdHJhbnNpdGlvbjpcbiAgICAgICAgICAgIGJhY2tncm91bmQtY29sb3IgMTIwbXMgZWFzZS1vdXQsXG4gICAgICAgICAgICBjb2xvciAxMjBtcyBlYXNlLW91dDtcbiAgICAgICAgfVxuXG4gICAgICAgIC5hdGUtY29udHJvbC1idG46aG92ZXIge1xuICAgICAgICAgIGJhY2tncm91bmQ6IHZhcigtLWF0ZS1zdXJmYWNlLXRlcnRpYXJ5KTtcbiAgICAgICAgICBjb2xvcjogdmFyKC0tYXRlLXRleHQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC5hdGUtY29udHJvbC1idG4gLmF0ZS1pY29uIHtcbiAgICAgICAgZm9udC1zaXplOiAxOHB4O1xuICAgICAgfVxuXG4gICAgICBAbWVkaWEgKG1heC13aWR0aDogNzY4cHgpIHtcbiAgICAgICAgOmhvc3Qge1xuICAgICAgICAgIGRpc3BsYXk6IG5vbmUgIWltcG9ydGFudDtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIGAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIEF0ZUJsb2NrQ29udHJvbHNDb21wb25lbnQgaW1wbGVtZW50cyBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3kge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaTE4biA9IGluamVjdChBdGVFZGl0b3JJMThuKTtcblxuICBlZGl0b3IgPSBpbnB1dC5yZXF1aXJlZDxFZGl0b3I+KCk7XG4gIGhvdmVyZWREYXRhID0gaW5wdXQ8eyBub2RlOiBQTU5vZGU7IGVsZW1lbnQ6IEhUTUxFbGVtZW50OyBwb3M6IG51bWJlciB9IHwgbnVsbD4obnVsbCk7XG5cbiAgbWVudVJlZiA9IHZpZXdDaGlsZC5yZXF1aXJlZDxFbGVtZW50UmVmPEhUTUxEaXZFbGVtZW50Pj4oXCJtZW51UmVmXCIpO1xuXG4gIHByb3RlY3RlZCBpc0ludGVyYWN0aW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJpdmF0ZSBsYXN0VmFsaWREYXRhOiB7IG5vZGU6IFBNTm9kZTsgZWxlbWVudDogSFRNTEVsZW1lbnQ7IHBvczogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsYXN0VmFsaWRSZWN0OiBET01SZWN0IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgdGlwcHlJbnN0YW5jZTogVGlwcHlJbnN0YW5jZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHVwZGF0ZVRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgZ2xpZGVGcmFtZTogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IGRhdGEgPSB0aGlzLmhvdmVyZWREYXRhKCk7XG4gICAgICBjb25zdCBpbnRlcmFjdGluZyA9IHRoaXMuaXNJbnRlcmFjdGluZygpO1xuXG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICB0aGlzLmxhc3RWYWxpZERhdGEgPSBkYXRhO1xuICAgICAgICBpZiAoZGF0YS5lbGVtZW50LmlzQ29ubmVjdGVkKSB7XG4gICAgICAgICAgdGhpcy5sYXN0VmFsaWRSZWN0ID0gZGF0YS5lbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHRoaXMudXBkYXRlTWVudSghIWRhdGEgfHwgaW50ZXJhY3RpbmcpO1xuICAgIH0pO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIHRoaXMuaW5pdFRpcHB5KCk7XG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCwgeyBjYXB0dXJlOiB0cnVlLCBwYXNzaXZlOiB0cnVlIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCwgeyBjYXB0dXJlOiB0cnVlIH0pO1xuICAgIGlmICh0aGlzLnVwZGF0ZVRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnVwZGF0ZVRpbWVvdXQpO1xuICAgIH1cbiAgICBpZiAodGhpcy5nbGlkZUZyYW1lICE9PSBudWxsKSB7XG4gICAgICBjYW5jZWxBbmltYXRpb25GcmFtZSh0aGlzLmdsaWRlRnJhbWUpO1xuICAgIH1cbiAgICBpZiAodGhpcy50aXBweUluc3RhbmNlKSB7XG4gICAgICB0aGlzLnRpcHB5SW5zdGFuY2UuZGVzdHJveSgpO1xuICAgICAgdGhpcy50aXBweUluc3RhbmNlID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRUaXBweSgpIHtcbiAgICBjb25zdCBuYXRpdmVFbGVtZW50ID0gdGhpcy5tZW51UmVmKCkubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIW5hdGl2ZUVsZW1lbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLnRpcHB5SW5zdGFuY2UgPSB0aXBweShkb2N1bWVudC5ib2R5LCB7XG4gICAgICBjb250ZW50OiBuYXRpdmVFbGVtZW50LFxuICAgICAgdHJpZ2dlcjogXCJtYW51YWxcIixcbiAgICAgIHBsYWNlbWVudDogXCJsZWZ0XCIsXG4gICAgICB0aGVtZTogXCJhdGUtYmxvY2stY29udHJvbHNcIixcbiAgICAgIGFwcGVuZFRvOiAoKSA9PiAodGhpcy5lZGl0b3IoKT8ub3B0aW9ucz8uZWxlbWVudCBhcyBIVE1MRWxlbWVudCkgfHwgZG9jdW1lbnQuYm9keSxcbiAgICAgIGludGVyYWN0aXZlOiB0cnVlLFxuICAgICAgaGlkZU9uQ2xpY2s6IGZhbHNlLFxuICAgICAgYXJyb3c6IGZhbHNlLFxuICAgICAgb2Zmc2V0OiBbMCwgOF0sXG4gICAgICB6SW5kZXg6IDk5LFxuICAgICAgcGx1Z2luczogW3N0aWNreV0sXG4gICAgICBzdGlja3k6IFwicmVmZXJlbmNlXCIsXG4gICAgICAvLyBUaGUgZ2xpZGUga2VlcHMgdGhlIGhhbmRsZSB2aXNpYmx5IHRoZSBzYW1lIG9uZSBtb3Zpbmcgd2l0aCB0aGUgcG9pbnRlciAoc2VlIHdpdGhvdXRHbGlkZSBmb3Igd2hlbiBpdCBpcyBza2lwcGVkKVxuICAgICAgbW92ZVRyYW5zaXRpb246IHByZWZlcnNSZWR1Y2VkTW90aW9uKCkgPyBcIlwiIDogQkxPQ0tfQ09OVFJPTFNfTU9WRV9UUkFOU0lUSU9OLFxuICAgICAgZ2V0UmVmZXJlbmNlQ2xpZW50UmVjdDogKCkgPT4gdGhpcy5nZXRTZWxlY3Rpb25SZWN0KCksXG4gICAgICBwb3BwZXJPcHRpb25zOiB7XG4gICAgICAgIG1vZGlmaWVyczogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIG5hbWU6IFwicHJldmVudE92ZXJmbG93XCIsXG4gICAgICAgICAgICBvcHRpb25zOiB7XG4gICAgICAgICAgICAgIGJvdW5kYXJ5OiAodGhpcy5lZGl0b3IoKT8ub3B0aW9ucz8uZWxlbWVudCBhcyBIVE1MRWxlbWVudCkgfHwgZG9jdW1lbnQuYm9keSxcbiAgICAgICAgICAgICAgcGFkZGluZzogOCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZU1lbnUoc2hvdzogYm9vbGVhbikge1xuICAgIGlmICh0aGlzLnVwZGF0ZVRpbWVvdXQpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLnVwZGF0ZVRpbWVvdXQpO1xuICAgIH1cbiAgICBjb25zdCBkZWxheSA9IHNob3cgPyAwIDogNDAwO1xuICAgIHRoaXMudXBkYXRlVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgaWYgKHNob3cpIHtcbiAgICAgICAgdGhpcy5zaG93VGlwcHkoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuaGlkZVRpcHB5KCk7XG4gICAgICB9XG4gICAgfSwgZGVsYXkpO1xuICB9XG5cbiAgLyoqIFdoaWxlIHNjcm9sbGluZywgdGhlIGNvbnRyb2xzIGZvbGxvdyB0aGVpciBibG9jayBldmVyeSBmcmFtZTogYSBnbGlkZSB3b3VsZCBtYWtlIHRoZW0gdHJhaWwgYmVoaW5kIGl0ICovXG4gIHByaXZhdGUgb25TY3JvbGwgPSAoKSA9PiB7XG4gICAgaWYgKHRoaXMudGlwcHlJbnN0YW5jZT8uc3RhdGUuaXNWaXNpYmxlKSB7XG4gICAgICB0aGlzLndpdGhvdXRHbGlkZSgpO1xuICAgIH1cbiAgfTtcblxuICAvKipcbiAgICogTW92ZXMgdGhlIGNvbnRyb2xzIHdpdGhvdXQgZ2xpZGluZyB1bnRpbCB0aGUgcG9zaXRpb24gc2V0dGxlcyAodHdvIGZyYW1lcyBhZnRlciB0aGUgbGFzdCBjYWxsKS5cbiAgICogVGlwcHkgb25seSBza2lwcyB0aGUgbW92ZSB0cmFuc2l0aW9uIG9uIGl0cyB2ZXJ5IGZpcnN0IHNob3c6IHRoZSBjb250cm9scyBhcmUgbmV2ZXIgdW5tb3VudGVkXG4gICAqIGFmdGVyd2FyZHMsIHNvIHRoZXkgd291bGQgb3RoZXJ3aXNlIGdsaWRlIGluIGZyb20gd2hlcmV2ZXIgdGhleSB3ZXJlIGxhc3Qgc2hvd24uXG4gICAqL1xuICBwcml2YXRlIHdpdGhvdXRHbGlkZSgpIHtcbiAgICBjb25zdCBwb3BwZXIgPSB0aGlzLnRpcHB5SW5zdGFuY2U/LnBvcHBlcjtcbiAgICBpZiAoIXBvcHBlcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBwb3BwZXIuc3R5bGUudHJhbnNpdGlvbiA9IFwibm9uZVwiO1xuICAgIGlmICh0aGlzLmdsaWRlRnJhbWUgIT09IG51bGwpIHtcbiAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuZ2xpZGVGcmFtZSk7XG4gICAgfVxuICAgIHRoaXMuZ2xpZGVGcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICB0aGlzLmdsaWRlRnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB0aGlzLmdsaWRlRnJhbWUgPSBudWxsO1xuICAgICAgICBwb3BwZXIuc3R5bGUudHJhbnNpdGlvbiA9IHRoaXMudGlwcHlJbnN0YW5jZT8ucHJvcHMubW92ZVRyYW5zaXRpb24gPz8gXCJcIjtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzaG93VGlwcHkoKSB7XG4gICAgaWYgKHRoaXMudGlwcHlJbnN0YW5jZSkge1xuICAgICAgLy8gQXBwZWFyaW5nOiBzaG93IHRoZSBjb250cm9scyBpbiBwbGFjZSwgdGhlIGdsaWRlIGlzIG9ubHkgZm9yIG1vdmluZyBiZXR3ZWVuIGJsb2Nrc1xuICAgICAgaWYgKCF0aGlzLnRpcHB5SW5zdGFuY2Uuc3RhdGUuaXNWaXNpYmxlKSB7XG4gICAgICAgIHRoaXMud2l0aG91dEdsaWRlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnRpcHB5SW5zdGFuY2Uuc2V0UHJvcHMoe1xuICAgICAgICBnZXRSZWZlcmVuY2VDbGllbnRSZWN0OiAoKSA9PiB0aGlzLmdldFNlbGVjdGlvblJlY3QoKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy50aXBweUluc3RhbmNlLnNob3coKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGhpZGVUaXBweSgpIHtcbiAgICBpZiAodGhpcy50aXBweUluc3RhbmNlKSB7XG4gICAgICB0aGlzLnRpcHB5SW5zdGFuY2UuaGlkZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0U2VsZWN0aW9uUmVjdCgpOiBET01SZWN0IHtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5ob3ZlcmVkRGF0YSgpO1xuICAgIC8vIEEgYmxvY2sgcmVtb3ZlZCBieSBhbiBlZGl0IGlzIGRldGFjaGVkOiBpdHMgcmVjdCBpcyAoMCwgMCksIHdoaWNoIHdvdWxkIHNlbmQgdGhlIGNvbnRyb2xzIHRvIHRoZSBlZGl0b3IncyBjb3JuZXJcbiAgICBpZiAoZGF0YT8uZWxlbWVudD8uaXNDb25uZWN0ZWQpIHtcbiAgICAgIHRoaXMubGFzdFZhbGlkUmVjdCA9IGRhdGEuZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHJldHVybiB0aGlzLmxhc3RWYWxpZFJlY3Q7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmxhc3RWYWxpZFJlY3QgfHwgbmV3IERPTVJlY3QoLTk5OTksIC05OTk5LCAwLCAwKTtcbiAgfVxuXG4gIG9uTW91c2VFbnRlcigpIHtcbiAgICB0aGlzLmlzSW50ZXJhY3Rpbmcuc2V0KHRydWUpO1xuICB9XG5cbiAgb25Nb3VzZUxlYXZlKCkge1xuICAgIHRoaXMuaXNJbnRlcmFjdGluZy5zZXQoZmFsc2UpO1xuICB9XG5cbiAgb25Db250YWluZXJNb3VzZURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZXZlbnQudGFyZ2V0ID09PSBldmVudC5jdXJyZW50VGFyZ2V0KSB7XG4gICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfVxuXG4gIG9uQnV0dG9uTW91c2VEb3duKGV2ZW50OiBNb3VzZUV2ZW50KSB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZWxlY3Rpb24gc3RyYXRlZ3kgdG8gYXZvaWQgcGFydGlhbCBub2RlIGRyYWdnaW5nIChnaG9zdCB0YWJsZSBpc3N1ZSkuXG4gICAqL1xuICBvbkRyYWdIYW5kbGVNb3VzZURvd24oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBlZCA9IHRoaXMuZWRpdG9yKCk7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuaG92ZXJlZERhdGEoKSB8fCB0aGlzLmxhc3RWYWxpZERhdGE7XG4gICAgaWYgKGVkICYmIGRhdGEgJiYgIWF0ZU11bHRpQmxvY2tTZWxlY3Rpb24oZWQuc3RhdGUsIGRhdGEucG9zKSkge1xuICAgICAgLy8gRm9yY2Ugd2hvbGUtbm9kZSBzZWxlY3Rpb24uIFRoaXMgaXMgY3J1Y2lhbCBmb3IgYXRvbWljIG5vZGVzIGxpa2UgdGFibGVzIGFuZCBpbWFnZXMuXG4gICAgICBlZC5jb21tYW5kcy5zZXROb2RlU2VsZWN0aW9uKGRhdGEucG9zKTtcbiAgICB9XG4gIH1cblxuICBhZGRCbG9jayhldmVudDogTW91c2VFdmVudCkge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGVkID0gdGhpcy5lZGl0b3IoKTtcbiAgICBjb25zdCBkYXRhID0gdGhpcy5ob3ZlcmVkRGF0YSgpIHx8IHRoaXMubGFzdFZhbGlkRGF0YTtcbiAgICBpZiAoIWVkIHx8ICFkYXRhKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBwb3MsIG5vZGUgfSA9IGRhdGE7XG4gICAgaWYgKG5vZGUuY29udGVudC5zaXplID09PSAwKSB7XG4gICAgICBlZC5jaGFpbigpXG4gICAgICAgIC5mb2N1cygpXG4gICAgICAgIC5zZXRUZXh0U2VsZWN0aW9uKHBvcyArIDEpXG4gICAgICAgIC5pbnNlcnRDb250ZW50KFwiL1wiKVxuICAgICAgICAucnVuKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IG5leHRQb3MgPSBwb3MgKyBub2RlLm5vZGVTaXplO1xuICAgICAgZWQuY2hhaW4oKVxuICAgICAgICAuZm9jdXMoKVxuICAgICAgICAuaW5zZXJ0Q29udGVudEF0KG5leHRQb3MsIHsgdHlwZTogXCJwYXJhZ3JhcGhcIiwgY29udGVudDogW3sgdHlwZTogXCJ0ZXh0XCIsIHRleHQ6IFwiL1wiIH1dIH0pXG4gICAgICAgIC5zZXRUZXh0U2VsZWN0aW9uKG5leHRQb3MgKyAyKVxuICAgICAgICAucnVuKCk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0ludGVyYWN0aW5nLnNldChmYWxzZSk7XG4gICAgdGhpcy5oaWRlVGlwcHkoKTtcbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGV2ZW50OiBEcmFnRXZlbnQpIHtcbiAgICBjb25zdCBlZCA9IHRoaXMuZWRpdG9yKCk7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMuaG92ZXJlZERhdGEoKSB8fCB0aGlzLmxhc3RWYWxpZERhdGE7XG4gICAgaWYgKCFlZCB8fCAhZGF0YSB8fCAhZXZlbnQuZGF0YVRyYW5zZmVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgeyBlbGVtZW50LCBwb3MgfSA9IGRhdGE7XG4gICAgY29uc3QgdmlldyA9IGVkLnZpZXc7XG5cbiAgICAvLyAxLiBTZWxlY3QgdGhlIGdyYWJiZWQgYmxvY2ssIHVubGVzcyBpdCBiZWxvbmdzIHRvIGEgbXVsdGktYmxvY2sgc2VsZWN0aW9uIHRoYXQgaXMgZHJhZ2dlZCBhcyBhIHdob2xlXG4gICAgdmlldy5mb2N1cygpO1xuICAgIGlmICghYXRlTXVsdGlCbG9ja1NlbGVjdGlvbihlZC5zdGF0ZSwgcG9zKSkge1xuICAgICAgZWQuY29tbWFuZHMuc2V0Tm9kZVNlbGVjdGlvbihwb3MpO1xuICAgIH1cblxuICAgIC8vIDIuIEJyb3dzZXIgRHJhZyBJbWFnZSAmIG1ldGFkYXRhXG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyLnNldERyYWdJbWFnZShlbGVtZW50LCAwLCAxMCk7XG4gICAgZXZlbnQuZGF0YVRyYW5zZmVyLmVmZmVjdEFsbG93ZWQgPSBcIm1vdmVcIjtcbiAgICBldmVudC5kYXRhVHJhbnNmZXIuc2V0RGF0YShBVEVfQkxPQ0tfRFJBR19NSU1FLCBcIjFcIik7XG5cbiAgICAvLyAzLiBEaXNwYXRjaCB2aXJ0dWFsIGRyYWdzdGFydCwgaGFuZGxlZCBieSB0aGUgYmxvY2sgZHJhZyBwbHVnaW4gb2YgQXRlQmxvY2tDb250cm9sc0V4dGVuc2lvblxuICAgIGNvbnN0IHBtRXZlbnQgPSBuZXcgRHJhZ0V2ZW50KFwiZHJhZ3N0YXJ0XCIsIHtcbiAgICAgIGRhdGFUcmFuc2ZlcjogZXZlbnQuZGF0YVRyYW5zZmVyLFxuICAgICAgYnViYmxlczogdHJ1ZSxcbiAgICAgIGNhbmNlbGFibGU6IHRydWUsXG4gICAgfSk7XG4gICAgZWxlbWVudC5kaXNwYXRjaEV2ZW50KHBtRXZlbnQpO1xuXG4gICAgLy8gNC4gQ2xlYW51cCBVSVxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWRlVGlwcHkoKTtcbiAgICAgIHRoaXMuaXNJbnRlcmFjdGluZy5zZXQoZmFsc2UpO1xuICAgIH0sIDApO1xuICB9XG5cbiAgb25EcmFnRW5kKCkge1xuICAgIGNvbnN0IGVkID0gdGhpcy5lZGl0b3IoKTtcbiAgICBpZiAoIWVkLmlzRGVzdHJveWVkKSB7XG4gICAgICBlbmRBdGVCbG9ja0RyYWcoZWQudmlldyk7XG4gICAgfVxuICAgIHRoaXMuaXNJbnRlcmFjdGluZy5zZXQoZmFsc2UpO1xuICB9XG59XG4iXX0=