@colijnit/homedecorator 258.1.1 → 258.1.2

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 (92) hide show
  1. package/app/core/enum/icon.enum.d.ts +1 -0
  2. package/app/core/enum/message-type.enum.d.ts +2 -1
  3. package/app/core/interface/message-with-payload.interface.d.ts +1 -0
  4. package/app/core/model/homedecorator-settings-options.d.ts +1 -1
  5. package/app/core/model/homedecorator-settings.d.ts +3 -0
  6. package/app/core/service/3dm-api.d.ts +2 -2
  7. package/app/core/service/homedecorator-app-event.service.d.ts +1 -0
  8. package/app/core/service/homedecorator-connector-adapter.service.d.ts +9 -1
  9. package/app/core/service/homedecorator-connector.service.d.ts +15 -2
  10. package/app/core/service/utils.service.d.ts +1 -1
  11. package/app/core/utils/object.utils.d.ts +2 -0
  12. package/app/homedecorator.module.d.ts +2 -1
  13. package/app/plugins/core3d/service/wall-measurements.service.d.ts +2 -0
  14. package/app/plugins/model-uploader/model-previewer/model-preview.component.d.ts +3 -0
  15. package/app/plugins/product-catalog/product-catalog/product-catalog.component.d.ts +2 -0
  16. package/app/plugins/product-configurator/product-configurator-selector-list-of-values.component.scss +28 -0
  17. package/app/plugins/product-configurator/product-configurator-selector-option-button.component.d.ts +19 -0
  18. package/app/plugins/product-configurator/product-configurator-selector-option-button.component.scss +38 -0
  19. package/app/plugins/product-configurator/product-configurator-selector-option-dropdown.component.d.ts +20 -0
  20. package/app/plugins/product-configurator/product-configurator-selector-option-dropdown.component.scss +0 -0
  21. package/app/plugins/product-configurator/product-configurator-selector-option-list-of-values.component.d.ts +19 -0
  22. package/app/plugins/product-configurator/product-configurator-selector-option-tile.component.scss +56 -0
  23. package/app/plugins/product-configurator/product-configurator-selector-option-tile.compontent.d.ts +20 -0
  24. package/app/plugins/product-configurator/product-configurator-selector.component.d.ts +26 -0
  25. package/app/plugins/product-configurator/product-configurator-selector.component.scss +46 -0
  26. package/app/plugins/product-configurator/product-configurator.component.d.ts +38 -0
  27. package/app/plugins/product-configurator/product-configurator.component.scss +35 -0
  28. package/app/plugins/product-configurator/product-configurator.module.d.ts +18 -0
  29. package/app/plugins/product-configurator/template_variables.scss +13 -0
  30. package/app/plugins/render/model/blender-render-settings.d.ts +10 -0
  31. package/app/plugins/render/model/blender-scene-settings.d.ts +18 -0
  32. package/app/plugins/render/render-controls/render-controls.component.d.ts +19 -7
  33. package/app/plugins/render/service/new-render.service.d.ts +21 -4
  34. package/app/plugins/room-planner/components/floor-catalog/floor-catalog.component.scss +1 -1
  35. package/app/plugins/threedselector/threedselector/service/build-furniture.service.d.ts +5 -0
  36. package/app/plugins/threedselector/threedselector/threedselector.component.d.ts +4 -0
  37. package/app/plugins/threedselector/threedselector/threedselector.component.scss +17 -0
  38. package/app/plugins/threedselector/threedselector.module.d.ts +2 -1
  39. package/app/plugins/toolbar/draw-dialog/draw-dialog.component.scss +1 -1
  40. package/assets/icons/circle_regular.svg +0 -0
  41. package/bundles/colijnit-homedecorator.umd.js +1986 -835
  42. package/bundles/colijnit-homedecorator.umd.js.map +1 -1
  43. package/esm2015/app/app.version.js +3 -3
  44. package/esm2015/app/core/enum/icon.enum.js +2 -1
  45. package/esm2015/app/core/enum/message-type.enum.js +2 -1
  46. package/esm2015/app/core/interface/message-with-payload.interface.js +1 -1
  47. package/esm2015/app/core/model/homedecorator-settings-options.js +2 -2
  48. package/esm2015/app/core/model/homedecorator-settings.js +3 -1
  49. package/esm2015/app/core/model/icon.js +2 -1
  50. package/esm2015/app/core/service/3dm-api.js +15 -22
  51. package/esm2015/app/core/service/homedecorator-app-event.service.js +3 -2
  52. package/esm2015/app/core/service/homedecorator-connector-adapter.service.js +65 -7
  53. package/esm2015/app/core/service/homedecorator-connector.service.js +150 -6
  54. package/esm2015/app/core/service/homedecorator-settings.service.js +8 -1
  55. package/esm2015/app/core/service/utils.service.js +116 -93
  56. package/esm2015/app/core/utils/object.utils.js +13 -1
  57. package/esm2015/app/homedecorator.component.js +1 -2
  58. package/esm2015/app/homedecorator.module.js +8 -4
  59. package/esm2015/app/plugins/core3d/core3d/core3d.component.js +2 -2
  60. package/esm2015/app/plugins/core3d/service/wall-measurements.service.js +7 -1
  61. package/esm2015/app/plugins/model-uploader/model-previewer/model-preview.component.js +98 -50
  62. package/esm2015/app/plugins/model-uploader/model-uploader/model-uploader.component.js +4 -4
  63. package/esm2015/app/plugins/product-catalog/product-catalog/product-catalog.component.js +21 -11
  64. package/esm2015/app/plugins/product-configurator/product-configurator-selector-option-button.component.js +67 -0
  65. package/esm2015/app/plugins/product-configurator/product-configurator-selector-option-dropdown.component.js +57 -0
  66. package/esm2015/app/plugins/product-configurator/product-configurator-selector-option-list-of-values.component.js +75 -0
  67. package/esm2015/app/plugins/product-configurator/product-configurator-selector-option-tile.compontent.js +90 -0
  68. package/esm2015/app/plugins/product-configurator/product-configurator-selector.component.js +253 -0
  69. package/esm2015/app/plugins/product-configurator/product-configurator.component.js +151 -0
  70. package/esm2015/app/plugins/product-configurator/product-configurator.module.js +115 -0
  71. package/esm2015/app/plugins/render/model/blender-render-settings.js +3 -0
  72. package/esm2015/app/plugins/render/model/blender-scene-settings.js +10 -0
  73. package/esm2015/app/plugins/render/model/render-parameters.js +3 -3
  74. package/esm2015/app/plugins/render/render-controls/render-controls.component.js +532 -446
  75. package/esm2015/app/plugins/render/render-dialog/render-dialog.component.js +6 -40
  76. package/esm2015/app/plugins/render/service/new-render.service.js +212 -44
  77. package/esm2015/app/plugins/render/service/render.service.js +6 -9
  78. package/esm2015/app/plugins/room-planner/components/floor-catalog/floor-catalog.component.js +1 -1
  79. package/esm2015/app/plugins/room-planner/components/texture-picker/texture-picker.component.js +1 -1
  80. package/esm2015/app/plugins/room-planner/room-planner/room-planner.component.js +12 -10
  81. package/esm2015/app/plugins/threedselector/element-buttons/element-buttons.component.js +2 -2
  82. package/esm2015/app/plugins/threedselector/threedselector/service/build-furniture.service.js +55 -1
  83. package/esm2015/app/plugins/threedselector/threedselector/service/load-furniture.service.js +3 -3
  84. package/esm2015/app/plugins/threedselector/threedselector/threedselector.component.js +64 -15
  85. package/esm2015/app/plugins/threedselector/threedselector/utils/asset.utils.js +1 -1
  86. package/esm2015/app/plugins/threedselector/threedselector.module.js +8 -4
  87. package/esm2015/app/plugins/toolbar/draw-dialog/draw-dialog.component.js +1 -1
  88. package/esm2015/app/shared/category-library/category-library.component.js +1 -1
  89. package/fesm2015/colijnit-homedecorator.js +2522 -1149
  90. package/fesm2015/colijnit-homedecorator.js.map +1 -1
  91. package/package.json +4 -4
  92. package/styles.scss +1 -1
@@ -13,9 +13,10 @@ import { RenderStatus } from '../enum/render-status';
13
13
  import { Box3, MathUtils, Vector3 } from 'three';
14
14
  import { ConfigurationKey } from '../../../core/enum/configuration-key.enum';
15
15
  import { RenderModes } from '../enum/render-modes';
16
- import { RenderQueueItem } from '../model/render-queue-item';
17
16
  import { MessageType } from '../../../core/enum/message-type.enum';
18
17
  import { IconEnum } from '../../../core/enum/icon.enum';
18
+ import { BlenderSceneSetting, BlenderSceneType } from '../model/blender-scene-settings';
19
+ import { BlenderRenderSettings } from '../model/blender-render-settings';
19
20
  import * as i0 from "@angular/core";
20
21
  import * as i1 from "../service/render.service";
21
22
  import * as i2 from "../../../core/service/message-bus.service";
@@ -28,20 +29,22 @@ import * as i8 from "../../core3d/service/camera.service";
28
29
  import * as i9 from "../../../core/service/configuration.service";
29
30
  import * as i10 from "../service/new-render.service";
30
31
  import * as i11 from "../../../core/service/utils.service";
31
- import * as i12 from "@colijnit/corecomponents";
32
- import * as i13 from "@angular/material/form-field";
33
- import * as i14 from "@angular/material/select";
34
- import * as i15 from "@angular/material/core";
35
- import * as i16 from "@angular/material/slider";
36
- import * as i17 from "@angular/material/button";
37
- import * as i18 from "@angular/material/icon";
38
- import * as i19 from "@angular/common";
39
- import * as i20 from "@angular/material/tooltip";
40
- import * as i21 from "@angular/forms";
41
- import * as i22 from "@angular/material/input";
42
- import * as i23 from "../../../core/pipe/localize.pipe";
32
+ import * as i12 from "../../room-planner/components/floorplanner/service/room.service";
33
+ import * as i13 from "../../core3d/service/wall-measurements.service";
34
+ import * as i14 from "@colijnit/corecomponents";
35
+ import * as i15 from "@angular/material/form-field";
36
+ import * as i16 from "@angular/material/select";
37
+ import * as i17 from "@angular/material/core";
38
+ import * as i18 from "@angular/material/slider";
39
+ import * as i19 from "@angular/material/icon";
40
+ import * as i20 from "@angular/material/button";
41
+ import * as i21 from "@angular/common";
42
+ import * as i22 from "@angular/material/tooltip";
43
+ import * as i23 from "@angular/forms";
44
+ import * as i24 from "@angular/material/input";
45
+ import * as i25 from "../../../core/pipe/localize.pipe";
43
46
  export class RenderControlsComponent {
44
- constructor(renderService, messageService, viewModeService, settingsService, iconService, _dialog, _sceneService, _cameraService, _configurationService, _settingsService, _newRenderService, _utilsService) {
47
+ constructor(renderService, messageService, viewModeService, settingsService, iconService, _dialog, _sceneService, _cameraService, _configurationService, _settingsService, _newRenderService, _utilsService, _roomService, _wallMeasurementsService) {
45
48
  this.renderService = renderService;
46
49
  this.messageService = messageService;
47
50
  this.viewModeService = viewModeService;
@@ -54,75 +57,78 @@ export class RenderControlsComponent {
54
57
  this._settingsService = _settingsService;
55
58
  this._newRenderService = _newRenderService;
56
59
  this._utilsService = _utilsService;
60
+ this._roomService = _roomService;
61
+ this._wallMeasurementsService = _wallMeasurementsService;
57
62
  this.icons = IconEnum;
58
- this.hdriIntensity = 100;
63
+ this.hdriIntensity = 1;
59
64
  this.hdriRotation = 0;
60
65
  this.lightingExposure = 1;
61
66
  this.showRenderSettings = false;
62
- this._subs = [];
63
- this.viewModes = ViewMode;
64
- this.renderStatus = RenderStatus;
67
+ this.sceneList = [];
65
68
  this.hasError = false;
66
69
  this.errorText = '';
67
70
  this.imageRenderSource = '';
68
71
  this.inPictureMode = false;
72
+ this.showCullingErrorDialog = false;
73
+ this._subs = [];
74
+ this.viewModes = ViewMode;
75
+ this.renderStatus = RenderStatus;
69
76
  this.renderModes = RenderModes;
70
77
  this._subs.push(this.messageService.subscribe(MessageType.BlenderRenderPreviewReady, (file) => this.showPreview(file)), this._cameraService.cameraMovementChanged.subscribe(() => {
71
78
  this.validateRenderPosition();
72
79
  // Make sure when the camera moves, we recheck the position and if we still need to show the render warning.
73
80
  }));
74
81
  }
82
+ ngOnInit() {
83
+ this.getRenderScenesFromSettings();
84
+ }
75
85
  get disablePictureButton() {
76
- if (this._settingsService.settings.options.useNewRender) {
77
- return this._newRenderService.currentQueueRenderItem.renderStatus === this.renderStatus.IsRunning;
78
- }
79
- else {
80
- return (this.renderService.currentQueueRenderItem.renderStatus === this.renderStatus.IsRunning ||
81
- this.renderService.serverData.setup === false);
82
- }
86
+ return this._newRenderService.currentQueueRenderItem.renderStatus === this.renderStatus.IsRunning;
83
87
  }
84
88
  showRenderForm(event) {
85
89
  this.inPictureMode = !this.inPictureMode;
86
90
  this.validateRenderPosition();
91
+ const cullingAllowed = this._allowCulling(this.hasError);
92
+ if (cullingAllowed && this.inPictureMode) {
93
+ this.showCullingErrorDialog = true;
94
+ }
87
95
  }
88
96
  startRenderingRoom() {
89
97
  return __awaiter(this, void 0, void 0, function* () {
90
- if (this._settingsService.settings.options.useNewRender) {
91
- this._newRenderService.renderRoom(this.renderService.getImageSizeOnId(this.renderService.selectedImageSize));
92
- }
93
- else {
94
- this.imageRenderSource = '';
95
- const queueItem = new RenderQueueItem();
96
- queueItem.params = this.renderService.getRenderParameters(this.renderModes.RenderRoom);
97
- this.renderService.renderQueue = [];
98
- this.renderService.renderQueue.push(queueItem);
99
- yield this.renderService.startRendering()
100
- .catch((e) => {
101
- console.error(e);
102
- this.renderService.renderQueue = [];
103
- });
104
- }
98
+ this._newRenderService.renderRoom(this.renderService.getImageSizeOnId(this.renderService.selectedImageSize));
105
99
  });
106
100
  }
107
101
  createBlenderRender() {
108
- const renderSize = this.renderService.getImageSizeOnId(this.renderService.selectedImageSize);
109
- const renderSceneAssetId = this.renderService.selectedRenderScene;
110
- if (this.lightingExposure < 1) {
111
- this.lightingExposure = 1;
102
+ if (!this.showCullingErrorDialog) {
103
+ if (this.viewModeService.isTopViewActive()) {
104
+ this._wallMeasurementsService.prepMeasurementsForRender();
105
+ }
106
+ // only render when the showCullingErrorDialog is false
107
+ this.messageService.emit(MessageType.ShowLoadingIndicator, { title: 'Uploading...' });
108
+ const renderSize = this.renderService.getImageSizeOnId(this.renderService.selectedImageSize);
109
+ const renderSceneAssetId = this.selectedRenderScene;
110
+ if (this.lightingExposure < 1) {
111
+ this.lightingExposure = 1;
112
+ }
113
+ this.validateRenderPosition(); // Check the camera position
114
+ const allowCulling = this._allowCulling(this.hasError);
115
+ const renderInput = new BlenderRenderSettings();
116
+ renderInput.height = renderSize.height;
117
+ renderInput.width = renderSize.width;
118
+ renderInput.sceneAsset = renderSceneAssetId;
119
+ renderInput.hdriIntensity = this.hdriIntensity;
120
+ renderInput.hdriRotation = this.hdriRotation;
121
+ renderInput.lightingExposure = this.lightingExposure;
122
+ renderInput.allowCulling = allowCulling;
123
+ this._utilsService.prepRoomForRender(false, renderInput);
124
+ if (this.viewModeService.isTopViewActive()) {
125
+ this._wallMeasurementsService.restoreMeasurementsAfterRender();
126
+ }
112
127
  }
113
- const renderInput = {
114
- 'height': renderSize.height,
115
- 'width': renderSize.width,
116
- 'sceneAssetId': renderSceneAssetId,
117
- 'hdriIntensity': this.hdriIntensity,
118
- 'hdriRotation': this.hdriRotation,
119
- 'lightingExposure': this.lightingExposure
120
- };
121
- this.messageService.emit(MessageType.ShowLoadingIndicator, { title: 'Uploading...' });
122
- this._utilsService.prepRoomForRender(false, renderInput);
123
128
  }
124
129
  resetBlenderRenderScene() {
125
130
  this.inPictureMode = false;
131
+ this.showCullingErrorDialog = false;
126
132
  }
127
133
  moveCameraWithinBounds() {
128
134
  const floorPlaneItem = this._sceneService.scene.getObjectByName('floor-plane');
@@ -143,14 +149,30 @@ export class RenderControlsComponent {
143
149
  this._cameraService.cameraMovementChanged.next();
144
150
  }
145
151
  getPreviewRender() {
146
- const renderSceneAssetId = this.renderService.selectedRenderScene;
147
- const renderInput = {
148
- 'height': 150,
149
- 'width': 275,
150
- 'sceneAssetId': renderSceneAssetId
151
- };
152
- this.messageService.emit(MessageType.ShowLoadingIndicator, { title: 'Uploading...' });
153
- this._utilsService.prepRoomForRender(false, renderInput, true);
152
+ if (!this.showCullingErrorDialog) {
153
+ if (this.viewModeService.isTopViewActive()) {
154
+ this._wallMeasurementsService.prepMeasurementsForRender();
155
+ }
156
+ const renderSceneAssetId = this.selectedRenderScene;
157
+ this.messageService.emit(MessageType.ShowLoadingIndicator, { title: 'Uploading...' });
158
+ if (this.lightingExposure < 1) {
159
+ this.lightingExposure = 1;
160
+ }
161
+ this.validateRenderPosition(); // Check the camera position
162
+ const allowCulling = this._allowCulling(this.hasError);
163
+ const renderInput = new BlenderRenderSettings();
164
+ renderInput.height = 150;
165
+ renderInput.width = 275;
166
+ renderInput.sceneAsset = renderSceneAssetId;
167
+ renderInput.hdriIntensity = this.hdriIntensity;
168
+ renderInput.hdriRotation = this.hdriRotation;
169
+ renderInput.lightingExposure = this.lightingExposure;
170
+ renderInput.allowCulling = allowCulling;
171
+ this._utilsService.prepRoomForRender(false, renderInput, true);
172
+ if (this.viewModeService.isTopViewActive()) {
173
+ this._wallMeasurementsService.restoreMeasurementsAfterRender();
174
+ }
175
+ }
154
176
  }
155
177
  showPreview(image) {
156
178
  this.blenderPreviewRender = image;
@@ -158,6 +180,12 @@ export class RenderControlsComponent {
158
180
  toggleRenderSettings() {
159
181
  this.showRenderSettings = !this.showRenderSettings;
160
182
  }
183
+ updateBlenderSceneSettings(event) {
184
+ this.selectedRenderScene = event.value; // Select the first one and set the values.
185
+ this.hdriIntensity = this.selectedRenderScene.hdriIntensity;
186
+ this.hdriRotation = this.selectedRenderScene.hdriRotation;
187
+ this.lightingExposure = this.selectedRenderScene.lightingExposure;
188
+ }
161
189
  validateRenderPosition() {
162
190
  /**
163
191
  * To make sure the user has a descent render, the camera position needs to be within the boundingbox of the floorplane.
@@ -171,7 +199,7 @@ export class RenderControlsComponent {
171
199
  for (const floorPlaneItem of floorPlaneItems) {
172
200
  const floorPlaneItemBox = new Box3().setFromObject(floorPlaneItem);
173
201
  floorPlaneItemBox.min.y = 0;
174
- floorPlaneItemBox.max.y = this._configurationService.getValue(ConfigurationKey.WallHeight); // units in threejs, so 10 = 10 meter.
202
+ floorPlaneItemBox.max.y = this._configurationService.getValue(ConfigurationKey.WallHeight) / 100; // units in threejs, so 10 = 10 meter.
175
203
  const cameraPosition = this._cameraService.camera.position;
176
204
  const isCameraWithinObject = floorPlaneItemBox.containsPoint(cameraPosition);
177
205
  if (!isCameraWithinObject) {
@@ -187,6 +215,29 @@ export class RenderControlsComponent {
187
215
  this.hasError = false;
188
216
  }
189
217
  }
218
+ getRenderScenesFromSettings() {
219
+ if (this._settingsService.settings.blenderSceneSettings && this._settingsService.settings.blenderSceneSettings.scenes) {
220
+ const scenes = this._settingsService.settings.blenderSceneSettings.scenes.filter(scene => scene.sceneType === BlenderSceneType.Room);
221
+ for (const scene of scenes) {
222
+ this.sceneList.push(scene);
223
+ }
224
+ }
225
+ else {
226
+ const fallback = new BlenderSceneSetting();
227
+ fallback.name = 'scene_grass_cycles_MRP';
228
+ fallback.multiSceneRender = false;
229
+ fallback.primarySceneName = 'scene_grass_cycles_MRP';
230
+ fallback.hdriIntensity = 1;
231
+ fallback.hdriRotation = 0;
232
+ fallback.lightingExposure = 1;
233
+ fallback.sceneType = BlenderSceneType.Room;
234
+ this.sceneList.push(fallback);
235
+ }
236
+ this.selectedRenderScene = this.sceneList[0]; // Select the first one and set the values.
237
+ this.hdriIntensity = this.selectedRenderScene.hdriIntensity;
238
+ this.hdriRotation = this.selectedRenderScene.hdriRotation;
239
+ this.lightingExposure = this.selectedRenderScene.lightingExposure;
240
+ }
190
241
  _getObjectsByName(scene, name) {
191
242
  const matchingObjects = [];
192
243
  scene.traverse((object) => {
@@ -196,418 +247,453 @@ export class RenderControlsComponent {
196
247
  });
197
248
  return matchingObjects;
198
249
  }
250
+ _allowCulling(cameraOutsideRoom) {
251
+ // if the camera is out of the room, cameraOutsideRoom will be true
252
+ // If true, we need to use culling
253
+ return cameraOutsideRoom; // If the camera is NOT within the room, we may use culling.
254
+ // Leave this code for now, when we pick up culling again we should make sure that we also use it to check if we may cull
255
+ // const floorPlanes: any = this._roomService.floorPlanes();
256
+ // if (floorPlanes.length > 1) {
257
+ // allowCulling = false;
258
+ // }
259
+ // return allowCulling;
260
+ }
199
261
  }
200
- RenderControlsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RenderControlsComponent, deps: [{ token: i1.RenderService }, { token: i2.MessageBusService }, { token: i3.ViewModeService }, { token: i4.HomedecoratorSettingsService }, { token: i5.HomedecoratorIconCacheService }, { token: i6.MatDialog }, { token: i7.SceneService }, { token: i8.CameraService }, { token: i9.ConfigurationService }, { token: i4.HomedecoratorSettingsService }, { token: i10.NewRenderService }, { token: i11.UtilsService }], target: i0.ɵɵFactoryTarget.Component });
262
+ RenderControlsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RenderControlsComponent, deps: [{ token: i1.RenderService }, { token: i2.MessageBusService }, { token: i3.ViewModeService }, { token: i4.HomedecoratorSettingsService }, { token: i5.HomedecoratorIconCacheService }, { token: i6.MatDialog }, { token: i7.SceneService }, { token: i8.CameraService }, { token: i9.ConfigurationService }, { token: i4.HomedecoratorSettingsService }, { token: i10.NewRenderService }, { token: i11.UtilsService }, { token: i12.RoomService }, { token: i13.WallMeasurementsService }], target: i0.ɵɵFactoryTarget.Component });
201
263
  RenderControlsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: RenderControlsComponent, selector: "rp-render-controls", viewQueries: [{ propertyName: "renderButton", first: true, predicate: ["renderButton"], descendants: true }], ngImport: i0, template: `
202
- <div class="render-container"
203
- *ngIf="renderService.serverData && renderService.serverData.renderMode !== renderService.renderModes.RenderShop">
204
- <div class="render-progress"
205
- *ngIf="renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning || renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess">
206
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress === 100 ? "RENDER_READY" : "") | localize }}
207
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress !== 100 ? "RENDER_STOPPED" : "") | localize }}
208
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning) ? renderService.currentQueueRenderItem.renderProgress + "%" : "" }}
209
- </div>
210
- <!-- the Yellow render indicators -->
211
- <div class="render-indicators" *ngIf="inPictureMode">
212
- <div class="render-indicator-top-left"></div>
213
- <div class="render-indicator-top-right"></div>
214
- <div class="render-indicator-bottom-left"></div>
215
- <div class="render-indicator-bottom-right"></div>
216
- </div>
217
- <div class="render-popup-container" *ngIf="inPictureMode">
218
- <div class="render-popup-header">
219
- <h3>
220
- <span>{{ 'PICTURE_MODE' | localize }}</span>
221
- <co-icon class="renderErrorIcon" *ngIf="hasError" [iconData]="iconService.getIcon(icons.TriangleExclamation)"
222
- [matTooltip]="'BLENDER_RENDER_ERROR' | localize"></co-icon>
223
- </h3>
224
-
225
- <button
226
- class="close-popup-container"
227
- (click)="resetBlenderRenderScene()">
228
- <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
229
- </button>
230
- </div>
231
- <div class="render-popup-preview">
264
+ <div class="render-container"
265
+ *ngIf="renderService.serverData && renderService.serverData.renderMode !== renderService.renderModes.RenderShop">
266
+ <div class="render-progress"
267
+ *ngIf="renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning || renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess">
268
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress === 100 ? "RENDER_READY" : "") | localize }}
269
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress !== 100 ? "RENDER_STOPPED" : "") | localize }}
270
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning) ? renderService.currentQueueRenderItem.renderProgress + "%" : "" }}
271
+ </div>
272
+ <!-- the Yellow render indicators -->
273
+ <div class="render-indicators" *ngIf="inPictureMode">
274
+ <div class="render-indicator-top-left"></div>
275
+ <div class="render-indicator-top-right"></div>
276
+ <div class="render-indicator-bottom-left"></div>
277
+ <div class="render-indicator-bottom-right"></div>
278
+ </div>
279
+ <div class="render-popup-container" *ngIf="inPictureMode">
280
+ <div class="render-popup-header">
281
+ <h3>
282
+ <span>{{ 'PICTURE_MODE' | localize }}</span>
283
+ <co-icon class="renderErrorIcon" *ngIf="hasError" [iconData]="iconService.getIcon(icons.TriangleExclamation)"
284
+ [matTooltip]="'BLENDER_RENDER_ERROR' | localize"></co-icon>
285
+ </h3>
232
286
 
233
- <ng-container *ngIf="blenderPreviewRender">
234
- <img [src]="blenderPreviewRender" alt="">
235
- </ng-container>
287
+ <button
288
+ class="close-popup-container"
289
+ (click)="resetBlenderRenderScene()">
290
+ <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
291
+ </button>
292
+ </div>
293
+ <div class="render-popup-preview">
236
294
 
237
- <ng-container *ngIf="!blenderPreviewRender">
238
- <div class="render-popup-preview-placeholder">
239
- <span>{{ 'PREVIEW' | localize }}</span>
240
- </div>
241
- </ng-container>
295
+ <ng-container *ngIf="blenderPreviewRender">
296
+ <img [src]="blenderPreviewRender" alt="">
297
+ </ng-container>
242
298
 
243
- <button
244
- class="render-popup-refresh-preview"
245
- (click)="getPreviewRender()"
246
- >
247
- <co-icon [iconData]="iconService.getIcon(icons.RetryButton)"></co-icon>
248
- </button>
249
- </div>
250
- <div *ngIf="renderService.blendFilesRender" class="render-popup-dropdown">
251
- <div class="toggleable" (click)="toggleRenderSettings()">
252
- <p>
253
- <span *ngIf="!showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_SHOW' | localize"></span>
254
- <span *ngIf="showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_HIDE' | localize"></span>
255
- </p>
256
- <co-icon [ngClass]="{'icon-rotate': showRenderSettings}" [iconData]="iconService.getIcon(icons.ArrowPointDown)"></co-icon>
257
- </div>
258
- <div class="advanced-render-settings" *ngIf="showRenderSettings">
259
- <div class="setting-part-container">
260
- <mat-form-field
261
- class="face-select-form"
262
- *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
263
- <mat-label>{{ "ENVIRONMENT" | localize }}</mat-label>
264
- <mat-select [(ngModel)]="renderService.selectedRenderScene">
265
- <mat-option
266
- *ngFor="let scene of renderService.renderScenes"
267
- [value]="scene.sceneAssetId">{{ scene.name }}
268
- </mat-option>
269
- </mat-select>
270
- </mat-form-field>
271
- </div>
299
+ <ng-container *ngIf="!blenderPreviewRender">
300
+ <div class="render-popup-preview-placeholder">
301
+ <span>{{ 'PREVIEW' | localize }}</span>
302
+ </div>
303
+ </ng-container>
272
304
 
273
- <div class="setting-part-container">
274
- <mat-form-field class="third-width">
275
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
276
- <mat-label [textContent]="'ENVIRONMENT_LIGHT' | localize"></mat-label>
277
- <input matInput [(ngModel)]="hdriIntensity">
278
- </mat-form-field>
279
- <div class="setting-part-buttons">
280
- <button class="amount-button" (click)="hdriIntensity = +hdriIntensity - 1">
281
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
282
- </button>
283
- <button class="amount-button" (click)="hdriIntensity = +hdriIntensity + 1">
284
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
285
- </button>
286
- </div>
287
- <div class="setting-part-slider">
288
- <mat-slider class="value" min="0" max="200" step="1" [value]="hdriIntensity" [(ngModel)]="hdriIntensity"></mat-slider>
289
- </div>
290
- </div>
305
+ <button
306
+ class="render-popup-refresh-preview"
307
+ (click)="getPreviewRender()"
308
+ >
309
+ <co-icon [iconData]="iconService.getIcon(icons.RetryButton)"></co-icon>
310
+ </button>
311
+ </div>
312
+ <div *ngIf="renderService.blendFilesRender" class="render-popup-dropdown">
313
+ <div class="toggleable" (click)="toggleRenderSettings()">
314
+ <p>
315
+ <span *ngIf="!showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_SHOW' | localize"></span>
316
+ <span *ngIf="showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_HIDE' | localize"></span>
317
+ </p>
318
+ <co-icon [ngClass]="{'icon-rotate': showRenderSettings}"
319
+ [iconData]="iconService.getIcon(icons.ArrowPointDown)"></co-icon>
320
+ </div>
321
+ <div class="advanced-render-settings" *ngIf="showRenderSettings">
322
+ <div class="setting-part-container">
323
+ <mat-form-field
324
+ class="face-select-form"
325
+ *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
326
+ <mat-label>{{ "ENVIRONMENT" | localize }}</mat-label>
327
+ <mat-select [(ngModel)]="selectedRenderScene" (selectionChange)="updateBlenderSceneSettings($event)">
328
+ <mat-option
329
+ *ngFor="let scene of sceneList"
330
+ [value]="scene">{{ scene.name }}
331
+ </mat-option>
332
+ </mat-select>
333
+ </mat-form-field>
334
+ </div>
291
335
 
292
- <div class="setting-part-container">
293
- <mat-form-field class="third-width">
294
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
295
- <mat-label [textContent]="'ROTATION' | localize"></mat-label>
296
- <input matInput [(ngModel)]="hdriRotation">
297
- </mat-form-field>
298
- <div class="setting-part-buttons">
299
- <button class="amount-button" (click)="hdriRotation = +hdriRotation - 1">
300
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
301
- </button>
302
- <button class="amount-button" (click)="hdriRotation = +hdriRotation + 1">
303
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
304
- </button>
305
- </div>
306
- <div class="setting-part-slider">
307
- <mat-slider class="value" min="0" max="360" step="1" [value]="hdriRotation" [(ngModel)]="hdriRotation"></mat-slider>
308
- </div>
309
- </div>
336
+ <div class="setting-part-container">
337
+ <mat-form-field class="third-width">
338
+ <mat-label [textContent]="'ENVIRONMENT_LIGHT' | localize"></mat-label>
339
+ <input
340
+ [type]="'number'"
341
+ matInput
342
+ [(ngModel)]="hdriIntensity"
343
+ (ngModelChange)="hdriIntensity = +$event">
344
+ </mat-form-field>
345
+ <div class="setting-part-buttons">
346
+ <button class="amount-button" (click)="hdriIntensity = +hdriIntensity - 1">
347
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
348
+ </button>
349
+ <button class="amount-button" (click)="hdriIntensity = +hdriIntensity + 1">
350
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
351
+ </button>
352
+ </div>
353
+ <div class="setting-part-slider">
354
+ <mat-slider class="value" min="1" max="20" step="1" [value]="hdriIntensity"
355
+ [(ngModel)]="hdriIntensity"></mat-slider>
356
+ </div>
357
+ </div>
310
358
 
311
- <div class="setting-part-container">
312
- <mat-form-field class="third-width">
313
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
314
- <mat-label [textContent]="'LIGHTS' | localize"></mat-label>
315
- <input matInput [(ngModel)]="lightingExposure">
316
- </mat-form-field>
317
- <div class="setting-part-buttons">
318
- <button class="amount-button" (click)="lightingExposure = +lightingExposure - 1">
319
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
320
- </button>
321
- <button class="amount-button" (click)="lightingExposure = +lightingExposure + 1">
322
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
323
- </button>
324
- </div>
325
- <div class="setting-part-slider">
326
- <mat-slider class="value" min="1" max="10" step="1" [value]="lightingExposure" [(ngModel)]="lightingExposure"></mat-slider>
327
- </div>
328
- </div>
329
- </div>
359
+ <div class="setting-part-container">
360
+ <mat-form-field class="third-width">
361
+ <mat-label [textContent]="'ROTATION' | localize"></mat-label>
362
+ <input
363
+ [type]="'number'"
364
+ matInput
365
+ [(ngModel)]="hdriRotation"
366
+ (ngModelChange)="hdriRotation = +$event">
367
+ </mat-form-field>
368
+ <div class="setting-part-buttons">
369
+ <button class="amount-button" (click)="hdriRotation = +hdriRotation - 1">
370
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
371
+ </button>
372
+ <button class="amount-button" (click)="hdriRotation = +hdriRotation + 1">
373
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
374
+ </button>
375
+ </div>
376
+ <div class="setting-part-slider">
377
+ <mat-slider class="value" min="0" max="360" step="1" [value]="hdriRotation"
378
+ [(ngModel)]="hdriRotation"></mat-slider>
379
+ </div>
380
+ </div>
381
+ <div class="setting-part-container">
382
+ <mat-form-field class="third-width">
383
+ <mat-label [textContent]="'LIGHTS' | localize"></mat-label>
384
+ <input
385
+ [type]="'number'"
386
+ matInput
387
+ [(ngModel)]="lightingExposure"
388
+ (ngModelChange)="lightingExposure = +$event">
389
+ </mat-form-field>
390
+ <div class="setting-part-buttons">
391
+ <button class="amount-button" (click)="lightingExposure = +lightingExposure - 1">
392
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
393
+ </button>
394
+ <button class="amount-button" (click)="lightingExposure = +lightingExposure + 1">
395
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
396
+ </button>
397
+ </div>
398
+ <div class="setting-part-slider">
399
+ <mat-slider class="value" min="1" max="10" step="1" [value]="lightingExposure"
400
+ [(ngModel)]="lightingExposure"></mat-slider>
401
+ </div>
402
+ </div>
403
+ </div>
404
+ </div>
405
+ <div class="render-popup-dropdown" *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
406
+ <mat-form-field class="face-select-form">
407
+ <mat-label>{{ "IMAGE_SIZE" | localize }}</mat-label>
408
+ <mat-select [(ngModel)]="renderService.selectedImageSize">
409
+ <mat-option *ngFor="let size of renderService.imageSizes" [value]="size.id">{{ size.name }} {{ size.width }}
410
+ x{{ size.height }}
411
+ </mat-option>
412
+ </mat-select>
413
+ </mat-form-field>
414
+ </div>
415
+ <div class="render-popup-button-container">
416
+ <button class="render-popup-button photo-button"
417
+ *ngIf="!renderService.blendFilesRender"
418
+ (click)="startRenderingRoom()"
419
+ title="{{'MAKE_A_PICTURE' | localize}}"
420
+ [disabled]="disablePictureButton">
421
+ {{ 'MAKE_A_PICTURE' | localize }}
422
+ </button>
423
+ <button class="render-popup-button photo-button"
424
+ *ngIf="renderService.blendFilesRender"
425
+ (click)="createBlenderRender()"
426
+ title="{{'MAKE_A_PICTURE' | localize}}"
427
+ [disabled]="disablePictureButton">
428
+ <co-icon [iconData]="iconService.getIcon(icons.CircleCheck)"></co-icon>
429
+ {{ 'MAKE_A_PICTURE' | localize }}
430
+ </button>
431
+ <button
432
+ class="render-popup-button cancel-button"
433
+ (click)="resetBlenderRenderScene()">
434
+ <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
435
+ {{ 'CLOSE_PHOTO_MODE' | localize }}
436
+ </button>
437
+ </div>
438
+ </div>
330
439
 
331
- </div>
332
- <div class="render-popup-dropdown" *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
333
- <mat-form-field class="face-select-form">
334
- <mat-label>{{ "IMAGE_SIZE" | localize }}</mat-label>
335
- <mat-select [(ngModel)]="renderService.selectedImageSize">
336
- <mat-option *ngFor="let size of renderService.imageSizes" [value]="size.id">{{ size.name }} {{ size.width }}x{{ size.height }}
337
- </mat-option>
338
- </mat-select>
339
- </mat-form-field>
340
- </div>
341
- <div class="render-popup-button-container">
342
- <button class="render-popup-button photo-button"
343
- *ngIf="!renderService.blendFilesRender"
344
- (click)="startRenderingRoom()"
345
- title="{{'MAKE_A_PICTURE' | localize}}"
346
- [disabled]="disablePictureButton">
347
- {{ 'MAKE_A_PICTURE' | localize }}
348
- </button>
349
- <button class="render-popup-button photo-button"
350
- *ngIf="renderService.blendFilesRender"
351
- (click)="createBlenderRender()"
352
- title="{{'MAKE_A_PICTURE' | localize}}"
353
- [disabled]="disablePictureButton">
354
- <co-icon [iconData]="iconService.getIcon(icons.CircleCheck)"></co-icon>
355
- {{ 'MAKE_A_PICTURE' | localize }}
356
- </button>
357
- <button
358
- class="render-popup-button cancel-button"
359
- (click)="resetBlenderRenderScene()">
360
- <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
361
- {{ 'CLOSE_PHOTO_MODE' | localize }}
362
- </button>
363
- </div>
364
- </div>
440
+ <div class="render-warning" *ngIf="showCullingErrorDialog">
441
+ <div class="render-warming-header">
442
+ <h2>{{ 'BLENDER_RENDER_ERROR_TITLE' | localize }}</h2>
443
+ <div class="render-warning-close" (click)="showCullingErrorDialog = false">
444
+ <mat-icon class="homedecorator-material-icons">cancel</mat-icon>
445
+ </div>
446
+ </div>
447
+ <div class="render-warning-body">
448
+ <p>{{ 'BLENDER_RENDER_WARNING_CULLING' | localize }}</p>
449
+ </div>
450
+ <div class="render-warning-footer">
451
+ <button
452
+ class="render-popup-button cancel-button"
453
+ (click)="showCullingErrorDialog = false">
454
+ <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
455
+ {{ 'CLOSE' | localize }}
456
+ </button>
457
+ </div>
458
+ </div>
365
459
 
366
- <!-- <div class="render-warning" *ngIf="hasError">-->
367
- <!-- <div class="render-warming-header">-->
368
- <!-- <h2>{{ 'BLENDER_RENDER_ERROR_TITLE' | localize }}</h2>-->
369
- <!-- <div class="render-warning-close" (click)="hasError = false">-->
370
- <!-- <mat-icon class="homedecorator-material-icons">cancel</mat-icon>-->
371
- <!-- </div>-->
372
- <!-- </div>-->
373
- <!-- <div class="render-warning-body">-->
374
- <!-- <p>{{ 'BLENDER_RENDER_ERROR' | localize }}</p>-->
375
- <!-- </div>-->
376
- <!-- <div class="render-warning-footer">-->
377
- <!-- <button-->
378
- <!-- class="render-popup-button cancel-button"-->
379
- <!-- (click)="hasError = false">-->
380
- <!-- <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>-->
381
- <!-- {{ 'CLOSE' | localize }}-->
382
- <!-- </button>-->
383
- <!-- </div>-->
384
- <!-- </div>-->
385
-
386
- <button
387
- #renderButton
388
- mat-raised-button
389
- matTooltip="{{'RENDER_TAKE_A_PICTURE' | localize}}"
390
- [id]="'standalone_render_picture'"
391
- [class.active]="(
460
+ <button
461
+ #renderButton
462
+ mat-raised-button
463
+ matTooltip="{{'RENDER_TAKE_A_PICTURE' | localize}}"
464
+ [id]="'standalone_render_picture'"
465
+ [class.active]="(
392
466
  (renderService.serverData.renderMode === renderService.renderModes.RenderRoom && viewModeService.viewMode === viewModes.WalkThrough) ||
393
467
  (renderService.serverData.renderMode === renderService.renderModes.RenderIone))"
394
- (click)="showRenderForm($event)"
395
- >
396
- <mat-icon class="icon homedecorator-material-icons"
397
- aria-hidden="true">{{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning ? 'open_in_browser' : 'photo_camera') }}
398
- </mat-icon>
399
- </button>
400
- </div>
401
- `, isInline: true, styles: [".render-container{position:relative}.render-container .render-popup-container{background:rgba(255,255,255,.7);padding:10px 25px 25px;border-radius:5px;box-shadow:0 1px 5px #0000001f;max-width:275px}.render-container .render-popup-container .render-popup-header{display:flex;justify-content:space-between;font-family:inherit}.render-container .render-popup-container .render-popup-header h3{display:flex;justify-content:space-between}.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon{width:20px;height:20px;margin-left:20px}.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon svg,.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon svg polygon{fill:#dc143c}.render-container .render-popup-container .render-popup-header .close-popup-container{cursor:pointer;border:none;background:none;float:none;height:auto;width:auto}.render-container .render-popup-container .render-popup-button-container{display:flex;justify-content:space-between;font-family:inherit}.render-container .render-popup-container .render-popup-button-container .render-popup-button{float:none;width:100%;max-width:130px;border-radius:3px;cursor:pointer;border:none;display:flex;height:40px;align-items:center;justify-content:space-evenly}.render-container .render-popup-container .render-popup-button-container .render-popup-button ::ng-deep co-icon{display:inline-block;height:18px;width:18px}.render-container .render-popup-container .render-popup-button-container .render-popup-button ::ng-deep co-icon svg path{fill:#fff}.render-container .render-popup-container .render-popup-button-container .photo-button{color:#fff;background-color:#dda73f}.render-container .render-popup-container .render-popup-button-container .cancel-button{color:#fff;background-color:#5b6875}.render-container .render-popup-container .render-popup-preview{background-color:#fff;min-height:150px;min-width:275px;margin:5px 0;position:relative;width:275px;height:150px}.render-container .render-popup-container .render-popup-preview .render-popup-preview-placeholder{background-color:#fff;display:flex;justify-content:space-around;align-items:center;vertical-align:middle;min-height:150px;border:1px solid #ddd;color:#ddd;font-size:14px}.render-container .render-popup-container .render-popup-preview .render-popup-refresh-preview{position:absolute;bottom:0;right:0;cursor:pointer;border-radius:0;border:none;height:30px;width:30px;background-color:#dda73f;color:#fff;margin:0}.render-container .render-popup-container .render-popup-preview .render-popup-refresh-preview ::ng-deep co-icon svg path{fill:#fff}.render-container .render-popup-container .render-popup-dropdown{margin:5px 0;width:100%}.render-container .render-popup-container .render-popup-dropdown .toggleable{cursor:pointer;display:flex;justify-content:right;align-content:center}.render-container .render-popup-container .render-popup-dropdown .toggleable p{padding:0;margin:0;font-size:12px;line-height:30px}.render-container .render-popup-container .render-popup-dropdown .toggleable .icon-rotate{transform:rotate(180deg)}.render-container .render-popup-container .render-popup-dropdown .mat-form-field{width:100%;font-size:14px}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-flex{background-color:#fff;color:#000;padding:3px 6px;border:1px solid #ddd}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-underline{display:none}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}.render-container .render-popup-container .render-popup-dropdown .setting-part-container{display:flex;justify-content:space-between;align-items:center;margin-bottom:5px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .third-width{width:32%}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button{float:none;box-sizing:border-box;padding:2px;background:none;cursor:pointer;border:none;width:25px;height:25px;margin:0 5px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button co-icon{display:block;width:25px;height:25px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button co-icon ::ng-deep svg{fill:#5b6875}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-slider .mat-slider-horizontal{min-width:110px;height:28px}.render-container .render-progress{float:left;min-width:50px;border-radius:25px;line-height:50px;text-align:center;padding:0 60px 0 20px;background:#fff;color:#74b77f;font-weight:bold;margin:0 -50px 0 0}.render-container .render-input-container{float:right}.render-container .render-input-container input{width:100px;height:24px;margin:5px 0;padding:0 10px;font-size:14px}.render-container button{pointer-events:all;width:50px;height:50px;float:right;border-radius:100%;position:relative;z-index:2;margin-bottom:10px}.render-container button.active{background:#74B77F;color:#fff}.render-container button>*{pointer-events:none}.render-indicators div{position:fixed;width:100px;height:100px}.render-indicators .render-indicator-top-left{left:5vw;top:10vh;border-left:10px solid #dda73f;border-top:10px solid #dda73f;border-top-left-radius:20px}.render-indicators .render-indicator-top-right{right:5vw;top:10vh;border-right:10px solid #dda73f;border-top:10px solid #dda73f;border-top-right-radius:20px}.render-indicators .render-indicator-bottom-left{left:5vw;bottom:5vh;border-left:10px solid #dda73f;border-bottom:10px solid #dda73f;border-bottom-left-radius:20px}.render-indicators .render-indicator-bottom-right{right:5vw;bottom:5vh;border-right:10px solid #dda73f;border-bottom:10px solid #dda73f;border-bottom-right-radius:20px}.render-warning{width:500px;position:fixed;top:20%;left:calc(50% - 250px);border-radius:15px;box-sizing:border-box;background-color:#fff;box-shadow:1px 0 20px #0000001f}.render-warning .render-warming-header{display:flex;justify-content:space-between;border-bottom:1px solid #c5c3c6;padding:20px 20px 10px;align-items:center}.render-warning .render-warming-header h2{padding:0;margin:0}.render-warning .render-warming-header .render-warning-close mat-icon{fill:#c5c3c6;color:#c5c3c6;cursor:pointer;transition:all .2s ease}.render-warning .render-warming-header .render-warning-close:hover mat-icon{fill:#46494c;color:#46494c}.render-warning .render-warning-body{padding:10px 20px}.render-warning .render-warning-footer{display:flex;justify-content:center;padding:0 20px 10px}.render-warning .render-warning-footer .render-popup-button{float:none;width:110px;border-radius:3px;cursor:pointer;border:none;display:flex;height:40px;align-items:center;justify-content:space-evenly;color:#fff;background-color:#5b6875}.render-warning .render-warning-footer .render-popup-button ::ng-deep co-icon{display:inline-block;height:18px;width:18px}.render-warning .render-warning-footer .render-popup-button ::ng-deep co-icon svg path{fill:#fff}\n"], components: [{ type: i12.ɵb, selector: "co-icon", inputs: ["icon", "iconData"] }, { type: i13.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i14.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i15.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i16.MatSlider, selector: "mat-slider", inputs: ["disabled", "color", "tabIndex", "invert", "max", "min", "step", "thumbLabel", "tickInterval", "value", "vertical", "displayWith", "valueText"], outputs: ["change", "input", "valueChange"], exportAs: ["matSlider"] }, { type: i17.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { type: i18.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }], directives: [{ type: i19.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i20.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i19.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i13.MatLabel, selector: "mat-label" }, { type: i21.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i21.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i19.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i22.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i21.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }], pipes: { "localize": i23.LocalizePipe } });
468
+ (click)="showRenderForm($event)"
469
+ >
470
+ <mat-icon class="icon homedecorator-material-icons"
471
+ aria-hidden="true">{{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning ? 'open_in_browser' : 'photo_camera') }}
472
+ </mat-icon>
473
+ </button>
474
+ </div>
475
+ `, isInline: true, styles: [".render-container{position:relative}.render-container .render-popup-container{background:rgba(255,255,255,.7);padding:10px 25px 25px;border-radius:5px;box-shadow:0 1px 5px #0000001f;max-width:275px}.render-container .render-popup-container .render-popup-header{display:flex;justify-content:space-between;font-family:inherit}.render-container .render-popup-container .render-popup-header h3{display:flex;justify-content:space-between}.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon{width:20px;height:20px;margin-left:20px}.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon svg,.render-container .render-popup-container .render-popup-header h3 ::ng-deep .renderErrorIcon svg polygon{fill:#dc143c}.render-container .render-popup-container .render-popup-header .close-popup-container{cursor:pointer;border:none;background:none;float:none;height:auto;width:auto}.render-container .render-popup-container .render-popup-button-container{display:flex;justify-content:space-between;font-family:inherit}.render-container .render-popup-container .render-popup-button-container .render-popup-button{float:none;width:100%;max-width:130px;border-radius:3px;cursor:pointer;border:none;display:flex;height:40px;align-items:center;justify-content:space-evenly}.render-container .render-popup-container .render-popup-button-container .render-popup-button ::ng-deep co-icon{display:inline-block;height:18px;width:18px}.render-container .render-popup-container .render-popup-button-container .render-popup-button ::ng-deep co-icon svg path{fill:#fff}.render-container .render-popup-container .render-popup-button-container .photo-button{color:#fff;background-color:#dda73f}.render-container .render-popup-container .render-popup-button-container .cancel-button{color:#fff;background-color:#5b6875}.render-container .render-popup-container .render-popup-preview{background-color:#fff;min-height:150px;min-width:275px;margin:5px 0;position:relative;width:275px;height:150px}.render-container .render-popup-container .render-popup-preview .render-popup-preview-placeholder{background-color:#fff;display:flex;justify-content:space-around;align-items:center;vertical-align:middle;min-height:150px;border:1px solid #ddd;color:#ddd;font-size:14px}.render-container .render-popup-container .render-popup-preview .render-popup-refresh-preview{position:absolute;bottom:0;right:0;cursor:pointer;border-radius:0;border:none;height:30px;width:30px;background-color:#dda73f;color:#fff;margin:0}.render-container .render-popup-container .render-popup-preview .render-popup-refresh-preview ::ng-deep co-icon svg path{fill:#fff}.render-container .render-popup-container .render-popup-dropdown{margin:5px 0;width:100%}.render-container .render-popup-container .render-popup-dropdown .toggleable{cursor:pointer;display:flex;justify-content:right;align-content:center}.render-container .render-popup-container .render-popup-dropdown .toggleable p{padding:0;margin:0;font-size:12px;line-height:30px}.render-container .render-popup-container .render-popup-dropdown .toggleable .icon-rotate{transform:rotate(180deg)}.render-container .render-popup-container .render-popup-dropdown .mat-form-field{width:100%;font-size:14px}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-flex{background-color:#fff;color:#000;padding:3px 6px;border:1px solid #ddd}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-underline{display:none}.render-container .render-popup-container .render-popup-dropdown .mat-form-field ::ng-deep .mat-form-field-wrapper{padding-bottom:0}.render-container .render-popup-container .render-popup-dropdown .setting-part-container{display:flex;justify-content:space-between;align-items:center;margin-bottom:5px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .third-width{width:32%}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button{float:none;box-sizing:border-box;padding:2px;background:none;cursor:pointer;border:none;width:25px;height:25px;margin:0 5px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button co-icon{display:block;width:25px;height:25px}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-buttons .amount-button co-icon ::ng-deep svg{fill:#5b6875}.render-container .render-popup-container .render-popup-dropdown .setting-part-container .setting-part-slider .mat-slider-horizontal{min-width:110px;height:28px}.render-container .render-progress{float:left;min-width:50px;border-radius:25px;line-height:50px;text-align:center;padding:0 60px 0 20px;background:#fff;color:#74b77f;font-weight:bold;margin:0 -50px 0 0}.render-container .render-input-container{float:right}.render-container .render-input-container input{width:100px;height:24px;margin:5px 0;padding:0 10px;font-size:14px}.render-container button{pointer-events:all;width:50px;height:50px;float:right;border-radius:100%;position:relative;z-index:2;margin-bottom:10px}.render-container button.active{background:#74B77F;color:#fff}.render-container button>*{pointer-events:none}.render-indicators div{position:fixed;width:100px;height:100px}.render-indicators .render-indicator-top-left{left:5vw;top:10vh;border-left:10px solid #dda73f;border-top:10px solid #dda73f;border-top-left-radius:20px}.render-indicators .render-indicator-top-right{right:5vw;top:10vh;border-right:10px solid #dda73f;border-top:10px solid #dda73f;border-top-right-radius:20px}.render-indicators .render-indicator-bottom-left{left:5vw;bottom:5vh;border-left:10px solid #dda73f;border-bottom:10px solid #dda73f;border-bottom-left-radius:20px}.render-indicators .render-indicator-bottom-right{right:5vw;bottom:5vh;border-right:10px solid #dda73f;border-bottom:10px solid #dda73f;border-bottom-right-radius:20px}.render-warning{width:500px;position:fixed;top:20%;left:calc(50% - 250px);border-radius:15px;box-sizing:border-box;background-color:#fff;box-shadow:1px 0 20px #0000001f}.render-warning .render-warming-header{display:flex;justify-content:space-between;border-bottom:1px solid #c5c3c6;padding:20px 20px 10px;align-items:center}.render-warning .render-warming-header h2{padding:0;margin:0}.render-warning .render-warming-header .render-warning-close mat-icon{fill:#c5c3c6;color:#c5c3c6;cursor:pointer;transition:all .2s ease}.render-warning .render-warming-header .render-warning-close:hover mat-icon{fill:#46494c;color:#46494c}.render-warning .render-warning-body{padding:10px 20px}.render-warning .render-warning-footer{display:flex;justify-content:center;padding:0 20px 10px}.render-warning .render-warning-footer .render-popup-button{float:none;width:110px;border-radius:3px;cursor:pointer;border:none;display:flex;height:40px;align-items:center;justify-content:space-evenly;color:#fff;background-color:#5b6875}.render-warning .render-warning-footer .render-popup-button ::ng-deep co-icon{display:inline-block;height:18px;width:18px}.render-warning .render-warning-footer .render-popup-button ::ng-deep co-icon svg path{fill:#fff}\n"], components: [{ type: i14.ɵb, selector: "co-icon", inputs: ["icon", "iconData"] }, { type: i15.MatFormField, selector: "mat-form-field", inputs: ["color", "floatLabel", "appearance", "hideRequiredMarker", "hintLabel"], exportAs: ["matFormField"] }, { type: i16.MatSelect, selector: "mat-select", inputs: ["disabled", "disableRipple", "tabIndex"], exportAs: ["matSelect"] }, { type: i17.MatOption, selector: "mat-option", exportAs: ["matOption"] }, { type: i18.MatSlider, selector: "mat-slider", inputs: ["disabled", "color", "tabIndex", "invert", "max", "min", "step", "thumbLabel", "tickInterval", "value", "vertical", "displayWith", "valueText"], outputs: ["change", "input", "valueChange"], exportAs: ["matSlider"] }, { type: i19.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { type: i20.MatButton, selector: "button[mat-button], button[mat-raised-button], button[mat-icon-button], button[mat-fab], button[mat-mini-fab], button[mat-stroked-button], button[mat-flat-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }], directives: [{ type: i21.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i22.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { type: i21.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i15.MatLabel, selector: "mat-label" }, { type: i23.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i23.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { type: i21.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i24.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["id", "disabled", "required", "type", "value", "readonly", "placeholder", "errorStateMatcher", "aria-describedby"], exportAs: ["matInput"] }, { type: i23.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }], pipes: { "localize": i25.LocalizePipe } });
402
476
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: RenderControlsComponent, decorators: [{
403
477
  type: Component,
404
478
  args: [{
405
479
  selector: 'rp-render-controls',
406
480
  template: `
407
- <div class="render-container"
408
- *ngIf="renderService.serverData && renderService.serverData.renderMode !== renderService.renderModes.RenderShop">
409
- <div class="render-progress"
410
- *ngIf="renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning || renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess">
411
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress === 100 ? "RENDER_READY" : "") | localize }}
412
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress !== 100 ? "RENDER_STOPPED" : "") | localize }}
413
- {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning) ? renderService.currentQueueRenderItem.renderProgress + "%" : "" }}
414
- </div>
415
- <!-- the Yellow render indicators -->
416
- <div class="render-indicators" *ngIf="inPictureMode">
417
- <div class="render-indicator-top-left"></div>
418
- <div class="render-indicator-top-right"></div>
419
- <div class="render-indicator-bottom-left"></div>
420
- <div class="render-indicator-bottom-right"></div>
421
- </div>
422
- <div class="render-popup-container" *ngIf="inPictureMode">
423
- <div class="render-popup-header">
424
- <h3>
425
- <span>{{ 'PICTURE_MODE' | localize }}</span>
426
- <co-icon class="renderErrorIcon" *ngIf="hasError" [iconData]="iconService.getIcon(icons.TriangleExclamation)"
427
- [matTooltip]="'BLENDER_RENDER_ERROR' | localize"></co-icon>
428
- </h3>
429
-
430
- <button
431
- class="close-popup-container"
432
- (click)="resetBlenderRenderScene()">
433
- <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
434
- </button>
435
- </div>
436
- <div class="render-popup-preview">
437
-
438
- <ng-container *ngIf="blenderPreviewRender">
439
- <img [src]="blenderPreviewRender" alt="">
440
- </ng-container>
481
+ <div class="render-container"
482
+ *ngIf="renderService.serverData && renderService.serverData.renderMode !== renderService.renderModes.RenderShop">
483
+ <div class="render-progress"
484
+ *ngIf="renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning || renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess">
485
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress === 100 ? "RENDER_READY" : "") | localize }}
486
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsSuccess && renderService.currentQueueRenderItem.renderProgress !== 100 ? "RENDER_STOPPED" : "") | localize }}
487
+ {{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning) ? renderService.currentQueueRenderItem.renderProgress + "%" : "" }}
488
+ </div>
489
+ <!-- the Yellow render indicators -->
490
+ <div class="render-indicators" *ngIf="inPictureMode">
491
+ <div class="render-indicator-top-left"></div>
492
+ <div class="render-indicator-top-right"></div>
493
+ <div class="render-indicator-bottom-left"></div>
494
+ <div class="render-indicator-bottom-right"></div>
495
+ </div>
496
+ <div class="render-popup-container" *ngIf="inPictureMode">
497
+ <div class="render-popup-header">
498
+ <h3>
499
+ <span>{{ 'PICTURE_MODE' | localize }}</span>
500
+ <co-icon class="renderErrorIcon" *ngIf="hasError" [iconData]="iconService.getIcon(icons.TriangleExclamation)"
501
+ [matTooltip]="'BLENDER_RENDER_ERROR' | localize"></co-icon>
502
+ </h3>
441
503
 
442
- <ng-container *ngIf="!blenderPreviewRender">
443
- <div class="render-popup-preview-placeholder">
444
- <span>{{ 'PREVIEW' | localize }}</span>
445
- </div>
446
- </ng-container>
504
+ <button
505
+ class="close-popup-container"
506
+ (click)="resetBlenderRenderScene()">
507
+ <co-icon [iconData]="iconService.getIcon(icons.Cross)"></co-icon>
508
+ </button>
509
+ </div>
510
+ <div class="render-popup-preview">
447
511
 
448
- <button
449
- class="render-popup-refresh-preview"
450
- (click)="getPreviewRender()"
451
- >
452
- <co-icon [iconData]="iconService.getIcon(icons.RetryButton)"></co-icon>
453
- </button>
454
- </div>
455
- <div *ngIf="renderService.blendFilesRender" class="render-popup-dropdown">
456
- <div class="toggleable" (click)="toggleRenderSettings()">
457
- <p>
458
- <span *ngIf="!showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_SHOW' | localize"></span>
459
- <span *ngIf="showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_HIDE' | localize"></span>
460
- </p>
461
- <co-icon [ngClass]="{'icon-rotate': showRenderSettings}" [iconData]="iconService.getIcon(icons.ArrowPointDown)"></co-icon>
462
- </div>
463
- <div class="advanced-render-settings" *ngIf="showRenderSettings">
464
- <div class="setting-part-container">
465
- <mat-form-field
466
- class="face-select-form"
467
- *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
468
- <mat-label>{{ "ENVIRONMENT" | localize }}</mat-label>
469
- <mat-select [(ngModel)]="renderService.selectedRenderScene">
470
- <mat-option
471
- *ngFor="let scene of renderService.renderScenes"
472
- [value]="scene.sceneAssetId">{{ scene.name }}
473
- </mat-option>
474
- </mat-select>
475
- </mat-form-field>
476
- </div>
512
+ <ng-container *ngIf="blenderPreviewRender">
513
+ <img [src]="blenderPreviewRender" alt="">
514
+ </ng-container>
477
515
 
478
- <div class="setting-part-container">
479
- <mat-form-field class="third-width">
480
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
481
- <mat-label [textContent]="'ENVIRONMENT_LIGHT' | localize"></mat-label>
482
- <input matInput [(ngModel)]="hdriIntensity">
483
- </mat-form-field>
484
- <div class="setting-part-buttons">
485
- <button class="amount-button" (click)="hdriIntensity = +hdriIntensity - 1">
486
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
487
- </button>
488
- <button class="amount-button" (click)="hdriIntensity = +hdriIntensity + 1">
489
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
490
- </button>
491
- </div>
492
- <div class="setting-part-slider">
493
- <mat-slider class="value" min="0" max="200" step="1" [value]="hdriIntensity" [(ngModel)]="hdriIntensity"></mat-slider>
494
- </div>
495
- </div>
516
+ <ng-container *ngIf="!blenderPreviewRender">
517
+ <div class="render-popup-preview-placeholder">
518
+ <span>{{ 'PREVIEW' | localize }}</span>
519
+ </div>
520
+ </ng-container>
496
521
 
497
- <div class="setting-part-container">
498
- <mat-form-field class="third-width">
499
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
500
- <mat-label [textContent]="'ROTATION' | localize"></mat-label>
501
- <input matInput [(ngModel)]="hdriRotation">
502
- </mat-form-field>
503
- <div class="setting-part-buttons">
504
- <button class="amount-button" (click)="hdriRotation = +hdriRotation - 1">
505
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
506
- </button>
507
- <button class="amount-button" (click)="hdriRotation = +hdriRotation + 1">
508
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
509
- </button>
510
- </div>
511
- <div class="setting-part-slider">
512
- <mat-slider class="value" min="0" max="360" step="1" [value]="hdriRotation" [(ngModel)]="hdriRotation"></mat-slider>
513
- </div>
514
- </div>
522
+ <button
523
+ class="render-popup-refresh-preview"
524
+ (click)="getPreviewRender()"
525
+ >
526
+ <co-icon [iconData]="iconService.getIcon(icons.RetryButton)"></co-icon>
527
+ </button>
528
+ </div>
529
+ <div *ngIf="renderService.blendFilesRender" class="render-popup-dropdown">
530
+ <div class="toggleable" (click)="toggleRenderSettings()">
531
+ <p>
532
+ <span *ngIf="!showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_SHOW' | localize"></span>
533
+ <span *ngIf="showRenderSettings" [textContent]="'RENDER_ADVANCED_SETTINGS_HIDE' | localize"></span>
534
+ </p>
535
+ <co-icon [ngClass]="{'icon-rotate': showRenderSettings}"
536
+ [iconData]="iconService.getIcon(icons.ArrowPointDown)"></co-icon>
537
+ </div>
538
+ <div class="advanced-render-settings" *ngIf="showRenderSettings">
539
+ <div class="setting-part-container">
540
+ <mat-form-field
541
+ class="face-select-form"
542
+ *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
543
+ <mat-label>{{ "ENVIRONMENT" | localize }}</mat-label>
544
+ <mat-select [(ngModel)]="selectedRenderScene" (selectionChange)="updateBlenderSceneSettings($event)">
545
+ <mat-option
546
+ *ngFor="let scene of sceneList"
547
+ [value]="scene">{{ scene.name }}
548
+ </mat-option>
549
+ </mat-select>
550
+ </mat-form-field>
551
+ </div>
515
552
 
516
- <div class="setting-part-container">
517
- <mat-form-field class="third-width">
518
- <!--<mat-label [textContent]="'NAME' | localize"></mat-label>-->
519
- <mat-label [textContent]="'LIGHTS' | localize"></mat-label>
520
- <input matInput [(ngModel)]="lightingExposure">
521
- </mat-form-field>
522
- <div class="setting-part-buttons">
523
- <button class="amount-button" (click)="lightingExposure = +lightingExposure - 1">
524
- <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
525
- </button>
526
- <button class="amount-button" (click)="lightingExposure = +lightingExposure + 1">
527
- <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
528
- </button>
529
- </div>
530
- <div class="setting-part-slider">
531
- <mat-slider class="value" min="1" max="10" step="1" [value]="lightingExposure" [(ngModel)]="lightingExposure"></mat-slider>
532
- </div>
533
- </div>
534
- </div>
553
+ <div class="setting-part-container">
554
+ <mat-form-field class="third-width">
555
+ <mat-label [textContent]="'ENVIRONMENT_LIGHT' | localize"></mat-label>
556
+ <input
557
+ [type]="'number'"
558
+ matInput
559
+ [(ngModel)]="hdriIntensity"
560
+ (ngModelChange)="hdriIntensity = +$event">
561
+ </mat-form-field>
562
+ <div class="setting-part-buttons">
563
+ <button class="amount-button" (click)="hdriIntensity = +hdriIntensity - 1">
564
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
565
+ </button>
566
+ <button class="amount-button" (click)="hdriIntensity = +hdriIntensity + 1">
567
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
568
+ </button>
569
+ </div>
570
+ <div class="setting-part-slider">
571
+ <mat-slider class="value" min="1" max="20" step="1" [value]="hdriIntensity"
572
+ [(ngModel)]="hdriIntensity"></mat-slider>
573
+ </div>
574
+ </div>
535
575
 
536
- </div>
537
- <div class="render-popup-dropdown" *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
538
- <mat-form-field class="face-select-form">
539
- <mat-label>{{ "IMAGE_SIZE" | localize }}</mat-label>
540
- <mat-select [(ngModel)]="renderService.selectedImageSize">
541
- <mat-option *ngFor="let size of renderService.imageSizes" [value]="size.id">{{ size.name }} {{ size.width }}x{{ size.height }}
542
- </mat-option>
543
- </mat-select>
544
- </mat-form-field>
545
- </div>
546
- <div class="render-popup-button-container">
547
- <button class="render-popup-button photo-button"
548
- *ngIf="!renderService.blendFilesRender"
549
- (click)="startRenderingRoom()"
550
- title="{{'MAKE_A_PICTURE' | localize}}"
551
- [disabled]="disablePictureButton">
552
- {{ 'MAKE_A_PICTURE' | localize }}
553
- </button>
554
- <button class="render-popup-button photo-button"
555
- *ngIf="renderService.blendFilesRender"
556
- (click)="createBlenderRender()"
557
- title="{{'MAKE_A_PICTURE' | localize}}"
558
- [disabled]="disablePictureButton">
559
- <co-icon [iconData]="iconService.getIcon(icons.CircleCheck)"></co-icon>
560
- {{ 'MAKE_A_PICTURE' | localize }}
561
- </button>
562
- <button
563
- class="render-popup-button cancel-button"
564
- (click)="resetBlenderRenderScene()">
565
- <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
566
- {{ 'CLOSE_PHOTO_MODE' | localize }}
567
- </button>
568
- </div>
569
- </div>
576
+ <div class="setting-part-container">
577
+ <mat-form-field class="third-width">
578
+ <mat-label [textContent]="'ROTATION' | localize"></mat-label>
579
+ <input
580
+ [type]="'number'"
581
+ matInput
582
+ [(ngModel)]="hdriRotation"
583
+ (ngModelChange)="hdriRotation = +$event">
584
+ </mat-form-field>
585
+ <div class="setting-part-buttons">
586
+ <button class="amount-button" (click)="hdriRotation = +hdriRotation - 1">
587
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
588
+ </button>
589
+ <button class="amount-button" (click)="hdriRotation = +hdriRotation + 1">
590
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
591
+ </button>
592
+ </div>
593
+ <div class="setting-part-slider">
594
+ <mat-slider class="value" min="0" max="360" step="1" [value]="hdriRotation"
595
+ [(ngModel)]="hdriRotation"></mat-slider>
596
+ </div>
597
+ </div>
598
+ <div class="setting-part-container">
599
+ <mat-form-field class="third-width">
600
+ <mat-label [textContent]="'LIGHTS' | localize"></mat-label>
601
+ <input
602
+ [type]="'number'"
603
+ matInput
604
+ [(ngModel)]="lightingExposure"
605
+ (ngModelChange)="lightingExposure = +$event">
606
+ </mat-form-field>
607
+ <div class="setting-part-buttons">
608
+ <button class="amount-button" (click)="lightingExposure = +lightingExposure - 1">
609
+ <co-icon [iconData]="iconService.getIcon(icons.CircleMinusLight)"></co-icon>
610
+ </button>
611
+ <button class="amount-button" (click)="lightingExposure = +lightingExposure + 1">
612
+ <co-icon [iconData]="iconService.getIcon(icons.CirclePlusLight)"></co-icon>
613
+ </button>
614
+ </div>
615
+ <div class="setting-part-slider">
616
+ <mat-slider class="value" min="1" max="10" step="1" [value]="lightingExposure"
617
+ [(ngModel)]="lightingExposure"></mat-slider>
618
+ </div>
619
+ </div>
620
+ </div>
621
+ </div>
622
+ <div class="render-popup-dropdown" *ngIf="renderService.serverData.renderMode === renderModes.RenderRoom">
623
+ <mat-form-field class="face-select-form">
624
+ <mat-label>{{ "IMAGE_SIZE" | localize }}</mat-label>
625
+ <mat-select [(ngModel)]="renderService.selectedImageSize">
626
+ <mat-option *ngFor="let size of renderService.imageSizes" [value]="size.id">{{ size.name }} {{ size.width }}
627
+ x{{ size.height }}
628
+ </mat-option>
629
+ </mat-select>
630
+ </mat-form-field>
631
+ </div>
632
+ <div class="render-popup-button-container">
633
+ <button class="render-popup-button photo-button"
634
+ *ngIf="!renderService.blendFilesRender"
635
+ (click)="startRenderingRoom()"
636
+ title="{{'MAKE_A_PICTURE' | localize}}"
637
+ [disabled]="disablePictureButton">
638
+ {{ 'MAKE_A_PICTURE' | localize }}
639
+ </button>
640
+ <button class="render-popup-button photo-button"
641
+ *ngIf="renderService.blendFilesRender"
642
+ (click)="createBlenderRender()"
643
+ title="{{'MAKE_A_PICTURE' | localize}}"
644
+ [disabled]="disablePictureButton">
645
+ <co-icon [iconData]="iconService.getIcon(icons.CircleCheck)"></co-icon>
646
+ {{ 'MAKE_A_PICTURE' | localize }}
647
+ </button>
648
+ <button
649
+ class="render-popup-button cancel-button"
650
+ (click)="resetBlenderRenderScene()">
651
+ <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
652
+ {{ 'CLOSE_PHOTO_MODE' | localize }}
653
+ </button>
654
+ </div>
655
+ </div>
570
656
 
571
- <!-- <div class="render-warning" *ngIf="hasError">-->
572
- <!-- <div class="render-warming-header">-->
573
- <!-- <h2>{{ 'BLENDER_RENDER_ERROR_TITLE' | localize }}</h2>-->
574
- <!-- <div class="render-warning-close" (click)="hasError = false">-->
575
- <!-- <mat-icon class="homedecorator-material-icons">cancel</mat-icon>-->
576
- <!-- </div>-->
577
- <!-- </div>-->
578
- <!-- <div class="render-warning-body">-->
579
- <!-- <p>{{ 'BLENDER_RENDER_ERROR' | localize }}</p>-->
580
- <!-- </div>-->
581
- <!-- <div class="render-warning-footer">-->
582
- <!-- <button-->
583
- <!-- class="render-popup-button cancel-button"-->
584
- <!-- (click)="hasError = false">-->
585
- <!-- <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>-->
586
- <!-- {{ 'CLOSE' | localize }}-->
587
- <!-- </button>-->
588
- <!-- </div>-->
589
- <!-- </div>-->
657
+ <div class="render-warning" *ngIf="showCullingErrorDialog">
658
+ <div class="render-warming-header">
659
+ <h2>{{ 'BLENDER_RENDER_ERROR_TITLE' | localize }}</h2>
660
+ <div class="render-warning-close" (click)="showCullingErrorDialog = false">
661
+ <mat-icon class="homedecorator-material-icons">cancel</mat-icon>
662
+ </div>
663
+ </div>
664
+ <div class="render-warning-body">
665
+ <p>{{ 'BLENDER_RENDER_WARNING_CULLING' | localize }}</p>
666
+ </div>
667
+ <div class="render-warning-footer">
668
+ <button
669
+ class="render-popup-button cancel-button"
670
+ (click)="showCullingErrorDialog = false">
671
+ <co-icon [iconData]="iconService.getIcon(icons.CircleXmark)"></co-icon>
672
+ {{ 'CLOSE' | localize }}
673
+ </button>
674
+ </div>
675
+ </div>
590
676
 
591
- <button
592
- #renderButton
593
- mat-raised-button
594
- matTooltip="{{'RENDER_TAKE_A_PICTURE' | localize}}"
595
- [id]="'standalone_render_picture'"
596
- [class.active]="(
677
+ <button
678
+ #renderButton
679
+ mat-raised-button
680
+ matTooltip="{{'RENDER_TAKE_A_PICTURE' | localize}}"
681
+ [id]="'standalone_render_picture'"
682
+ [class.active]="(
597
683
  (renderService.serverData.renderMode === renderService.renderModes.RenderRoom && viewModeService.viewMode === viewModes.WalkThrough) ||
598
684
  (renderService.serverData.renderMode === renderService.renderModes.RenderIone))"
599
- (click)="showRenderForm($event)"
600
- >
601
- <mat-icon class="icon homedecorator-material-icons"
602
- aria-hidden="true">{{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning ? 'open_in_browser' : 'photo_camera') }}
603
- </mat-icon>
604
- </button>
605
- </div>
606
- `,
685
+ (click)="showRenderForm($event)"
686
+ >
687
+ <mat-icon class="icon homedecorator-material-icons"
688
+ aria-hidden="true">{{ (renderService.currentQueueRenderItem.renderStatus === renderStatus.IsRunning ? 'open_in_browser' : 'photo_camera') }}
689
+ </mat-icon>
690
+ </button>
691
+ </div>
692
+ `,
607
693
  styleUrls: ['./render-controls.component.scss']
608
694
  }]
609
- }], ctorParameters: function () { return [{ type: i1.RenderService }, { type: i2.MessageBusService }, { type: i3.ViewModeService }, { type: i4.HomedecoratorSettingsService }, { type: i5.HomedecoratorIconCacheService }, { type: i6.MatDialog }, { type: i7.SceneService }, { type: i8.CameraService }, { type: i9.ConfigurationService }, { type: i4.HomedecoratorSettingsService }, { type: i10.NewRenderService }, { type: i11.UtilsService }]; }, propDecorators: { renderButton: [{
695
+ }], ctorParameters: function () { return [{ type: i1.RenderService }, { type: i2.MessageBusService }, { type: i3.ViewModeService }, { type: i4.HomedecoratorSettingsService }, { type: i5.HomedecoratorIconCacheService }, { type: i6.MatDialog }, { type: i7.SceneService }, { type: i8.CameraService }, { type: i9.ConfigurationService }, { type: i4.HomedecoratorSettingsService }, { type: i10.NewRenderService }, { type: i11.UtilsService }, { type: i12.RoomService }, { type: i13.WallMeasurementsService }]; }, propDecorators: { renderButton: [{
610
696
  type: ViewChild,
611
697
  args: ['renderButton']
612
698
  }] } });
613
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLWNvbnRyb2xzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jbGllbnQvYXBwL3BsdWdpbnMvcmVuZGVyL3JlbmRlci1jb250cm9scy9yZW5kZXItY29udHJvbHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQWMsU0FBUyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRS9ELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxtQ0FBbUMsQ0FBQztBQUMzRCxPQUFPLEVBQUMsWUFBWSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFPbkQsT0FBTyxFQUFDLElBQUksRUFBRSxTQUFTLEVBQVksT0FBTyxFQUFDLE1BQU0sT0FBTyxDQUFDO0FBQ3pELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLDJDQUEyQyxDQUFDO0FBRTNFLE9BQU8sRUFBQyxXQUFXLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEVBQUMsZUFBZSxFQUFDLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBSWpFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWdOdEQsTUFBTSxPQUFPLHVCQUF1QjtJQVVsQyxZQUNTLGFBQTRCLEVBQzVCLGNBQWlDLEVBQ2pDLGVBQWdDLEVBQ2hDLGVBQTZDLEVBQzdDLFdBQTBDLEVBQ3pDLE9BQWtCLEVBQ2xCLGFBQTJCLEVBQzNCLGNBQTZCLEVBQzdCLHFCQUEyQyxFQUMzQyxnQkFBOEMsRUFDOUMsaUJBQW1DLEVBQ25DLGFBQTJCO1FBWDVCLGtCQUFhLEdBQWIsYUFBYSxDQUFlO1FBQzVCLG1CQUFjLEdBQWQsY0FBYyxDQUFtQjtRQUNqQyxvQkFBZSxHQUFmLGVBQWUs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RSxFQUFFO1lBQ3hCLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxJQUFJLEVBQUU7Z0JBQ3hCLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7YUFDOUI7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUNILE9BQU8sZUFBZSxDQUFDO0lBQ3pCLENBQUM7O3FIQWxMVSx1QkFBdUI7eUdBQXZCLHVCQUF1Qix3S0EzTXhCOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdNVDs0RkFHVSx1QkFBdUI7a0JBN01uQyxTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F3TVQ7b0JBQ0QsU0FBUyxFQUFFLENBQUMsa0NBQWtDLENBQUM7aUJBQ2hEO2tkQStDbUMsWUFBWTtzQkFBN0MsU0FBUzt1QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21wb25lbnQsIEVsZW1lbnRSZWYsIFZpZXdDaGlsZH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7TWF0RGlhbG9nfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xyXG5pbXBvcnQge1ZpZXdNb2RlfSBmcm9tICcuLi8uLi8uLi9jb3JlL2VudW0vdmlldy1tb2RlLmVudW0nO1xyXG5pbXBvcnQge1JlbmRlclN0YXR1c30gZnJvbSAnLi4vZW51bS9yZW5kZXItc3RhdHVzJztcclxuaW1wb3J0IHtSZW5kZXJTZXJ2aWNlfSBmcm9tICcuLi9zZXJ2aWNlL3JlbmRlci5zZXJ2aWNlJztcclxuaW1wb3J0IHtWaWV3TW9kZVNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZS92aWV3LW1vZGUuc2VydmljZSc7XHJcbmltcG9ydCB7SG9tZWRlY29yYXRvclNldHRpbmdzU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlL2hvbWVkZWNvcmF0b3Itc2V0dGluZ3Muc2VydmljZSc7XHJcbmltcG9ydCB7TWVzc2FnZUJ1c1NlcnZpY2V9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZS9tZXNzYWdlLWJ1cy5zZXJ2aWNlJztcclxuaW1wb3J0IHtTY2VuZVNlcnZpY2V9IGZyb20gJy4uLy4uL2NvcmUzZC9zZXJ2aWNlL3NjZW5lLnNlcnZpY2UnO1xyXG5pbXBvcnQge0NhbWVyYVNlcnZpY2V9IGZyb20gJy4uLy4uL2NvcmUzZC9zZXJ2aWNlL2NhbWVyYS5zZXJ2aWNlJztcclxuaW1wb3J0IHtCb3gzLCBNYXRoVXRpbHMsIE9iamVjdDNELCBWZWN0b3IzfSBmcm9tICd0aHJlZSc7XHJcbmltcG9ydCB7Q29uZmlndXJhdGlvbktleX0gZnJvbSAnLi4vLi4vLi4vY29yZS9lbnVtL2NvbmZpZ3VyYXRpb24ta2V5LmVudW0nO1xyXG5pbXBvcnQge0NvbmZpZ3VyYXRpb25TZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9jb3JlL3NlcnZpY2UvY29uZmlndXJhdGlvbi5zZXJ2aWNlJztcclxuaW1wb3J0IHtSZW5kZXJNb2Rlc30gZnJvbSAnLi4vZW51bS9yZW5kZXItbW9kZXMnO1xyXG5pbXBvcnQge1JlbmRlclF1ZXVlSXRlbX0gZnJvbSAnLi4vbW9kZWwvcmVuZGVyLXF1ZXVlLWl0ZW0nO1xyXG5pbXBvcnQge01lc3NhZ2VUeXBlfSBmcm9tICcuLi8uLi8uLi9jb3JlL2VudW0vbWVzc2FnZS10eXBlLmVudW0nO1xyXG5pbXBvcnQge05ld1JlbmRlclNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2UvbmV3LXJlbmRlci5zZXJ2aWNlJztcclxuaW1wb3J0IHtVdGlsc1NlcnZpY2V9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZS91dGlscy5zZXJ2aWNlJztcclxuaW1wb3J0IHtTdWJzY3JpcHRpb259IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQge0ljb25FbnVtfSBmcm9tICcuLi8uLi8uLi9jb3JlL2VudW0vaWNvbi5lbnVtJztcclxuaW1wb3J0IHtIb21lZGVjb3JhdG9ySWNvbkNhY2hlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlL2hvbWVkZWNvcmF0b3ItaWNvbi1jYWNoZS5zZXJ2aWNlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAncnAtcmVuZGVyLWNvbnRyb2xzJyxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWNvbnRhaW5lclwiXHJcbiAgICAgICAgICAgKm5nSWY9XCJyZW5kZXJTZXJ2aWNlLnNlcnZlckRhdGEgJiYgIHJlbmRlclNlcnZpY2Uuc2VydmVyRGF0YS5yZW5kZXJNb2RlICE9PSByZW5kZXJTZXJ2aWNlLnJlbmRlck1vZGVzLlJlbmRlclNob3BcIj5cclxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItcHJvZ3Jlc3NcIlxyXG4gICAgICAgICAgICAgICAqbmdJZj1cInJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJTdGF0dXMgPT09IHJlbmRlclN0YXR1cy5Jc1J1bm5pbmcgfHwgcmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gcmVuZGVyU3RhdHVzLklzU3VjY2Vzc1wiPlxyXG4gICAgICAgICAgICAgIHt7IChyZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyU3RhdHVzID09PSByZW5kZXJTdGF0dXMuSXNTdWNjZXNzICYmIHJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJQcm9ncmVzcyA9PT0gMTAwID8gXCJSRU5ERVJfUkVBRFlcIiA6IFwiXCIpIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICB7eyAocmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gcmVuZGVyU3RhdHVzLklzU3VjY2VzcyAmJiByZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyUHJvZ3Jlc3MgIT09IDEwMCA/IFwiUkVOREVSX1NUT1BQRURcIiA6IFwiXCIpIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICB7eyAocmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gcmVuZGVyU3RhdHVzLklzUnVubmluZykgPyByZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyUHJvZ3Jlc3MgKyBcIiVcIiA6IFwiXCIgfX1cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPCEtLSB0aGUgWWVsbG93IHJlbmRlciBpbmRpY2F0b3JzIC0tPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1pbmRpY2F0b3JzXCIgKm5nSWY9XCJpblBpY3R1cmVNb2RlXCI+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1pbmRpY2F0b3ItdG9wLWxlZnRcIj48L2Rpdj5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWluZGljYXRvci10b3AtcmlnaHRcIj48L2Rpdj5cclxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWluZGljYXRvci1ib3R0b20tbGVmdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItaW5kaWNhdG9yLWJvdHRvbS1yaWdodFwiPjwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXBvcHVwLWNvbnRhaW5lclwiICpuZ0lmPVwiaW5QaWN0dXJlTW9kZVwiPlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItcG9wdXAtaGVhZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgIDxoMz5cclxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7ICdQSUNUVVJFX01PREUnIHwgbG9jYWxpemUgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBjbGFzcz1cInJlbmRlckVycm9ySWNvblwiICpuZ0lmPVwiaGFzRXJyb3JcIiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5UcmlhbmdsZUV4Y2xhbWF0aW9uKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCInQkxFTkRFUl9SRU5ERVJfRVJST1InIHwgbG9jYWxpemVcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgIDwvaDM+XHJcblxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjbG9zZS1wb3B1cC1jb250YWluZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldEJsZW5kZXJSZW5kZXJTY2VuZSgpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5Dcm9zcylcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItcG9wdXAtcHJldmlld1wiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImJsZW5kZXJQcmV2aWV3UmVuZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8aW1nIFtzcmNdPVwiYmxlbmRlclByZXZpZXdSZW5kZXJcIiBhbHQ9XCJcIj5cclxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWJsZW5kZXJQcmV2aWV3UmVuZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXBvcHVwLXByZXZpZXctcGxhY2Vob2xkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyAnUFJFVklFVycgfCBsb2NhbGl6ZSB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cclxuXHJcbiAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJlbmRlci1wb3B1cC1yZWZyZXNoLXByZXZpZXdcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJnZXRQcmV2aWV3UmVuZGVyKClcIlxyXG4gICAgICAgICAgICAgICAgICA+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5SZXRyeUJ1dHRvbilcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyZW5kZXJTZXJ2aWNlLmJsZW5kRmlsZXNSZW5kZXJcIiBjbGFzcz1cInJlbmRlci1wb3B1cC1kcm9wZG93blwiPlxyXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwidG9nZ2xlYWJsZVwiIChjbGljayk9XCJ0b2dnbGVSZW5kZXJTZXR0aW5ncygpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8cD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzaG93UmVuZGVyU2V0dGluZ3NcIiBbdGV4dENvbnRlbnRdPVwiJ1JFTkRFUl9BRFZBTkNFRF9TRVRUSU5HU19TSE9XJyB8IGxvY2FsaXplXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwic2hvd1JlbmRlclNldHRpbmdzXCIgW3RleHRDb250ZW50XT1cIidSRU5ERVJfQURWQU5DRURfU0VUVElOR1NfSElERScgfCBsb2NhbGl6ZVwiPjwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvcD5cclxuICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtuZ0NsYXNzXT1cInsnaWNvbi1yb3RhdGUnOiBzaG93UmVuZGVyU2V0dGluZ3N9XCIgW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQXJyb3dQb2ludERvd24pXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFkdmFuY2VkLXJlbmRlci1zZXR0aW5nc1wiICpuZ0lmPVwic2hvd1JlbmRlclNldHRpbmdzXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmYWNlLXNlbGVjdC1mb3JtXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicmVuZGVyU2VydmljZS5zZXJ2ZXJEYXRhLnJlbmRlck1vZGUgPT09IHJlbmRlck1vZGVzLlJlbmRlclJvb21cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBcIkVOVklST05NRU5UXCIgfCBsb2NhbGl6ZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBbKG5nTW9kZWwpXT1cInJlbmRlclNlcnZpY2Uuc2VsZWN0ZWRSZW5kZXJTY2VuZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb25cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHNjZW5lIG9mIHJlbmRlclNlcnZpY2UucmVuZGVyU2NlbmVzXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cInNjZW5lLnNjZW5lQXNzZXRJZFwiPnt7IHNjZW5lLm5hbWUgfX1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cInRoaXJkLXdpZHRoXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwhLS08bWF0LWxhYmVsIFt0ZXh0Q29udGVudF09XCInTkFNRScgfCBsb2NhbGl6ZVwiPjwvbWF0LWxhYmVsPi0tPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsIFt0ZXh0Q29udGVudF09XCInRU5WSVJPTk1FTlRfTElHSFQnIHwgbG9jYWxpemVcIj48L21hdC1sYWJlbD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0IG1hdElucHV0IFsobmdNb2RlbCldPVwiaGRyaUludGVuc2l0eVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1idXR0b25zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImhkcmlJbnRlbnNpdHkgPSAraGRyaUludGVuc2l0eSAtIDFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZU1pbnVzTGlnaHQpXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImFtb3VudC1idXR0b25cIiAoY2xpY2spPVwiaGRyaUludGVuc2l0eSA9ICtoZHJpSW50ZW5zaXR5ICsgMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvLWljb24gW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQ2lyY2xlUGx1c0xpZ2h0KVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1zbGlkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZXIgY2xhc3M9XCJ2YWx1ZVwiIG1pbj1cIjBcIiBtYXg9XCIyMDBcIiBzdGVwPVwiMVwiIFt2YWx1ZV09XCJoZHJpSW50ZW5zaXR5XCIgWyhuZ01vZGVsKV09XCJoZHJpSW50ZW5zaXR5XCI+PC9tYXQtc2xpZGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJ0aGlyZC13aWR0aFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG1hdC1sYWJlbCBbdGV4dENvbnRlbnRdPVwiJ05BTUUnIHwgbG9jYWxpemVcIj48L21hdC1sYWJlbD4tLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbCBbdGV4dENvbnRlbnRdPVwiJ1JPVEFUSU9OJyB8IGxvY2FsaXplXCI+PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dCBtYXRJbnB1dCBbKG5nTW9kZWwpXT1cImhkcmlSb3RhdGlvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1idXR0b25zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImhkcmlSb3RhdGlvbiA9ICtoZHJpUm90YXRpb24gLSAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVNaW51c0xpZ2h0KVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImhkcmlSb3RhdGlvbiA9ICtoZHJpUm90YXRpb24gKyAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVQbHVzTGlnaHQpXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LXNsaWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlciBjbGFzcz1cInZhbHVlXCIgbWluPVwiMFwiIG1heD1cIjM2MFwiIHN0ZXA9XCIxXCIgW3ZhbHVlXT1cImhkcmlSb3RhdGlvblwiIFsobmdNb2RlbCldPVwiaGRyaVJvdGF0aW9uXCI+PC9tYXQtc2xpZGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1jb250YWluZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJ0aGlyZC13aWR0aFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8IS0tPG1hdC1sYWJlbCBbdGV4dENvbnRlbnRdPVwiJ05BTUUnIHwgbG9jYWxpemVcIj48L21hdC1sYWJlbD4tLT5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbCBbdGV4dENvbnRlbnRdPVwiJ0xJR0hUUycgfCBsb2NhbGl6ZVwiPjwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgbWF0SW5wdXQgWyhuZ01vZGVsKV09XCJsaWdodGluZ0V4cG9zdXJlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWJ1dHRvbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImFtb3VudC1idXR0b25cIiAoY2xpY2spPVwibGlnaHRpbmdFeHBvc3VyZSA9ICtsaWdodGluZ0V4cG9zdXJlIC0gMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvLWljb24gW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQ2lyY2xlTWludXNMaWdodClcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYW1vdW50LWJ1dHRvblwiIChjbGljayk9XCJsaWdodGluZ0V4cG9zdXJlID0gK2xpZ2h0aW5nRXhwb3N1cmUgKyAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVQbHVzTGlnaHQpXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LXNsaWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlciBjbGFzcz1cInZhbHVlXCIgbWluPVwiMVwiIG1heD1cIjEwXCIgc3RlcD1cIjFcIiBbdmFsdWVdPVwibGlnaHRpbmdFeHBvc3VyZVwiIFsobmdNb2RlbCldPVwibGlnaHRpbmdFeHBvc3VyZVwiPjwvbWF0LXNsaWRlcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1wb3B1cC1kcm9wZG93blwiICpuZ0lmPVwicmVuZGVyU2VydmljZS5zZXJ2ZXJEYXRhLnJlbmRlck1vZGUgPT09IHJlbmRlck1vZGVzLlJlbmRlclJvb21cIj5cclxuICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZmFjZS1zZWxlY3QtZm9ybVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBcIklNQUdFX1NJWkVcIiB8IGxvY2FsaXplIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdCBbKG5nTW9kZWwpXT1cInJlbmRlclNlcnZpY2Uuc2VsZWN0ZWRJbWFnZVNpemVcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiAqbmdGb3I9XCJsZXQgc2l6ZSBvZiByZW5kZXJTZXJ2aWNlLmltYWdlU2l6ZXNcIiBbdmFsdWVdPVwic2l6ZS5pZFwiPnt7IHNpemUubmFtZSB9fSB7eyBzaXplLndpZHRoIH19eHt7IHNpemUuaGVpZ2h0IH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxyXG4gICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItcG9wdXAtYnV0dG9uLWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicmVuZGVyLXBvcHVwLWJ1dHRvbiBwaG90by1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXJlbmRlclNlcnZpY2UuYmxlbmRGaWxlc1JlbmRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInN0YXJ0UmVuZGVyaW5nUm9vbSgpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cInt7J01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlUGljdHVyZUJ1dHRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAge3sgJ01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplIH19XHJcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicmVuZGVyLXBvcHVwLWJ1dHRvbiBwaG90by1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwicmVuZGVyU2VydmljZS5ibGVuZEZpbGVzUmVuZGVyXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiY3JlYXRlQmxlbmRlclJlbmRlcigpXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cInt7J01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlUGljdHVyZUJ1dHRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgPGNvLWljb24gW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQ2lyY2xlQ2hlY2spXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAge3sgJ01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplIH19XHJcbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZW5kZXItcG9wdXAtYnV0dG9uIGNhbmNlbC1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldEJsZW5kZXJSZW5kZXJTY2VuZSgpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVYbWFyaylcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICB7eyAnQ0xPU0VfUEhPVE9fTU9ERScgfCBsb2NhbGl6ZSB9fVxyXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICAgIDwhLS0gICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXdhcm5pbmdcIiAqbmdJZj1cImhhc0Vycm9yXCI+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXdhcm1pbmctaGVhZGVyXCI+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICAgIDxoMj57eyAnQkxFTkRFUl9SRU5ERVJfRVJST1JfVElUTEUnIHwgbG9jYWxpemUgfX08L2gyPi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXdhcm5pbmctY2xvc2VcIiAoY2xpY2spPVwiaGFzRXJyb3IgPSBmYWxzZVwiPi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImhvbWVkZWNvcmF0b3ItbWF0ZXJpYWwtaWNvbnNcIj5jYW5jZWw8L21hdC1pY29uPi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgICA8L2Rpdj4tLT5cclxuICAgICAgICAgIDwhLS0gICAgICAgIDwvZGl2Pi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci13YXJuaW5nLWJvZHlcIj4tLT5cclxuICAgICAgICAgIDwhLS0gICAgICAgICAgPHA+e3sgJ0JMRU5ERVJfUkVOREVSX0VSUk9SJyB8IGxvY2FsaXplIH19PC9wPi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgPC9kaXY+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXdhcm5pbmctZm9vdGVyXCI+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICAgIDxidXR0b24tLT5cclxuICAgICAgICAgIDwhLS0gICAgICAgICAgICBjbGFzcz1cInJlbmRlci1wb3B1cC1idXR0b24gY2FuY2VsLWJ1dHRvblwiLS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICAgICAgKGNsaWNrKT1cImhhc0Vycm9yID0gZmFsc2VcIj4tLT5cclxuICAgICAgICAgIDwhLS0gICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVYbWFyaylcIj48L2NvLWljb24+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICAgICAge3sgJ0NMT1NFJyB8IGxvY2FsaXplIH19LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgICAgIDwvYnV0dG9uPi0tPlxyXG4gICAgICAgICAgPCEtLSAgICAgICAgPC9kaXY+LS0+XHJcbiAgICAgICAgICA8IS0tICAgICAgPC9kaXY+LS0+XHJcblxyXG4gICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAjcmVuZGVyQnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIG1hdC1yYWlzZWQtYnV0dG9uXHJcbiAgICAgICAgICAgICAgICAgIG1hdFRvb2x0aXA9XCJ7eydSRU5ERVJfVEFLRV9BX1BJQ1RVUkUnIHwgbG9jYWxpemV9fVwiXHJcbiAgICAgICAgICAgICAgICAgIFtpZF09XCInc3RhbmRhbG9uZV9yZW5kZXJfcGljdHVyZSdcIlxyXG4gICAgICAgICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIihcclxuICAgICAgICAocmVuZGVyU2VydmljZS5zZXJ2ZXJEYXRhLnJlbmRlck1vZGUgPT09IHJlbmRlclNlcnZpY2UucmVuZGVyTW9kZXMuUmVuZGVyUm9vbSAmJiB2aWV3TW9kZVNlcnZpY2Uudmlld01vZGUgPT09IHZpZXdNb2Rlcy5XYWxrVGhyb3VnaCkgfHxcclxuICAgICAgICAocmVuZGVyU2VydmljZS5zZXJ2ZXJEYXRhLnJlbmRlck1vZGUgPT09IHJlbmRlclNlcnZpY2UucmVuZGVyTW9kZXMuUmVuZGVySW9uZSkpXCJcclxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNob3dSZW5kZXJGb3JtKCRldmVudClcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImljb24gaG9tZWRlY29yYXRvci1tYXRlcmlhbC1pY29uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPnt7IChyZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyU3RhdHVzID09PSByZW5kZXJTdGF0dXMuSXNSdW5uaW5nID8gJ29wZW5faW5fYnJvd3NlcicgOiAncGhvdG9fY2FtZXJhJykgfX1cclxuICAgICAgICAgICAgICA8L21hdC1pY29uPlxyXG4gICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgIDwvZGl2PlxyXG4gIGAsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcmVuZGVyLWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFJlbmRlckNvbnRyb2xzQ29tcG9uZW50IHtcclxuICBwdWJsaWMgcmVhZG9ubHkgaWNvbnM6IHR5cGVvZiBJY29uRW51bSA9IEljb25FbnVtO1xyXG4gIHB1YmxpYyBibGVuZGVyUHJldmlld1JlbmRlcjogc3RyaW5nO1xyXG4gIHB1YmxpYyBoZHJpSW50ZW5zaXR5OiBudW1iZXIgPSAxMDA7XHJcbiAgcHVibGljIGhkcmlSb3RhdGlvbjogbnVtYmVyID0gMDtcclxuICBwdWJsaWMgbGlnaHRpbmdFeHBvc3VyZTogbnVtYmVyID0gMTtcclxuICBwdWJsaWMgc2hvd1JlbmRlclNldHRpbmdzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgX3N1YnM6IFN1YnNjcmlwdGlvbltdID0gW107XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHVibGljIHJlbmRlclNlcnZpY2U6IFJlbmRlclNlcnZpY2UsXHJcbiAgICBwdWJsaWMgbWVzc2FnZVNlcnZpY2U6IE1lc3NhZ2VCdXNTZXJ2aWNlLFxyXG4gICAgcHVibGljIHZpZXdNb2RlU2VydmljZTogVmlld01vZGVTZXJ2aWNlLFxyXG4gICAgcHVibGljIHNldHRpbmdzU2VydmljZTogSG9tZWRlY29yYXRvclNldHRpbmdzU2VydmljZSxcclxuICAgIHB1YmxpYyBpY29uU2VydmljZTogSG9tZWRlY29yYXRvckljb25DYWNoZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF9kaWFsb2c6IE1hdERpYWxvZyxcclxuICAgIHByaXZhdGUgX3NjZW5lU2VydmljZTogU2NlbmVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBfY2FtZXJhU2VydmljZTogQ2FtZXJhU2VydmljZSxcclxuICAgIHByaXZhdGUgX2NvbmZpZ3VyYXRpb25TZXJ2aWNlOiBDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgIHByaXZhdGUgX3NldHRpbmdzU2VydmljZTogSG9tZWRlY29yYXRvclNldHRpbmdzU2VydmljZSxcclxuICAgIHByaXZhdGUgX25ld1JlbmRlclNlcnZpY2U6IE5ld1JlbmRlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIF91dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZVxyXG4gICkge1xyXG4gICAgdGhpcy5fc3Vicy5wdXNoKFxyXG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLnN1YnNjcmliZShNZXNzYWdlVHlwZS5CbGVuZGVyUmVuZGVyUHJldmlld1JlYWR5LCAoZmlsZSkgPT4gdGhpcy5zaG93UHJldmlldyhmaWxlKSksXHJcbiAgICAgIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhTW92ZW1lbnRDaGFuZ2VkLnN1YnNjcmliZSgoKSA9PiB7XHJcbiAgICAgICAgdGhpcy52YWxpZGF0ZVJlbmRlclBvc2l0aW9uKCk7XHJcbiAgICAgICAgLy8gTWFrZSBzdXJlIHdoZW4gdGhlIGNhbWVyYSBtb3Zlcywgd2UgcmVjaGVjayB0aGUgcG9zaXRpb24gYW5kIGlmIHdlIHN0aWxsIG5lZWQgdG8gc2hvdyB0aGUgcmVuZGVyIHdhcm5pbmcuXHJcbiAgICAgIH0pLFxyXG4gICAgKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnZXQgZGlzYWJsZVBpY3R1cmVCdXR0b24oKTogYm9vbGVhbiB7XHJcbiAgICBpZiAodGhpcy5fc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzLm9wdGlvbnMudXNlTmV3UmVuZGVyKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLl9uZXdSZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyU3RhdHVzID09PSB0aGlzLnJlbmRlclN0YXR1cy5Jc1J1bm5pbmc7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXR1cm4gKFxyXG4gICAgICAgIHRoaXMucmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gdGhpcy5yZW5kZXJTdGF0dXMuSXNSdW5uaW5nIHx8XHJcbiAgICAgICAgdGhpcy5yZW5kZXJTZXJ2aWNlLnNlcnZlckRhdGEuc2V0dXAgPT09IGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyByZWFkb25seSB2aWV3TW9kZXM6IHR5cGVvZiBWaWV3TW9kZSA9IFZpZXdNb2RlO1xyXG4gIHB1YmxpYyByZWFkb25seSByZW5kZXJTdGF0dXMgPSBSZW5kZXJTdGF0dXM7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3JlbmRlckJ1dHRvbicpIHB1YmxpYyByZW5kZXJCdXR0b246IEVsZW1lbnRSZWY7XHJcblxyXG4gIHB1YmxpYyBoYXNFcnJvcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHB1YmxpYyBlcnJvclRleHQ6IHN0cmluZyA9ICcnO1xyXG4gIHB1YmxpYyBpbWFnZVJlbmRlclNvdXJjZTogYW55ID0gJyc7XHJcbiAgcHVibGljIGluUGljdHVyZU1vZGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcHVibGljIHJlYWRvbmx5IHJlbmRlck1vZGVzID0gUmVuZGVyTW9kZXM7XHJcblxyXG4gIHB1YmxpYyBzaG93UmVuZGVyRm9ybShldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgdGhpcy5pblBpY3R1cmVNb2RlID0gIXRoaXMuaW5QaWN0dXJlTW9kZTtcclxuICAgIHRoaXMudmFsaWRhdGVSZW5kZXJQb3NpdGlvbigpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGFzeW5jIHN0YXJ0UmVuZGVyaW5nUm9vbSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgIGlmICh0aGlzLl9zZXR0aW5nc1NlcnZpY2Uuc2V0dGluZ3Mub3B0aW9ucy51c2VOZXdSZW5kZXIpIHtcclxuICAgICAgdGhpcy5fbmV3UmVuZGVyU2VydmljZS5yZW5kZXJSb29tKHRoaXMucmVuZGVyU2VydmljZS5nZXRJbWFnZVNpemVPbklkKHRoaXMucmVuZGVyU2VydmljZS5zZWxlY3RlZEltYWdlU2l6ZSkpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5pbWFnZVJlbmRlclNvdXJjZSA9ICcnO1xyXG4gICAgICBjb25zdCBxdWV1ZUl0ZW0gPSBuZXcgUmVuZGVyUXVldWVJdGVtKCk7XHJcbiAgICAgIHF1ZXVlSXRlbS5wYXJhbXMgPSB0aGlzLnJlbmRlclNlcnZpY2UuZ2V0UmVuZGVyUGFyYW1ldGVycyh0aGlzLnJlbmRlck1vZGVzLlJlbmRlclJvb20pO1xyXG4gICAgICB0aGlzLnJlbmRlclNlcnZpY2UucmVuZGVyUXVldWUgPSBbXTtcclxuICAgICAgdGhpcy5yZW5kZXJTZXJ2aWNlLnJlbmRlclF1ZXVlLnB1c2gocXVldWVJdGVtKTtcclxuXHJcbiAgICAgIGF3YWl0IHRoaXMucmVuZGVyU2VydmljZS5zdGFydFJlbmRlcmluZygpXHJcbiAgICAgICAgLmNhdGNoKChlKSA9PiB7XHJcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGUpO1xyXG4gICAgICAgICAgdGhpcy5yZW5kZXJTZXJ2aWNlLnJlbmRlclF1ZXVlID0gW107XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgY3JlYXRlQmxlbmRlclJlbmRlcigpOiB2b2lkIHtcclxuICAgIGNvbnN0IHJlbmRlclNpemUgPSB0aGlzLnJlbmRlclNlcnZpY2UuZ2V0SW1hZ2VTaXplT25JZCh0aGlzLnJlbmRlclNlcnZpY2Uuc2VsZWN0ZWRJbWFnZVNpemUpO1xyXG4gICAgY29uc3QgcmVuZGVyU2NlbmVBc3NldElkOiBzdHJpbmcgPSB0aGlzLnJlbmRlclNlcnZpY2Uuc2VsZWN0ZWRSZW5kZXJTY2VuZTtcclxuXHJcbiAgICBpZiAodGhpcy5saWdodGluZ0V4cG9zdXJlIDwgMSkge1xyXG4gICAgICB0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPSAxO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHJlbmRlcklucHV0OiBhbnkgPSB7XHJcbiAgICAgICdoZWlnaHQnOiByZW5kZXJTaXplLmhlaWdodCxcclxuICAgICAgJ3dpZHRoJzogcmVuZGVyU2l6ZS53aWR0aCxcclxuICAgICAgJ3NjZW5lQXNzZXRJZCc6IHJlbmRlclNjZW5lQXNzZXRJZCxcclxuICAgICAgJ2hkcmlJbnRlbnNpdHknOiB0aGlzLmhkcmlJbnRlbnNpdHksXHJcbiAgICAgICdoZHJpUm90YXRpb24nOiB0aGlzLmhkcmlSb3RhdGlvbixcclxuICAgICAgJ2xpZ2h0aW5nRXhwb3N1cmUnOiB0aGlzLmxpZ2h0aW5nRXhwb3N1cmVcclxuICAgIH07XHJcbiAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmVtaXQoTWVzc2FnZVR5cGUuU2hvd0xvYWRpbmdJbmRpY2F0b3IsIHt0aXRsZTogJ1VwbG9hZGluZy4uLid9KTtcclxuICAgIHRoaXMuX3V0aWxzU2VydmljZS5wcmVwUm9vbUZvclJlbmRlcihmYWxzZSwgcmVuZGVySW5wdXQpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIHJlc2V0QmxlbmRlclJlbmRlclNjZW5lKCkge1xyXG4gICAgdGhpcy5pblBpY3R1cmVNb2RlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbW92ZUNhbWVyYVdpdGhpbkJvdW5kcygpOiB2b2lkIHtcclxuICAgIGNvbnN0IGZsb29yUGxhbmVJdGVtID0gdGhpcy5fc2NlbmVTZXJ2aWNlLnNjZW5lLmdldE9iamVjdEJ5TmFtZSgnZmxvb3ItcGxhbmUnKTtcclxuICAgIGNvbnN0IGNhbWVyYU9iamVjdCA9IHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhO1xyXG4gICAgY29uc3Qgd2FsbEhlaWdodDogbnVtYmVyID0gdGhpcy5fY29uZmlndXJhdGlvblNlcnZpY2UuZ2V0VmFsdWUoQ29uZmlndXJhdGlvbktleS5XYWxsSGVpZ2h0KSAvIDEwMDsgLy8gY29udmVydCBjbSB0byBtIHNvIHRoZSB1bml0cyBtYXRjaFxyXG5cclxuICAgIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhLnVwZGF0ZU1hdHJpeFdvcmxkKHRydWUpO1xyXG4gICAgY29uc3QgdGFyZ2V0Qm94OiBCb3gzID0gbmV3IEJveDMoKS5zZXRGcm9tT2JqZWN0KGZsb29yUGxhbmVJdGVtKTtcclxuICAgIGNvbnN0IG1vdmluZ0JveDogQm94MyA9IG5ldyBCb3gzKCkuc2V0RnJvbU9iamVjdChjYW1lcmFPYmplY3QpO1xyXG4gICAgY29uc3QgbW92aW5nU2l6ZTogVmVjdG9yMyA9IG5ldyBWZWN0b3IzKCk7XHJcbiAgICBtb3ZpbmdCb3guZ2V0U2l6ZShtb3ZpbmdTaXplKTtcclxuICAgIGNvbnN0IG1vdmluZ1Bvc2l0aW9uOiBWZWN0b3IzID0gY2FtZXJhT2JqZWN0LnBvc2l0aW9uO1xyXG4gICAgbW92aW5nUG9zaXRpb24ueCA9IE1hdGhVdGlscy5jbGFtcChtb3ZpbmdQb3NpdGlvbi54LCB0YXJnZXRCb3gubWluLnggKyBtb3ZpbmdTaXplLnggLyAyLCB0YXJnZXRCb3gubWF4LnggLSBtb3ZpbmdTaXplLnggLyAyKTtcclxuICAgIC8vIG1vdmluZ1Bvc2l0aW9uLnkgPSBNYXRoVXRpbHMuY2xhbXAobW92aW5nUG9zaXRpb24ueSwgdGFyZ2V0Qm94Lm1pbi55ICsgbW92aW5nU2l6ZS55IC8gMiwgdGFyZ2V0Qm94Lm1heC55IC0gbW92aW5nU2l6ZS55IC8gMik7XHJcbiAgICBtb3ZpbmdQb3NpdGlvbi55ID0gd2FsbEhlaWdodCAvIDI7XHJcbiAgICBtb3ZpbmdQb3NpdGlvbi56ID0gTWF0aFV0aWxzLmNsYW1wKG1vdmluZ1Bvc2l0aW9uLnosIHRhcmdldEJveC5taW4ueiArIG1vdmluZ1NpemUueiAvIDIsIHRhcmdldEJveC5tYXgueiAtIG1vdmluZ1NpemUueiAvIDIpO1xyXG4gICAgdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmEucm90YXRpb24uc2V0KDAsIDAsIDApO1xyXG4gICAgdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmEucG9zaXRpb24uc2V0KG1vdmluZ1Bvc2l0aW9uLngsIG1vdmluZ1Bvc2l0aW9uLnksIG1vdmluZ1Bvc2l0aW9uLnopO1xyXG4gICAgdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmFNb3ZlbWVudENoYW5nZWQubmV4dCgpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldFByZXZpZXdSZW5kZXIoKSB7XHJcbiAgICBjb25zdCByZW5kZXJTY2VuZUFzc2V0SWQ6IHN0cmluZyA9IHRoaXMucmVuZGVyU2VydmljZS5zZWxlY3RlZFJlbmRlclNjZW5lO1xyXG4gICAgY29uc3QgcmVuZGVySW5wdXQ6IGFueSA9IHtcclxuICAgICAgJ2hlaWdodCc6IDE1MCxcclxuICAgICAgJ3dpZHRoJzogMjc1LFxyXG4gICAgICAnc2NlbmVBc3NldElkJzogcmVuZGVyU2NlbmVBc3NldElkXHJcbiAgICB9O1xyXG4gICAgdGhpcy5tZXNzYWdlU2VydmljZS5lbWl0KE1lc3NhZ2VUeXBlLlNob3dMb2FkaW5nSW5kaWNhdG9yLCB7dGl0bGU6ICdVcGxvYWRpbmcuLi4nfSk7XHJcbiAgICB0aGlzLl91dGlsc1NlcnZpY2UucHJlcFJvb21Gb3JSZW5kZXIoZmFsc2UsIHJlbmRlcklucHV0LCB0cnVlKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzaG93UHJldmlldyhpbWFnZTogc3RyaW5nKTogdm9pZCB7XHJcbiAgICB0aGlzLmJsZW5kZXJQcmV2aWV3UmVuZGVyID0gaW1hZ2U7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgdG9nZ2xlUmVuZGVyU2V0dGluZ3MoKTogdm9pZCB7XHJcbiAgICB0aGlzLnNob3dSZW5kZXJTZXR0aW5ncyA9ICF0aGlzLnNob3dSZW5kZXJTZXR0aW5ncztcclxuICB9XHJcblxyXG4gIHB1YmxpYyB2YWxpZGF0ZVJlbmRlclBvc2l0aW9uKCk6IHZvaWQge1xyXG4gICAgLyoqXHJcbiAgICAgKiBUbyBtYWtlIHN1cmUgdGhlIHVzZXIgaGFzIGEgZGVzY2VudCByZW5kZXIsIHRoZSBjYW1lcmEgcG9zaXRpb24gbmVlZHMgdG8gYmUgd2l0aGluIHRoZSBib3VuZGluZ2JveCBvZiB0aGUgZmxvb3JwbGFuZS5cclxuICAgICAqIEFsc28gY29uc2lkZXIgdGhlIHpvb20gb2YgdGhlIGNhbWVyYT9cclxuICAgICAqIFdoZW4gdGhlcmUncyBtb3JlIHRoYW4gb25lIHJvb20sIHRoZXJlIGFyZSBtdWx0aXBseSBmbG9vci1wbGFuZSdzXHJcbiAgICAgKiBXZSBuZWVkIHRvIG1ha2Ugc3VyZSB3ZSBjaGVjayB0aGVtIGFsbCBzb21laG93XHJcbiAgICAgKiovXHJcbiAgICBjb25zdCBlcnJvckxpc3Q6IGFueVtdID0gW107XHJcbiAgICBjb25zdCBmbG9vclBsYW5lSXRlbXM6IGFueSA9IHRoaXMuX2dldE9iamVjdHNCeU5hbWUodGhpcy5fc2NlbmVTZXJ2aWNlLnNjZW5lLCAnZmxvb3ItcGxhbmUnKTtcclxuICAgIGlmIChmbG9vclBsYW5lSXRlbXMpIHtcclxuICAgICAgZm9yIChjb25zdCBmbG9vclBsYW5lSXRlbSBvZiBmbG9vclBsYW5lSXRlbXMpIHtcclxuICAgICAgICBjb25zdCBmbG9vclBsYW5lSXRlbUJveDogQm94MyA9IG5ldyBCb3gzKCkuc2V0RnJvbU9iamVjdChmbG9vclBsYW5lSXRlbSk7XHJcbiAgICAgICAgZmxvb3JQbGFuZUl0ZW1Cb3gubWluLnkgPSAwO1xyXG4gICAgICAgIGZsb29yUGxhbmVJdGVtQm94Lm1heC55ID0gdGhpcy5fY29uZmlndXJhdGlvblNlcnZpY2UuZ2V0VmFsdWUoQ29uZmlndXJhdGlvbktleS5XYWxsSGVpZ2h0KTsgLy8gdW5pdHMgaW4gdGhyZWVqcywgc28gMTAgPSAxMCBtZXRlci5cclxuICAgICAgICBjb25zdCBjYW1lcmFQb3NpdGlvbjogVmVjdG9yMyA9IHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhLnBvc2l0aW9uO1xyXG4gICAgICAgIGNvbnN0IGlzQ2FtZXJhV2l0aGluT2JqZWN0OiBib29sZWFuID0gZmxvb3JQbGFuZUl0ZW1Cb3guY29udGFpbnNQb2ludChjYW1lcmFQb3NpdGlvbik7XHJcbiAgICAgICAgaWYgKCFpc0NhbWVyYVdpdGhpbk9iamVjdCkge1xyXG4gICAgICAgICAgZXJyb3JMaXN0LnB1c2godHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBJZiB0aGUgY291bnQgb2YgZXJyb3JMaXN0IGlzIGdyZWF0ZXIgdGhlbiB0aGUgYW1vdW50IG9mIGZsb29ycGxhbnMsIHdlIGdvdCBhbiBlcnJvclxyXG4gICAgaWYgKGVycm9yTGlzdC5sZW5ndGggPj0gZmxvb3JQbGFuZUl0ZW1zLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLmhhc0Vycm9yID0gdHJ1ZTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuaGFzRXJyb3IgPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgX2dldE9iamVjdHNCeU5hbWUoc2NlbmU6IE9iamVjdDNELCBuYW1lOiBzdHJpbmcpOiBhbnlbXSB7XHJcbiAgICBjb25zdCBtYXRjaGluZ09iamVjdHMgPSBbXTtcclxuICAgIHNjZW5lLnRyYXZlcnNlKChvYmplY3QpID0+IHtcclxuICAgICAgaWYgKG9iamVjdC5uYW1lID09PSBuYW1lKSB7XHJcbiAgICAgICAgbWF0Y2hpbmdPYmplY3RzLnB1c2gob2JqZWN0KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gbWF0Y2hpbmdPYmplY3RzO1xyXG4gIH1cclxuXHJcbn1cclxuIl19
699
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyLWNvbnRyb2xzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9jbGllbnQvYXBwL3BsdWdpbnMvcmVuZGVyL3JlbmRlci1jb250cm9scy9yZW5kZXItY29udHJvbHMuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBLE9BQU8sRUFBQyxTQUFTLEVBQXNCLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUV2RSxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sbUNBQW1DLENBQUM7QUFDM0QsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBT25ELE9BQU8sRUFBQyxJQUFJLEVBQUUsU0FBUyxFQUFZLE9BQU8sRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUN6RCxPQUFPLEVBQUMsZ0JBQWdCLEVBQUMsTUFBTSwyQ0FBMkMsQ0FBQztBQUUzRSxPQUFPLEVBQUMsV0FBVyxFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDakQsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLHNDQUFzQyxDQUFDO0FBSWpFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSw4QkFBOEIsQ0FBQztBQUl0RCxPQUFPLEVBQUMsbUJBQW1CLEVBQUUsZ0JBQWdCLEVBQUMsTUFBTSxpQ0FBaUMsQ0FBQztBQUN0RixPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSxrQ0FBa0MsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMk52RSxNQUFNLE9BQU8sdUJBQXVCO0lBbUJoQyxZQUNXLGFBQTRCLEVBQzVCLGNBQWlDLEVBQ2pDLGVBQWdDLEVBQ2hDLGVBQTZDLEVBQzdDLFdBQTBDLEVBQ3pDLE9BQWtCLEVBQ2xCLGFBQTJCLEVBQzNCLGNBQTZCLEVBQzdCLHFCQUEyQyxFQUMzQyxnQkFBOEMsRUFDOUMsaUJBQW1DLEVBQ25DLGFBQTJCLEVBQzNCLFlBQXlCLEVB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dUI7a0JBek5uQyxTQUFTO21CQUFDO29CQUNQLFFBQVEsRUFBRSxvQkFBb0I7b0JBQzlCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7S0FvTlQ7b0JBQ0QsU0FBUyxFQUFFLENBQUMsa0NBQWtDLENBQUM7aUJBQ2xEO29oQkEwRFUsWUFBWTtzQkFEbEIsU0FBUzt1QkFBQyxjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDb21wb25lbnQsIEVsZW1lbnRSZWYsIE9uSW5pdCwgVmlld0NoaWxkfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHtNYXREaWFsb2d9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XHJcbmltcG9ydCB7Vmlld01vZGV9IGZyb20gJy4uLy4uLy4uL2NvcmUvZW51bS92aWV3LW1vZGUuZW51bSc7XHJcbmltcG9ydCB7UmVuZGVyU3RhdHVzfSBmcm9tICcuLi9lbnVtL3JlbmRlci1zdGF0dXMnO1xyXG5pbXBvcnQge1JlbmRlclNlcnZpY2V9IGZyb20gJy4uL3NlcnZpY2UvcmVuZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQge1ZpZXdNb2RlU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlL3ZpZXctbW9kZS5zZXJ2aWNlJztcclxuaW1wb3J0IHtIb21lZGVjb3JhdG9yU2V0dGluZ3NTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9jb3JlL3NlcnZpY2UvaG9tZWRlY29yYXRvci1zZXR0aW5ncy5zZXJ2aWNlJztcclxuaW1wb3J0IHtNZXNzYWdlQnVzU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlL21lc3NhZ2UtYnVzLnNlcnZpY2UnO1xyXG5pbXBvcnQge1NjZW5lU2VydmljZX0gZnJvbSAnLi4vLi4vY29yZTNkL3NlcnZpY2Uvc2NlbmUuc2VydmljZSc7XHJcbmltcG9ydCB7Q2FtZXJhU2VydmljZX0gZnJvbSAnLi4vLi4vY29yZTNkL3NlcnZpY2UvY2FtZXJhLnNlcnZpY2UnO1xyXG5pbXBvcnQge0JveDMsIE1hdGhVdGlscywgT2JqZWN0M0QsIFZlY3RvcjN9IGZyb20gJ3RocmVlJztcclxuaW1wb3J0IHtDb25maWd1cmF0aW9uS2V5fSBmcm9tICcuLi8uLi8uLi9jb3JlL2VudW0vY29uZmlndXJhdGlvbi1rZXkuZW51bSc7XHJcbmltcG9ydCB7Q29uZmlndXJhdGlvblNlcnZpY2V9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZS9jb25maWd1cmF0aW9uLnNlcnZpY2UnO1xyXG5pbXBvcnQge1JlbmRlck1vZGVzfSBmcm9tICcuLi9lbnVtL3JlbmRlci1tb2Rlcyc7XHJcbmltcG9ydCB7TWVzc2FnZVR5cGV9IGZyb20gJy4uLy4uLy4uL2NvcmUvZW51bS9tZXNzYWdlLXR5cGUuZW51bSc7XHJcbmltcG9ydCB7TmV3UmVuZGVyU2VydmljZX0gZnJvbSAnLi4vc2VydmljZS9uZXctcmVuZGVyLnNlcnZpY2UnO1xyXG5pbXBvcnQge1V0aWxzU2VydmljZX0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlL3V0aWxzLnNlcnZpY2UnO1xyXG5pbXBvcnQge1N1YnNjcmlwdGlvbn0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7SWNvbkVudW19IGZyb20gJy4uLy4uLy4uL2NvcmUvZW51bS9pY29uLmVudW0nO1xyXG5pbXBvcnQge0hvbWVkZWNvcmF0b3JJY29uQ2FjaGVTZXJ2aWNlfSBmcm9tICcuLi8uLi8uLi9jb3JlL3NlcnZpY2UvaG9tZWRlY29yYXRvci1pY29uLWNhY2hlLnNlcnZpY2UnO1xyXG5pbXBvcnQge1Jvb21TZXJ2aWNlfSBmcm9tICcuLi8uLi9yb29tLXBsYW5uZXIvY29tcG9uZW50cy9mbG9vcnBsYW5uZXIvc2VydmljZS9yb29tLnNlcnZpY2UnO1xyXG5pbXBvcnQge1dhbGxNZWFzdXJlbWVudHNTZXJ2aWNlfSBmcm9tICcuLi8uLi9jb3JlM2Qvc2VydmljZS93YWxsLW1lYXN1cmVtZW50cy5zZXJ2aWNlJztcclxuaW1wb3J0IHtCbGVuZGVyU2NlbmVTZXR0aW5nLCBCbGVuZGVyU2NlbmVUeXBlfSBmcm9tICcuLi9tb2RlbC9ibGVuZGVyLXNjZW5lLXNldHRpbmdzJztcclxuaW1wb3J0IHtCbGVuZGVyUmVuZGVyU2V0dGluZ3N9IGZyb20gJy4uL21vZGVsL2JsZW5kZXItcmVuZGVyLXNldHRpbmdzJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdycC1yZW5kZXItY29udHJvbHMnLFxyXG4gICAgdGVtcGxhdGU6IGBcclxuICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWNvbnRhaW5lclwiXHJcbiAgICAgICAgICAgICAqbmdJZj1cInJlbmRlclNlcnZpY2Uuc2VydmVyRGF0YSAmJiAgcmVuZGVyU2VydmljZS5zZXJ2ZXJEYXRhLnJlbmRlck1vZGUgIT09IHJlbmRlclNlcnZpY2UucmVuZGVyTW9kZXMuUmVuZGVyU2hvcFwiPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXByb2dyZXNzXCJcclxuICAgICAgICAgICAgICAgICAqbmdJZj1cInJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJTdGF0dXMgPT09IHJlbmRlclN0YXR1cy5Jc1J1bm5pbmcgfHwgcmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gcmVuZGVyU3RhdHVzLklzU3VjY2Vzc1wiPlxyXG4gICAgICAgICAgICAgICAge3sgKHJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJTdGF0dXMgPT09IHJlbmRlclN0YXR1cy5Jc1N1Y2Nlc3MgJiYgcmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclByb2dyZXNzID09PSAxMDAgPyBcIlJFTkRFUl9SRUFEWVwiIDogXCJcIikgfCBsb2NhbGl6ZSB9fVxyXG4gICAgICAgICAgICAgICAge3sgKHJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJTdGF0dXMgPT09IHJlbmRlclN0YXR1cy5Jc1N1Y2Nlc3MgJiYgcmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclByb2dyZXNzICE9PSAxMDAgPyBcIlJFTkRFUl9TVE9QUEVEXCIgOiBcIlwiKSB8IGxvY2FsaXplIH19XHJcbiAgICAgICAgICAgICAgICB7eyAocmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gcmVuZGVyU3RhdHVzLklzUnVubmluZykgPyByZW5kZXJTZXJ2aWNlLmN1cnJlbnRRdWV1ZVJlbmRlckl0ZW0ucmVuZGVyUHJvZ3Jlc3MgKyBcIiVcIiA6IFwiXCIgfX1cclxuICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgIDwhLS0gdGhlIFllbGxvdyByZW5kZXIgaW5kaWNhdG9ycyAtLT5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1pbmRpY2F0b3JzXCIgKm5nSWY9XCJpblBpY3R1cmVNb2RlXCI+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWluZGljYXRvci10b3AtbGVmdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1pbmRpY2F0b3ItdG9wLXJpZ2h0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLWluZGljYXRvci1ib3R0b20tbGVmdFwiPjwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1pbmRpY2F0b3ItYm90dG9tLXJpZ2h0XCI+PC9kaXY+XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXBvcHVwLWNvbnRhaW5lclwiICpuZ0lmPVwiaW5QaWN0dXJlTW9kZVwiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1wb3B1cC1oZWFkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICA8aDM+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPnt7ICdQSUNUVVJFX01PREUnIHwgbG9jYWxpemUgfX08L3NwYW4+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIGNsYXNzPVwicmVuZGVyRXJyb3JJY29uXCIgKm5nSWY9XCJoYXNFcnJvclwiIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLlRyaWFuZ2xlRXhjbGFtYXRpb24pXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiJ0JMRU5ERVJfUkVOREVSX0VSUk9SJyB8IGxvY2FsaXplXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvaDM+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjbG9zZS1wb3B1cC1jb250YWluZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVzZXRCbGVuZGVyUmVuZGVyU2NlbmUoKVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5Dcm9zcylcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItcG9wdXAtcHJldmlld1wiPlxyXG5cclxuICAgICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiYmxlbmRlclByZXZpZXdSZW5kZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGltZyBbc3JjXT1cImJsZW5kZXJQcmV2aWV3UmVuZGVyXCIgYWx0PVwiXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhYmxlbmRlclByZXZpZXdSZW5kZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1wb3B1cC1wcmV2aWV3LXBsYWNlaG9sZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyAnUFJFVklFVycgfCBsb2NhbGl6ZSB9fTwvc3Bhbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZW5kZXItcG9wdXAtcmVmcmVzaC1wcmV2aWV3XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImdldFByZXZpZXdSZW5kZXIoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5SZXRyeUJ1dHRvbilcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyZW5kZXJTZXJ2aWNlLmJsZW5kRmlsZXNSZW5kZXJcIiBjbGFzcz1cInJlbmRlci1wb3B1cC1kcm9wZG93blwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0b2dnbGVhYmxlXCIgKGNsaWNrKT1cInRvZ2dsZVJlbmRlclNldHRpbmdzKClcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPHA+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiFzaG93UmVuZGVyU2V0dGluZ3NcIiBbdGV4dENvbnRlbnRdPVwiJ1JFTkRFUl9BRFZBTkNFRF9TRVRUSU5HU19TSE9XJyB8IGxvY2FsaXplXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJzaG93UmVuZGVyU2V0dGluZ3NcIiBbdGV4dENvbnRlbnRdPVwiJ1JFTkRFUl9BRFZBTkNFRF9TRVRUSU5HU19ISURFJyB8IGxvY2FsaXplXCI+PC9zcGFuPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L3A+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtuZ0NsYXNzXT1cInsnaWNvbi1yb3RhdGUnOiBzaG93UmVuZGVyU2V0dGluZ3N9XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQXJyb3dQb2ludERvd24pXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZHZhbmNlZC1yZW5kZXItc2V0dGluZ3NcIiAqbmdJZj1cInNob3dSZW5kZXJTZXR0aW5nc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmYWNlLXNlbGVjdC1mb3JtXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdJZj1cInJlbmRlclNlcnZpY2Uuc2VydmVyRGF0YS5yZW5kZXJNb2RlID09PSByZW5kZXJNb2Rlcy5SZW5kZXJSb29tXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBcIkVOVklST05NRU5UXCIgfCBsb2NhbGl6ZSB9fTwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwic2VsZWN0ZWRSZW5kZXJTY2VuZVwiIChzZWxlY3Rpb25DaGFuZ2UpPVwidXBkYXRlQmxlbmRlclNjZW5lU2V0dGluZ3MoJGV2ZW50KVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IHNjZW5lIG9mIHNjZW5lTGlzdFwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2NlbmVcIj57eyBzY2VuZS5uYW1lIH19XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXR0aW5nLXBhcnQtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJ0aGlyZC13aWR0aFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWwgW3RleHRDb250ZW50XT1cIidFTlZJUk9OTUVOVF9MSUdIVCcgfCBsb2NhbGl6ZVwiPjwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCInbnVtYmVyJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGRyaUludGVuc2l0eVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImhkcmlJbnRlbnNpdHkgPSArJGV2ZW50XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1idXR0b25zXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImFtb3VudC1idXR0b25cIiAoY2xpY2spPVwiaGRyaUludGVuc2l0eSA9ICtoZHJpSW50ZW5zaXR5IC0gMVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8Y28taWNvbiBbaWNvbkRhdGFdPVwiaWNvblNlcnZpY2UuZ2V0SWNvbihpY29ucy5DaXJjbGVNaW51c0xpZ2h0KVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYW1vdW50LWJ1dHRvblwiIChjbGljayk9XCJoZHJpSW50ZW5zaXR5ID0gK2hkcmlJbnRlbnNpdHkgKyAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZVBsdXNMaWdodClcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXR0aW5nLXBhcnQtc2xpZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZXIgY2xhc3M9XCJ2YWx1ZVwiIG1pbj1cIjFcIiBtYXg9XCIyMFwiIHN0ZXA9XCIxXCIgW3ZhbHVlXT1cImhkcmlJbnRlbnNpdHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGRyaUludGVuc2l0eVwiPjwvbWF0LXNsaWRlcj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXR0aW5nLXBhcnQtY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJ0aGlyZC13aWR0aFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWwgW3RleHRDb250ZW50XT1cIidST1RBVElPTicgfCBsb2NhbGl6ZVwiPjwvbWF0LWxhYmVsPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdHlwZV09XCInbnVtYmVyJ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGRyaVJvdGF0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwiaGRyaVJvdGF0aW9uID0gKyRldmVudFwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXR0aW5nLXBhcnQtYnV0dG9uc1wiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImhkcmlSb3RhdGlvbiA9ICtoZHJpUm90YXRpb24gLSAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZU1pbnVzTGlnaHQpXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImhkcmlSb3RhdGlvbiA9ICtoZHJpUm90YXRpb24gKyAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZVBsdXNMaWdodClcIj48L2NvLWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzZXR0aW5nLXBhcnQtc2xpZGVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZXIgY2xhc3M9XCJ2YWx1ZVwiIG1pbj1cIjBcIiBtYXg9XCIzNjBcIiBzdGVwPVwiMVwiIFt2YWx1ZV09XCJoZHJpUm90YXRpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiaGRyaVJvdGF0aW9uXCI+PC9tYXQtc2xpZGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWNvbnRhaW5lclwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwidGhpcmQtd2lkdGhcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsIFt0ZXh0Q29udGVudF09XCInTElHSFRTJyB8IGxvY2FsaXplXCI+PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt0eXBlXT1cIidudW1iZXInXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJsaWdodGluZ0V4cG9zdXJlXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwibGlnaHRpbmdFeHBvc3VyZSA9ICskZXZlbnRcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic2V0dGluZy1wYXJ0LWJ1dHRvbnNcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYW1vdW50LWJ1dHRvblwiIChjbGljayk9XCJsaWdodGluZ0V4cG9zdXJlID0gK2xpZ2h0aW5nRXhwb3N1cmUgLSAxXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZU1pbnVzTGlnaHQpXCI+PC9jby1pY29uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJhbW91bnQtYnV0dG9uXCIgKGNsaWNrKT1cImxpZ2h0aW5nRXhwb3N1cmUgPSArbGlnaHRpbmdFeHBvc3VyZSArIDFcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPGNvLWljb24gW2ljb25EYXRhXT1cImljb25TZXJ2aWNlLmdldEljb24oaWNvbnMuQ2lyY2xlUGx1c0xpZ2h0KVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNldHRpbmctcGFydC1zbGlkZXJcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNsaWRlciBjbGFzcz1cInZhbHVlXCIgbWluPVwiMVwiIG1heD1cIjEwXCIgc3RlcD1cIjFcIiBbdmFsdWVdPVwibGlnaHRpbmdFeHBvc3VyZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJsaWdodGluZ0V4cG9zdXJlXCI+PC9tYXQtc2xpZGVyPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicmVuZGVyLXBvcHVwLWRyb3Bkb3duXCIgKm5nSWY9XCJyZW5kZXJTZXJ2aWNlLnNlcnZlckRhdGEucmVuZGVyTW9kZSA9PT0gcmVuZGVyTW9kZXMuUmVuZGVyUm9vbVwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZhY2Utc2VsZWN0LWZvcm1cIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD57eyBcIklNQUdFX1NJWkVcIiB8IGxvY2FsaXplIH19PC9tYXQtbGFiZWw+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0IFsobmdNb2RlbCldPVwicmVuZGVyU2VydmljZS5zZWxlY3RlZEltYWdlU2l6ZVwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gKm5nRm9yPVwibGV0IHNpemUgb2YgcmVuZGVyU2VydmljZS5pbWFnZVNpemVzXCIgW3ZhbHVlXT1cInNpemUuaWRcIj57eyBzaXplLm5hbWUgfX0ge3sgc2l6ZS53aWR0aCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHh7eyBzaXplLmhlaWdodCB9fVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci1wb3B1cC1idXR0b24tY29udGFpbmVyXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cInJlbmRlci1wb3B1cC1idXR0b24gcGhvdG8tYnV0dG9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiIXJlbmRlclNlcnZpY2UuYmxlbmRGaWxlc1JlbmRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic3RhcnRSZW5kZXJpbmdSb29tKClcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJ7eydNQUtFX0FfUElDVFVSRScgfCBsb2NhbGl6ZX19XCJcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJkaXNhYmxlUGljdHVyZUJ1dHRvblwiPlxyXG4gICAgICAgICAgICAgICAgICAgICAgICB7eyAnTUFLRV9BX1BJQ1RVUkUnIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwicmVuZGVyLXBvcHVwLWJ1dHRvbiBwaG90by1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKm5nSWY9XCJyZW5kZXJTZXJ2aWNlLmJsZW5kRmlsZXNSZW5kZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNyZWF0ZUJsZW5kZXJSZW5kZXIoKVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cInt7J01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRpc2FibGVQaWN0dXJlQnV0dG9uXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZUNoZWNrKVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgJ01BS0VfQV9QSUNUVVJFJyB8IGxvY2FsaXplIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cInJlbmRlci1wb3B1cC1idXR0b24gY2FuY2VsLWJ1dHRvblwiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZXNldEJsZW5kZXJSZW5kZXJTY2VuZSgpXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZVhtYXJrKVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgJ0NMT1NFX1BIT1RPX01PREUnIHwgbG9jYWxpemUgfX1cclxuICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItd2FybmluZ1wiICpuZ0lmPVwic2hvd0N1bGxpbmdFcnJvckRpYWxvZ1wiPlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci13YXJtaW5nLWhlYWRlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxoMj57eyAnQkxFTkRFUl9SRU5ERVJfRVJST1JfVElUTEUnIHwgbG9jYWxpemUgfX08L2gyPlxyXG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItd2FybmluZy1jbG9zZVwiIChjbGljayk9XCJzaG93Q3VsbGluZ0Vycm9yRGlhbG9nID0gZmFsc2VcIj5cclxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1pY29uIGNsYXNzPVwiaG9tZWRlY29yYXRvci1tYXRlcmlhbC1pY29uc1wiPmNhbmNlbDwvbWF0LWljb24+XHJcbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZW5kZXItd2FybmluZy1ib2R5XCI+XHJcbiAgICAgICAgICAgICAgICAgICAgPHA+e3sgJ0JMRU5ERVJfUkVOREVSX1dBUk5JTkdfQ1VMTElORycgfCBsb2NhbGl6ZSB9fTwvcD5cclxuICAgICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInJlbmRlci13YXJuaW5nLWZvb3RlclwiPlxyXG4gICAgICAgICAgICAgICAgICAgIDxidXR0b25cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZW5kZXItcG9wdXAtYnV0dG9uIGNhbmNlbC1idXR0b25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd0N1bGxpbmdFcnJvckRpYWxvZyA9IGZhbHNlXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDxjby1pY29uIFtpY29uRGF0YV09XCJpY29uU2VydmljZS5nZXRJY29uKGljb25zLkNpcmNsZVhtYXJrKVwiPjwvY28taWNvbj5cclxuICAgICAgICAgICAgICAgICAgICAgICAge3sgJ0NMT1NFJyB8IGxvY2FsaXplIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPC9kaXY+XHJcblxyXG4gICAgICAgICAgICA8YnV0dG9uXHJcbiAgICAgICAgICAgICAgICAjcmVuZGVyQnV0dG9uXHJcbiAgICAgICAgICAgICAgICBtYXQtcmFpc2VkLWJ1dHRvblxyXG4gICAgICAgICAgICAgICAgbWF0VG9vbHRpcD1cInt7J1JFTkRFUl9UQUtFX0FfUElDVFVSRScgfCBsb2NhbGl6ZX19XCJcclxuICAgICAgICAgICAgICAgIFtpZF09XCInc3RhbmRhbG9uZV9yZW5kZXJfcGljdHVyZSdcIlxyXG4gICAgICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCIoXHJcbiAgICAgICAgKHJlbmRlclNlcnZpY2Uuc2VydmVyRGF0YS5yZW5kZXJNb2RlID09PSByZW5kZXJTZXJ2aWNlLnJlbmRlck1vZGVzLlJlbmRlclJvb20gJiYgdmlld01vZGVTZXJ2aWNlLnZpZXdNb2RlID09PSB2aWV3TW9kZXMuV2Fsa1Rocm91Z2gpIHx8XHJcbiAgICAgICAgKHJlbmRlclNlcnZpY2Uuc2VydmVyRGF0YS5yZW5kZXJNb2RlID09PSByZW5kZXJTZXJ2aWNlLnJlbmRlck1vZGVzLlJlbmRlcklvbmUpKVwiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwic2hvd1JlbmRlckZvcm0oJGV2ZW50KVwiXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgICAgICAgIDxtYXQtaWNvbiBjbGFzcz1cImljb24gaG9tZWRlY29yYXRvci1tYXRlcmlhbC1pY29uc1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCI+e3sgKHJlbmRlclNlcnZpY2UuY3VycmVudFF1ZXVlUmVuZGVySXRlbS5yZW5kZXJTdGF0dXMgPT09IHJlbmRlclN0YXR1cy5Jc1J1bm5pbmcgPyAnb3Blbl9pbl9icm93c2VyJyA6ICdwaG90b19jYW1lcmEnKSB9fVxyXG4gICAgICAgICAgICAgICAgPC9tYXQtaWNvbj5cclxuICAgICAgICAgICAgPC9idXR0b24+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICBgLFxyXG4gICAgc3R5bGVVcmxzOiBbJy4vcmVuZGVyLWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIFJlbmRlckNvbnRyb2xzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcclxuICAgIHB1YmxpYyByZWFkb25seSBpY29uczogdHlwZW9mIEljb25FbnVtID0gSWNvbkVudW07XHJcbiAgICBwdWJsaWMgYmxlbmRlclByZXZpZXdSZW5kZXI6IHN0cmluZztcclxuICAgIHB1YmxpYyBoZHJpSW50ZW5zaXR5OiBudW1iZXIgPSAxO1xyXG4gICAgcHVibGljIGhkcmlSb3RhdGlvbjogbnVtYmVyID0gMDtcclxuICAgIHB1YmxpYyBsaWdodGluZ0V4cG9zdXJlOiBudW1iZXIgPSAxO1xyXG4gICAgcHVibGljIHNob3dSZW5kZXJTZXR0aW5nczogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHVibGljIHNlbGVjdGVkUmVuZGVyU2NlbmU6IEJsZW5kZXJTY2VuZVNldHRpbmc7XHJcbiAgICBwdWJsaWMgc2NlbmVMaXN0OiBCbGVuZGVyU2NlbmVTZXR0aW5nW10gPSBbXTtcclxuICAgIHB1YmxpYyBoYXNFcnJvcjogYm9vbGVhbiA9IGZhbHNlO1xyXG4gICAgcHVibGljIGVycm9yVGV4dDogc3RyaW5nID0gJyc7XHJcbiAgICBwdWJsaWMgaW1hZ2VSZW5kZXJTb3VyY2U6IGFueSA9ICcnO1xyXG4gICAgcHVibGljIGluUGljdHVyZU1vZGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgICBwdWJsaWMgc2hvd0N1bGxpbmdFcnJvckRpYWxvZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuXHJcbiAgICBwcml2YXRlIF9zdWJzOiBTdWJzY3JpcHRpb25bXSA9IFtdO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHB1YmxpYyByZW5kZXJTZXJ2aWNlOiBSZW5kZXJTZXJ2aWNlLFxyXG4gICAgICAgIHB1YmxpYyBtZXNzYWdlU2VydmljZTogTWVzc2FnZUJ1c1NlcnZpY2UsXHJcbiAgICAgICAgcHVibGljIHZpZXdNb2RlU2VydmljZTogVmlld01vZGVTZXJ2aWNlLFxyXG4gICAgICAgIHB1YmxpYyBzZXR0aW5nc1NlcnZpY2U6IEhvbWVkZWNvcmF0b3JTZXR0aW5nc1NlcnZpY2UsXHJcbiAgICAgICAgcHVibGljIGljb25TZXJ2aWNlOiBIb21lZGVjb3JhdG9ySWNvbkNhY2hlU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9kaWFsb2c6IE1hdERpYWxvZyxcclxuICAgICAgICBwcml2YXRlIF9zY2VuZVNlcnZpY2U6IFNjZW5lU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9jYW1lcmFTZXJ2aWNlOiBDYW1lcmFTZXJ2aWNlLFxyXG4gICAgICAgIHByaXZhdGUgX2NvbmZpZ3VyYXRpb25TZXJ2aWNlOiBDb25maWd1cmF0aW9uU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9zZXR0aW5nc1NlcnZpY2U6IEhvbWVkZWNvcmF0b3JTZXR0aW5nc1NlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBfbmV3UmVuZGVyU2VydmljZTogTmV3UmVuZGVyU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF91dGlsc1NlcnZpY2U6IFV0aWxzU2VydmljZSxcclxuICAgICAgICBwcml2YXRlIF9yb29tU2VydmljZTogUm9vbVNlcnZpY2UsXHJcbiAgICAgICAgcHJpdmF0ZSBfd2FsbE1lYXN1cmVtZW50c1NlcnZpY2U6IFdhbGxNZWFzdXJlbWVudHNTZXJ2aWNlXHJcbiAgICApIHtcclxuICAgICAgICB0aGlzLl9zdWJzLnB1c2goXHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2Uuc3Vic2NyaWJlKE1lc3NhZ2VUeXBlLkJsZW5kZXJSZW5kZXJQcmV2aWV3UmVhZHksIChmaWxlKSA9PiB0aGlzLnNob3dQcmV2aWV3KGZpbGUpKSxcclxuICAgICAgICAgICAgdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmFNb3ZlbWVudENoYW5nZWQuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsaWRhdGVSZW5kZXJQb3NpdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgLy8gTWFrZSBzdXJlIHdoZW4gdGhlIGNhbWVyYSBtb3Zlcywgd2UgcmVjaGVjayB0aGUgcG9zaXRpb24gYW5kIGlmIHdlIHN0aWxsIG5lZWQgdG8gc2hvdyB0aGUgcmVuZGVyIHdhcm5pbmcuXHJcbiAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICk7XHJcbiAgICB9XHJcblxyXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5nZXRSZW5kZXJTY2VuZXNGcm9tU2V0dGluZ3MoKTtcclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldCBkaXNhYmxlUGljdHVyZUJ1dHRvbigpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5fbmV3UmVuZGVyU2VydmljZS5jdXJyZW50UXVldWVSZW5kZXJJdGVtLnJlbmRlclN0YXR1cyA9PT0gdGhpcy5yZW5kZXJTdGF0dXMuSXNSdW5uaW5nO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyByZWFkb25seSB2aWV3TW9kZXM6IHR5cGVvZiBWaWV3TW9kZSA9IFZpZXdNb2RlO1xyXG4gICAgcHVibGljIHJlYWRvbmx5IHJlbmRlclN0YXR1cyA9IFJlbmRlclN0YXR1cztcclxuXHJcbiAgICBAVmlld0NoaWxkKCdyZW5kZXJCdXR0b24nKVxyXG4gICAgcHVibGljIHJlbmRlckJ1dHRvbjogRWxlbWVudFJlZjtcclxuXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgcmVuZGVyTW9kZXMgPSBSZW5kZXJNb2RlcztcclxuXHJcbiAgICBwdWJsaWMgc2hvd1JlbmRlckZvcm0oZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgICAgICB0aGlzLmluUGljdHVyZU1vZGUgPSAhdGhpcy5pblBpY3R1cmVNb2RlO1xyXG4gICAgICAgIHRoaXMudmFsaWRhdGVSZW5kZXJQb3NpdGlvbigpO1xyXG4gICAgICAgIGNvbnN0IGN1bGxpbmdBbGxvd2VkOiBib29sZWFuID0gdGhpcy5fYWxsb3dDdWxsaW5nKHRoaXMuaGFzRXJyb3IpO1xyXG4gICAgICAgIGlmIChjdWxsaW5nQWxsb3dlZCAmJiB0aGlzLmluUGljdHVyZU1vZGUpIHtcclxuICAgICAgICAgICAgdGhpcy5zaG93Q3VsbGluZ0Vycm9yRGlhbG9nID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFzeW5jIHN0YXJ0UmVuZGVyaW5nUm9vbSgpOiBQcm9taXNlPHZvaWQ+IHtcclxuICAgICAgICB0aGlzLl9uZXdSZW5kZXJTZXJ2aWNlLnJlbmRlclJvb20odGhpcy5yZW5kZXJTZXJ2aWNlLmdldEltYWdlU2l6ZU9uSWQodGhpcy5yZW5kZXJTZXJ2aWNlLnNlbGVjdGVkSW1hZ2VTaXplKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGNyZWF0ZUJsZW5kZXJSZW5kZXIoKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnNob3dDdWxsaW5nRXJyb3JEaWFsb2cpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld01vZGVTZXJ2aWNlLmlzVG9wVmlld0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YWxsTWVhc3VyZW1lbnRzU2VydmljZS5wcmVwTWVhc3VyZW1lbnRzRm9yUmVuZGVyKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gb25seSByZW5kZXIgd2hlbiB0aGUgc2hvd0N1bGxpbmdFcnJvckRpYWxvZyBpcyBmYWxzZVxyXG4gICAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmVtaXQoTWVzc2FnZVR5cGUuU2hvd0xvYWRpbmdJbmRpY2F0b3IsIHt0aXRsZTogJ1VwbG9hZGluZy4uLid9KTtcclxuICAgICAgICAgICAgY29uc3QgcmVuZGVyU2l6ZSA9IHRoaXMucmVuZGVyU2VydmljZS5nZXRJbWFnZVNpemVPbklkKHRoaXMucmVuZGVyU2VydmljZS5zZWxlY3RlZEltYWdlU2l6ZSk7XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclNjZW5lQXNzZXRJZDogQmxlbmRlclNjZW5lU2V0dGluZyA9IHRoaXMuc2VsZWN0ZWRSZW5kZXJTY2VuZTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGVSZW5kZXJQb3NpdGlvbigpOyAvLyBDaGVjayB0aGUgY2FtZXJhIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGNvbnN0IGFsbG93Q3VsbGluZzogYm9vbGVhbiA9IHRoaXMuX2FsbG93Q3VsbGluZyh0aGlzLmhhc0Vycm9yKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcklucHV0OiBCbGVuZGVyUmVuZGVyU2V0dGluZ3MgPSBuZXcgQmxlbmRlclJlbmRlclNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhlaWdodCA9IHJlbmRlclNpemUuaGVpZ2h0O1xyXG4gICAgICAgICAgICByZW5kZXJJbnB1dC53aWR0aCA9IHJlbmRlclNpemUud2lkdGg7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LnNjZW5lQXNzZXQgPSByZW5kZXJTY2VuZUFzc2V0SWQ7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhkcmlJbnRlbnNpdHkgPSB0aGlzLmhkcmlJbnRlbnNpdHk7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhkcmlSb3RhdGlvbiA9IHRoaXMuaGRyaVJvdGF0aW9uO1xyXG4gICAgICAgICAgICByZW5kZXJJbnB1dC5saWdodGluZ0V4cG9zdXJlID0gdGhpcy5saWdodGluZ0V4cG9zdXJlO1xyXG4gICAgICAgICAgICByZW5kZXJJbnB1dC5hbGxvd0N1bGxpbmcgPSBhbGxvd0N1bGxpbmc7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl91dGlsc1NlcnZpY2UucHJlcFJvb21Gb3JSZW5kZXIoZmFsc2UsIHJlbmRlcklucHV0KTtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld01vZGVTZXJ2aWNlLmlzVG9wVmlld0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YWxsTWVhc3VyZW1lbnRzU2VydmljZS5yZXN0b3JlTWVhc3VyZW1lbnRzQWZ0ZXJSZW5kZXIoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHJlc2V0QmxlbmRlclJlbmRlclNjZW5lKCkge1xyXG4gICAgICAgIHRoaXMuaW5QaWN0dXJlTW9kZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMuc2hvd0N1bGxpbmdFcnJvckRpYWxvZyA9IGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBtb3ZlQ2FtZXJhV2l0aGluQm91bmRzKCk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IGZsb29yUGxhbmVJdGVtID0gdGhpcy5fc2NlbmVTZXJ2aWNlLnNjZW5lLmdldE9iamVjdEJ5TmFtZSgnZmxvb3ItcGxhbmUnKTtcclxuICAgICAgICBjb25zdCBjYW1lcmFPYmplY3QgPSB0aGlzLl9jYW1lcmFTZXJ2aWNlLmNhbWVyYTtcclxuICAgICAgICBjb25zdCB3YWxsSGVpZ2h0OiBudW1iZXIgPSB0aGlzLl9jb25maWd1cmF0aW9uU2VydmljZS5nZXRWYWx1ZShDb25maWd1cmF0aW9uS2V5LldhbGxIZWlnaHQpIC8gMTAwOyAvLyBjb252ZXJ0IGNtIHRvIG0gc28gdGhlIHVuaXRzIG1hdGNoXHJcblxyXG4gICAgICAgIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhLnVwZGF0ZU1hdHJpeFdvcmxkKHRydWUpO1xyXG4gICAgICAgIGNvbnN0IHRhcmdldEJveDogQm94MyA9IG5ldyBCb3gzKCkuc2V0RnJvbU9iamVjdChmbG9vclBsYW5lSXRlbSk7XHJcbiAgICAgICAgY29uc3QgbW92aW5nQm94OiBCb3gzID0gbmV3IEJveDMoKS5zZXRGcm9tT2JqZWN0KGNhbWVyYU9iamVjdCk7XHJcbiAgICAgICAgY29uc3QgbW92aW5nU2l6ZTogVmVjdG9yMyA9IG5ldyBWZWN0b3IzKCk7XHJcbiAgICAgICAgbW92aW5nQm94LmdldFNpemUobW92aW5nU2l6ZSk7XHJcbiAgICAgICAgY29uc3QgbW92aW5nUG9zaXRpb246IFZlY3RvcjMgPSBjYW1lcmFPYmplY3QucG9zaXRpb247XHJcbiAgICAgICAgbW92aW5nUG9zaXRpb24ueCA9IE1hdGhVdGlscy5jbGFtcChtb3ZpbmdQb3NpdGlvbi54LCB0YXJnZXRCb3gubWluLnggKyBtb3ZpbmdTaXplLnggLyAyLCB0YXJnZXRCb3gubWF4LnggLSBtb3ZpbmdTaXplLnggLyAyKTtcclxuICAgICAgICAvLyBtb3ZpbmdQb3NpdGlvbi55ID0gTWF0aFV0aWxzLmNsYW1wKG1vdmluZ1Bvc2l0aW9uLnksIHRhcmdldEJveC5taW4ueSArIG1vdmluZ1NpemUueSAvIDIsIHRhcmdldEJveC5tYXgueSAtIG1vdmluZ1NpemUueSAvIDIpO1xyXG4gICAgICAgIG1vdmluZ1Bvc2l0aW9uLnkgPSB3YWxsSGVpZ2h0IC8gMjtcclxuICAgICAgICBtb3ZpbmdQb3NpdGlvbi56ID0gTWF0aFV0aWxzLmNsYW1wKG1vdmluZ1Bvc2l0aW9uLnosIHRhcmdldEJveC5taW4ueiArIG1vdmluZ1NpemUueiAvIDIsIHRhcmdldEJveC5tYXgueiAtIG1vdmluZ1NpemUueiAvIDIpO1xyXG4gICAgICAgIHRoaXMuX2NhbWVyYVNlcnZpY2UuY2FtZXJhLnJvdGF0aW9uLnNldCgwLCAwLCAwKTtcclxuICAgICAgICB0aGlzLl9jYW1lcmFTZXJ2aWNlLmNhbWVyYS5wb3NpdGlvbi5zZXQobW92aW5nUG9zaXRpb24ueCwgbW92aW5nUG9zaXRpb24ueSwgbW92aW5nUG9zaXRpb24ueik7XHJcbiAgICAgICAgdGhpcy5fY2FtZXJhU2VydmljZS5jYW1lcmFNb3ZlbWVudENoYW5nZWQubmV4dCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBnZXRQcmV2aWV3UmVuZGVyKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5zaG93Q3VsbGluZ0Vycm9yRGlhbG9nKSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnZpZXdNb2RlU2VydmljZS5pc1RvcFZpZXdBY3RpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fd2FsbE1lYXN1cmVtZW50c1NlcnZpY2UucHJlcE1lYXN1cmVtZW50c0ZvclJlbmRlcigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlclNjZW5lQXNzZXRJZDogQmxlbmRlclNjZW5lU2V0dGluZyA9IHRoaXMuc2VsZWN0ZWRSZW5kZXJTY2VuZTtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5lbWl0KE1lc3NhZ2VUeXBlLlNob3dMb2FkaW5nSW5kaWNhdG9yLCB7dGl0bGU6ICdVcGxvYWRpbmcuLi4nfSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPCAxKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMudmFsaWRhdGVSZW5kZXJQb3NpdGlvbigpOyAvLyBDaGVjayB0aGUgY2FtZXJhIHBvc2l0aW9uXHJcbiAgICAgICAgICAgIGNvbnN0IGFsbG93Q3VsbGluZzogYm9vbGVhbiA9IHRoaXMuX2FsbG93Q3VsbGluZyh0aGlzLmhhc0Vycm9yKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IHJlbmRlcklucHV0OiBCbGVuZGVyUmVuZGVyU2V0dGluZ3MgPSBuZXcgQmxlbmRlclJlbmRlclNldHRpbmdzKCk7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhlaWdodCA9IDE1MDtcclxuICAgICAgICAgICAgcmVuZGVySW5wdXQud2lkdGggPSAyNzU7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LnNjZW5lQXNzZXQgPSByZW5kZXJTY2VuZUFzc2V0SWQ7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhkcmlJbnRlbnNpdHkgPSB0aGlzLmhkcmlJbnRlbnNpdHk7XHJcbiAgICAgICAgICAgIHJlbmRlcklucHV0LmhkcmlSb3RhdGlvbiA9IHRoaXMuaGRyaVJvdGF0aW9uO1xyXG4gICAgICAgICAgICByZW5kZXJJbnB1dC5saWdodGluZ0V4cG9zdXJlID0gdGhpcy5saWdodGluZ0V4cG9zdXJlO1xyXG4gICAgICAgICAgICByZW5kZXJJbnB1dC5hbGxvd0N1bGxpbmcgPSBhbGxvd0N1bGxpbmc7XHJcblxyXG4gICAgICAgICAgICB0aGlzLl91dGlsc1NlcnZpY2UucHJlcFJvb21Gb3JSZW5kZXIoZmFsc2UsIHJlbmRlcklucHV0LCB0cnVlKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMudmlld01vZGVTZXJ2aWNlLmlzVG9wVmlld0FjdGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl93YWxsTWVhc3VyZW1lbnRzU2VydmljZS5yZXN0b3JlTWVhc3VyZW1lbnRzQWZ0ZXJSZW5kZXIoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc2hvd1ByZXZpZXcoaW1hZ2U6IHN0cmluZyk6IHZvaWQge1xyXG4gICAgICAgIHRoaXMuYmxlbmRlclByZXZpZXdSZW5kZXIgPSBpbWFnZTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgdG9nZ2xlUmVuZGVyU2V0dGluZ3MoKTogdm9pZCB7XHJcbiAgICAgICAgdGhpcy5zaG93UmVuZGVyU2V0dGluZ3MgPSAhdGhpcy5zaG93UmVuZGVyU2V0dGluZ3M7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHVwZGF0ZUJsZW5kZXJTY2VuZVNldHRpbmdzKGV2ZW50OiBhbnkpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkUmVuZGVyU2NlbmUgPSBldmVudC52YWx1ZTsgLy8gU2VsZWN0IHRoZSBmaXJzdCBvbmUgYW5kIHNldCB0aGUgdmFsdWVzLlxyXG4gICAgICAgIHRoaXMuaGRyaUludGVuc2l0eSA9IHRoaXMuc2VsZWN0ZWRSZW5kZXJTY2VuZS5oZHJpSW50ZW5zaXR5O1xyXG4gICAgICAgIHRoaXMuaGRyaVJvdGF0aW9uID0gdGhpcy5zZWxlY3RlZFJlbmRlclNjZW5lLmhkcmlSb3RhdGlvbjtcclxuICAgICAgICB0aGlzLmxpZ2h0aW5nRXhwb3N1cmUgPSB0aGlzLnNlbGVjdGVkUmVuZGVyU2NlbmUubGlnaHRpbmdFeHBvc3VyZTtcclxuICAgIH1cclxuXHJcblxyXG4gICAgcHVibGljIHZhbGlkYXRlUmVuZGVyUG9zaXRpb24oKTogdm9pZCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVG8gbWFrZSBzdXJlIHRoZSB1c2VyIGhhcyBhIGRlc2NlbnQgcmVuZGVyLCB0aGUgY2FtZXJhIHBvc2l0aW9uIG5lZWRzIHRvIGJlIHdpdGhpbiB0aGUgYm91bmRpbmdib3ggb2YgdGhlIGZsb29ycGxhbmUuXHJcbiAgICAgICAgICogQWxzbyBjb25zaWRlciB0aGUgem9vbSBvZiB0aGUgY2FtZXJhP1xyXG4gICAgICAgICAqIFdoZW4gdGhlcmUncyBtb3JlIHRoYW4gb25lIHJvb20sIHRoZXJlIGFyZSBtdWx0aXBseSBmbG9vci1wbGFuZSdzXHJcbiAgICAgICAgICogV2UgbmVlZCB0byBtYWtlIHN1cmUgd2UgY2hlY2sgdGhlbSBhbGwgc29tZWhvd1xyXG4gICAgICAgICAqKi9cclxuICAgICAgICBjb25zdCBlcnJvckxpc3Q6IGFueVtdID0gW107XHJcbiAgICAgICAgY29uc3QgZmxvb3JQbGFuZUl0ZW1zOiBhbnkgPSB0aGlzLl9nZXRPYmplY3RzQnlOYW1lKHRoaXMuX3NjZW5lU2VydmljZS5zY2VuZSwgJ2Zsb29yLXBsYW5lJyk7XHJcbiAgICAgICAgaWYgKGZsb29yUGxhbmVJdGVtcykge1xyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZsb29yUGxhbmVJdGVtIG9mIGZsb29yUGxhbmVJdGVtcykge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZmxvb3JQbGFuZUl0ZW1Cb3g6IEJveDMgPSBuZXcgQm94MygpLnNldEZyb21PYmplY3QoZmxvb3JQbGFuZUl0ZW0pO1xyXG4gICAgICAgICAgICAgICAgZmxvb3JQbGFuZUl0ZW1Cb3gubWluLnkgPSAwO1xyXG4gICAgICAgICAgICAgICAgZmxvb3JQbGFuZUl0ZW1Cb3gubWF4LnkgPSB0aGlzLl9jb25maWd1cmF0aW9uU2VydmljZS5nZXRWYWx1ZShDb25maWd1cmF0aW9uS2V5LldhbGxIZWlnaHQpIC8gMTAwOyAvLyB1bml0cyBpbiB0aHJlZWpzLCBzbyAxMCA9IDEwIG1ldGVyLlxyXG4gICAgICAgICAgICAgICAgY29uc3QgY2FtZXJhUG9zaXRpb246IFZlY3RvcjMgPSB0aGlzLl9jYW1lcmFTZXJ2aWNlLmNhbWVyYS5wb3NpdGlvbjtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlzQ2FtZXJhV2l0aGluT2JqZWN0OiBib29sZWFuID0gZmxvb3JQbGFuZUl0ZW1Cb3guY29udGFpbnNQb2ludChjYW1lcmFQb3NpdGlvbik7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzQ2FtZXJhV2l0aGluT2JqZWN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZXJyb3JMaXN0LnB1c2godHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gSWYgdGhlIGNvdW50IG9mIGVycm9yTGlzdCBpcyBncmVhdGVyIHRoZW4gdGhlIGFtb3VudCBvZiBmbG9vcnBsYW5zLCB3ZSBnb3QgYW4gZXJyb3JcclxuICAgICAgICBpZiAoZXJyb3JMaXN0Lmxlbmd0aCA+PSBmbG9vclBsYW5lSXRlbXMubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzRXJyb3IgPSB0cnVlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzRXJyb3IgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGdldFJlbmRlclNjZW5lc0Zyb21TZXR0aW5ncygpOiB2b2lkIHtcclxuICAgICAgICBpZiAodGhpcy5fc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzLmJsZW5kZXJTY2VuZVNldHRpbmdzICYmIHRoaXMuX3NldHRpbmdzU2VydmljZS5zZXR0aW5ncy5ibGVuZGVyU2NlbmVTZXR0aW5ncy5zY2VuZXMpIHtcclxuICAgICAgICAgICAgY29uc3Qgc2NlbmVzID0gdGhpcy5fc2V0dGluZ3NTZXJ2aWNlLnNldHRpbmdzLmJsZW5kZXJTY2VuZVNldHRpbmdzLnNjZW5lcy5maWx0ZXIoXHJcbiAgICAgICAgICAgICAgICBzY2VuZSA9PiBzY2VuZS5zY2VuZVR5cGUgPT09IEJsZW5kZXJTY2VuZVR5cGUuUm9vbSk7XHJcblxyXG4gICAgICAgICAgICBmb3IgKGNvbnN0IHNjZW5lIG9mIHNjZW5lcykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zY2VuZUxpc3QucHVzaChzY2VuZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCBmYWxsYmFjazogQmxlbmRlclNjZW5lU2V0dGluZyA9IG5ldyBCbGVuZGVyU2NlbmVTZXR0aW5nKCk7XHJcbiAgICAgICAgICAgIGZhbGxiYWNrLm5hbWUgPSAnc2NlbmVfZ3Jhc3NfY3ljbGVzX01SUCc7XHJcbiAgICAgICAgICAgIGZhbGxiYWNrLm11bHRpU2NlbmVSZW5kZXIgPSBmYWxzZTtcclxuICAgICAgICAgICAgZmFsbGJhY2sucHJpbWFyeVNjZW5lTmFtZSA9ICdzY2VuZV9ncmFzc19jeWNsZXNfTVJQJztcclxuICAgICAgICAgICAgZmFsbGJhY2suaGRyaUludGVuc2l0eSA9IDE7XHJcbiAgICAgICAgICAgIGZhbGxiYWNrLmhkcmlSb3RhdGlvbiA9IDA7XHJcbiAgICAgICAgICAgIGZhbGxiYWNrLmxpZ2h0aW5nRXhwb3N1cmUgPSAxO1xyXG4gICAgICAgICAgICBmYWxsYmFjay5zY2VuZVR5cGUgPSBCbGVuZGVyU2NlbmVUeXBlLlJvb207XHJcblxyXG4gICAgICAgICAgICB0aGlzLnNjZW5lTGlzdC5wdXNoKGZhbGxiYWNrKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZFJlbmRlclNjZW5lID0gdGhpcy5zY2VuZUxpc3RbMF07IC8vIFNlbGVjdCB0aGUgZmlyc3Qgb25lIGFuZCBzZXQgdGhlIHZhbHVlcy5cclxuICAgICAgICB0aGlzLmhkcmlJbnRlbnNpdHkgPSB0aGlzLnNlbGVjdGVkUmVuZGVyU2NlbmUuaGRyaUludGVuc2l0eTtcclxuICAgICAgICB0aGlzLmhkcmlSb3RhdGlvbiA9IHRoaXMuc2VsZWN0ZWRSZW5kZXJTY2VuZS5oZHJpUm90YXRpb247XHJcbiAgICAgICAgdGhpcy5saWdodGluZ0V4cG9zdXJlID0gdGhpcy5zZWxlY3RlZFJlbmRlclNjZW5lLmxpZ2h0aW5nRXhwb3N1cmU7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfZ2V0T2JqZWN0c0J5TmFtZShzY2VuZTogT2JqZWN0M0QsIG5hbWU6IHN0cmluZyk6IGFueVtdIHtcclxuICAgICAgICBjb25zdCBtYXRjaGluZ09iamVjdHMgPSBbXTtcclxuICAgICAgICBzY2VuZS50cmF2ZXJzZSgob2JqZWN0KSA9PiB7XHJcbiAgICAgICAgICAgIGlmIChvYmplY3QubmFtZSA9PT0gbmFtZSkge1xyXG4gICAgICAgICAgICAgICAgbWF0Y2hpbmdPYmplY3RzLnB1c2gob2JqZWN0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBtYXRjaGluZ09iamVjdHM7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBfYWxsb3dDdWxsaW5nKGNhbWVyYU91dHNpZGVSb29tOiBib29sZWFuKTogYm9vbGVhbiB7XHJcbiAgICAgICAgLy8gaWYgdGhlIGNhbWVyYSBpcyBvdXQgb2YgdGhlIHJvb20sIGNhbWVyYU91dHNpZGVSb29tIHdpbGwgYmUgdHJ1ZVxyXG4gICAgICAgIC8vIElmIHRydWUsIHdlIG5lZWQgdG8gdXNlIGN1bGxpbmdcclxuICAgICAgICByZXR1cm4gY2FtZXJhT3V0c2lkZVJvb207IC8vIElmIHRoZSBjYW1lcmEgaXMgTk9UIHdpdGhpbiB0aGUgcm9vbSwgd2UgbWF5IHVzZSBjdWxsaW5nLlxyXG5cclxuICAgICAgICAvLyBMZWF2ZSB0aGlzIGNvZGUgZm9yIG5vdywgd2hlbiB3ZSBwaWNrIHVwIGN1bGxpbmcgYWdhaW4gd2Ugc2hvdWxkIG1ha2Ugc3VyZSB0aGF0IHdlIGFsc28gdXNlIGl0IHRvIGNoZWNrIGlmIHdlIG1heSBjdWxsXHJcbiAgICAgICAgLy8gY29uc3QgZmxvb3JQbGFuZXM6IGFueSA9IHRoaXMuX3Jvb21TZXJ2aWNlLmZsb29yUGxhbmVzKCk7XHJcbiAgICAgICAgLy8gaWYgKGZsb29yUGxhbmVzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAvLyAgIGFsbG93Q3VsbGluZyA9IGZhbHNlO1xyXG4gICAgICAgIC8vIH1cclxuICAgICAgICAvLyByZXR1cm4gYWxsb3dDdWxsaW5nO1xyXG4gICAgfVxyXG5cclxufVxyXG4iXX0=