@rocketshow/designer 1.40.0 → 1.44.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. package/fesm2022/rocketshow-designer.mjs +1389 -1148
  2. package/fesm2022/rocketshow-designer.mjs.map +1 -1
  3. package/index.d.ts +1676 -5
  4. package/package.json +2 -4
  5. package/rocketshow-designer-1.44.0.tgz +0 -0
  6. package/esm2022/lib/array-sort-pipe.mjs +0 -30
  7. package/esm2022/lib/designer.component.mjs +0 -672
  8. package/esm2022/lib/designer.module.mjs +0 -186
  9. package/esm2022/lib/designer.service.mjs +0 -14
  10. package/esm2022/lib/dropzone/dropzone.component.mjs +0 -93
  11. package/esm2022/lib/effect/effect-curve/effect-curve.component.mjs +0 -577
  12. package/esm2022/lib/effect/effect-pan-tilt/effect-pan-tilt.component.mjs +0 -36
  13. package/esm2022/lib/effect/effect.component.mjs +0 -174
  14. package/esm2022/lib/error-dialog/error-dialog.component.mjs +0 -75
  15. package/esm2022/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.mjs +0 -370
  16. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.mjs +0 -147
  17. package/esm2022/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.mjs +0 -213
  18. package/esm2022/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.mjs +0 -78
  19. package/esm2022/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.mjs +0 -119
  20. package/esm2022/lib/fixture/fixture-capability/fixture-capability.component.mjs +0 -191
  21. package/esm2022/lib/fixture/fixture-channel/fixture-channel.component.mjs +0 -162
  22. package/esm2022/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.mjs +0 -365
  23. package/esm2022/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.mjs +0 -151
  24. package/esm2022/lib/fixture/fixture-settings/fixture-settings.component.mjs +0 -46
  25. package/esm2022/lib/fixture/fixture.component.mjs +0 -148
  26. package/esm2022/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.mjs +0 -145
  27. package/esm2022/lib/fixture-pool/fixture-pool.component.mjs +0 -641
  28. package/esm2022/lib/intro/intro.component.mjs +0 -95
  29. package/esm2022/lib/master-dimmer/master-dimmer.component.mjs +0 -66
  30. package/esm2022/lib/models/cached-fixture-capability.mjs +0 -9
  31. package/esm2022/lib/models/cached-fixture-channel.mjs +0 -7
  32. package/esm2022/lib/models/cached-fixture.mjs +0 -6
  33. package/esm2022/lib/models/color.mjs +0 -8
  34. package/esm2022/lib/models/composition.mjs +0 -46
  35. package/esm2022/lib/models/effect-curve-profile-channel.mjs +0 -15
  36. package/esm2022/lib/models/effect-curve.mjs +0 -69
  37. package/esm2022/lib/models/effect-pan-tilt.mjs +0 -19
  38. package/esm2022/lib/models/effect.mjs +0 -12
  39. package/esm2022/lib/models/fixture-capability-value.mjs +0 -15
  40. package/esm2022/lib/models/fixture-capability.mjs +0 -127
  41. package/esm2022/lib/models/fixture-channel-value.mjs +0 -11
  42. package/esm2022/lib/models/fixture-channel.mjs +0 -24
  43. package/esm2022/lib/models/fixture-matrix-pixel-group-constraints.mjs +0 -27
  44. package/esm2022/lib/models/fixture-matrix-pixel-group.mjs +0 -12
  45. package/esm2022/lib/models/fixture-matrix.mjs +0 -25
  46. package/esm2022/lib/models/fixture-mode-channel.mjs +0 -26
  47. package/esm2022/lib/models/fixture-mode.mjs +0 -17
  48. package/esm2022/lib/models/fixture-physical.mjs +0 -14
  49. package/esm2022/lib/models/fixture-profile.mjs +0 -85
  50. package/esm2022/lib/models/fixture-wheel-slot.mjs +0 -26
  51. package/esm2022/lib/models/fixture-wheel.mjs +0 -15
  52. package/esm2022/lib/models/fixture.mjs +0 -40
  53. package/esm2022/lib/models/preset-fixture.mjs +0 -10
  54. package/esm2022/lib/models/preset-region-scene.mjs +0 -8
  55. package/esm2022/lib/models/preset.mjs +0 -65
  56. package/esm2022/lib/models/project.mjs +0 -78
  57. package/esm2022/lib/models/scene-playback-region.mjs +0 -11
  58. package/esm2022/lib/models/scene.mjs +0 -27
  59. package/esm2022/lib/preset/preset-settings/preset-settings.component.mjs +0 -194
  60. package/esm2022/lib/preset/preset.component.mjs +0 -131
  61. package/esm2022/lib/preview/models/color-changer-3d.mjs +0 -52
  62. package/esm2022/lib/preview/models/fixture-3d.mjs +0 -260
  63. package/esm2022/lib/preview/models/moving-head-3d.mjs +0 -115
  64. package/esm2022/lib/preview/preview.component.mjs +0 -216
  65. package/esm2022/lib/project/project-browser/project-browser.component.mjs +0 -143
  66. package/esm2022/lib/project/project-import/project-import.component.mjs +0 -107
  67. package/esm2022/lib/project/project-save/project-save.component.mjs +0 -178
  68. package/esm2022/lib/project/project-share/project-share.component.mjs +0 -71
  69. package/esm2022/lib/scene/scene-settings/scene-settings.component.mjs +0 -146
  70. package/esm2022/lib/scene/scene.component.mjs +0 -110
  71. package/esm2022/lib/services/animation.service.mjs +0 -16
  72. package/esm2022/lib/services/config.service.mjs +0 -28
  73. package/esm2022/lib/services/effect.service.mjs +0 -14
  74. package/esm2022/lib/services/error-dialog.service.mjs +0 -39
  75. package/esm2022/lib/services/fixture-pool.service.mjs +0 -30
  76. package/esm2022/lib/services/fixture.service.mjs +0 -699
  77. package/esm2022/lib/services/hotkey-target-exclude.service.mjs +0 -24
  78. package/esm2022/lib/services/intro.service.mjs +0 -140
  79. package/esm2022/lib/services/preset.service.mjs +0 -450
  80. package/esm2022/lib/services/preview-mesh.service.mjs +0 -57
  81. package/esm2022/lib/services/preview.service.mjs +0 -481
  82. package/esm2022/lib/services/project-load.service.mjs +0 -206
  83. package/esm2022/lib/services/project.service.mjs +0 -93
  84. package/esm2022/lib/services/scene.service.mjs +0 -164
  85. package/esm2022/lib/services/timeline.service.mjs +0 -726
  86. package/esm2022/lib/services/user-ensure-login.service.mjs +0 -38
  87. package/esm2022/lib/services/user.service.mjs +0 -89
  88. package/esm2022/lib/services/uuid.service.mjs +0 -23
  89. package/esm2022/lib/services/warning-dialog.service.mjs +0 -38
  90. package/esm2022/lib/timeline/composition-settings/composition-settings.component.mjs +0 -304
  91. package/esm2022/lib/timeline/timeline-grid/timeline-grid.component.mjs +0 -216
  92. package/esm2022/lib/timeline/timeline.component.mjs +0 -418
  93. package/esm2022/lib/user/user-login/user-login.component.mjs +0 -144
  94. package/esm2022/lib/user/user-register/user-register.component.mjs +0 -220
  95. package/esm2022/lib/wait-dialog/wait-dialog.component.mjs +0 -26
  96. package/esm2022/lib/warning-dialog/warning-dialog.component.mjs +0 -68
  97. package/esm2022/public_api.mjs +0 -7
  98. package/esm2022/rocketshow-designer.mjs +0 -5
  99. package/lib/array-sort-pipe.d.ts +0 -7
  100. package/lib/designer.component.d.ts +0 -73
  101. package/lib/designer.module.d.ts +0 -57
  102. package/lib/designer.service.d.ts +0 -6
  103. package/lib/dropzone/dropzone.component.d.ts +0 -24
  104. package/lib/effect/effect-curve/effect-curve.component.d.ts +0 -59
  105. package/lib/effect/effect-pan-tilt/effect-pan-tilt.component.d.ts +0 -15
  106. package/lib/effect/effect.component.d.ts +0 -22
  107. package/lib/error-dialog/error-dialog.component.d.ts +0 -17
  108. package/lib/fixture/fixture-capability/fixture-capability-channel/fixture-capability-channel.component.d.ts +0 -41
  109. package/lib/fixture/fixture-capability/fixture-capability-color/fixture-capability-color.component.d.ts +0 -26
  110. package/lib/fixture/fixture-capability/fixture-capability-color-wheel/fixture-capability-color-wheel.component.d.ts +0 -34
  111. package/lib/fixture/fixture-capability/fixture-capability-dimmer/fixture-capability-dimmer.component.d.ts +0 -15
  112. package/lib/fixture/fixture-capability/fixture-capability-pan-tilt/fixture-capability-pan-tilt.component.d.ts +0 -18
  113. package/lib/fixture/fixture-capability/fixture-capability.component.d.ts +0 -31
  114. package/lib/fixture/fixture-channel/fixture-channel.component.d.ts +0 -25
  115. package/lib/fixture/fixture-settings/fixture-settings-position/fixture-settings-position.component.d.ts +0 -32
  116. package/lib/fixture/fixture-settings/fixture-settings-stage/fixture-settings-stage.component.d.ts +0 -14
  117. package/lib/fixture/fixture-settings/fixture-settings.component.d.ts +0 -14
  118. package/lib/fixture/fixture.component.d.ts +0 -25
  119. package/lib/fixture-pool/fixture-pool-create-from-file/fixture-pool-create-from-file.component.d.ts +0 -28
  120. package/lib/fixture-pool/fixture-pool.component.d.ts +0 -62
  121. package/lib/intro/intro.component.d.ts +0 -11
  122. package/lib/master-dimmer/master-dimmer.component.d.ts +0 -15
  123. package/lib/models/cached-fixture-capability.d.ts +0 -11
  124. package/lib/models/cached-fixture-channel.d.ts +0 -11
  125. package/lib/models/cached-fixture.d.ts +0 -11
  126. package/lib/models/color.d.ts +0 -6
  127. package/lib/models/composition.d.ts +0 -19
  128. package/lib/models/effect-curve-profile-channel.d.ts +0 -5
  129. package/lib/models/effect-curve.d.ts +0 -15
  130. package/lib/models/effect-pan-tilt.d.ts +0 -6
  131. package/lib/models/effect.d.ts +0 -6
  132. package/lib/models/fixture-capability-value.d.ts +0 -10
  133. package/lib/models/fixture-capability.d.ts +0 -117
  134. package/lib/models/fixture-channel-value.d.ts +0 -6
  135. package/lib/models/fixture-channel.d.ts +0 -9
  136. package/lib/models/fixture-matrix-pixel-group-constraints.d.ts +0 -8
  137. package/lib/models/fixture-matrix-pixel-group.d.ts +0 -6
  138. package/lib/models/fixture-matrix.d.ts +0 -6
  139. package/lib/models/fixture-mode-channel.d.ts +0 -8
  140. package/lib/models/fixture-mode.d.ts +0 -8
  141. package/lib/models/fixture-physical.d.ts +0 -4
  142. package/lib/models/fixture-profile.d.ts +0 -39
  143. package/lib/models/fixture-wheel-slot.d.ts +0 -17
  144. package/lib/models/fixture-wheel.d.ts +0 -5
  145. package/lib/models/fixture.d.ts +0 -23
  146. package/lib/models/preset-fixture.d.ts +0 -5
  147. package/lib/models/preset-region-scene.d.ts +0 -9
  148. package/lib/models/preset.d.ts +0 -20
  149. package/lib/models/project.d.ts +0 -31
  150. package/lib/models/scene-playback-region.d.ts +0 -6
  151. package/lib/models/scene.d.ts +0 -11
  152. package/lib/preset/preset-settings/preset-settings.component.d.ts +0 -22
  153. package/lib/preset/preset.component.d.ts +0 -25
  154. package/lib/preview/models/color-changer-3d.d.ts +0 -16
  155. package/lib/preview/models/fixture-3d.d.ts +0 -38
  156. package/lib/preview/models/moving-head-3d.d.ts +0 -23
  157. package/lib/preview/preview.component.d.ts +0 -38
  158. package/lib/project/project-browser/project-browser.component.d.ts +0 -27
  159. package/lib/project/project-import/project-import.component.d.ts +0 -23
  160. package/lib/project/project-save/project-save.component.d.ts +0 -28
  161. package/lib/project/project-share/project-share.component.d.ts +0 -16
  162. package/lib/scene/scene-settings/scene-settings.component.d.ts +0 -20
  163. package/lib/scene/scene.component.d.ts +0 -22
  164. package/lib/services/animation.service.d.ts +0 -7
  165. package/lib/services/config.service.d.ts +0 -20
  166. package/lib/services/effect.service.d.ts +0 -8
  167. package/lib/services/error-dialog.service.d.ts +0 -12
  168. package/lib/services/fixture-pool.service.d.ts +0 -10
  169. package/lib/services/fixture.service.d.ts +0 -70
  170. package/lib/services/hotkey-target-exclude.service.d.ts +0 -7
  171. package/lib/services/intro.service.d.ts +0 -21
  172. package/lib/services/preset.service.d.ts +0 -64
  173. package/lib/services/preview-mesh.service.d.ts +0 -14
  174. package/lib/services/preview.service.d.ts +0 -42
  175. package/lib/services/project-load.service.d.ts +0 -36
  176. package/lib/services/project.service.d.ts +0 -26
  177. package/lib/services/scene.service.d.ts +0 -30
  178. package/lib/services/timeline.service.d.ts +0 -70
  179. package/lib/services/user-ensure-login.service.d.ts +0 -14
  180. package/lib/services/user.service.d.ts +0 -22
  181. package/lib/services/uuid.service.d.ts +0 -7
  182. package/lib/services/warning-dialog.service.d.ts +0 -12
  183. package/lib/timeline/composition-settings/composition-settings.component.d.ts +0 -48
  184. package/lib/timeline/timeline-grid/timeline-grid.component.d.ts +0 -22
  185. package/lib/timeline/timeline.component.d.ts +0 -50
  186. package/lib/user/user-login/user-login.component.d.ts +0 -21
  187. package/lib/user/user-register/user-register.component.d.ts +0 -26
  188. package/lib/wait-dialog/wait-dialog.component.d.ts +0 -8
  189. package/lib/warning-dialog/warning-dialog.component.d.ts +0 -16
  190. package/public_api.d.ts +0 -3
  191. package/rocketshow-designer-1.40.0.tgz +0 -0
@@ -1,577 +0,0 @@
1
- import { Component, ElementRef, Input, ViewChild } from '@angular/core';
2
- import { TranslateService } from '@ngx-translate/core';
3
- import { timer } from 'rxjs';
4
- import { map } from 'rxjs/operators';
5
- import { EffectCurveProfileChannels } from '../../models/effect-curve-profile-channel';
6
- import { FixtureCapability, FixtureCapabilityColor, FixtureCapabilityType } from '../../models/fixture-capability';
7
- import { FixtureService } from '../../services/fixture.service';
8
- import { PresetService } from '../../services/preset.service';
9
- import { EffectCurve } from './../../models/effect-curve';
10
- import { AnimationService } from './../../services/animation.service';
11
- import * as i0 from "@angular/core";
12
- import * as i1 from "../../services/preset.service";
13
- import * as i2 from "./../../services/animation.service";
14
- import * as i3 from "../../services/fixture.service";
15
- import * as i4 from "@ngx-translate/core";
16
- import * as i5 from "@angular/common";
17
- import * as i6 from "@angular/forms";
18
- import * as i7 from "ngx-bootstrap-slider";
19
- import * as i8 from "ngx-bootstrap/popover";
20
- const _c0 = ["curveGrid"];
21
- function EffectCurveComponent_div_73_Template(rf, ctx) { if (rf & 1) {
22
- const _r2 = i0.ɵɵgetCurrentView();
23
- i0.ɵɵelementStart(0, "div", 29)(1, "input", 30);
24
- i0.ɵɵlistener("change", function EffectCurveComponent_div_73_Template_input_change_1_listener($event) { const capability_r3 = i0.ɵɵrestoreView(_r2).$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleCapability($event, capability_r3)); });
25
- i0.ɵɵelementEnd();
26
- i0.ɵɵelementStart(2, "label", 31);
27
- i0.ɵɵtext(3);
28
- i0.ɵɵpipe(4, "async");
29
- i0.ɵɵelementEnd()();
30
- } if (rf & 2) {
31
- const capability_r3 = ctx.$implicit;
32
- const i_r5 = ctx.index;
33
- const ctx_r3 = i0.ɵɵnextContext();
34
- i0.ɵɵadvance();
35
- i0.ɵɵpropertyInterpolate1("id", "capability_", (ctx_r3.curve == null ? null : ctx_r3.curve.uuid) + "_" + i_r5, "");
36
- i0.ɵɵproperty("ngModel", ctx_r3.capabilityChecked(capability_r3));
37
- i0.ɵɵadvance();
38
- i0.ɵɵpropertyInterpolate1("for", "capability_", (ctx_r3.curve == null ? null : ctx_r3.curve.uuid) + "_" + i_r5, "");
39
- i0.ɵɵadvance();
40
- i0.ɵɵtextInterpolate(i0.ɵɵpipeBind1(4, 6, ctx_r3.getCapabilityName(capability_r3)));
41
- } }
42
- function EffectCurveComponent_div_75_div_1_Template(rf, ctx) { if (rf & 1) {
43
- const _r6 = i0.ɵɵgetCurrentView();
44
- i0.ɵɵelementStart(0, "div", 29)(1, "input", 30);
45
- i0.ɵɵlistener("change", function EffectCurveComponent_div_75_div_1_Template_input_change_1_listener($event) { const profile_r7 = i0.ɵɵrestoreView(_r6).$implicit; const ctx_r3 = i0.ɵɵnextContext(2); return i0.ɵɵresetView(ctx_r3.changeProfileSelection($event, profile_r7)); });
46
- i0.ɵɵelementEnd();
47
- i0.ɵɵelementStart(2, "label", 31);
48
- i0.ɵɵtext(3);
49
- i0.ɵɵelementEnd()();
50
- } if (rf & 2) {
51
- const profile_r7 = ctx.$implicit;
52
- const ctx_r3 = i0.ɵɵnextContext(2);
53
- i0.ɵɵadvance();
54
- i0.ɵɵpropertyInterpolate2("id", "channel_profile_", ctx_r3.curve == null ? null : ctx_r3.curve.uuid, "_", profile_r7.uuid, "");
55
- i0.ɵɵproperty("ngModel", ctx_r3.selectedProfiles.indexOf(profile_r7) >= 0);
56
- i0.ɵɵadvance();
57
- i0.ɵɵpropertyInterpolate2("for", "channel_profile_", ctx_r3.curve == null ? null : ctx_r3.curve.uuid, "_", profile_r7.uuid, "");
58
- i0.ɵɵadvance();
59
- i0.ɵɵtextInterpolate(profile_r7.name);
60
- } }
61
- function EffectCurveComponent_div_75_Template(rf, ctx) { if (rf & 1) {
62
- i0.ɵɵelementStart(0, "div");
63
- i0.ɵɵtemplate(1, EffectCurveComponent_div_75_div_1_Template, 4, 8, "div", 25);
64
- i0.ɵɵelement(2, "hr", 32);
65
- i0.ɵɵelementEnd();
66
- } if (rf & 2) {
67
- const ctx_r3 = i0.ɵɵnextContext();
68
- i0.ɵɵadvance();
69
- i0.ɵɵproperty("ngForOf", ctx_r3.availableProfiles);
70
- } }
71
- function EffectCurveComponent_ng_container_76_div_1_Template(rf, ctx) { if (rf & 1) {
72
- const _r8 = i0.ɵɵgetCurrentView();
73
- i0.ɵɵelementStart(0, "div", 29)(1, "input", 30);
74
- i0.ɵɵlistener("change", function EffectCurveComponent_ng_container_76_div_1_Template_input_change_1_listener($event) { const channel_r9 = i0.ɵɵrestoreView(_r8).$implicit; const entry_r10 = i0.ɵɵnextContext().$implicit; const ctx_r3 = i0.ɵɵnextContext(); return i0.ɵɵresetView(ctx_r3.toggleChannel($event, entry_r10.key, channel_r9)); });
75
- i0.ɵɵelementEnd();
76
- i0.ɵɵelementStart(2, "label", 31);
77
- i0.ɵɵtext(3);
78
- i0.ɵɵelementEnd()();
79
- } if (rf & 2) {
80
- const channel_r9 = ctx.$implicit;
81
- const j_r11 = ctx.index;
82
- const ctx_r11 = i0.ɵɵnextContext();
83
- const entry_r10 = ctx_r11.$implicit;
84
- const i_r13 = ctx_r11.index;
85
- const ctx_r3 = i0.ɵɵnextContext();
86
- i0.ɵɵadvance();
87
- i0.ɵɵpropertyInterpolate3("id", "channel_", ctx_r3.curve == null ? null : ctx_r3.curve.uuid, "_", i_r13, "_", j_r11, "");
88
- i0.ɵɵproperty("ngModel", ctx_r3.channelChecked(entry_r10.key, channel_r9));
89
- i0.ɵɵadvance();
90
- i0.ɵɵpropertyInterpolate3("for", "channel_", ctx_r3.curve == null ? null : ctx_r3.curve.uuid, "_", i_r13, "_", j_r11, "");
91
- i0.ɵɵadvance();
92
- i0.ɵɵtextInterpolate(ctx_r3.getChannelName(entry_r10.key.name, channel_r9.name));
93
- } }
94
- function EffectCurveComponent_ng_container_76_Template(rf, ctx) { if (rf & 1) {
95
- i0.ɵɵelementContainerStart(0);
96
- i0.ɵɵtemplate(1, EffectCurveComponent_ng_container_76_div_1_Template, 4, 10, "div", 25);
97
- i0.ɵɵelementContainerEnd();
98
- } if (rf & 2) {
99
- const entry_r10 = ctx.$implicit;
100
- i0.ɵɵadvance();
101
- i0.ɵɵproperty("ngForOf", entry_r10.value);
102
- } }
103
- export class EffectCurveComponent {
104
- // whether the effect is currently being edited (open) or not
105
- set isSelected(value) {
106
- if (value) {
107
- // start the update timer
108
- if (!this.gridUpdateSubscription) {
109
- this.gridUpdateSubscription = timer(0, 15).subscribe(() => {
110
- this.redraw();
111
- });
112
- }
113
- }
114
- else {
115
- // stop the update timer
116
- if (this.gridUpdateSubscription) {
117
- this.gridUpdateSubscription.unsubscribe();
118
- this.gridUpdateSubscription = undefined;
119
- }
120
- }
121
- }
122
- constructor(presetService, animationService, fixtureService, translate) {
123
- this.presetService = presetService;
124
- this.animationService = animationService;
125
- this.fixtureService = fixtureService;
126
- this.translate = translate;
127
- this.lengthMillisMin = 20;
128
- this.lengthMillisMax = 8000;
129
- this.amplitudeMin = 0;
130
- this.amplitudeMax = 4;
131
- this.percentageMin = 0;
132
- this.percentageMax = 1;
133
- this.phaseMillisMin = -1000;
134
- this.phaseMillisMax = 1000;
135
- this.phasingMillisMin = 0;
136
- this.phasingMillisMax = 1000;
137
- // the selected capabilities
138
- this.availableCapabilities = [];
139
- // the selected channels
140
- this.availableChannels = new Map();
141
- this.availableProfiles = [];
142
- this.selectedProfiles = [];
143
- this.presetService.fixtureSelectionChanged.subscribe(() => {
144
- this.updateCapabilitiesAndChannels();
145
- });
146
- this.updateCapabilitiesAndChannels();
147
- }
148
- ngOnInit() {
149
- const canvas = this.curveGrid.nativeElement;
150
- this.ctx = canvas.getContext('2d');
151
- this.maxWidth = canvas.width;
152
- this.maxHeight = canvas.height;
153
- this.redraw();
154
- }
155
- drawCurrentValue(currMillis, radius, lineWidth, durationMillis, maxHeight) {
156
- const currVal = 1 - this.curve.getValueAtMillis(currMillis);
157
- const x = (this.maxWidth * (currMillis % durationMillis)) / durationMillis;
158
- const y = maxHeight * currVal + lineWidth;
159
- this.ctx.beginPath();
160
- this.ctx.arc(x, y, radius, 0, 2 * Math.PI, false);
161
- this.ctx.fillStyle = '#fff';
162
- this.ctx.fill();
163
- this.ctx.lineWidth = 1;
164
- this.ctx.strokeStyle = '#000';
165
- this.ctx.stroke();
166
- }
167
- getPhasingCount() {
168
- let count = 0;
169
- const countedFirstDmxChannelPixelKey = [];
170
- for (const presetFixture of this.presetService.selectedPreset.fixtures) {
171
- const fixture = this.fixtureService.getFixtureByUuid(presetFixture.fixtureUuid);
172
- const firstDmxChannelAndFixtureUuid = {
173
- firstDmxChannel: fixture.dmxFirstChannel,
174
- pixelKey: presetFixture.pixelKey,
175
- };
176
- const exists = countedFirstDmxChannelPixelKey.some((item) => item.firstDmxChannel === firstDmxChannelAndFixtureUuid.firstDmxChannel &&
177
- ((!item.pixelKey && !firstDmxChannelAndFixtureUuid.pixelKey) || item.pixelKey === firstDmxChannelAndFixtureUuid.pixelKey));
178
- // don't count it, if it has the same DMX address and pixel key (if available),
179
- // as an already counted one
180
- if (!exists) {
181
- count++;
182
- countedFirstDmxChannelPixelKey.push(firstDmxChannelAndFixtureUuid);
183
- }
184
- }
185
- return count;
186
- }
187
- redraw() {
188
- this.ctx.clearRect(0, 0, this.maxWidth, this.maxHeight);
189
- this.ctx.fillStyle = '#fff';
190
- this.ctx.strokeStyle = '#fff';
191
- // the width of the lines
192
- const width = 3;
193
- this.ctx.lineWidth = width;
194
- let oldX;
195
- let oldY;
196
- let step = 50;
197
- if (length < 500) {
198
- step = 5;
199
- }
200
- const durationMillis = this.curve.lengthMillis * Math.max(Math.round(4 - this.curve.lengthMillis / 1000), 1);
201
- const maxHeight = this.maxHeight - width * 2;
202
- // draw the curve
203
- for (let i = -step * 2; i < durationMillis + step * 2; i += step) {
204
- const val = 1 - this.curve.getValueAtMillis(i);
205
- // Scale the values to the grid dimensions
206
- const x = (this.maxWidth * i) / durationMillis;
207
- const y = maxHeight * val + width;
208
- if (oldY) {
209
- this.ctx.beginPath();
210
- this.ctx.moveTo(oldX, oldY);
211
- this.ctx.lineTo(x, y);
212
- this.ctx.stroke();
213
- }
214
- oldX = x;
215
- oldY = y;
216
- }
217
- // draw the current value
218
- this.drawCurrentValue(this.animationService.timeMillis % durationMillis, 5, width, durationMillis, maxHeight);
219
- // draw the phasing values (chase), if required
220
- let phasingCount = 0;
221
- if (this.curve.phasingMillis > 0 && this.presetService.selectedPreset) {
222
- phasingCount = this.getPhasingCount();
223
- }
224
- for (let i = 1; i < phasingCount; i++) {
225
- this.drawCurrentValue((this.animationService.timeMillis - i * this.curve.phasingMillis) % durationMillis, 3, width, durationMillis, maxHeight);
226
- }
227
- }
228
- calculateChannelCapabilities() {
229
- this.availableChannels = this.presetService.getSelectedProfileChannels(this.selectedProfiles);
230
- }
231
- changeProfileSelection($event, profile) {
232
- if (this.selectedProfiles.indexOf(profile) >= 0) {
233
- this.selectedProfiles.splice(this.selectedProfiles.indexOf(profile), 1);
234
- }
235
- else {
236
- this.selectedProfiles.push(profile);
237
- }
238
- this.calculateChannelCapabilities();
239
- }
240
- updateCapabilitiesAndChannels() {
241
- // capabilities
242
- this.availableCapabilities = [];
243
- if (this.presetService.hasCapabilityDimmer()) {
244
- const capability = new FixtureCapability();
245
- capability.type = FixtureCapabilityType.Intensity;
246
- this.availableCapabilities.push(capability);
247
- }
248
- if (this.presetService.hasCapabilityColor()) {
249
- let capability = new FixtureCapability();
250
- capability.type = FixtureCapabilityType.ColorIntensity;
251
- capability.color = FixtureCapabilityColor.Red;
252
- this.availableCapabilities.push(capability);
253
- capability = new FixtureCapability();
254
- capability.type = FixtureCapabilityType.ColorIntensity;
255
- capability.color = FixtureCapabilityColor.Green;
256
- this.availableCapabilities.push(capability);
257
- capability = new FixtureCapability();
258
- capability.type = FixtureCapabilityType.ColorIntensity;
259
- capability.color = FixtureCapabilityColor.Blue;
260
- this.availableCapabilities.push(capability);
261
- }
262
- if (this.presetService.hasCapabilityPanTilt()) {
263
- let capability = new FixtureCapability();
264
- capability.type = FixtureCapabilityType.Pan;
265
- this.availableCapabilities.push(capability);
266
- capability = new FixtureCapability();
267
- capability.type = FixtureCapabilityType.Tilt;
268
- this.availableCapabilities.push(capability);
269
- }
270
- // calculate all profiles
271
- this.availableProfiles = this.presetService.getSelectedProfiles();
272
- // select all profiles by default
273
- this.selectedProfiles = [...this.availableProfiles];
274
- // calculate all channels
275
- this.calculateChannelCapabilities();
276
- }
277
- getCapabilityName(capability) {
278
- return this.translate
279
- .get(['designer.fixtureCapabilityType.' + capability.type, 'designer.fixtureCapabilityColor.' + capability.color])
280
- .pipe(map((result) => {
281
- let name = '';
282
- name += result['designer.fixtureCapabilityType.' + capability.type];
283
- if (capability.color) {
284
- name += ', ' + result['designer.fixtureCapabilityColor.' + capability.color];
285
- }
286
- else {
287
- return name;
288
- }
289
- return name;
290
- }));
291
- }
292
- capabilityChecked(capability) {
293
- for (const existingCapability of this.curve.capabilities) {
294
- if (this.fixtureService.capabilitiesMatch(existingCapability.type, capability.type, existingCapability.color, capability.color, null, null, null, null)) {
295
- return true;
296
- }
297
- }
298
- return false;
299
- }
300
- toggleCapability(event, capability) {
301
- if (event.currentTarget.checked) {
302
- // add the capability
303
- this.curve.capabilities.push(capability);
304
- }
305
- else {
306
- // Remove the channel
307
- for (let i = 0; i < this.curve.capabilities.length; i++) {
308
- const existingCapability = this.curve.capabilities[i];
309
- if (this.fixtureService.capabilitiesMatch(existingCapability.type, capability.type, existingCapability.color, capability.color, null, null, null, null)) {
310
- this.curve.capabilities.splice(i, 1);
311
- }
312
- }
313
- }
314
- this.presetService.previewLive();
315
- }
316
- getChannelName(profileName, channelName) {
317
- if (this.availableProfiles.length > 1) {
318
- return profileName + ' - ' + channelName;
319
- }
320
- return channelName;
321
- }
322
- channelChecked(profile, channel) {
323
- for (const profileChannels of this.curve.channels) {
324
- if (profileChannels.profileUuid === profile.uuid) {
325
- if (profileChannels.channels.includes(channel.name)) {
326
- return true;
327
- }
328
- break;
329
- }
330
- }
331
- return false;
332
- }
333
- toggleChannel(event, profile, channel) {
334
- // add the profile, if necessary
335
- let profileContained = false;
336
- for (const profileChannels of this.curve.channels) {
337
- if (profileChannels.profileUuid === profile.uuid) {
338
- profileContained = true;
339
- break;
340
- }
341
- }
342
- if (!profileContained) {
343
- const profileChannels = new EffectCurveProfileChannels();
344
- profileChannels.profileUuid = profile.uuid;
345
- this.curve.channels.push(profileChannels);
346
- }
347
- // add or delete the channel
348
- for (const profileChannels of this.curve.channels) {
349
- if (profileChannels.profileUuid === profile.uuid) {
350
- const index = profileChannels.channels.indexOf(channel.name);
351
- if (index >= 0) {
352
- profileChannels.channels.splice(index, 1);
353
- }
354
- else {
355
- profileChannels.channels.push(channel.name);
356
- }
357
- break;
358
- }
359
- }
360
- this.presetService.previewLive();
361
- }
362
- setLengthMillis(value) {
363
- if (!isNaN(value) && value >= this.lengthMillisMin && value <= this.lengthMillisMax) {
364
- this.curve.lengthMillis = +value;
365
- this.presetService.previewLive();
366
- }
367
- }
368
- setAmplitude(value) {
369
- if (!isNaN(value) && value >= this.amplitudeMin && value <= this.amplitudeMax) {
370
- this.curve.amplitude = +value;
371
- this.presetService.previewLive();
372
- }
373
- }
374
- setPosition(value) {
375
- if (!isNaN(value) && value >= this.percentageMin && value <= this.percentageMax) {
376
- this.curve.position = +value;
377
- this.presetService.previewLive();
378
- }
379
- }
380
- setPhaseMillis(value) {
381
- if (!isNaN(value) && value >= this.phaseMillisMin && value <= this.phaseMillisMax) {
382
- this.curve.phaseMillis = +value;
383
- this.presetService.previewLive();
384
- }
385
- }
386
- setPhasingMillis(value) {
387
- if (!isNaN(value) && value >= this.phasingMillisMin && value <= this.phasingMillisMax) {
388
- this.curve.phasingMillis = +value;
389
- this.presetService.previewLive();
390
- }
391
- }
392
- static { this.ɵfac = function EffectCurveComponent_Factory(t) { return new (t || EffectCurveComponent)(i0.ɵɵdirectiveInject(i1.PresetService), i0.ɵɵdirectiveInject(i2.AnimationService), i0.ɵɵdirectiveInject(i3.FixtureService), i0.ɵɵdirectiveInject(i4.TranslateService)); }; }
393
- static { this.ɵcmp = /*@__PURE__*/ i0.ɵɵdefineComponent({ type: EffectCurveComponent, selectors: [["lib-app-effect-curve"]], viewQuery: function EffectCurveComponent_Query(rf, ctx) { if (rf & 1) {
394
- i0.ɵɵviewQuery(_c0, 7);
395
- } if (rf & 2) {
396
- let _t;
397
- i0.ɵɵqueryRefresh(_t = i0.ɵɵloadQuery()) && (ctx.curveGrid = _t.first);
398
- } }, inputs: { curve: "curve", isSelected: "isSelected" }, decls: 78, vars: 83, consts: [["curveGrid", ""], [1, "mr-3", 2, "float", "left"], [1, "mb-2"], [2, "width", "200px", "height", "20px", 3, "ngModelChange", "ngModel"], [3, "value"], ["width", "200", "height", "100", "viewBox", "150 -75 4850 5150", "preserveAspectRatio", "none", 1, "curve-grid"], [1, "mr-4", 2, "float", "left"], [1, "d-flex"], [1, "my-auto", 2, "width", "100px", "float", "left"], [1, "my-auto", 2, "float", "left"], [2, "width", "80px", 3, "change", "valueChange", "value", "tooltip", "value", "min", "max", "step"], [1, "my-auto"], ["type", "text", 1, "slider-input", 3, "ngModelChange", "ngModel"], [1, "my-auto", "ml-1"], [2, "width", "80px", 3, "change", "valueChange", "value", "tooltip", "min", "max", "step"], [2, "width", "80px", "height", "18px", 3, "change", "valueChange", "value", "tooltip", "min", "max", "step"], [1, "col", "col-auto", "p-0", 2, "margin-right", "1px", "width", "50px", "float", "left"], ["id", "v-pills-tab", "role", "tablist", "aria-orientation", "vertical", 1, "nav", "flex-column", "nav-pills"], ["id", "v-pills-effect-capabilities-tab", "container", "body", "placement", "right", "triggers", "mouseenter:mouseleave", "data-toggle", "pill", "role", "tab", "aria-controls", "v-pills-capabilities", "aria-selected", "true", 1, "nav-link", "px-3", "active", 3, "popover", "href"], ["aria-hidden", "true", 1, "fa", "fa-bolt", "fa-fw"], ["id", "v-pills-effect-channels-tab", "container", "body", "placement", "right", "triggers", "mouseenter:mouseleave", "data-toggle", "pill", "role", "tab", "aria-controls", "v-pills-channels", "aria-selected", "false", 1, "nav-link", "px-3", 3, "popover", "href"], ["aria-hidden", "true", 1, "fa", "fa-sliders", "fa-fw"], [1, "applying-to"], ["id", "v-pills-tabContent", 1, "tab-content", "h-100"], ["role", "tabpanel", 1, "tab-pane", "h-100", "show", "active", 3, "id"], ["class", "form-check", 4, "ngFor", "ngForOf"], ["role", "tabpanel", 1, "tab-pane", "h-100", "show", 3, "id"], [4, "ngIf"], [4, "ngFor", "ngForOf"], [1, "form-check"], ["type", "checkbox", 1, "form-check-input", 3, "change", "id", "ngModel"], [1, "form-check-label", 3, "for"], [1, "my-1", 2, "border-color", "white"]], template: function EffectCurveComponent_Template(rf, ctx) { if (rf & 1) {
399
- const _r1 = i0.ɵɵgetCurrentView();
400
- i0.ɵɵelementStart(0, "div", 1)(1, "div", 2)(2, "select", 3);
401
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_select_ngModelChange_2_listener($event) { i0.ɵɵrestoreView(_r1); ctx.curve.curveType = $event; return i0.ɵɵresetView(ctx.presetService.previewLive()); });
402
- i0.ɵɵelementStart(3, "option", 4);
403
- i0.ɵɵtext(4);
404
- i0.ɵɵpipe(5, "translate");
405
- i0.ɵɵelementEnd();
406
- i0.ɵɵelementStart(6, "option", 4);
407
- i0.ɵɵtext(7);
408
- i0.ɵɵpipe(8, "translate");
409
- i0.ɵɵelementEnd()()();
410
- i0.ɵɵelementStart(9, "div");
411
- i0.ɵɵelement(10, "canvas", 5, 0);
412
- i0.ɵɵelementEnd()();
413
- i0.ɵɵelementStart(12, "div", 6)(13, "div", 7)(14, "div", 8);
414
- i0.ɵɵtext(15);
415
- i0.ɵɵpipe(16, "translate");
416
- i0.ɵɵelementEnd();
417
- i0.ɵɵelementStart(17, "div", 9)(18, "mv-slider", 10);
418
- i0.ɵɵlistener("change", function EffectCurveComponent_Template_mv_slider_change_18_listener() { i0.ɵɵrestoreView(_r1); ctx.redraw(); return i0.ɵɵresetView(ctx.presetService.previewLive()); });
419
- i0.ɵɵtwoWayListener("valueChange", function EffectCurveComponent_Template_mv_slider_valueChange_18_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.curve.lengthMillis, $event) || (ctx.curve.lengthMillis = $event); return i0.ɵɵresetView($event); });
420
- i0.ɵɵelementEnd()();
421
- i0.ɵɵelementStart(19, "div", 11)(20, "input", 12);
422
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_input_ngModelChange_20_listener($event) { i0.ɵɵrestoreView(_r1); ctx.setLengthMillis($event); return i0.ɵɵresetView(ctx.redraw()); });
423
- i0.ɵɵelementEnd()();
424
- i0.ɵɵelementStart(21, "div", 13);
425
- i0.ɵɵtext(22);
426
- i0.ɵɵpipe(23, "translate");
427
- i0.ɵɵelementEnd()();
428
- i0.ɵɵelementStart(24, "div", 7)(25, "div", 8);
429
- i0.ɵɵtext(26);
430
- i0.ɵɵpipe(27, "translate");
431
- i0.ɵɵelementEnd();
432
- i0.ɵɵelementStart(28, "div", 9)(29, "mv-slider", 14);
433
- i0.ɵɵlistener("change", function EffectCurveComponent_Template_mv_slider_change_29_listener() { i0.ɵɵrestoreView(_r1); ctx.redraw(); return i0.ɵɵresetView(ctx.presetService.previewLive()); });
434
- i0.ɵɵtwoWayListener("valueChange", function EffectCurveComponent_Template_mv_slider_valueChange_29_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.curve.amplitude, $event) || (ctx.curve.amplitude = $event); return i0.ɵɵresetView($event); });
435
- i0.ɵɵelementEnd()();
436
- i0.ɵɵelementStart(30, "div", 11)(31, "input", 12);
437
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_input_ngModelChange_31_listener($event) { i0.ɵɵrestoreView(_r1); ctx.setAmplitude($event); return i0.ɵɵresetView(ctx.redraw()); });
438
- i0.ɵɵelementEnd()()();
439
- i0.ɵɵelementStart(32, "div", 7)(33, "div", 8);
440
- i0.ɵɵtext(34);
441
- i0.ɵɵpipe(35, "translate");
442
- i0.ɵɵelementEnd();
443
- i0.ɵɵelementStart(36, "div", 9)(37, "mv-slider", 15);
444
- i0.ɵɵlistener("change", function EffectCurveComponent_Template_mv_slider_change_37_listener() { i0.ɵɵrestoreView(_r1); ctx.redraw(); return i0.ɵɵresetView(ctx.presetService.previewLive()); });
445
- i0.ɵɵtwoWayListener("valueChange", function EffectCurveComponent_Template_mv_slider_valueChange_37_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.curve.position, $event) || (ctx.curve.position = $event); return i0.ɵɵresetView($event); });
446
- i0.ɵɵelementEnd()();
447
- i0.ɵɵelementStart(38, "div", 11)(39, "input", 12);
448
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_input_ngModelChange_39_listener($event) { i0.ɵɵrestoreView(_r1); ctx.setPosition($event); return i0.ɵɵresetView(ctx.redraw()); });
449
- i0.ɵɵelementEnd()()();
450
- i0.ɵɵelementStart(40, "div", 7)(41, "div", 8);
451
- i0.ɵɵtext(42);
452
- i0.ɵɵpipe(43, "translate");
453
- i0.ɵɵelementEnd();
454
- i0.ɵɵelementStart(44, "div", 9)(45, "mv-slider", 15);
455
- i0.ɵɵlistener("change", function EffectCurveComponent_Template_mv_slider_change_45_listener() { i0.ɵɵrestoreView(_r1); ctx.redraw(); return i0.ɵɵresetView(ctx.presetService.previewLive()); });
456
- i0.ɵɵtwoWayListener("valueChange", function EffectCurveComponent_Template_mv_slider_valueChange_45_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.curve.phaseMillis, $event) || (ctx.curve.phaseMillis = $event); return i0.ɵɵresetView($event); });
457
- i0.ɵɵelementEnd()();
458
- i0.ɵɵelementStart(46, "div", 11)(47, "input", 12);
459
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_input_ngModelChange_47_listener($event) { i0.ɵɵrestoreView(_r1); ctx.setPhaseMillis($event); return i0.ɵɵresetView(ctx.redraw()); });
460
- i0.ɵɵelementEnd()();
461
- i0.ɵɵelementStart(48, "div", 13);
462
- i0.ɵɵtext(49);
463
- i0.ɵɵpipe(50, "translate");
464
- i0.ɵɵelementEnd()();
465
- i0.ɵɵelementStart(51, "div", 7)(52, "div", 8);
466
- i0.ɵɵtext(53);
467
- i0.ɵɵpipe(54, "translate");
468
- i0.ɵɵelementEnd();
469
- i0.ɵɵelementStart(55, "div", 9)(56, "mv-slider", 15);
470
- i0.ɵɵlistener("change", function EffectCurveComponent_Template_mv_slider_change_56_listener() { i0.ɵɵrestoreView(_r1); ctx.redraw(); return i0.ɵɵresetView(ctx.presetService.previewLive()); });
471
- i0.ɵɵtwoWayListener("valueChange", function EffectCurveComponent_Template_mv_slider_valueChange_56_listener($event) { i0.ɵɵrestoreView(_r1); i0.ɵɵtwoWayBindingSet(ctx.curve.phasingMillis, $event) || (ctx.curve.phasingMillis = $event); return i0.ɵɵresetView($event); });
472
- i0.ɵɵelementEnd()();
473
- i0.ɵɵelementStart(57, "div", 11)(58, "input", 12);
474
- i0.ɵɵlistener("ngModelChange", function EffectCurveComponent_Template_input_ngModelChange_58_listener($event) { i0.ɵɵrestoreView(_r1); ctx.setPhasingMillis($event); return i0.ɵɵresetView(ctx.redraw()); });
475
- i0.ɵɵelementEnd()();
476
- i0.ɵɵelementStart(59, "div", 13);
477
- i0.ɵɵtext(60);
478
- i0.ɵɵpipe(61, "translate");
479
- i0.ɵɵelementEnd()()();
480
- i0.ɵɵelementStart(62, "div", 16)(63, "div", 17)(64, "a", 18);
481
- i0.ɵɵpipe(65, "translate");
482
- i0.ɵɵelement(66, "i", 19);
483
- i0.ɵɵelementEnd();
484
- i0.ɵɵelementStart(67, "a", 20);
485
- i0.ɵɵpipe(68, "translate");
486
- i0.ɵɵelement(69, "i", 21);
487
- i0.ɵɵelementEnd()()();
488
- i0.ɵɵelementStart(70, "div", 22)(71, "div", 23)(72, "div", 24);
489
- i0.ɵɵtemplate(73, EffectCurveComponent_div_73_Template, 5, 8, "div", 25);
490
- i0.ɵɵelementEnd();
491
- i0.ɵɵelementStart(74, "div", 26);
492
- i0.ɵɵtemplate(75, EffectCurveComponent_div_75_Template, 3, 1, "div", 27)(76, EffectCurveComponent_ng_container_76_Template, 2, 1, "ng-container", 28);
493
- i0.ɵɵpipe(77, "keyvalue");
494
- i0.ɵɵelementEnd()()();
495
- } if (rf & 2) {
496
- i0.ɵɵadvance(2);
497
- i0.ɵɵproperty("ngModel", ctx.curve.curveType);
498
- i0.ɵɵadvance();
499
- i0.ɵɵproperty("value", "sine");
500
- i0.ɵɵadvance();
501
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(5, 57, "designer.effect.curve-sine"), " ");
502
- i0.ɵɵadvance(2);
503
- i0.ɵɵproperty("value", "square");
504
- i0.ɵɵadvance();
505
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(8, 59, "designer.effect.curve-square"), " ");
506
- i0.ɵɵadvance(8);
507
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(16, 61, "designer.effect.curve-length"), " ");
508
- i0.ɵɵadvance(3);
509
- i0.ɵɵtwoWayProperty("value", ctx.curve.lengthMillis);
510
- i0.ɵɵproperty("tooltip", "hide")("value", 0)("min", ctx.lengthMillisMin)("max", ctx.lengthMillisMax)("step", 1);
511
- i0.ɵɵadvance(2);
512
- i0.ɵɵproperty("ngModel", ctx.curve.lengthMillis);
513
- i0.ɵɵadvance(2);
514
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(23, 63, "designer.misc.ms"), " ");
515
- i0.ɵɵadvance(4);
516
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(27, 65, "designer.effect.curve-amplitude"), " ");
517
- i0.ɵɵadvance(3);
518
- i0.ɵɵtwoWayProperty("value", ctx.curve.amplitude);
519
- i0.ɵɵproperty("tooltip", "hide")("min", ctx.amplitudeMin)("max", ctx.amplitudeMax)("step", 0.01);
520
- i0.ɵɵadvance(2);
521
- i0.ɵɵproperty("ngModel", ctx.curve.amplitude);
522
- i0.ɵɵadvance(3);
523
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(35, 67, "designer.effect.curve-position"), " ");
524
- i0.ɵɵadvance(3);
525
- i0.ɵɵtwoWayProperty("value", ctx.curve.position);
526
- i0.ɵɵproperty("tooltip", "hide")("min", ctx.percentageMin)("max", ctx.percentageMax)("step", 0.01);
527
- i0.ɵɵadvance(2);
528
- i0.ɵɵproperty("ngModel", ctx.curve.position);
529
- i0.ɵɵadvance(3);
530
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(43, 69, "designer.effect.curve-phase"), " ");
531
- i0.ɵɵadvance(3);
532
- i0.ɵɵtwoWayProperty("value", ctx.curve.phaseMillis);
533
- i0.ɵɵproperty("tooltip", "hide")("min", ctx.phaseMillisMin)("max", ctx.phaseMillisMax)("step", 1);
534
- i0.ɵɵadvance(2);
535
- i0.ɵɵproperty("ngModel", ctx.curve.phaseMillis);
536
- i0.ɵɵadvance(2);
537
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(50, 71, "designer.misc.ms"), " ");
538
- i0.ɵɵadvance(4);
539
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(54, 73, "designer.effect.curve-chase"), " ");
540
- i0.ɵɵadvance(3);
541
- i0.ɵɵtwoWayProperty("value", ctx.curve.phasingMillis);
542
- i0.ɵɵproperty("tooltip", "hide")("min", ctx.phasingMillisMin)("max", ctx.phasingMillisMax)("step", 1);
543
- i0.ɵɵadvance(2);
544
- i0.ɵɵproperty("ngModel", ctx.curve.phasingMillis);
545
- i0.ɵɵadvance(2);
546
- i0.ɵɵtextInterpolate1(" ", i0.ɵɵpipeBind1(61, 75, "designer.misc.ms"), " ");
547
- i0.ɵɵadvance(4);
548
- i0.ɵɵpropertyInterpolate("popover", i0.ɵɵpipeBind1(65, 77, "designer.misc.capabilities"));
549
- i0.ɵɵpropertyInterpolate1("href", "#v-pills-effect-capabilities-", ctx.curve == null ? null : ctx.curve.uuid, "", i0.ɵɵsanitizeUrl);
550
- i0.ɵɵadvance(3);
551
- i0.ɵɵpropertyInterpolate("popover", i0.ɵɵpipeBind1(68, 79, "designer.misc.channels"));
552
- i0.ɵɵpropertyInterpolate1("href", "#v-pills-effect-channels-", ctx.curve == null ? null : ctx.curve.uuid, "", i0.ɵɵsanitizeUrl);
553
- i0.ɵɵadvance(5);
554
- i0.ɵɵpropertyInterpolate1("id", "v-pills-effect-capabilities-", ctx.curve == null ? null : ctx.curve.uuid, "");
555
- i0.ɵɵadvance();
556
- i0.ɵɵproperty("ngForOf", ctx.availableCapabilities);
557
- i0.ɵɵadvance();
558
- i0.ɵɵpropertyInterpolate1("id", "v-pills-effect-channels-", ctx.curve == null ? null : ctx.curve.uuid, "");
559
- i0.ɵɵadvance();
560
- i0.ɵɵproperty("ngIf", ctx.availableProfiles.length > 1);
561
- i0.ɵɵadvance();
562
- i0.ɵɵproperty("ngForOf", i0.ɵɵpipeBind1(77, 81, ctx.availableChannels));
563
- } }, dependencies: [i5.NgForOf, i5.NgIf, i6.NgSelectOption, i6.ɵNgSelectMultipleOption, i6.DefaultValueAccessor, i6.CheckboxControlValueAccessor, i6.SelectControlValueAccessor, i6.NgControlStatus, i6.NgModel, i7.SliderComponent, i8.PopoverDirective, i5.AsyncPipe, i5.KeyValuePipe, i4.TranslatePipe], styles: [".curve-grid[_ngcontent-%COMP%]{background-color:#000;border:1px solid white}.applying-to[_ngcontent-%COMP%]{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to[_ngcontent-%COMP%] .form-check[_ngcontent-%COMP%]:last-child{margin-bottom:.5rem}"] }); }
564
- }
565
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(EffectCurveComponent, [{
566
- type: Component,
567
- args: [{ selector: 'lib-app-effect-curve', template: "<div class=\"mr-3\" style=\"float: left\">\n <div class=\"mb-2\">\n <select\n [ngModel]=\"curve.curveType\"\n (ngModelChange)=\"curve.curveType = $event; presetService.previewLive()\"\n style=\"width: 200px; height: 20px\"\n >\n <option [value]=\"'sine'\">\n {{ 'designer.effect.curve-sine' | translate }}\n </option>\n <option [value]=\"'square'\">\n {{ 'designer.effect.curve-square' | translate }}\n </option>\n <!-- <option [value]=\"'triangle'\">\n {{ 'designer.effect.curve-triangle' | translate }}</option>\n <option [value]=\"'sawtooth'\">\n {{ 'designer.effect.curve-sawtooth' | translate }}</option>\n <option [value]=\"'reverse-sawtooth'\">\n {{ 'designer.effect.curve-reverse-sawtooth' | translate }}</option> -->\n </select>\n </div>\n <div>\n <canvas #curveGrid class=\"curve-grid\" width=\"200\" height=\"100\" viewBox=\"150 -75 4850 5150\" preserveAspectRatio=\"none\"></canvas>\n </div>\n</div>\n\n<div class=\"mr-4\" style=\"float: left\">\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-length' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.lengthMillis\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [value]=\"0\"\n [min]=\"lengthMillisMin\"\n [max]=\"lengthMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.lengthMillis\" (ngModelChange)=\"setLengthMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-amplitude' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.amplitude\"\n style=\"width: 80px\"\n [tooltip]=\"'hide'\"\n [min]=\"amplitudeMin\"\n [max]=\"amplitudeMax\"\n [step]=\"0.01\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.amplitude\" (ngModelChange)=\"setAmplitude($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-position' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.position\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"percentageMin\"\n [max]=\"percentageMax\"\n [step]=\"0.01\"\n >\n </mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.position\" (ngModelChange)=\"setPosition($event); redraw()\" />\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-phase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phaseMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phaseMillisMin\"\n [max]=\"phaseMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phaseMillis\" (ngModelChange)=\"setPhaseMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n\n <div class=\"d-flex\">\n <div class=\"my-auto\" style=\"width: 100px; float: left\">\n {{ 'designer.effect.curve-chase' | translate }}\n </div>\n <div class=\"my-auto\" style=\"float: left\">\n <mv-slider\n (change)=\"redraw(); presetService.previewLive()\"\n [(value)]=\"curve.phasingMillis\"\n style=\"width: 80px; height: 18px\"\n [tooltip]=\"'hide'\"\n [min]=\"phasingMillisMin\"\n [max]=\"phasingMillisMax\"\n [step]=\"1\"\n ></mv-slider>\n </div>\n <div class=\"my-auto\">\n <input type=\"text\" class=\"slider-input\" [ngModel]=\"curve.phasingMillis\" (ngModelChange)=\"setPhasingMillis($event); redraw()\" />\n </div>\n <div class=\"my-auto ml-1\">\n {{ 'designer.misc.ms' | translate }}\n </div>\n </div>\n</div>\n\n<!-- Menu for the capabilities and channels-->\n<div class=\"col col-auto p-0\" style=\"margin-right: 1px; width: 50px; float: left\">\n <div class=\"nav flex-column nav-pills\" id=\"v-pills-tab\" role=\"tablist\" aria-orientation=\"vertical\">\n <a\n class=\"nav-link px-3 active\"\n id=\"v-pills-effect-capabilities-tab\"\n popover=\"{{ 'designer.misc.capabilities' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-capabilities-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-capabilities\"\n aria-selected=\"true\"\n >\n <i class=\"fa fa-bolt fa-fw\" aria-hidden=\"true\"></i>\n </a>\n <a\n class=\"nav-link px-3\"\n id=\"v-pills-effect-channels-tab\"\n popover=\"{{ 'designer.misc.channels' | translate }}\"\n container=\"body\"\n placement=\"right\"\n triggers=\"mouseenter:mouseleave\"\n data-toggle=\"pill\"\n href=\"#v-pills-effect-channels-{{ curve?.uuid }}\"\n role=\"tab\"\n aria-controls=\"v-pills-channels\"\n aria-selected=\"false\"\n >\n <i class=\"fa fa-sliders fa-fw\" aria-hidden=\"true\"></i>\n </a>\n </div>\n</div>\n\n<div class=\"h-100\" class=\"applying-to\">\n <div class=\"tab-content h-100\" id=\"v-pills-tabContent\">\n <div class=\"tab-pane h-100 show active\" id=\"v-pills-effect-capabilities-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- Capabilities-->\n <div *ngFor=\"let capability of availableCapabilities; let i = index\" class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"capability_{{ curve?.uuid + '_' + i }}\"\n [ngModel]=\"capabilityChecked(capability)\"\n (change)=\"toggleCapability($event, capability)\"\n />\n <label class=\"form-check-label\" for=\"capability_{{ curve?.uuid + '_' + i }}\">{{ getCapabilityName(capability) | async }}</label>\n </div>\n </div>\n <div class=\"tab-pane h-100 show\" id=\"v-pills-effect-channels-{{ curve?.uuid }}\" role=\"tabpanel\">\n <!-- channels -->\n\n <!-- profile selection -->\n <div *ngIf=\"availableProfiles.length > 1\">\n <div *ngFor=\"let profile of availableProfiles; let i = index\" class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\"\n [ngModel]=\"selectedProfiles.indexOf(profile) >= 0\"\n (change)=\"changeProfileSelection($event, profile)\"\n />\n <label class=\"form-check-label\" for=\"channel_profile_{{ curve?.uuid }}_{{ profile.uuid }}\">{{ profile.name }}</label>\n </div>\n\n <hr class=\"my-1\" style=\"border-color: white\" />\n </div>\n\n <!-- channels -->\n <ng-container *ngFor=\"let entry of availableChannels | keyvalue; let i = index\">\n <div *ngFor=\"let channel of entry.value; let j = index\" class=\"form-check\">\n <input\n type=\"checkbox\"\n class=\"form-check-input\"\n id=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\"\n [ngModel]=\"channelChecked(entry.key, channel)\"\n (change)=\"toggleChannel($event, entry.key, channel)\"\n />\n <label class=\"form-check-label\" for=\"channel_{{ curve?.uuid }}_{{ i }}_{{ j }}\">{{\n getChannelName(entry.key.name, channel.name)\n }}</label>\n </div>\n </ng-container>\n </div>\n </div>\n</div>\n", styles: [".curve-grid{background-color:#000;border:1px solid white}.applying-to{overflow-y:scroll;height:130px!important;background-color:#222;border:1px solid white;padding:.5rem}.applying-to .form-check:last-child{margin-bottom:.5rem}\n"] }]
568
- }], () => [{ type: i1.PresetService }, { type: i2.AnimationService }, { type: i3.FixtureService }, { type: i4.TranslateService }], { curve: [{
569
- type: Input
570
- }], isSelected: [{
571
- type: Input
572
- }], curveGrid: [{
573
- type: ViewChild,
574
- args: ['curveGrid', { static: true }]
575
- }] }); })();
576
- (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassDebugInfo(EffectCurveComponent, { className: "EffectCurveComponent" }); })();
577
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWZmZWN0LWN1cnZlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Rlc2lnbmVyL3NyYy9saWIvZWZmZWN0L2VmZmVjdC1jdXJ2ZS9lZmZlY3QtY3VydmUuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvZGVzaWduZXIvc3JjL2xpYi9lZmZlY3QvZWZmZWN0LWN1cnZlL2VmZmVjdC1jdXJ2ZS5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQVUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3ZELE9BQU8sRUFBNEIsS0FBSyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3ZELE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVyQyxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUN2RixPQUFPLEVBQUUsaUJBQWlCLEVBQUUsc0JBQXNCLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUVuSCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDaEUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLCtCQUErQixDQUFDO0FBQzlELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxvQ0FBb0MsQ0FBQzs7Ozs7Ozs7Ozs7OztJQ3lLOUQsQUFERiwrQkFBd0YsZ0JBT3BGO0lBREEsd05BQVUsOENBQW9DLEtBQUM7SUFMakQsaUJBTUU7SUFDRixpQ0FBNkU7SUFBQSxZQUEyQzs7SUFDMUgsQUFEMEgsaUJBQVEsRUFDNUg7Ozs7O0lB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LCBJbnB1dCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIFN1YnNjcmlwdGlvbiwgdGltZXIgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IENhY2hlZEZpeHR1cmVDaGFubmVsIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2NhY2hlZC1maXh0dXJlLWNoYW5uZWwnO1xuaW1wb3J0IHsgRWZmZWN0Q3VydmVQcm9maWxlQ2hhbm5lbHMgfSBmcm9tICcuLi8uLi9tb2RlbHMvZWZmZWN0LWN1cnZlLXByb2ZpbGUtY2hhbm5lbCc7XG5pbXBvcnQgeyBGaXh0dXJlQ2FwYWJpbGl0eSwgRml4dHVyZUNhcGFiaWxpdHlDb2xvciwgRml4dHVyZUNhcGFiaWxpdHlUeXBlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2ZpeHR1cmUtY2FwYWJpbGl0eSc7XG5pbXBvcnQgeyBGaXh0dXJlUHJvZmlsZSB9IGZyb20gJy4uLy4uL21vZGVscy9maXh0dXJlLXByb2ZpbGUnO1xuaW1wb3J0IHsgRml4dHVyZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9maXh0dXJlLnNlcnZpY2UnO1xuaW1wb3J0IHsgUHJlc2V0U2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3ByZXNldC5zZXJ2aWNlJztcbmltcG9ydCB7IEVmZmVjdEN1cnZlIH0gZnJvbSAnLi8uLi8uLi9tb2RlbHMvZWZmZWN0LWN1cnZlJztcbmltcG9ydCB7IEFuaW1hdGlvblNlcnZpY2UgfSBmcm9tICcuLy4uLy4uL3NlcnZpY2VzL2FuaW1hdGlvbi5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbGliLWFwcC1lZmZlY3QtY3VydmUnLFxuICB0ZW1wbGF0ZVVybDogJy4vZWZmZWN0LWN1cnZlLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vZWZmZWN0LWN1cnZlLmNvbXBvbmVudC5jc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgRWZmZWN0Q3VydmVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBwcml2YXRlIGdyaWRVcGRhdGVTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBjdHg6IGFueTtcbiAgcHJpdmF0ZSBtYXhXaWR0aDogbnVtYmVyO1xuICBwcml2YXRlIG1heEhlaWdodDogbnVtYmVyO1xuXG4gIHB1YmxpYyBsZW5ndGhNaWxsaXNNaW4gPSAyMDtcbiAgcHVibGljIGxlbmd0aE1pbGxpc01heCA9IDgwMDA7XG4gIHB1YmxpYyBhbXBsaXR1ZGVNaW4gPSAwO1xuICBwdWJsaWMgYW1wbGl0dWRlTWF4ID0gNDtcbiAgcHVibGljIHBlcmNlbnRhZ2VNaW4gPSAwO1xuICBwdWJsaWMgcGVyY2VudGFnZU1heCA9IDE7XG4gIHB1YmxpYyBwaGFzZU1pbGxpc01pbiA9IC0xMDAwO1xuICBwdWJsaWMgcGhhc2VNaWxsaXNNYXggPSAxMDAwO1xuICBwdWJsaWMgcGhhc2luZ01pbGxpc01pbiA9IDA7XG4gIHB1YmxpYyBwaGFzaW5nTWlsbGlzTWF4ID0gMTAwMDtcblxuICAvLyB0aGUgc2VsZWN0ZWQgY2FwYWJpbGl0aWVzXG4gIHB1YmxpYyBhdmFpbGFibGVDYXBhYmlsaXRpZXM6IEZpeHR1cmVDYXBhYmlsaXR5W10gPSBbXTtcblxuICAvLyB0aGUgc2VsZWN0ZWQgY2hhbm5lbHNcbiAgcHVibGljIGF2YWlsYWJsZUNoYW5uZWxzOiBNYXA8Rml4dHVyZVByb2ZpbGUsIENhY2hlZEZpeHR1cmVDaGFubmVsW10+ID0gbmV3IE1hcDxGaXh0dXJlUHJvZmlsZSwgQ2FjaGVkRml4dHVyZUNoYW5uZWxbXT4oKTtcbiAgcHVibGljIGF2YWlsYWJsZVByb2ZpbGVzOiBGaXh0dXJlUHJvZmlsZVtdID0gW107XG4gIHB1YmxpYyBzZWxlY3RlZFByb2ZpbGVzOiBGaXh0dXJlUHJvZmlsZVtdID0gW107XG5cbiAgQElucHV0KCkgY3VydmU6IEVmZmVjdEN1cnZlO1xuXG4gIC8vIHdoZXRoZXIgdGhlIGVmZmVjdCBpcyBjdXJyZW50bHkgYmVpbmcgZWRpdGVkIChvcGVuKSBvciBub3RcbiAgQElucHV0KClcbiAgc2V0IGlzU2VsZWN0ZWQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICBpZiAodmFsdWUpIHtcbiAgICAgIC8vIHN0YXJ0IHRoZSB1cGRhdGUgdGltZXJcbiAgICAgIGlmICghdGhpcy5ncmlkVXBkYXRlU3Vic2NyaXB0aW9uKSB7XG4gICAgICAgIHRoaXMuZ3JpZFVwZGF0ZVN1YnNjcmlwdGlvbiA9IHRpbWVyKDAsIDE1KS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBzdG9wIHRoZSB1cGRhdGUgdGltZXJcbiAgICAgIGlmICh0aGlzLmdyaWRVcGRhdGVTdWJzY3JpcHRpb24pIHtcbiAgICAgICAgdGhpcy5ncmlkVXBkYXRlU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuZ3JpZFVwZGF0ZVN1YnNjcmlwdGlvbiA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBAVmlld0NoaWxkKCdjdXJ2ZUdyaWQnLCB7IHN0YXRpYzogdHJ1ZSB9KSBjdXJ2ZUdyaWQ6IEVsZW1lbnRSZWY7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHByZXNldFNlcnZpY2U6IFByZXNldFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBhbmltYXRpb25TZXJ2aWNlOiBBbmltYXRpb25TZXJ2aWNlLFxuICAgIHByaXZhdGUgZml4dHVyZVNlcnZpY2U6IEZpeHR1cmVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdHJhbnNsYXRlOiBUcmFuc2xhdGVTZXJ2aWNlXG4gICkge1xuICAgIHRoaXMucHJlc2V0U2VydmljZS5maXh0dXJlU2VsZWN0aW9uQ2hhbmdlZC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgdGhpcy51cGRhdGVDYXBhYmlsaXRpZXNBbmRDaGFubmVscygpO1xuICAgIH0pO1xuXG4gICAgdGhpcy51cGRhdGVDYXBhYmlsaXRpZXNBbmRDaGFubmVscygpO1xuICB9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgY29uc3QgY2FudmFzID0gdGhpcy5jdXJ2ZUdyaWQubmF0aXZlRWxlbWVudDtcbiAgICB0aGlzLmN0eCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xuICAgIHRoaXMubWF4V2lkdGggPSBjYW52YXMud2lkdGg7XG4gICAgdGhpcy5tYXhIZWlnaHQgPSBjYW52YXMuaGVpZ2h0O1xuXG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfVxuXG4gIHByaXZhdGUgZHJhd0N1cnJlbnRWYWx1ZShjdXJyTWlsbGlzOiBudW1iZXIsIHJhZGl1czogbnVtYmVyLCBsaW5lV2lkdGg6IG51bWJlciwgZHVyYXRpb25NaWxsaXM6IG51bWJlciwgbWF4SGVpZ2h0OiBudW1iZXIpIHtcbiAgICBjb25zdCBjdXJyVmFsID0gMSAtIHRoaXMuY3VydmUuZ2V0VmFsdWVBdE1pbGxpcyhjdXJyTWlsbGlzKTtcblxuICAgIGNvbnN0IHggPSAodGhpcy5tYXhXaWR0aCAqIChjdXJyTWlsbGlzICUgZHVyYXRpb25NaWxsaXMpKSAvIGR1cmF0aW9uTWlsbGlzO1xuICAgIGNvbnN0IHkgPSBtYXhIZWlnaHQgKiBjdXJyVmFsICsgbGluZVdpZHRoO1xuXG4gICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgdGhpcy5jdHguYXJjKHgsIHksIHJhZGl1cywgMCwgMiAqIE1hdGguUEksIGZhbHNlKTtcbiAgICB0aGlzLmN0eC5maWxsU3R5bGUgPSAnI2ZmZic7XG4gICAgdGhpcy5jdHguZmlsbCgpO1xuICAgIHRoaXMuY3R4LmxpbmVXaWR0aCA9IDE7XG4gICAgdGhpcy5jdHguc3Ryb2tlU3R5bGUgPSAnIzAwMCc7XG4gICAgdGhpcy5jdHguc3Ryb2tlKCk7XG4gIH1cblxuICBwcml2YXRlIGdldFBoYXNpbmdDb3VudCgpOiBudW1iZXIge1xuICAgIGxldCBjb3VudCA9IDA7XG4gICAgY29uc3QgY291bnRlZEZpcnN0RG14Q2hhbm5lbFBpeGVsS2V5OiBhbnlbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBwcmVzZXRGaXh0dXJlIG9mIHRoaXMucHJlc2V0U2VydmljZS5zZWxlY3RlZFByZXNldC5maXh0dXJlcykge1xuICAgICAgY29uc3QgZml4dHVyZSA9IHRoaXMuZml4dHVyZVNlcnZpY2UuZ2V0Rml4dHVyZUJ5VXVpZChwcmVzZXRGaXh0dXJlLmZpeHR1cmVVdWlkKTtcbiAgICAgIGNvbnN0IGZpcnN0RG14Q2hhbm5lbEFuZEZpeHR1cmVVdWlkID0ge1xuICAgICAgICBmaXJzdERteENoYW5uZWw6IGZpeHR1cmUuZG14Rmlyc3RDaGFubmVsLFxuICAgICAgICBwaXhlbEtleTogcHJlc2V0Rml4dHVyZS5waXhlbEtleSxcbiAgICAgIH07XG5cbiAgICAgIGNvbnN0IGV4aXN0cyA9IGNvdW50ZWRGaXJzdERteENoYW5uZWxQaXhlbEtleS5zb21lKFxuICAgICAgICAoaXRlbSkgPT5cbiAgICAgICAgICBpdGVtLmZpcnN0RG14Q2hhbm5lbCA9PT0gZmlyc3REbXhDaGFubmVsQW5kRml4dHVyZVV1aWQuZmlyc3REbXhDaGFubmVsICYmXG4gICAgICAgICAgKCghaXRlbS5waXhlbEtleSAmJiAhZmlyc3REbXhDaGFubmVsQW5kRml4dHVyZVV1aWQucGl4ZWxLZXkpIHx8IGl0ZW0ucGl4ZWxLZXkgPT09IGZpcnN0RG14Q2hhbm5lbEFuZEZpeHR1cmVVdWlkLnBpeGVsS2V5KVxuICAgICAgKTtcblxuICAgICAgLy8gZG9uJ3QgY291bnQgaXQsIGlmIGl0IGhhcyB0aGUgc2FtZSBETVggYWRkcmVzcyBhbmQgcGl4ZWwga2V5IChpZiBhdmFpbGFibGUpLFxuICAgICAgLy8gYXMgYW4gYWxyZWFkeSBjb3VudGVkIG9uZVxuICAgICAgaWYgKCFleGlzdHMpIHtcbiAgICAgICAgY291bnQrKztcbiAgICAgICAgY291bnRlZEZpcnN0RG14Q2hhbm5lbFBpeGVsS2V5LnB1c2goZmlyc3REbXhDaGFubmVsQW5kRml4dHVyZVV1aWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBjb3VudDtcbiAgfVxuXG4gIHJlZHJhdygpIHtcbiAgICB0aGlzLmN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5tYXhXaWR0aCwgdGhpcy5tYXhIZWlnaHQpO1xuICAgIHRoaXMuY3R4LmZpbGxTdHlsZSA9ICcjZmZmJztcbiAgICB0aGlzLmN0eC5zdHJva2VTdHlsZSA9ICcjZmZmJztcblxuICAgIC8vIHRoZSB3aWR0aCBvZiB0aGUgbGluZXNcbiAgICBjb25zdCB3aWR0aCA9IDM7XG5cbiAgICB0aGlzLmN0eC5saW5lV2lkdGggPSB3aWR0aDtcblxuICAgIGxldCBvbGRYOiBudW1iZXI7XG4gICAgbGV0IG9sZFk6IG51bWJlcjtcblxuICAgIGxldCBzdGVwID0gNTA7XG5cbiAgICBpZiAobGVuZ3RoIDwgNTAwKSB7XG4gICAgICBzdGVwID0gNTtcbiAgICB9XG5cbiAgICBjb25zdCBkdXJhdGlvbk1pbGxpcyA9IHRoaXMuY3VydmUubGVuZ3RoTWlsbGlzICogTWF0aC5tYXgoTWF0aC5yb3VuZCg0IC0gdGhpcy5jdXJ2ZS5sZW5ndGhNaWxsaXMgLyAxMDAwKSwgMSk7XG4gICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5tYXhIZWlnaHQgLSB3aWR0aCAqIDI7XG5cbiAgICAvLyBkcmF3IHRoZSBjdXJ2ZVxuICAgIGZvciAobGV0IGkgPSAtc3RlcCAqIDI7IGkgPCBkdXJhdGlvbk1pbGxpcyArIHN0ZXAgKiAyOyBpICs9IHN0ZXApIHtcbiAgICAgIGNvbnN0IHZhbCA9IDEgLSB0aGlzLmN1cnZlLmdldFZhbHVlQXRNaWxsaXMoaSk7XG5cbiAgICAgIC8vIFNjYWxlIHRoZSB2YWx1ZXMgdG8gdGhlIGdyaWQgZGltZW5zaW9uc1xuICAgICAgY29uc3QgeCA9ICh0aGlzLm1heFdpZHRoICogaSkgLyBkdXJhdGlvbk1pbGxpcztcbiAgICAgIGNvbnN0IHkgPSBtYXhIZWlnaHQgKiB2YWwgKyB3aWR0aDtcblxuICAgICAgaWYgKG9sZFkpIHtcbiAgICAgICAgdGhpcy5jdHguYmVnaW5QYXRoKCk7XG4gICAgICAgIHRoaXMuY3R4Lm1vdmVUbyhvbGRYLCBvbGRZKTtcbiAgICAgICAgdGhpcy5jdHgubGluZVRvKHgsIHkpO1xuICAgICAgICB0aGlzLmN0eC5zdHJva2UoKTtcbiAgICAgIH1cblxuICAgICAgb2xkWCA9IHg7XG4gICAgICBvbGRZID0geTtcbiAgICB9XG5cbiAgICAvLyBkcmF3IHRoZSBjdXJyZW50IHZhbHVlXG4gICAgdGhpcy5kcmF3Q3VycmVudFZhbHVlKHRoaXMuYW5pbWF0aW9uU2VydmljZS50aW1lTWlsbGlzICUgZHVyYXRpb25NaWxsaXMsIDUsIHdpZHRoLCBkdXJhdGlvbk1pbGxpcywgbWF4SGVpZ2h0KTtcblxuICAgIC8vIGRyYXcgdGhlIHBoYXNpbmcgdmFsdWVzIChjaGFzZSksIGlmIHJlcXVpcmVkXG4gICAgbGV0IHBoYXNpbmdDb3VudCA9IDA7XG5cbiAgICBpZiAodGhpcy5jdXJ2ZS5waGFzaW5nTWlsbGlzID4gMCAmJiB0aGlzLnByZXNldFNlcnZpY2Uuc2VsZWN0ZWRQcmVzZXQpIHtcbiAgICAgIHBoYXNpbmdDb3VudCA9IHRoaXMuZ2V0UGhhc2luZ0NvdW50KCk7XG4gICAgfVxuXG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCBwaGFzaW5nQ291bnQ7IGkrKykge1xuICAgICAgdGhpcy5kcmF3Q3VycmVudFZhbHVlKFxuICAgICAgICAodGhpcy5hbmltYXRpb25TZXJ2aWNlLnRpbWVNaWxsaXMgLSBpICogdGhpcy5jdXJ2ZS5waGFzaW5nTWlsbGlzKSAlIGR1cmF0aW9uTWlsbGlzLFxuICAgICAgICAzLFxuICAgICAgICB3aWR0aCxcbiAgICAgICAgZHVyYXRpb25NaWxsaXMsXG4gICAgICAgIG1heEhlaWdodFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNhbGN1bGF0ZUNoYW5uZWxDYXBhYmlsaXRpZXMoKSB7XG4gICAgdGhpcy5hdmFpbGFibGVDaGFubmVscyA9IHRoaXMucHJlc2V0U2VydmljZS5nZXRTZWxlY3RlZFByb2ZpbGVDaGFubmVscyh0aGlzLnNlbGVjdGVkUHJvZmlsZXMpO1xuICB9XG5cbiAgY2hhbmdlUHJvZmlsZVNlbGVjdGlvbigkZXZlbnQ6IGFueSwgcHJvZmlsZTogRml4dHVyZVByb2ZpbGUpIHtcbiAgICBpZiAodGhpcy5zZWxlY3RlZFByb2ZpbGVzLmluZGV4T2YocHJvZmlsZSkgPj0gMCkge1xuICAgICAgdGhpcy5zZWxlY3RlZFByb2ZpbGVzLnNwbGljZSh0aGlzLnNlbGVjdGVkUHJvZmlsZXMuaW5kZXhPZihwcm9maWxlKSwgMSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQcm9maWxlcy5wdXNoKHByb2ZpbGUpO1xuICAgIH1cblxuICAgIHRoaXMuY2FsY3VsYXRlQ2hhbm5lbENhcGFiaWxpdGllcygpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVDYXBhYmlsaXRpZXNBbmRDaGFubmVscygpIHtcbiAgICAvLyBjYXBhYmlsaXRpZXNcbiAgICB0aGlzLmF2YWlsYWJsZUNhcGFiaWxpdGllcyA9IFtdO1xuXG4gICAgaWYgKHRoaXMucHJlc2V0U2VydmljZS5oYXNDYXBhYmlsaXR5RGltbWVyKCkpIHtcbiAgICAgIGNvbnN0IGNhcGFiaWxpdHkgPSBuZXcgRml4dHVyZUNhcGFiaWxpdHkoKTtcbiAgICAgIGNhcGFiaWxpdHkudHlwZSA9IEZpeHR1cmVDYXBhYmlsaXR5VHlwZS5JbnRlbnNpdHk7XG4gICAgICB0aGlzLmF2YWlsYWJsZUNhcGFiaWxpdGllcy5wdXNoKGNhcGFiaWxpdHkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByZXNldFNlcnZpY2UuaGFzQ2FwYWJpbGl0eUNvbG9yKCkpIHtcbiAgICAgIGxldCBjYXBhYmlsaXR5ID0gbmV3IEZpeHR1cmVDYXBhYmlsaXR5KCk7XG4gICAgICBjYXBhYmlsaXR5LnR5cGUgPSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuQ29sb3JJbnRlbnNpdHk7XG4gICAgICBjYXBhYmlsaXR5LmNvbG9yID0gRml4dHVyZUNhcGFiaWxpdHlDb2xvci5SZWQ7XG4gICAgICB0aGlzLmF2YWlsYWJsZUNhcGFiaWxpdGllcy5wdXNoKGNhcGFiaWxpdHkpO1xuXG4gICAgICBjYXBhYmlsaXR5ID0gbmV3IEZpeHR1cmVDYXBhYmlsaXR5KCk7XG4gICAgICBjYXBhYmlsaXR5LnR5cGUgPSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuQ29sb3JJbnRlbnNpdHk7XG4gICAgICBjYXBhYmlsaXR5LmNvbG9yID0gRml4dHVyZUNhcGFiaWxpdHlDb2xvci5HcmVlbjtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQ2FwYWJpbGl0aWVzLnB1c2goY2FwYWJpbGl0eSk7XG5cbiAgICAgIGNhcGFiaWxpdHkgPSBuZXcgRml4dHVyZUNhcGFiaWxpdHkoKTtcbiAgICAgIGNhcGFiaWxpdHkudHlwZSA9IEZpeHR1cmVDYXBhYmlsaXR5VHlwZS5Db2xvckludGVuc2l0eTtcbiAgICAgIGNhcGFiaWxpdHkuY29sb3IgPSBGaXh0dXJlQ2FwYWJpbGl0eUNvbG9yLkJsdWU7XG4gICAgICB0aGlzLmF2YWlsYWJsZUNhcGFiaWxpdGllcy5wdXNoKGNhcGFiaWxpdHkpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnByZXNldFNlcnZpY2UuaGFzQ2FwYWJpbGl0eVBhblRpbHQoKSkge1xuICAgICAgbGV0IGNhcGFiaWxpdHkgPSBuZXcgRml4dHVyZUNhcGFiaWxpdHkoKTtcbiAgICAgIGNhcGFiaWxpdHkudHlwZSA9IEZpeHR1cmVDYXBhYmlsaXR5VHlwZS5QYW47XG4gICAgICB0aGlzLmF2YWlsYWJsZUNhcGFiaWxpdGllcy5wdXNoKGNhcGFiaWxpdHkpO1xuXG4gICAgICBjYXBhYmlsaXR5ID0gbmV3IEZpeHR1cmVDYXBhYmlsaXR5KCk7XG4gICAgICBjYXBhYmlsaXR5LnR5cGUgPSBGaXh0dXJlQ2FwYWJpbGl0eVR5cGUuVGlsdDtcbiAgICAgIHRoaXMuYXZhaWxhYmxlQ2FwYWJpbGl0aWVzLnB1c2goY2FwYWJpbGl0eSk7XG4gICAgfVxuXG4gICAgLy8gY2FsY3VsYXRlIGFsbCBwcm9maWxlc1xuICAgIHRoaXMuYXZhaWxhYmxlUHJvZmlsZXMgPSB0aGlzLnByZXNldFNlcnZpY2UuZ2V0U2VsZWN0ZWRQcm9maWxlcygpO1xuXG4gICAgLy8gc2VsZWN0IGFsbCBwcm9maWxlcyBieSBkZWZhdWx0XG4gICAgdGhpcy5zZWxlY3RlZFByb2ZpbGVzID0gWy4uLnRoaXMuYXZhaWxhYmxlUHJvZmlsZXNdO1xuXG4gICAgLy8gY2FsY3VsYXRlIGFsbCBjaGFubmVsc1xuICAgIHRoaXMuY2FsY3VsYXRlQ2hhbm5lbENhcGFiaWxpdGllcygpO1xuICB9XG5cbiAgZ2V0Q2FwYWJpbGl0eU5hbWUoY2FwYWJpbGl0eTogRml4dHVyZUNhcGFiaWxpdHkpOiBPYnNlcnZhYmxlPHN0cmluZz4ge1xuICAgIHJldHVybiB0aGlzLnRyYW5zbGF0ZVxuICAgICAgLmdldChbJ2Rlc2lnbmVyLmZpeHR1cmVDYXBhYmlsaXR5VHlwZS4nICsgY2FwYWJpbGl0eS50eXBlLCAnZGVzaWduZXIuZml4dHVyZUNhcGFiaWxpdHlDb2xvci4nICsgY2FwYWJpbGl0eS5jb2xvcl0pXG4gICAgICAucGlwZShcbiAgICAgICAgbWFwKChyZXN1bHQ6IHN0cmluZykgPT4ge1xuICAgICAgICAgIGxldCBuYW1lID0gJyc7XG4gICAgICAgICAgbmFtZSArPSByZXN1bHRbJ2Rlc2lnbmVyLmZpeHR1cmVDYXBhYmlsaXR5VHlwZS4nICsgY2FwYWJpbGl0eS50eXBlXTtcblxuICAgICAgICAgIGlmIChjYXBhYmlsaXR5LmNvbG9yKSB7XG4gICAgICAgICAgICBuYW1lICs9ICcsICcgKyByZXN1bHRbJ2Rlc2lnbmVyLmZpeHR1cmVDYXBhYmlsaXR5Q29sb3IuJyArIGNhcGFiaWxpdHkuY29sb3JdO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gbmFtZTtcbiAgICAgICAgfSlcbiAgICAgICk7XG4gIH1cblxuICBjYXBhYmlsaXR5Q2hlY2tlZChjYXBhYmlsaXR5OiBGaXh0dXJlQ2FwYWJpbGl0eSk6IGJvb2xlYW4ge1xuICAgIGZvciAoY29uc3QgZXhpc3RpbmdDYXBhYmlsaXR5IG9mIHRoaXMuY3VydmUuY2FwYWJpbGl0aWVzKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuZml4dHVyZVNlcnZpY2UuY2FwYWJpbGl0aWVzTWF0Y2goXG4gICAgICAgICAgZXhpc3RpbmdDYXBhYmlsaXR5LnR5cGUsXG4gICAgICAgICAgY2FwYWJpbGl0eS50eXBlLFxuICAgICAgICAgIGV4aXN0aW5nQ2FwYWJpbGl0eS5jb2xvcixcbiAgICAgICAgICBjYXBhYmlsaXR5LmNvbG9yLFxuICAgICAgICAgIG51bGwsXG4gICAgICAgICAgbnVsbCxcbiAgICAgICAgICBudWxsLFxuICAgICAgICAgIG51bGxcbiAgICAgICAgKVxuICAgICAgKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0b2dnbGVDYXBhYmlsaXR5KGV2ZW50OiBhbnksIGNhcGFiaWxpdHk6IEZpeHR1cmVDYXBhYmlsaXR5KSB7XG4gICAgaWYgKGV2ZW50LmN1cnJlbnRUYXJnZXQuY2hlY2tlZCkge1xuICAgICAgLy8gYWRkIHRoZSBjYXBhYmlsaXR5XG4gICAgICB0aGlzLmN1cnZlLmNhcGFiaWxpdGllcy5wdXNoKGNhcGFiaWxpdHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBSZW1vdmUgdGhlIGNoYW5uZWxcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jdXJ2ZS5jYXBhYmlsaXRpZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgZXhpc3RpbmdDYXBhYmlsaXR5ID0gdGhpcy5jdXJ2ZS5jYXBhYmlsaXRpZXNbaV07XG4gICAgICAgIGlmIChcbiAgICAgICAgICB0aGlzLmZpeHR1cmVTZXJ2aWNlLmNhcGFiaWxpdGllc01hdGNoKFxuICAgICAgICAgICAgZXhpc3RpbmdDYXBhYmlsaXR5LnR5cGUsXG4gICAgICAgICAgICBjYXBhYmlsaXR5LnR5cGUsXG4gICAgICAgICAgICBleGlzdGluZ0NhcGFiaWxpdHkuY29sb3IsXG4gICAgICAgICAgICBjYXBhYmlsaXR5LmNvbG9yLFxuICAgICAgICAgICAgbnVsbCxcbiAgICAgICAgICAgIG51bGwsXG4gICAgICAgICAgICBudWxsLFxuICAgICAgICAgICAgbnVsbFxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgdGhpcy5jdXJ2ZS5jYXBhYmlsaXRpZXMuc3BsaWNlKGksIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gIH1cblxuICBnZXRDaGFubmVsTmFtZShwcm9maWxlTmFtZTogc3RyaW5nLCBjaGFubmVsTmFtZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuYXZhaWxhYmxlUHJvZmlsZXMubGVuZ3RoID4gMSkge1xuICAgICAgcmV0dXJuIHByb2ZpbGVOYW1lICsgJyAtICcgKyBjaGFubmVsTmFtZTtcbiAgICB9XG5cbiAgICByZXR1cm4gY2hhbm5lbE5hbWU7XG4gIH1cblxuICBjaGFubmVsQ2hlY2tlZChwcm9maWxlOiBGaXh0dXJlUHJvZmlsZSwgY2hhbm5lbDogQ2FjaGVkRml4dHVyZUNoYW5uZWwpOiBib29sZWFuIHtcbiAgICBmb3IgKGNvbnN0IHByb2ZpbGVDaGFubmVscyBvZiB0aGlzLmN1cnZlLmNoYW5uZWxzKSB7XG4gICAgICBpZiAocHJvZmlsZUNoYW5uZWxzLnByb2ZpbGVVdWlkID09PSBwcm9maWxlLnV1aWQpIHtcbiAgICAgICAgaWYgKHByb2ZpbGVDaGFubmVscy5jaGFubmVscy5pbmNsdWRlcyhjaGFubmVsLm5hbWUpKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICB0b2dnbGVDaGFubmVsKGV2ZW50OiBhbnksIHByb2ZpbGU6IEZpeHR1cmVQcm9maWxlLCBjaGFubmVsOiBDYWNoZWRGaXh0dXJlQ2hhbm5lbCkge1xuICAgIC8vIGFkZCB0aGUgcHJvZmlsZSwgaWYgbmVjZXNzYXJ5XG4gICAgbGV0IHByb2ZpbGVDb250YWluZWQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IHByb2ZpbGVDaGFubmVscyBvZiB0aGlzLmN1cnZlLmNoYW5uZWxzKSB7XG4gICAgICBpZiAocHJvZmlsZUNoYW5uZWxzLnByb2ZpbGVVdWlkID09PSBwcm9maWxlLnV1aWQpIHtcbiAgICAgICAgcHJvZmlsZUNvbnRhaW5lZCA9IHRydWU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICghcHJvZmlsZUNvbnRhaW5lZCkge1xuICAgICAgY29uc3QgcHJvZmlsZUNoYW5uZWxzID0gbmV3IEVmZmVjdEN1cnZlUHJvZmlsZUNoYW5uZWxzKCk7XG4gICAgICBwcm9maWxlQ2hhbm5lbHMucHJvZmlsZVV1aWQgPSBwcm9maWxlLnV1aWQ7XG4gICAgICB0aGlzLmN1cnZlLmNoYW5uZWxzLnB1c2gocHJvZmlsZUNoYW5uZWxzKTtcbiAgICB9XG5cbiAgICAvLyBhZGQgb3IgZGVsZXRlIHRoZSBjaGFubmVsXG4gICAgZm9yIChjb25zdCBwcm9maWxlQ2hhbm5lbHMgb2YgdGhpcy5jdXJ2ZS5jaGFubmVscykge1xuICAgICAgaWYgKHByb2ZpbGVDaGFubmVscy5wcm9maWxlVXVpZCA9PT0gcHJvZmlsZS51dWlkKSB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gcHJvZmlsZUNoYW5uZWxzLmNoYW5uZWxzLmluZGV4T2YoY2hhbm5lbC5uYW1lKTtcblxuICAgICAgICBpZiAoaW5kZXggPj0gMCkge1xuICAgICAgICAgIHByb2ZpbGVDaGFubmVscy5jaGFubmVscy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHByb2ZpbGVDaGFubmVscy5jaGFubmVscy5wdXNoKGNoYW5uZWwubmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKTtcbiAgfVxuXG4gIHNldExlbmd0aE1pbGxpcyh2YWx1ZTogYW55KSB7XG4gICAgaWYgKCFpc05hTih2YWx1ZSkgJiYgdmFsdWUgPj0gdGhpcy5sZW5ndGhNaWxsaXNNaW4gJiYgdmFsdWUgPD0gdGhpcy5sZW5ndGhNaWxsaXNNYXgpIHtcbiAgICAgIHRoaXMuY3VydmUubGVuZ3RoTWlsbGlzID0gK3ZhbHVlO1xuICAgICAgdGhpcy5wcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKCk7XG4gICAgfVxuICB9XG5cbiAgc2V0QW1wbGl0dWRlKHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoIWlzTmFOKHZhbHVlKSAmJiB2YWx1ZSA+PSB0aGlzLmFtcGxpdHVkZU1pbiAmJiB2YWx1ZSA8PSB0aGlzLmFtcGxpdHVkZU1heCkge1xuICAgICAgdGhpcy5jdXJ2ZS5hbXBsaXR1ZGUgPSArdmFsdWU7XG4gICAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKTtcbiAgICB9XG4gIH1cblxuICBzZXRQb3NpdGlvbih2YWx1ZTogYW55KSB7XG4gICAgaWYgKCFpc05hTih2YWx1ZSkgJiYgdmFsdWUgPj0gdGhpcy5wZXJjZW50YWdlTWluICYmIHZhbHVlIDw9IHRoaXMucGVyY2VudGFnZU1heCkge1xuICAgICAgdGhpcy5jdXJ2ZS5wb3NpdGlvbiA9ICt2YWx1ZTtcbiAgICAgIHRoaXMucHJlc2V0U2VydmljZS5wcmV2aWV3TGl2ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHNldFBoYXNlTWlsbGlzKHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoIWlzTmFOKHZhbHVlKSAmJiB2YWx1ZSA+PSB0aGlzLnBoYXNlTWlsbGlzTWluICYmIHZhbHVlIDw9IHRoaXMucGhhc2VNaWxsaXNNYXgpIHtcbiAgICAgIHRoaXMuY3VydmUucGhhc2VNaWxsaXMgPSArdmFsdWU7XG4gICAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKTtcbiAgICB9XG4gIH1cblxuICBzZXRQaGFzaW5nTWlsbGlzKHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoIWlzTmFOKHZhbHVlKSAmJiB2YWx1ZSA+PSB0aGlzLnBoYXNpbmdNaWxsaXNNaW4gJiYgdmFsdWUgPD0gdGhpcy5waGFzaW5nTWlsbGlzTWF4KSB7XG4gICAgICB0aGlzLmN1cnZlLnBoYXNpbmdNaWxsaXMgPSArdmFsdWU7XG4gICAgICB0aGlzLnByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKTtcbiAgICB9XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJtci0zXCIgc3R5bGU9XCJmbG9hdDogbGVmdFwiPlxuICA8ZGl2IGNsYXNzPVwibWItMlwiPlxuICAgIDxzZWxlY3RcbiAgICAgIFtuZ01vZGVsXT1cImN1cnZlLmN1cnZlVHlwZVwiXG4gICAgICAobmdNb2RlbENoYW5nZSk9XCJjdXJ2ZS5jdXJ2ZVR5cGUgPSAkZXZlbnQ7IHByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKVwiXG4gICAgICBzdHlsZT1cIndpZHRoOiAyMDBweDsgaGVpZ2h0OiAyMHB4XCJcbiAgICA+XG4gICAgICA8b3B0aW9uIFt2YWx1ZV09XCInc2luZSdcIj5cbiAgICAgICAge3sgJ2Rlc2lnbmVyLmVmZmVjdC5jdXJ2ZS1zaW5lJyB8IHRyYW5zbGF0ZSB9fVxuICAgICAgPC9vcHRpb24+XG4gICAgICA8b3B0aW9uIFt2YWx1ZV09XCInc3F1YXJlJ1wiPlxuICAgICAgICB7eyAnZGVzaWduZXIuZWZmZWN0LmN1cnZlLXNxdWFyZScgfCB0cmFuc2xhdGUgfX1cbiAgICAgIDwvb3B0aW9uPlxuICAgICAgPCEtLSA8b3B0aW9uIFt2YWx1ZV09XCIndHJpYW5nbGUnXCI+XG4gICAgICAgIHt7ICdkZXNpZ25lci5lZmZlY3QuY3VydmUtdHJpYW5nbGUnIHwgdHJhbnNsYXRlIH19PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIFt2YWx1ZV09XCInc2F3dG9vdGgnXCI+XG4gICAgICAgIHt7ICdkZXNpZ25lci5lZmZlY3QuY3VydmUtc2F3dG9vdGgnIHwgdHJhbnNsYXRlIH19PC9vcHRpb24+XG4gICAgICA8b3B0aW9uIFt2YWx1ZV09XCIncmV2ZXJzZS1zYXd0b290aCdcIj5cbiAgICAgICAge3sgJ2Rlc2lnbmVyLmVmZmVjdC5jdXJ2ZS1yZXZlcnNlLXNhd3Rvb3RoJyB8IHRyYW5zbGF0ZSB9fTwvb3B0aW9uPiAtLT5cbiAgICA8L3NlbGVjdD5cbiAgPC9kaXY+XG4gIDxkaXY+XG4gICAgPGNhbnZhcyAjY3VydmVHcmlkIGNsYXNzPVwiY3VydmUtZ3JpZFwiIHdpZHRoPVwiMjAwXCIgaGVpZ2h0PVwiMTAwXCIgdmlld0JveD1cIjE1MCAtNzUgNDg1MCA1MTUwXCIgcHJlc2VydmVBc3BlY3RSYXRpbz1cIm5vbmVcIj48L2NhbnZhcz5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPGRpdiBjbGFzcz1cIm1yLTRcIiBzdHlsZT1cImZsb2F0OiBsZWZ0XCI+XG4gIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0b1wiIHN0eWxlPVwid2lkdGg6IDEwMHB4OyBmbG9hdDogbGVmdFwiPlxuICAgICAge3sgJ2Rlc2lnbmVyLmVmZmVjdC5jdXJ2ZS1sZW5ndGgnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm15LWF1dG9cIiBzdHlsZT1cImZsb2F0OiBsZWZ0XCI+XG4gICAgICA8bXYtc2xpZGVyXG4gICAgICAgIChjaGFuZ2UpPVwicmVkcmF3KCk7IHByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKVwiXG4gICAgICAgIFsodmFsdWUpXT1cImN1cnZlLmxlbmd0aE1pbGxpc1wiXG4gICAgICAgIHN0eWxlPVwid2lkdGg6IDgwcHhcIlxuICAgICAgICBbdG9vbHRpcF09XCInaGlkZSdcIlxuICAgICAgICBbdmFsdWVdPVwiMFwiXG4gICAgICAgIFttaW5dPVwibGVuZ3RoTWlsbGlzTWluXCJcbiAgICAgICAgW21heF09XCJsZW5ndGhNaWxsaXNNYXhcIlxuICAgICAgICBbc3RlcF09XCIxXCJcbiAgICAgID48L212LXNsaWRlcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0b1wiPlxuICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJzbGlkZXItaW5wdXRcIiBbbmdNb2RlbF09XCJjdXJ2ZS5sZW5ndGhNaWxsaXNcIiAobmdNb2RlbENoYW5nZSk9XCJzZXRMZW5ndGhNaWxsaXMoJGV2ZW50KTsgcmVkcmF3KClcIiAvPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvIG1sLTFcIj5cbiAgICAgIHt7ICdkZXNpZ25lci5taXNjLm1zJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XG4gICAgPGRpdiBjbGFzcz1cIm15LWF1dG9cIiBzdHlsZT1cIndpZHRoOiAxMDBweDsgZmxvYXQ6IGxlZnRcIj5cbiAgICAgIHt7ICdkZXNpZ25lci5lZmZlY3QuY3VydmUtYW1wbGl0dWRlJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvXCIgc3R5bGU9XCJmbG9hdDogbGVmdFwiPlxuICAgICAgPG12LXNsaWRlclxuICAgICAgICAoY2hhbmdlKT1cInJlZHJhdygpOyBwcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKClcIlxuICAgICAgICBbKHZhbHVlKV09XCJjdXJ2ZS5hbXBsaXR1ZGVcIlxuICAgICAgICBzdHlsZT1cIndpZHRoOiA4MHB4XCJcbiAgICAgICAgW3Rvb2x0aXBdPVwiJ2hpZGUnXCJcbiAgICAgICAgW21pbl09XCJhbXBsaXR1ZGVNaW5cIlxuICAgICAgICBbbWF4XT1cImFtcGxpdHVkZU1heFwiXG4gICAgICAgIFtzdGVwXT1cIjAuMDFcIlxuICAgICAgPjwvbXYtc2xpZGVyPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInNsaWRlci1pbnB1dFwiIFtuZ01vZGVsXT1cImN1cnZlLmFtcGxpdHVkZVwiIChuZ01vZGVsQ2hhbmdlKT1cInNldEFtcGxpdHVkZSgkZXZlbnQpOyByZWRyYXcoKVwiIC8+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJkLWZsZXhcIj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0b1wiIHN0eWxlPVwid2lkdGg6IDEwMHB4OyBmbG9hdDogbGVmdFwiPlxuICAgICAge3sgJ2Rlc2lnbmVyLmVmZmVjdC5jdXJ2ZS1wb3NpdGlvbicgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0b1wiIHN0eWxlPVwiZmxvYXQ6IGxlZnRcIj5cbiAgICAgIDxtdi1zbGlkZXJcbiAgICAgICAgKGNoYW5nZSk9XCJyZWRyYXcoKTsgcHJlc2V0U2VydmljZS5wcmV2aWV3TGl2ZSgpXCJcbiAgICAgICAgWyh2YWx1ZSldPVwiY3VydmUucG9zaXRpb25cIlxuICAgICAgICBzdHlsZT1cIndpZHRoOiA4MHB4OyBoZWlnaHQ6IDE4cHhcIlxuICAgICAgICBbdG9vbHRpcF09XCInaGlkZSdcIlxuICAgICAgICBbbWluXT1cInBlcmNlbnRhZ2VNaW5cIlxuICAgICAgICBbbWF4XT1cInBlcmNlbnRhZ2VNYXhcIlxuICAgICAgICBbc3RlcF09XCIwLjAxXCJcbiAgICAgID5cbiAgICAgIDwvbXYtc2xpZGVyPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cInNsaWRlci1pbnB1dFwiIFtuZ01vZGVsXT1cImN1cnZlLnBvc2l0aW9uXCIgKG5nTW9kZWxDaGFuZ2UpPVwic2V0UG9zaXRpb24oJGV2ZW50KTsgcmVkcmF3KClcIiAvPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cblxuICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XG4gICAgPGRpdiBjbGFzcz1cIm15LWF1dG9cIiBzdHlsZT1cIndpZHRoOiAxMDBweDsgZmxvYXQ6IGxlZnRcIj5cbiAgICAgIHt7ICdkZXNpZ25lci5lZmZlY3QuY3VydmUtcGhhc2UnIHwgdHJhbnNsYXRlIH19XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm15LWF1dG9cIiBzdHlsZT1cImZsb2F0OiBsZWZ0XCI+XG4gICAgICA8bXYtc2xpZGVyXG4gICAgICAgIChjaGFuZ2UpPVwicmVkcmF3KCk7IHByZXNldFNlcnZpY2UucHJldmlld0xpdmUoKVwiXG4gICAgICAgIFsodmFsdWUpXT1cImN1cnZlLnBoYXNlTWlsbGlzXCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogODBweDsgaGVpZ2h0OiAxOHB4XCJcbiAgICAgICAgW3Rvb2x0aXBdPVwiJ2hpZGUnXCJcbiAgICAgICAgW21pbl09XCJwaGFzZU1pbGxpc01pblwiXG4gICAgICAgIFttYXhdPVwicGhhc2VNaWxsaXNNYXhcIlxuICAgICAgICBbc3RlcF09XCIxXCJcbiAgICAgID48L212LXNsaWRlcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0b1wiPlxuICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJzbGlkZXItaW5wdXRcIiBbbmdNb2RlbF09XCJjdXJ2ZS5waGFzZU1pbGxpc1wiIChuZ01vZGVsQ2hhbmdlKT1cInNldFBoYXNlTWlsbGlzKCRldmVudCk7IHJlZHJhdygpXCIgLz5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibXktYXV0byBtbC0xXCI+XG4gICAgICB7eyAnZGVzaWduZXIubWlzYy5tcycgfCB0cmFuc2xhdGUgfX1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImQtZmxleFwiPlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvXCIgc3R5bGU9XCJ3aWR0aDogMTAwcHg7IGZsb2F0OiBsZWZ0XCI+XG4gICAgICB7eyAnZGVzaWduZXIuZWZmZWN0LmN1cnZlLWNoYXNlJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvXCIgc3R5bGU9XCJmbG9hdDogbGVmdFwiPlxuICAgICAgPG12LXNsaWRlclxuICAgICAgICAoY2hhbmdlKT1cInJlZHJhdygpOyBwcmVzZXRTZXJ2aWNlLnByZXZpZXdMaXZlKClcIlxuICAgICAgICBbKHZhbHVlKV09XCJjdXJ2ZS5waGFzaW5nTWlsbGlzXCJcbiAgICAgICAgc3R5bGU9XCJ3aWR0aDogODBweDsgaGVpZ2h0OiAxOHB4XCJcbiAgICAgICAgW3Rvb2x0aXBdPVwiJ2hpZGUnXCJcbiAgICAgICAgW21pbl09XCJwaGFzaW5nTWlsbGlzTWluXCJcbiAgICAgICAgW21heF09XCJwaGFzaW5nTWlsbGlzTWF4XCJcbiAgICAgICAgW3N0ZXBdPVwiMVwiXG4gICAgICA+PC9tdi1zbGlkZXI+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm15LWF1dG9cIj5cbiAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwic2xpZGVyLWlucHV0XCIgW25nTW9kZWxdPVwiY3VydmUucGhhc2luZ01pbGxpc1wiIChuZ01vZGVsQ2hhbmdlKT1cInNldFBoYXNpbmdNaWxsaXMoJGV2ZW50KTsgcmVkcmF3KClcIiAvPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJteS1hdXRvIG1sLTFcIj5cbiAgICAgIHt7ICdkZXNpZ25lci5taXNjLm1zJyB8IHRyYW5zbGF0ZSB9fVxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48IS0tIE1lbnUgZm9yIHRoZSBjYXBhYmlsaXRpZXMgYW5kIGNoYW5uZWxzLS0+XG48ZGl2IGNsYXNzPVwiY29sIGNvbC1hdXRvIHAtMFwiIHN0eWxlPVwibWFyZ2luLXJpZ2h0OiAxcHg7IHdpZHRoOiA1MHB4OyBmbG9hdDogbGVmdFwiPlxuICA8ZGl2IGNsYXNzPVwibmF2IGZsZXgtY29sdW1uIG5hdi1waWxsc1wiIGlkPVwidi1waWxscy10YWJcIiByb2xlPVwidGFibGlzdFwiIGFyaWEtb3JpZW50YXRpb249XCJ2ZXJ0aWNhbFwiPlxuICAgIDxhXG4gICAgICBjbGFzcz1cIm5hdi1saW5rIHB4LTMgYWN0aXZlXCJcbiAgICAgIGlkPVwidi1waWxscy1lZmZlY3QtY2FwYWJpbGl0aWVzLXRhYlwiXG4gICAgICBwb3BvdmVyPVwie3sgJ2Rlc2lnbmVyLm1pc2MuY2FwYWJpbGl0aWVzJyB8IHRyYW5zbGF0ZSB9fVwiXG4gICAgICBjb250YWluZXI9XCJib2R5XCJcbiAgICAgIHBsYWNlbWVudD1cInJpZ2h0XCJcbiAgICAgIHRyaWdnZXJzPVwibW91c2VlbnRlcjptb3VzZWxlYXZlXCJcbiAgICAgIGRhdGEtdG9nZ2xlPVwicGlsbFwiXG4gICAgICBocmVmPVwiI3YtcGlsbHMtZWZmZWN0LWNhcGFiaWxpdGllcy17eyBjdXJ2ZT8udXVpZCB9fVwiXG4gICAgICByb2xlPVwidGFiXCJcbiAgICAgIGFyaWEtY29udHJvbHM9XCJ2LXBpbGxzLWNhcGFiaWxpdGllc1wiXG4gICAgICBhcmlhLXNlbGVjdGVkPVwidHJ1ZVwiXG4gICAgPlxuICAgICAgPGkgY2xhc3M9XCJmYSBmYS1ib2x0IGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgIDwvYT5cbiAgICA8YVxuICAgICAgY2xhc3M9XCJuYXYtbGluayBweC0zXCJcbiAgICAgIGlkPVwidi1waWxscy1lZmZlY3QtY2hhbm5lbHMtdGFiXCJcbiAgICAgIHBvcG92ZXI9XCJ7eyAnZGVzaWduZXIubWlzYy5jaGFubmVscycgfCB0cmFuc2xhdGUgfX1cIlxuICAgICAgY29udGFpbmVyPVwiYm9keVwiXG4gICAgICBwbGFjZW1lbnQ9XCJyaWdodFwiXG4gICAgICB0cmlnZ2Vycz1cIm1vdXNlZW50ZXI6bW91c2VsZWF2ZVwiXG4gICAgICBkYXRhLXRvZ2dsZT1cInBpbGxcIlxuICAgICAgaHJlZj1cIiN2LXBpbGxzLWVmZmVjdC1jaGFubmVscy17eyBjdXJ2ZT8udXVpZCB9fVwiXG4gICAgICByb2xlPVwidGFiXCJcbiAgICAgIGFyaWEtY29udHJvbHM9XCJ2LXBpbGxzLWNoYW5uZWxzXCJcbiAgICAgIGFyaWEtc2VsZWN0ZWQ9XCJmYWxzZVwiXG4gICAgPlxuICAgICAgPGkgY2xhc3M9XCJmYSBmYS1zbGlkZXJzIGZhLWZ3XCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+PC9pPlxuICAgIDwvYT5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPGRpdiBjbGFzcz1cImgtMTAwXCIgY2xhc3M9XCJhcHBseWluZy10b1wiPlxuICA8ZGl2IGNsYXNzPVwidGFiLWNvbnRlbnQgaC0xMDBcIiBpZD1cInYtcGlsbHMtdGFiQ29udGVudFwiPlxuICAgIDxkaXYgY2xhc3M9XCJ0YWItcGFuZSBoLTEwMCBzaG93IGFjdGl2ZVwiIGlkPVwidi1waWxscy1lZmZlY3QtY2FwYWJpbGl0aWVzLXt7IGN1cnZlPy51dWlkIH19XCIgcm9sZT1cInRhYnBhbmVsXCI+XG4gICAgICA8IS0tIENhcGFiaWxpdGllcy0tPlxuICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgY2FwYWJpbGl0eSBvZiBhdmFpbGFibGVDYXBhYmlsaXRpZXM7IGxldCBpID0gaW5kZXhcIiBjbGFzcz1cImZvcm0tY2hlY2tcIj5cbiAgICAgICAgPGlucHV0XG4gICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIlxuICAgICAgICAgIGlkPVwiY2FwYWJpbGl0eV97eyBjdXJ2ZT8udXVpZCArICdfJyArIGkgfX1cIlxuICAgICAgICAgIFtuZ01vZGVsXT1cImNhcGFiaWxpdHlDaGVja2VkKGNhcGFiaWxpdHkpXCJcbiAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZUNhcGFiaWxpdHkoJGV2ZW50LCBjYXBhYmlsaXR5KVwiXG4gICAgICAgIC8+XG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJjYXBhYmlsaXR5X3t7IGN1cnZlPy51dWlkICsgJ18nICsgaSB9fVwiPnt7IGdldENhcGFiaWxpdHlOYW1lKGNhcGFiaWxpdHkpIHwgYXN5bmMgfX08L2xhYmVsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInRhYi1wYW5lIGgtMTAwIHNob3dcIiBpZD1cInYtcGlsbHMtZWZmZWN0LWNoYW5uZWxzLXt7IGN1cnZlPy51dWlkIH19XCIgcm9sZT1cInRhYnBhbmVsXCI+XG4gICAgICA8IS0tIGNoYW5uZWxzIC0tPlxuXG4gICAgICA8IS0tIHByb2ZpbGUgc2VsZWN0aW9uIC0tPlxuICAgICAgPGRpdiAqbmdJZj1cImF2YWlsYWJsZVByb2ZpbGVzLmxlbmd0aCA+IDFcIj5cbiAgICAgICAgPGRpdiAqbmdGb3I9XCJsZXQgcHJvZmlsZSBvZiBhdmFpbGFibGVQcm9maWxlczsgbGV0IGkgPSBpbmRleFwiIGNsYXNzPVwiZm9ybS1jaGVja1wiPlxuICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgdHlwZT1cImNoZWNrYm94XCJcbiAgICAgICAgICAgIGNsYXNzPVwiZm9ybS1jaGVjay1pbnB1dFwiXG4gICAgICAgICAgICBpZD1cImNoYW5uZWxfcHJvZmlsZV97eyBjdXJ2ZT8udXVpZCB9fV97eyBwcm9maWxlLnV1aWQgfX1cIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwic2VsZWN0ZWRQcm9maWxlcy5pbmRleE9mKHByb2ZpbGUpID49IDBcIlxuICAgICAgICAgICAgKGNoYW5nZSk9XCJjaGFuZ2VQcm9maWxlU2VsZWN0aW9uKCRldmVudCwgcHJvZmlsZSlcIlxuICAgICAgICAgIC8+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cImNoYW5uZWxfcHJvZmlsZV97eyBjdXJ2ZT8udXVpZCB9fV97eyBwcm9maWxlLnV1aWQgfX1cIj57eyBwcm9maWxlLm5hbWUgfX08L2xhYmVsPlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgICA8aHIgY2xhc3M9XCJteS0xXCIgc3R5bGU9XCJib3JkZXItY29sb3I6IHdoaXRlXCIgLz5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIGNoYW5uZWxzIC0tPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZW50cnkgb2YgYXZhaWxhYmxlQ2hhbm5lbHMgfCBrZXl2YWx1ZTsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBjaGFubmVsIG9mIGVudHJ5LnZhbHVlOyBsZXQgaiA9IGluZGV4XCIgY2xhc3M9XCJmb3JtLWNoZWNrXCI+XG4gICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0XCJcbiAgICAgICAgICAgIGlkPVwiY2hhbm5lbF97eyBjdXJ2ZT8udXVpZCB9fV97eyBpIH19X3t7IGogfX1cIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwiY2hhbm5lbENoZWNrZWQoZW50cnkua2V5LCBjaGFubmVsKVwiXG4gICAgICAgICAgICAoY2hhbmdlKT1cInRvZ2dsZUNoYW5uZWwoJGV2ZW50LCBlbnRyeS5rZXksIGNoYW5uZWwpXCJcbiAgICAgICAgICAvPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJjaGFubmVsX3t7IGN1cnZlPy51dWlkIH19X3t7IGkgfX1fe3sgaiB9fVwiPnt7XG4gICAgICAgICAgICBnZXRDaGFubmVsTmFtZShlbnRyeS5rZXkubmFtZSwgY2hhbm5lbC5uYW1lKVxuICAgICAgICAgIH19PC9sYWJlbD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==