@smarterplan/ngx-smarterplan-locations 0.2.44 → 0.2.46
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2020/lib/components/carousel/carousel.component.mjs +28 -0
- package/esm2020/lib/components/chevron/chevron.component.mjs +18 -0
- package/esm2020/lib/components/detail-location/detail-location.component.mjs +168 -0
- package/esm2020/lib/components/form-location/form-location.component.mjs +237 -0
- package/esm2020/lib/components/images/images.component.mjs +107 -0
- package/esm2020/lib/components/locations/locations.component.mjs +145 -0
- package/esm2020/lib/components/locations/map/map-popup/map-popup.component.mjs +66 -0
- package/esm2020/lib/components/locations/map/map.component.mjs +91 -0
- package/esm2020/lib/components/plan-legend/plan-legend.component.mjs +47 -0
- package/esm2020/lib/components/plans/calibration/calibration.component.mjs +468 -0
- package/esm2020/lib/components/plans/edit-plan/edit-plan.component.mjs +324 -0
- package/esm2020/lib/components/plans/plans.component.mjs +225 -0
- package/esm2020/lib/components/tab-navigation/tab-navigation.component.mjs +41 -0
- package/esm2020/lib/components/visits/visits.component.mjs +283 -0
- package/esm2020/lib/components/zones/add-audio-zone/add-audio-zone.component.mjs +230 -0
- package/esm2020/lib/components/zones/add-zone/add-zone.component.mjs +315 -0
- package/esm2020/lib/components/zones/add-zone/selection/selection.component.mjs +77 -0
- package/esm2020/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.mjs +502 -0
- package/esm2020/lib/components/zones/zones.component.mjs +268 -0
- package/esm2020/lib/helper.service.mjs +134 -0
- package/esm2020/lib/ngx-smarterplan-location-routing.module.mjs +49 -0
- package/esm2020/lib/ngx-smarterplan-locations.module.mjs +125 -0
- package/esm2020/lib/ngx-smarterplan-locations.service.mjs +14 -0
- package/esm2020/lib/pipes/count-audio-sweeps.pipe.mjs +27 -0
- package/esm2020/lib/radio-button/radio-button.component.mjs +26 -0
- package/esm2020/public-api.mjs +9 -0
- package/esm2020/smarterplan-ngx-smarterplan-locations.mjs +5 -0
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs +3991 -0
- package/fesm2015/smarterplan-ngx-smarterplan-locations.mjs.map +1 -0
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs +3828 -0
- package/fesm2020/smarterplan-ngx-smarterplan-locations.mjs.map +1 -0
- package/lib/components/carousel/carousel.component.d.ts +12 -0
- package/lib/components/chevron/chevron.component.d.ts +9 -0
- package/lib/components/detail-location/detail-location.component.d.ts +55 -0
- package/lib/components/form-location/form-location.component.d.ts +45 -0
- package/lib/components/images/images.component.d.ts +33 -0
- package/lib/components/locations/locations.component.d.ts +51 -0
- package/lib/components/locations/map/map-popup/map-popup.component.d.ts +22 -0
- package/lib/components/locations/map/map.component.d.ts +22 -0
- package/lib/components/plan-legend/plan-legend.component.d.ts +14 -0
- package/lib/components/plans/calibration/calibration.component.d.ts +140 -0
- package/lib/components/plans/edit-plan/edit-plan.component.d.ts +55 -0
- package/lib/components/plans/plans.component.d.ts +63 -0
- package/lib/components/tab-navigation/tab-navigation.component.d.ts +13 -0
- package/lib/components/visits/visits.component.d.ts +62 -0
- package/lib/components/zones/add-audio-zone/add-audio-zone.component.d.ts +63 -0
- package/lib/components/zones/add-zone/add-zone.component.d.ts +69 -0
- package/lib/components/zones/add-zone/selection/selection.component.d.ts +44 -0
- package/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.d.ts +107 -0
- package/lib/components/zones/zones.component.d.ts +73 -0
- package/lib/helper.service.d.ts +53 -0
- package/lib/ngx-smarterplan-location-routing.module.d.ts +7 -0
- package/lib/ngx-smarterplan-locations.module.d.ts +36 -0
- package/lib/ngx-smarterplan-locations.service.d.ts +6 -0
- package/lib/pipes/count-audio-sweeps.pipe.d.ts +10 -0
- package/lib/radio-button/radio-button.component.d.ts +12 -0
- package/package.json +23 -6
- package/{src/public-api.ts → public-api.d.ts} +4 -11
- package/smarterplan-ngx-smarterplan-locations.d.ts +5 -0
- package/.browserslistrc +0 -16
- package/karma.conf.js +0 -44
- package/ng-package.json +0 -7
- package/src/lib/components/carousel/carousel.component.html +0 -13
- package/src/lib/components/carousel/carousel.component.scss +0 -0
- package/src/lib/components/carousel/carousel.component.spec.ts +0 -25
- package/src/lib/components/carousel/carousel.component.ts +0 -31
- package/src/lib/components/chevron/chevron.component.html +0 -5
- package/src/lib/components/chevron/chevron.component.scss +0 -16
- package/src/lib/components/chevron/chevron.component.spec.ts +0 -25
- package/src/lib/components/chevron/chevron.component.ts +0 -17
- package/src/lib/components/detail-location/detail-location.component.html +0 -108
- package/src/lib/components/detail-location/detail-location.component.scss +0 -0
- package/src/lib/components/detail-location/detail-location.component.spec.ts +0 -25
- package/src/lib/components/detail-location/detail-location.component.ts +0 -215
- package/src/lib/components/form-location/form-location.component.html +0 -160
- package/src/lib/components/form-location/form-location.component.scss +0 -62
- package/src/lib/components/form-location/form-location.component.spec.ts +0 -25
- package/src/lib/components/form-location/form-location.component.ts +0 -274
- package/src/lib/components/images/images.component.html +0 -27
- package/src/lib/components/images/images.component.scss +0 -0
- package/src/lib/components/images/images.component.spec.ts +0 -25
- package/src/lib/components/images/images.component.ts +0 -133
- package/src/lib/components/locations/locations.component.html +0 -63
- package/src/lib/components/locations/locations.component.scss +0 -121
- package/src/lib/components/locations/locations.component.spec.ts +0 -25
- package/src/lib/components/locations/locations.component.ts +0 -186
- package/src/lib/components/locations/map/map-popup/map-popup.component.html +0 -11
- package/src/lib/components/locations/map/map-popup/map-popup.component.scss +0 -51
- package/src/lib/components/locations/map/map-popup/map-popup.component.spec.ts +0 -25
- package/src/lib/components/locations/map/map-popup/map-popup.component.ts +0 -79
- package/src/lib/components/locations/map/map.component.html +0 -2
- package/src/lib/components/locations/map/map.component.scss +0 -0
- package/src/lib/components/locations/map/map.component.spec.ts +0 -25
- package/src/lib/components/locations/map/map.component.ts +0 -111
- package/src/lib/components/plan-legend/plan-legend.component.html +0 -9
- package/src/lib/components/plan-legend/plan-legend.component.scss +0 -38
- package/src/lib/components/plan-legend/plan-legend.component.spec.ts +0 -25
- package/src/lib/components/plan-legend/plan-legend.component.ts +0 -50
- package/src/lib/components/plans/calibration/calibration.component.html +0 -98
- package/src/lib/components/plans/calibration/calibration.component.scss +0 -136
- package/src/lib/components/plans/calibration/calibration.component.spec.ts +0 -25
- package/src/lib/components/plans/calibration/calibration.component.ts +0 -603
- package/src/lib/components/plans/edit-plan/edit-plan.component.html +0 -77
- package/src/lib/components/plans/edit-plan/edit-plan.component.scss +0 -9
- package/src/lib/components/plans/edit-plan/edit-plan.component.spec.ts +0 -25
- package/src/lib/components/plans/edit-plan/edit-plan.component.ts +0 -421
- package/src/lib/components/plans/plans.component.html +0 -102
- package/src/lib/components/plans/plans.component.scss +0 -24
- package/src/lib/components/plans/plans.component.spec.ts +0 -25
- package/src/lib/components/plans/plans.component.ts +0 -305
- package/src/lib/components/tab-navigation/tab-navigation.component.html +0 -7
- package/src/lib/components/tab-navigation/tab-navigation.component.scss +0 -27
- package/src/lib/components/tab-navigation/tab-navigation.component.spec.ts +0 -25
- package/src/lib/components/tab-navigation/tab-navigation.component.ts +0 -35
- package/src/lib/components/visits/visits.component.html +0 -134
- package/src/lib/components/visits/visits.component.scss +0 -24
- package/src/lib/components/visits/visits.component.spec.ts +0 -25
- package/src/lib/components/visits/visits.component.ts +0 -357
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.html +0 -73
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.scss +0 -14
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.spec.ts +0 -25
- package/src/lib/components/zones/add-audio-zone/add-audio-zone.component.ts +0 -269
- package/src/lib/components/zones/add-zone/add-zone.component.html +0 -153
- package/src/lib/components/zones/add-zone/add-zone.component.scss +0 -44
- package/src/lib/components/zones/add-zone/add-zone.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/add-zone.component.ts +0 -377
- package/src/lib/components/zones/add-zone/selection/selection.component.html +0 -3
- package/src/lib/components/zones/add-zone/selection/selection.component.scss +0 -16
- package/src/lib/components/zones/add-zone/selection/selection.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/selection/selection.component.ts +0 -95
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.html +0 -73
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.scss +0 -23
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.spec.ts +0 -25
- package/src/lib/components/zones/add-zone/sweep-plan-selection/sweep-plan-selection.component.ts +0 -595
- package/src/lib/components/zones/zones.component.html +0 -181
- package/src/lib/components/zones/zones.component.scss +0 -36
- package/src/lib/components/zones/zones.component.spec.ts +0 -25
- package/src/lib/components/zones/zones.component.ts +0 -339
- package/src/lib/helper.service.ts +0 -161
- package/src/lib/ngx-smarterplan-location-routing.module.ts +0 -41
- package/src/lib/ngx-smarterplan-locations.module.ts +0 -74
- package/src/lib/ngx-smarterplan-locations.service.spec.ts +0 -16
- package/src/lib/ngx-smarterplan-locations.service.ts +0 -9
- package/src/lib/pipes/count-audio-sweeps.pipe.ts +0 -21
- package/src/lib/radio-button/radio-button.component.html +0 -9
- package/src/lib/radio-button/radio-button.component.scss +0 -152
- package/src/lib/radio-button/radio-button.component.spec.ts +0 -25
- package/src/lib/radio-button/radio-button.component.ts +0 -26
- package/src/test.ts +0 -27
- package/tsconfig.lib.json +0 -15
- package/tsconfig.lib.prod.json +0 -10
- package/tsconfig.spec.json +0 -17
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
|
|
2
|
+
import { Validators } from '@angular/forms';
|
|
3
|
+
import { LevelStatus, enumToArray, uploadFileToS3, PropertyType, getSignedImageUrlForSpace, deleteFromS3 } from '@smarterplan/ngx-smarterplan-core';
|
|
4
|
+
import { textValidator, noEmptyValidator, floatValidator } from "@smarterplan/ngx-smarterplan-core";
|
|
5
|
+
import * as i0 from "@angular/core";
|
|
6
|
+
import * as i1 from "@smarterplan/ngx-smarterplan-core";
|
|
7
|
+
import * as i2 from "@angular/forms";
|
|
8
|
+
import * as i3 from "@ng-bootstrap/ng-bootstrap";
|
|
9
|
+
import * as i4 from "@angular/common";
|
|
10
|
+
import * as i5 from "@ngx-translate/core";
|
|
11
|
+
export class FormLocationComponent {
|
|
12
|
+
constructor(spaceService, propertyService, userService, fb, missionService, layerService, validatorsService) {
|
|
13
|
+
this.spaceService = spaceService;
|
|
14
|
+
this.propertyService = propertyService;
|
|
15
|
+
this.userService = userService;
|
|
16
|
+
this.fb = fb;
|
|
17
|
+
this.missionService = missionService;
|
|
18
|
+
this.layerService = layerService;
|
|
19
|
+
this.validatorsService = validatorsService;
|
|
20
|
+
this.isSubmitted = false;
|
|
21
|
+
this.addMissionForNewSpace = true;
|
|
22
|
+
this.imageToBeDeleted = false;
|
|
23
|
+
this.errorForm = false;
|
|
24
|
+
this.onChange = new EventEmitter();
|
|
25
|
+
this.levels = enumToArray(LevelStatus);
|
|
26
|
+
}
|
|
27
|
+
ngOnInit() {
|
|
28
|
+
if (this.location) {
|
|
29
|
+
this.initEditForm();
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
this.initForm();
|
|
33
|
+
}
|
|
34
|
+
this.handleInputImageText();
|
|
35
|
+
}
|
|
36
|
+
initForm() {
|
|
37
|
+
this.form = this.fb.group({
|
|
38
|
+
name: ["", [Validators.required, Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
39
|
+
addresses: ["", [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
40
|
+
latitude: [null, [Validators.maxLength(255), noEmptyValidator(), floatValidator()]],
|
|
41
|
+
longitude: [null, [Validators.maxLength(255), noEmptyValidator(), floatValidator()]],
|
|
42
|
+
level: LevelStatus.LOW,
|
|
43
|
+
classGes: ["", [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
44
|
+
classEnergyConsumption: ["", [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
45
|
+
constructionYear: ["", [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
initEditForm() {
|
|
49
|
+
this.form = this.fb.group({
|
|
50
|
+
id: this.location.id,
|
|
51
|
+
name: [this.location.name, [Validators.required, Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
52
|
+
addresses: [this.location.addresses, [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
53
|
+
latitude: [this.location.latitude, [Validators.maxLength(255), floatValidator()]],
|
|
54
|
+
longitude: [this.location.longitude, [Validators.maxLength(255), floatValidator()]],
|
|
55
|
+
level: this.location.level,
|
|
56
|
+
classGes: [this.location.classGes, [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
57
|
+
classEnergyConsumption: [this.location.classEnergyConsumption, [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
58
|
+
constructionYear: [this.location.constructionYear, [Validators.maxLength(255), textValidator(), noEmptyValidator()]],
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
handleImageInput(target) {
|
|
62
|
+
this.imageToUpload = target.files[0];
|
|
63
|
+
if (this.imageToUpload) {
|
|
64
|
+
this.imageInputContainer.nativeElement.style.display = "none";
|
|
65
|
+
const reader = new FileReader();
|
|
66
|
+
reader.addEventListener("load", () => {
|
|
67
|
+
this.currentImage = reader.result;
|
|
68
|
+
});
|
|
69
|
+
reader.readAsDataURL(this.imageToUpload);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
async uploadImage(spaceID) {
|
|
73
|
+
if (this.imageToUpload) {
|
|
74
|
+
uploadFileToS3("locations/", this.imageToUpload, spaceID).then(async (url) => {
|
|
75
|
+
if (url) {
|
|
76
|
+
await this.spaceService.updateSpace({
|
|
77
|
+
id: spaceID,
|
|
78
|
+
annexes: url,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
else if (this.imageToBeDeleted) {
|
|
84
|
+
await this.spaceService.updateSpace({
|
|
85
|
+
id: spaceID,
|
|
86
|
+
annexes: null,
|
|
87
|
+
});
|
|
88
|
+
await deleteFromS3(this.location.annexes);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
clearImageFile() {
|
|
92
|
+
this.imageToUpload = null;
|
|
93
|
+
this.currentImage = null;
|
|
94
|
+
this.imageInputContainer.nativeElement.style.display = "flex";
|
|
95
|
+
this.imageInput.nativeElement.value = "";
|
|
96
|
+
this.imageInputText = "Add picture";
|
|
97
|
+
}
|
|
98
|
+
async getLayerByName(name) {
|
|
99
|
+
const currentOrgId = this.userService.currentOrganisation().id;
|
|
100
|
+
const layers = await this.layerService.getLayerByNameForOrganisation(name, currentOrgId);
|
|
101
|
+
if (layers) {
|
|
102
|
+
return layers[0];
|
|
103
|
+
}
|
|
104
|
+
// create then
|
|
105
|
+
return this.layerService.createLayerForOrganisation(name, currentOrgId);
|
|
106
|
+
}
|
|
107
|
+
async onSubmit() {
|
|
108
|
+
this.isSubmitted = true;
|
|
109
|
+
if (!this.form.valid) {
|
|
110
|
+
this.errorForm = true;
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
this.errorForm = false;
|
|
115
|
+
let space;
|
|
116
|
+
if (this.location) {
|
|
117
|
+
this.changeCommaToDot();
|
|
118
|
+
space = await this.spaceService.updateSpace(this.form.value);
|
|
119
|
+
if (space) {
|
|
120
|
+
await this.uploadImage(space.id);
|
|
121
|
+
this.location = space;
|
|
122
|
+
this.onChange.emit(space);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
this.changeCommaToDot();
|
|
127
|
+
const spaceInput = this.form.value;
|
|
128
|
+
const currentOrgID = this.userService.currentOrganisation().id;
|
|
129
|
+
spaceInput.organisationID = currentOrgID;
|
|
130
|
+
let layer = await this.getLayerByName("BUILDING");
|
|
131
|
+
if (!layer) {
|
|
132
|
+
layer = await this.layerService.createLayerForOrganisation("BUILDING", currentOrgID);
|
|
133
|
+
}
|
|
134
|
+
space = await this.spaceService.createSpace(spaceInput, layer);
|
|
135
|
+
const missions = this.userService.getManagerMissions();
|
|
136
|
+
if (space && missions.length > 0) {
|
|
137
|
+
const exampleMission = missions[0];
|
|
138
|
+
await this.uploadImage(space.id);
|
|
139
|
+
try {
|
|
140
|
+
await this.propertyService.createProperty({
|
|
141
|
+
type: PropertyType.PROPERTY,
|
|
142
|
+
spaceID: space.id,
|
|
143
|
+
organisationID: currentOrgID,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
catch (e) {
|
|
147
|
+
console.log("API Service does not have Property requests");
|
|
148
|
+
}
|
|
149
|
+
// add directly a mission for this space
|
|
150
|
+
if (this.addMissionForNewSpace) {
|
|
151
|
+
await this.missionService.create({
|
|
152
|
+
spaceID: space.id,
|
|
153
|
+
userID: exampleMission.userID,
|
|
154
|
+
role: exampleMission.role,
|
|
155
|
+
level: exampleMission.level,
|
|
156
|
+
organisationID: exampleMission.organisationID,
|
|
157
|
+
orderedOrganisationID: exampleMission.organisationID,
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
this.onChange.emit(space);
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
this.onChange.emit(null);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
catch (error) {
|
|
168
|
+
console.error(error);
|
|
169
|
+
this.onChange.emit(null);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
onCancel() {
|
|
173
|
+
this.form.reset();
|
|
174
|
+
this.onChange.emit(null);
|
|
175
|
+
}
|
|
176
|
+
get name() {
|
|
177
|
+
return this.form.get("name");
|
|
178
|
+
}
|
|
179
|
+
changeCommaToDot() {
|
|
180
|
+
const updatedSpace = this.form.value;
|
|
181
|
+
if (updatedSpace.latitude &&
|
|
182
|
+
updatedSpace.latitude.toString().includes(",")) {
|
|
183
|
+
updatedSpace.latitude = updatedSpace.latitude
|
|
184
|
+
.toString()
|
|
185
|
+
.replace(",", ".");
|
|
186
|
+
Number.parseFloat(updatedSpace.latitude);
|
|
187
|
+
}
|
|
188
|
+
if (updatedSpace.longitude &&
|
|
189
|
+
updatedSpace.longitude.toString().includes(",")) {
|
|
190
|
+
updatedSpace.longitude = updatedSpace.longitude
|
|
191
|
+
.toString()
|
|
192
|
+
.replace(",", ".");
|
|
193
|
+
Number.parseFloat(updatedSpace.longitude);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
handleInputImageText() {
|
|
197
|
+
if (this.location && this.location.annexes) {
|
|
198
|
+
this.imageInputText = "Change picture";
|
|
199
|
+
getSignedImageUrlForSpace(this.location).then((url) => {
|
|
200
|
+
if (url) {
|
|
201
|
+
this.currentImage = url;
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
this.imageInputText = "Add picture";
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
isFormError(control) {
|
|
210
|
+
return control && control.invalid && this.errorForm;
|
|
211
|
+
}
|
|
212
|
+
onFormChange() {
|
|
213
|
+
if (this.errorForm && this.form.valid) {
|
|
214
|
+
this.errorForm = false;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
FormLocationComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormLocationComponent, deps: [{ token: i1.SpaceService }, { token: i1.PropertyService }, { token: i1.BaseUserService }, { token: i2.FormBuilder }, { token: i1.MissionService }, { token: i1.LayerService }, { token: i1.ValidatorsService }], target: i0.ɵɵFactoryTarget.Component });
|
|
219
|
+
FormLocationComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: FormLocationComponent, selector: "lib-form-location", inputs: { location: "location" }, outputs: { onChange: "onChange" }, viewQueries: [{ propertyName: "imageInputContainer", first: true, predicate: ["imageInputContainer"], descendants: true }, { propertyName: "imageInput", first: true, predicate: ["imageInput"], descendants: true }, { propertyName: "imageBasePreview", first: true, predicate: ["imageBasePreview"], descendants: true }], ngImport: i0, template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\n required formControlName=\"name\">\n\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \n || isFormError(form.controls['name'])\">\n {{validatorsService.getError(form.controls['name']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\n <div class=\"invalid-feedback\">\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\n\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\n\n {{validatorsService.getError(form.controls['addresses']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\n {{validatorsService.getError(form.controls['latitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\n {{validatorsService.getError(form.controls['longitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\n <div class=\"col-sm-9\">\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\n {{validatorsService.getError(form.controls['classGes']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\n <div class=\"col-sm-9\">\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\n <label #imageInputContainer for=\"image\"\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\n {{ imageInputText | translate}}</label>\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\n <p>{{ imageToUpload.name}}</p>\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!location\">\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\n\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n\n </ngb-alert>\n </div>\n </form>\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:-moz-fit-content;width:fit-content;height:-moz-fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"], components: [{ type: i3.NgbAlert, selector: "ngb-alert", inputs: ["animation", "dismissible", "type"], outputs: ["closed"], exportAs: ["ngbAlert"] }], directives: [{ type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { type: i4.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i5.TranslateDirective, selector: "[translate],[ngx-translate]", inputs: ["translate", "translateParams"] }, { type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], pipes: { "translate": i5.TranslatePipe } });
|
|
220
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: FormLocationComponent, decorators: [{
|
|
221
|
+
type: Component,
|
|
222
|
+
args: [{ selector: 'lib-form-location', template: "<div class=\"col-md-6 form-new-loc\" *ngIf=\"form\">\n <form (ngSubmit)=\"onSubmit()\" [formGroup]=\"form\">\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Name' | translate}} *</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" data-testid=\"new-location-name\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['name'])|| isFormError(form.controls['name'])}\"\n required formControlName=\"name\">\n\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-name-invalid\" [dismissible]=\"false\" type=\"danger\" *ngIf=\"validatorsService.isControlError(form.controls['name']) \n || isFormError(form.controls['name'])\">\n {{validatorsService.getError(form.controls['name']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Address' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"addresses\" data-testid=\"new-location-address\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['addresses']) || isFormError(form.controls['addresses'])}\">\n <div class=\"invalid-feedback\">\n <span data-testid=\"\" [translate]=\"validatorsService.getError(form.controls['addresses'])\"\n *ngIf=\" validatorsService.isControlError(form.controls['addresses'])\"></span>\n\n <ngb-alert data-testid=\"new-location-address-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['addresses']) \">\n\n {{validatorsService.getError(form.controls['addresses']) | translate}}\n </ngb-alert>\n\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Construction year' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"constructionYear\"\n data-testid=\"new-location-constructionYear\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-constructionYear-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['constructionYear']) || isFormError(form.controls['constructionYear'])\">\n {{validatorsService.getError(form.controls['constructionYear']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Latitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"latitude\" data-testid=\"new-location-latitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['latitude'])|| isFormError(form.controls['latitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-latitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['latitude']) || isFormError(form.controls['latitude'])\">\n {{validatorsService.getError(form.controls['latitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Longitude' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"longitude\" data-testid=\"new-location-longitude\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['longitude'])|| isFormError(form.controls['longitude'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-longitude-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['longitude']) || isFormError(form.controls['longitude'])\">\n {{validatorsService.getError(form.controls['longitude']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Access level' | translate}}</label>\n <div class=\"col-sm-9\">\n <select class=\"d-inline-block custom-select rounded-pill\" formControlName=\"level\">\n <option *ngFor=\"let level of levels\" [value]=\"level\">{{level | translate}}</option>\n </select>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Energy Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classEnergyConsumption\"\n data-testid=\"new-location-classEnergyConsumption\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classEnergyConsumption-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classEnergyConsumption']) || isFormError(form.controls['classEnergyConsumption'])\">\n {{validatorsService.getError(form.controls['classEnergyConsumption']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Greenhouse gas emission Class' | translate}}</label>\n <div class=\"col-sm-9\">\n <input type=\"text\" class=\"form-control\" formControlName=\"classGes\" data-testid=\"new-location-classGes\" (ngModelChange)=\"onFormChange()\"\n [ngClass]=\"{'is-invalid' : validatorsService.isControlError(form.controls['classGes'])|| isFormError(form.controls['classGes'])}\">\n <div class=\"invalid-feedback\">\n <ngb-alert data-testid=\"new-location-classGes-invalid\" [dismissible]=\"false\" type=\"danger\"\n *ngIf=\"validatorsService.isControlError(form.controls['classGes']) || isFormError(form.controls['classGes'])\">\n {{validatorsService.getError(form.controls['classGes']) | translate}}\n </ngb-alert>\n </div>\n </div>\n </div>\n\n <div class=\"mb-3 row\">\n <label class=\"col-sm-3 col-form-label\">{{'Cover picture' | translate}}</label>\n <div class=\"col-sm-9\">\n <img #imageBasePreview *ngIf=\"currentImage\" class=\"image-preview\" [src]=\"currentImage\">\n <label #imageInputContainer for=\"image\"\n class=\"btn btn-label-file btn-outline-primary rounded-pill imageInputContainer\">\n <input #imageInput type=\"file\" id=\"image\" (change)=\"handleImageInput($event.target)\" />\n {{ imageInputText | translate}}</label>\n <button *ngIf=\"currentImage && !imageToUpload\" class=\"btn btn-outline-primary rounded-pill\"\n (click)=\"imageToBeDeleted=true;clearImageFile()\">{{'Delete picture' | translate }}</button>\n <div class=\"image-name\" *ngIf=\"imageToUpload\">\n <p>{{ imageToUpload.name}}</p>\n <div (click)=\"clearImageFile()\" [style.cursor]=\"'pointer'\">\n <span class=\"iconify\" data-icon=\"mdi:trash-can-outline\"></span>\n </div>\n </div>\n\n </div>\n </div>\n <div class=\"mb-3 row\" *ngIf=\"!location\">\n <label class=\"col-sm-3 col-form-label\">{{'Create mission for this space' | translate}}</label>\n <div class=\"col-sm-3\">\n <input type=\"checkbox\" [(ngModel)]=\"addMissionForNewSpace\" [ngModelOptions]=\"{standalone: true}\">\n </div>\n </div>\n\n <button data-testid=\"new-location-submit-btn\" [ngClass]=\"{'is-invalid' : errorForm }\" type=\"submit\"\n class=\"btn btn-outline-primary rounded-pill me-3\">{{'Save' | translate}}</button>\n\n <button data-testid=\"new-location-close-btn\" type=\"button\" (click)=\"onCancel()\"\n class=\"btn btn-outline-primary rounded-pill\">{{'Cancel' |\n translate}}</button>\n\n <div class=\"invalid-feedback\" *ngIf=\"errorForm\">\n <ngb-alert data-testid=\"new-location-form-invalid\" [dismissible]=\"false\" type=\"danger\">\n {{'errorForm.infoBtn' |translate}}\n\n </ngb-alert>\n </div>\n </form>\n</div>", styles: ["input[type=file]{display:none}.custom-select{border-color:var(--smarterplan-primary);width:auto}.form-new-loc{background-color:#d3d3d3;padding-top:10px;padding-bottom:10px;margin-bottom:15px}.btn-outline-primary{background-color:#fff}h4{color:var(--smarterplan-primary)}.image-preview{object-fit:cover;max-height:400px;max-width:400px;display:flex;margin-bottom:15px}.imageInputContainer{width:-moz-fit-content;width:fit-content;height:-moz-fit-content;height:fit-content}.image-name{display:flex}.col-form-label{margin-bottom:1rem;width:230px}.form-new-loc{background-color:#d3d3d3;margin-bottom:15px;padding:10px;width:80%;border-radius:10px}.col-sm-9 select{width:100%;height:31.25px;padding-left:10px}.btn-outline-primary{width:200px;margin-bottom:1rem;margin-right:1rem}.is-invalid,.btn-outline-primary.is-invalid{border-color:red!important}\n"] }]
|
|
223
|
+
}], ctorParameters: function () { return [{ type: i1.SpaceService }, { type: i1.PropertyService }, { type: i1.BaseUserService }, { type: i2.FormBuilder }, { type: i1.MissionService }, { type: i1.LayerService }, { type: i1.ValidatorsService }]; }, propDecorators: { imageInputContainer: [{
|
|
224
|
+
type: ViewChild,
|
|
225
|
+
args: ["imageInputContainer"]
|
|
226
|
+
}], imageInput: [{
|
|
227
|
+
type: ViewChild,
|
|
228
|
+
args: ["imageInput"]
|
|
229
|
+
}], imageBasePreview: [{
|
|
230
|
+
type: ViewChild,
|
|
231
|
+
args: ["imageBasePreview"]
|
|
232
|
+
}], location: [{
|
|
233
|
+
type: Input
|
|
234
|
+
}], onChange: [{
|
|
235
|
+
type: Output
|
|
236
|
+
}] } });
|
|
237
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS1sb2NhdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtc21hcnRlcnBsYW4tbG9jYXRpb25zL3NyYy9saWIvY29tcG9uZW50cy9mb3JtLWxvY2F0aW9uL2Zvcm0tbG9jYXRpb24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvZm9ybS1sb2NhdGlvbi9mb3JtLWxvY2F0aW9uLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsWUFBWSxFQUFFLEtBQUssRUFBVSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3RHLE9BQU8sRUFBMEIsVUFBVSxFQUFtQixNQUFNLGdCQUFnQixDQUFDO0FBQ3JGLE9BQU8sRUFBUyxXQUFXLEVBQWtFLFdBQVcsRUFBRSxjQUFjLEVBQVMsWUFBWSxFQUFFLHlCQUF5QixFQUFnQixZQUFZLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUNoUCxPQUFPLEVBQXFCLGFBQWEsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQzs7Ozs7OztBQU92SCxNQUFNLE9BQU8scUJBQXFCO0lBa0M5QixZQUNZLFlBQTBCLEVBQzFCLGVBQWdDLEVBQ2hDLFdBQTRCLEVBQzVCLEVBQWUsRUFDZixjQUE4QixFQUM5QixZQUEwQixFQUMzQixpQkFBb0M7UUFObkMsaUJBQVksR0FBWixZQUFZLENBQWM7UUFDMUIsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQ2hDLGdCQUFXLEdBQVgsV0FBVyxDQUFpQjtRQUM1QixPQUFFLEdBQUYsRUFBRSxDQUFhO1FBQ2YsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBQzlCLGlCQUFZLEdBQVosWUFBWSxDQUFj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QUFyQixxQkFBcUIsNGJDVmxDLDQyUkErSk07MkZEckpPLHFCQUFxQjtrQkFMakMsU0FBUzsrQkFDSSxtQkFBbUI7aVJBUzdCLG1CQUFtQjtzQkFEbEIsU0FBUzt1QkFBQyxxQkFBcUI7Z0JBSWhDLFVBQVU7c0JBRFQsU0FBUzt1QkFBQyxZQUFZO2dCQUl2QixnQkFBZ0I7c0JBRGYsU0FBUzt1QkFBQyxrQkFBa0I7Z0JBSTdCLFFBQVE7c0JBRFAsS0FBSztnQkFtQkksUUFBUTtzQkFBakIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT25Jbml0LCBPdXRwdXQsIFZpZXdDaGlsZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUdyb3VwLCBGb3JtQnVpbGRlciwgVmFsaWRhdG9ycywgQWJzdHJhY3RDb250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgU3BhY2UsIExldmVsU3RhdHVzLCBTcGFjZVNlcnZpY2UsIFByb3BlcnR5U2VydmljZSwgQmFzZVVzZXJTZXJ2aWNlLCBNaXNzaW9uU2VydmljZSwgZW51bVRvQXJyYXksIHVwbG9hZEZpbGVUb1MzLCBMYXllciwgUHJvcGVydHlUeXBlLCBnZXRTaWduZWRJbWFnZVVybEZvclNwYWNlLCBMYXllclNlcnZpY2UsIGRlbGV0ZUZyb21TMyB9IGZyb20gJ0BzbWFydGVycGxhbi9uZ3gtc21hcnRlcnBsYW4tY29yZSc7XG5pbXBvcnQgeyBWYWxpZGF0b3JzU2VydmljZSwgdGV4dFZhbGlkYXRvciwgbm9FbXB0eVZhbGlkYXRvciwgZmxvYXRWYWxpZGF0b3IgfSBmcm9tIFwiQHNtYXJ0ZXJwbGFuL25neC1zbWFydGVycGxhbi1jb3JlXCI7XG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnbGliLWZvcm0tbG9jYXRpb24nLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9mb3JtLWxvY2F0aW9uLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9mb3JtLWxvY2F0aW9uLmNvbXBvbmVudC5zY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgRm9ybUxvY2F0aW9uQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAgIGZvcm06IEZvcm1Hcm91cDtcblxuICAgIEBWaWV3Q2hpbGQoXCJpbWFnZUlucHV0Q29udGFpbmVyXCIpXG4gICAgaW1hZ2VJbnB1dENvbnRhaW5lcjogRWxlbWVudFJlZjtcblxuICAgIEBWaWV3Q2hpbGQoXCJpbWFnZUlucHV0XCIpXG4gICAgaW1hZ2VJbnB1dDogRWxlbWVudFJlZjtcblxuICAgIEBWaWV3Q2hpbGQoXCJpbWFnZUJhc2VQcmV2aWV3XCIpXG4gICAgaW1hZ2VCYXNlUHJldmlldzogRWxlbWVudFJlZjtcblxuICAgIEBJbnB1dCgpXG4gICAgbG9jYXRpb246IFNwYWNlO1xuXG4gICAgaW1hZ2VUb1VwbG9hZDogYW55O1xuXG4gICAgaXNTdWJtaXR0ZWQgPSBmYWxzZTtcblxuICAgIGxldmVsczogQXJyYXk8TGV2ZWxTdGF0dXM+O1xuXG4gICAgYWRkTWlzc2lvbkZvck5ld1NwYWNlID0gdHJ1ZTtcblxuICAgIGltYWdlSW5wdXRUZXh0OiBzdHJpbmc7XG5cbiAgICBjdXJyZW50SW1hZ2U6IHN0cmluZztcblxuICAgIGltYWdlVG9CZURlbGV0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIGVycm9yRm9ybTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgQE91dHB1dCgpIG9uQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxTcGFjZSB8IG51bGw+KCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBzcGFjZVNlcnZpY2U6IFNwYWNlU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBwcm9wZXJ0eVNlcnZpY2U6IFByb3BlcnR5U2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSB1c2VyU2VydmljZTogQmFzZVVzZXJTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIGZiOiBGb3JtQnVpbGRlcixcbiAgICAgICAgcHJpdmF0ZSBtaXNzaW9uU2VydmljZTogTWlzc2lvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbGF5ZXJTZXJ2aWNlOiBMYXllclNlcnZpY2UsXG4gICAgICAgIHB1YmxpYyB2YWxpZGF0b3JzU2VydmljZTogVmFsaWRhdG9yc1NlcnZpY2VcbiAgICApIHtcbiAgICAgICAgdGhpcy5sZXZlbHMgPSBlbnVtVG9BcnJheShMZXZlbFN0YXR1cyk7XG4gICAgfVxuXG4gICAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgICAgIGlmICh0aGlzLmxvY2F0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmluaXRFZGl0Rm9ybSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5pbml0Rm9ybSgpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuaGFuZGxlSW5wdXRJbWFnZVRleHQoKTtcbiAgICB9XG5cbiAgICBpbml0Rm9ybSgpIHtcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICBuYW1lOiBbXCJcIiwgW1ZhbGlkYXRvcnMucmVxdWlyZWQsIFZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIHRleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXG4gICAgICAgICAgICBhZGRyZXNzZXM6IFtcIlwiLCBbVmFsaWRhdG9ycy5tYXhMZW5ndGgoMjU1KSwgdGV4dFZhbGlkYXRvcigpLCBub0VtcHR5VmFsaWRhdG9yKCldXSxcbiAgICAgICAgICAgIGxhdGl0dWRlOiBbbnVsbCwgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIG5vRW1wdHlWYWxpZGF0b3IoKSwgZmxvYXRWYWxpZGF0b3IoKV1dLFxuICAgICAgICAgICAgbG9uZ2l0dWRlOiBbbnVsbCwgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIG5vRW1wdHlWYWxpZGF0b3IoKSwgZmxvYXRWYWxpZGF0b3IoKV1dLFxuICAgICAgICAgICAgbGV2ZWw6IExldmVsU3RhdHVzLkxPVyxcbiAgICAgICAgICAgIGNsYXNzR2VzOiBbXCJcIiwgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIHRleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXG4gICAgICAgICAgICBjbGFzc0VuZXJneUNvbnN1bXB0aW9uOiBbXCJcIiwgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIHRleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXG4gICAgICAgICAgICBjb25zdHJ1Y3Rpb25ZZWFyOiBbXCJcIiwgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIHRleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIGluaXRFZGl0Rm9ybSgpIHtcbiAgICAgICAgdGhpcy5mb3JtID0gdGhpcy5mYi5ncm91cCh7XG4gICAgICAgICAgICBpZDogdGhpcy5sb2NhdGlvbi5pZCxcbiAgICAgICAgICAgIG5hbWU6IFt0aGlzLmxvY2F0aW9uLm5hbWUsIFtWYWxpZGF0b3JzLnJlcXVpcmVkLCBWYWxpZGF0b3JzLm1heExlbmd0aCgyNTUpLCB0ZXh0VmFsaWRhdG9yKCksIG5vRW1wdHlWYWxpZGF0b3IoKV1dLFxuICAgICAgICAgICAgYWRkcmVzc2VzOiBbdGhpcy5sb2NhdGlvbi5hZGRyZXNzZXMsIFtWYWxpZGF0b3JzLm1heExlbmd0aCgyNTUpLCB0ZXh0VmFsaWRhdG9yKCksIG5vRW1wdHlWYWxpZGF0b3IoKV1dLFxuICAgICAgICAgICAgbGF0aXR1ZGU6IFt0aGlzLmxvY2F0aW9uLmxhdGl0dWRlLCBbVmFsaWRhdG9ycy5tYXhMZW5ndGgoMjU1KSwgZmxvYXRWYWxpZGF0b3IoKV1dLFxuICAgICAgICAgICAgbG9uZ2l0dWRlOiBbdGhpcy5sb2NhdGlvbi5sb25naXR1ZGUsIFtWYWxpZGF0b3JzLm1heExlbmd0aCgyNTUpLCBmbG9hdFZhbGlkYXRvcigpXV0sXG4gICAgICAgICAgICBsZXZlbDogdGhpcy5sb2NhdGlvbi5sZXZlbCxcbiAgICAgICAgICAgIGNsYXNzR2VzOiBbdGhpcy5sb2NhdGlvbi5jbGFzc0dlcywgW1ZhbGlkYXRvcnMubWF4TGVuZ3RoKDI1NSksIHRleHRWYWxpZGF0b3IoKSwgbm9FbXB0eVZhbGlkYXRvcigpXV0sXG4gICAgICAgICAgICBjbGFzc0VuZXJneUNvbnN1bXB0aW9uOiBbdGhpcy5sb2NhdGlvbi5jbGFzc0VuZXJneUNvbnN1bXB0aW9uLCBbVmFsaWRhdG9ycy5tYXhMZW5ndGgoMjU1KSwgdGV4dFZhbGlkYXRvcigpLCBub0VtcHR5VmFsaWRhdG9yKCldXSxcbiAgICAgICAgICAgIGNvbnN0cnVjdGlvblllYXI6IFt0aGlzLmxvY2F0aW9uLmNvbnN0cnVjdGlvblllYXIsIFtWYWxpZGF0b3JzLm1heExlbmd0aCgyNTUpLCB0ZXh0VmFsaWRhdG9yKCksIG5vRW1wdHlWYWxpZGF0b3IoKV1dLFxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBoYW5kbGVJbWFnZUlucHV0KHRhcmdldDogRXZlbnRUYXJnZXQpIHtcbiAgICAgICAgdGhpcy5pbWFnZVRvVXBsb2FkID0gKHRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS5maWxlc1swXTtcbiAgICAgICAgaWYgKHRoaXMuaW1hZ2VUb1VwbG9hZCkge1xuICAgICAgICAgICAgdGhpcy5pbWFnZUlucHV0Q29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgICAgICAgY29uc3QgcmVhZGVyID0gbmV3IEZpbGVSZWFkZXIoKTtcbiAgICAgICAgICAgIHJlYWRlci5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLCAoKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50SW1hZ2UgPSByZWFkZXIucmVzdWx0IGFzIHN0cmluZztcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVhZGVyLnJlYWRBc0RhdGFVUkwodGhpcy5pbWFnZVRvVXBsb2FkKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGFzeW5jIHVwbG9hZEltYWdlKHNwYWNlSUQ6IHN0cmluZykge1xuICAgICAgICBpZiAodGhpcy5pbWFnZVRvVXBsb2FkKSB7XG4gICAgICAgICAgICB1cGxvYWRGaWxlVG9TMyhcImxvY2F0aW9ucy9cIiwgdGhpcy5pbWFnZVRvVXBsb2FkLCBzcGFjZUlEKS50aGVuKFxuICAgICAgICAgICAgICAgIGFzeW5jICh1cmwpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHVybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zcGFjZVNlcnZpY2UudXBkYXRlU3BhY2Uoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlkOiBzcGFjZUlELFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFubmV4ZXM6IHVybCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5pbWFnZVRvQmVEZWxldGVkKSB7XG4gICAgICAgICAgICBhd2FpdCB0aGlzLnNwYWNlU2VydmljZS51cGRhdGVTcGFjZSh7XG4gICAgICAgICAgICAgICAgaWQ6IHNwYWNlSUQsXG4gICAgICAgICAgICAgICAgYW5uZXhlczogbnVsbCxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYXdhaXQgZGVsZXRlRnJvbVMzKHRoaXMubG9jYXRpb24uYW5uZXhlcyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbGVhckltYWdlRmlsZSgpIHtcbiAgICAgICAgdGhpcy5pbWFnZVRvVXBsb2FkID0gbnVsbDtcbiAgICAgICAgdGhpcy5jdXJyZW50SW1hZ2UgPSBudWxsO1xuICAgICAgICB0aGlzLmltYWdlSW5wdXRDb250YWluZXIubmF0aXZlRWxlbWVudC5zdHlsZS5kaXNwbGF5ID0gXCJmbGV4XCI7XG4gICAgICAgIHRoaXMuaW1hZ2VJbnB1dC5uYXRpdmVFbGVtZW50LnZhbHVlID0gXCJcIjtcbiAgICAgICAgdGhpcy5pbWFnZUlucHV0VGV4dCA9IFwiQWRkIHBpY3R1cmVcIjtcbiAgICB9XG5cbiAgICBhc3luYyBnZXRMYXllckJ5TmFtZShuYW1lOiBzdHJpbmcpOiBQcm9taXNlPExheWVyPiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnRPcmdJZCA9IHRoaXMudXNlclNlcnZpY2UuY3VycmVudE9yZ2FuaXNhdGlvbigpLmlkO1xuICAgICAgICBjb25zdCBsYXllcnMgPSBhd2FpdCB0aGlzLmxheWVyU2VydmljZS5nZXRMYXllckJ5TmFtZUZvck9yZ2FuaXNhdGlvbihcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICBjdXJyZW50T3JnSWQsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChsYXllcnMpIHtcbiAgICAgICAgICAgIHJldHVybiBsYXllcnNbMF07XG4gICAgICAgIH1cbiAgICAgICAgLy8gY3JlYXRlIHRoZW5cbiAgICAgICAgcmV0dXJuIHRoaXMubGF5ZXJTZXJ2aWNlLmNyZWF0ZUxheWVyRm9yT3JnYW5pc2F0aW9uKG5hbWUsIGN1cnJlbnRPcmdJZCk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25TdWJtaXQoKSB7XG4gICAgICAgIHRoaXMuaXNTdWJtaXR0ZWQgPSB0cnVlO1xuICAgICAgICBpZiAoIXRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgICAgICAgdGhpcy5lcnJvckZvcm0gPSB0cnVlO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRyeSB7IFxuICAgICAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBzcGFjZTtcbiAgICAgICAgICAgIGlmICh0aGlzLmxvY2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VDb21tYVRvRG90KCk7XG4gICAgICAgICAgICAgICAgc3BhY2UgPSBhd2FpdCB0aGlzLnNwYWNlU2VydmljZS51cGRhdGVTcGFjZSh0aGlzLmZvcm0udmFsdWUpO1xuICAgICAgICAgICAgICAgIGlmIChzcGFjZSkge1xuICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnVwbG9hZEltYWdlKHNwYWNlLmlkKTtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5sb2NhdGlvbiA9IHNwYWNlO1xuICAgICAgICAgICAgICAgICAgICB0aGlzLm9uQ2hhbmdlLmVtaXQoc3BhY2UpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgdGhpcy5jaGFuZ2VDb21tYVRvRG90KCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc3BhY2VJbnB1dCA9IHRoaXMuZm9ybS52YWx1ZSBhcyBTcGFjZTtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXJyZW50T3JnSUQgPSB0aGlzLnVzZXJTZXJ2aWNlLmN1cnJlbnRPcmdhbmlzYXRpb24oKS5pZDtcbiAgICAgICAgICAgICAgICBzcGFjZUlucHV0Lm9yZ2FuaXNhdGlvbklEID0gY3VycmVudE9yZ0lEO1xuICAgICAgICAgICAgICAgIGxldCBsYXllciA9IGF3YWl0IHRoaXMuZ2V0TGF5ZXJCeU5hbWUoXCJCVUlMRElOR1wiKTtcbiAgICAgICAgICAgICAgICBpZiAoIWxheWVyKSB7XG4gICAgICAgICAgICAgICAgICAgIGxheWVyID0gYXdhaXQgdGhpcy5sYXllclNlcnZpY2UuY3JlYXRlTGF5ZXJGb3JPcmdhbmlzYXRpb24oXG4gICAgICAgICAgICAgICAgICAgICAgICBcIkJVSUxESU5HXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50T3JnSUQsXG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHNwYWNlID0gYXdhaXQgdGhpcy5zcGFjZVNlcnZpY2UuY3JlYXRlU3BhY2UoXG4gICAgICAgICAgICAgICAgICAgIHNwYWNlSW5wdXQsXG4gICAgICAgICAgICAgICAgICAgIGxheWVyLFxuICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICBjb25zdCBtaXNzaW9ucyA9IHRoaXMudXNlclNlcnZpY2UuZ2V0TWFuYWdlck1pc3Npb25zKCk7XG4gICAgICAgICAgICAgICAgaWYgKHNwYWNlICYmIG1pc3Npb25zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZXhhbXBsZU1pc3Npb24gPSBtaXNzaW9uc1swXTtcbiAgICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy51cGxvYWRJbWFnZShzcGFjZS5pZCk7XG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnByb3BlcnR5U2VydmljZS5jcmVhdGVQcm9wZXJ0eSh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZTogUHJvcGVydHlUeXBlLlBST1BFUlRZLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYWNlSUQ6IHNwYWNlLmlkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZ2FuaXNhdGlvbklEOiBjdXJyZW50T3JnSUQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJBUEkgU2VydmljZSBkb2VzIG5vdCBoYXZlIFByb3BlcnR5IHJlcXVlc3RzXCIpO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLy8gYWRkIGRpcmVjdGx5IGEgbWlzc2lvbiBmb3IgdGhpcyBzcGFjZVxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5hZGRNaXNzaW9uRm9yTmV3U3BhY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMubWlzc2lvblNlcnZpY2UuY3JlYXRlKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGFjZUlEOiBzcGFjZS5pZCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VySUQ6IGV4YW1wbGVNaXNzaW9uLnVzZXJJRCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb2xlOiBleGFtcGxlTWlzc2lvbi5yb2xlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVsOiBleGFtcGxlTWlzc2lvbi5sZXZlbCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcmdhbmlzYXRpb25JRDogZXhhbXBsZU1pc3Npb24ub3JnYW5pc2F0aW9uSUQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JkZXJlZE9yZ2FuaXNhdGlvbklEOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBleGFtcGxlTWlzc2lvbi5vcmdhbmlzYXRpb25JRCxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHRoaXMub25DaGFuZ2UuZW1pdChzcGFjZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KG51bGwpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpO1xuICAgICAgICAgICAgdGhpcy5vbkNoYW5nZS5lbWl0KG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgb25DYW5jZWwoKSB7XG4gICAgICAgIHRoaXMuZm9ybS5yZXNldCgpO1xuICAgICAgICB0aGlzLm9uQ2hhbmdlLmVtaXQobnVsbCk7XG4gICAgfVxuXG4gICAgZ2V0IG5hbWUoKTogQWJzdHJhY3RDb250cm9sIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZm9ybS5nZXQoXCJuYW1lXCIpO1xuICAgIH1cblxuICAgIGNoYW5nZUNvbW1hVG9Eb3QoKSB7XG4gICAgICAgIGNvbnN0IHVwZGF0ZWRTcGFjZSA9IHRoaXMuZm9ybS52YWx1ZTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgdXBkYXRlZFNwYWNlLmxhdGl0dWRlICYmXG4gICAgICAgICAgICB1cGRhdGVkU3BhY2UubGF0aXR1ZGUudG9TdHJpbmcoKS5pbmNsdWRlcyhcIixcIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB1cGRhdGVkU3BhY2UubGF0aXR1ZGUgPSB1cGRhdGVkU3BhY2UubGF0aXR1ZGVcbiAgICAgICAgICAgICAgICAudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAgIC5yZXBsYWNlKFwiLFwiLCBcIi5cIik7XG4gICAgICAgICAgICBOdW1iZXIucGFyc2VGbG9hdCh1cGRhdGVkU3BhY2UubGF0aXR1ZGUpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHVwZGF0ZWRTcGFjZS5sb25naXR1ZGUgJiZcbiAgICAgICAgICAgIHVwZGF0ZWRTcGFjZS5sb25naXR1ZGUudG9TdHJpbmcoKS5pbmNsdWRlcyhcIixcIilcbiAgICAgICAgKSB7XG4gICAgICAgICAgICB1cGRhdGVkU3BhY2UubG9uZ2l0dWRlID0gdXBkYXRlZFNwYWNlLmxvbmdpdHVkZVxuICAgICAgICAgICAgICAgIC50b1N0cmluZygpXG4gICAgICAgICAgICAgICAgLnJlcGxhY2UoXCIsXCIsIFwiLlwiKTtcbiAgICAgICAgICAgIE51bWJlci5wYXJzZUZsb2F0KHVwZGF0ZWRTcGFjZS5sb25naXR1ZGUpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgaGFuZGxlSW5wdXRJbWFnZVRleHQoKSB7XG4gICAgICAgIGlmICh0aGlzLmxvY2F0aW9uICYmIHRoaXMubG9jYXRpb24uYW5uZXhlcykge1xuICAgICAgICAgICAgdGhpcy5pbWFnZUlucHV0VGV4dCA9IFwiQ2hhbmdlIHBpY3R1cmVcIjtcbiAgICAgICAgICAgIGdldFNpZ25lZEltYWdlVXJsRm9yU3BhY2UodGhpcy5sb2NhdGlvbikudGhlbigodXJsKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHVybCkge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZSA9IHVybDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VJbnB1dFRleHQgPSBcIkFkZCBwaWN0dXJlXCI7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBcbiAgICBpc0Zvcm1FcnJvcihjb250cm9sKSB7XG4gICAgICAgIHJldHVybiBjb250cm9sICYmIGNvbnRyb2wuaW52YWxpZCAmJiB0aGlzLmVycm9yRm9ybTtcbiAgICB9XG5cbiAgICBcbiAgICBvbkZvcm1DaGFuZ2UoKXtcbiAgICAgICAgaWYgKHRoaXMuZXJyb3JGb3JtICYmIHRoaXMuZm9ybS52YWxpZCkge1xuICAgICAgICAgICAgdGhpcy5lcnJvckZvcm0gPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNvbC1tZC02IGZvcm0tbmV3LWxvY1wiICpuZ0lmPVwiZm9ybVwiPlxuICA8Zm9ybSAobmdTdWJtaXQpPVwib25TdWJtaXQoKVwiIFtmb3JtR3JvdXBdPVwiZm9ybVwiPlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMyBjb2wtZm9ybS1sYWJlbFwiPnt7J05hbWUnIHwgdHJhbnNsYXRlfX0gKjwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTlcIj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1uYW1lXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25Gb3JtQ2hhbmdlKClcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsnaXMtaW52YWxpZCcgOiB2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcihmb3JtLmNvbnRyb2xzWyduYW1lJ10pfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ25hbWUnXSl9XCJcbiAgICAgICAgICByZXF1aXJlZCBmb3JtQ29udHJvbE5hbWU9XCJuYW1lXCI+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLW5hbWUtaW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIiAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ25hbWUnXSkgXG4gICAgICAgICAgfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ25hbWUnXSlcIj5cbiAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IoZm9ybS5jb250cm9sc1snbmFtZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snQWRkcmVzcycgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTlcIj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJhZGRyZXNzZXNcIiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1hZGRyZXNzXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25Gb3JtQ2hhbmdlKClcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsnaXMtaW52YWxpZCcgOiB2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcihmb3JtLmNvbnRyb2xzWydhZGRyZXNzZXMnXSkgfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ2FkZHJlc3NlcyddKX1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICA8c3BhbiBkYXRhLXRlc3RpZD1cIlwiIFt0cmFuc2xhdGVdPVwidmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IoZm9ybS5jb250cm9sc1snYWRkcmVzc2VzJ10pXCJcbiAgICAgICAgICAgICpuZ0lmPVwiIHZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2FkZHJlc3NlcyddKVwiPjwvc3Bhbj5cblxuICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJuZXctbG9jYXRpb24tYWRkcmVzcy1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2FkZHJlc3NlcyddKSBcIj5cblxuICAgICAgICAgICAge3t2YWxpZGF0b3JzU2VydmljZS5nZXRFcnJvcihmb3JtLmNvbnRyb2xzWydhZGRyZXNzZXMnXSkgfCB0cmFuc2xhdGV9fVxuICAgICAgICAgIDwvbmdiLWFsZXJ0PlxuXG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snQ29uc3RydWN0aW9uIHllYXInIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS05XCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwiY29uc3RydWN0aW9uWWVhclwiXG4gICAgICAgICAgZGF0YS10ZXN0aWQ9XCJuZXctbG9jYXRpb24tY29uc3RydWN0aW9uWWVhclwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uRm9ybUNoYW5nZSgpXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IoZm9ybS5jb250cm9sc1snY29uc3RydWN0aW9uWWVhciddKSB8fCBpc0Zvcm1FcnJvcihmb3JtLmNvbnRyb2xzWydjb25zdHJ1Y3Rpb25ZZWFyJ10pfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiPlxuICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJuZXctbG9jYXRpb24tY29uc3RydWN0aW9uWWVhci1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2NvbnN0cnVjdGlvblllYXInXSkgfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ2NvbnN0cnVjdGlvblllYXInXSlcIj5cbiAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IoZm9ybS5jb250cm9sc1snY29uc3RydWN0aW9uWWVhciddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snTGF0aXR1ZGUnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS05XCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwibGF0aXR1ZGVcIiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1sYXRpdHVkZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uRm9ybUNoYW5nZSgpXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IoZm9ybS5jb250cm9sc1snbGF0aXR1ZGUnXSl8fCAgaXNGb3JtRXJyb3IoZm9ybS5jb250cm9sc1snbGF0aXR1ZGUnXSl9XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XG4gICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1sYXRpdHVkZS1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2xhdGl0dWRlJ10pIHx8ICBpc0Zvcm1FcnJvcihmb3JtLmNvbnRyb2xzWydsYXRpdHVkZSddKVwiPlxuICAgICAgICAgICAge3t2YWxpZGF0b3JzU2VydmljZS5nZXRFcnJvcihmb3JtLmNvbnRyb2xzWydsYXRpdHVkZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snTG9uZ2l0dWRlJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOVwiPlxuICAgICAgICA8aW5wdXQgdHlwZT1cInRleHRcIiBjbGFzcz1cImZvcm0tY29udHJvbFwiIGZvcm1Db250cm9sTmFtZT1cImxvbmdpdHVkZVwiIGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWxvbmdpdHVkZVwiIChuZ01vZGVsQ2hhbmdlKT1cIm9uRm9ybUNoYW5nZSgpXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IoZm9ybS5jb250cm9sc1snbG9uZ2l0dWRlJ10pfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ2xvbmdpdHVkZSddKX1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImludmFsaWQtZmVlZGJhY2tcIj5cbiAgICAgICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWxvbmdpdHVkZS1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2xvbmdpdHVkZSddKSB8fCAgaXNGb3JtRXJyb3IoZm9ybS5jb250cm9sc1snbG9uZ2l0dWRlJ10pXCI+XG4gICAgICAgICAgICB7e3ZhbGlkYXRvcnNTZXJ2aWNlLmdldEVycm9yKGZvcm0uY29udHJvbHNbJ2xvbmdpdHVkZSddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snQWNjZXNzIGxldmVsJyB8IHRyYW5zbGF0ZX19PC9sYWJlbD5cbiAgICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tOVwiPlxuICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZC1pbmxpbmUtYmxvY2sgY3VzdG9tLXNlbGVjdCByb3VuZGVkLXBpbGxcIiBmb3JtQ29udHJvbE5hbWU9XCJsZXZlbFwiPlxuICAgICAgICAgIDxvcHRpb24gKm5nRm9yPVwibGV0IGxldmVsIG9mIGxldmVsc1wiIFt2YWx1ZV09XCJsZXZlbFwiPnt7bGV2ZWwgfCB0cmFuc2xhdGV9fTwvb3B0aW9uPlxuICAgICAgICA8L3NlbGVjdD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCI+XG4gICAgICA8bGFiZWwgY2xhc3M9XCJjb2wtc20tMyBjb2wtZm9ybS1sYWJlbFwiPnt7J0VuZXJneSBDbGFzcycgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTlcIj5cbiAgICAgICAgPGlucHV0IHR5cGU9XCJ0ZXh0XCIgY2xhc3M9XCJmb3JtLWNvbnRyb2xcIiBmb3JtQ29udHJvbE5hbWU9XCJjbGFzc0VuZXJneUNvbnN1bXB0aW9uXCJcbiAgICAgICAgICBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1jbGFzc0VuZXJneUNvbnN1bXB0aW9uXCIgKG5nTW9kZWxDaGFuZ2UpPVwib25Gb3JtQ2hhbmdlKClcIlxuICAgICAgICAgIFtuZ0NsYXNzXT1cInsnaXMtaW52YWxpZCcgOiB2YWxpZGF0b3JzU2VydmljZS5pc0NvbnRyb2xFcnJvcihmb3JtLmNvbnRyb2xzWydjbGFzc0VuZXJneUNvbnN1bXB0aW9uJ10pIHx8ICBpc0Zvcm1FcnJvcihmb3JtLmNvbnRyb2xzWydjbGFzc0VuZXJneUNvbnN1bXB0aW9uJ10pfVwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiPlxuICAgICAgICAgIDxuZ2ItYWxlcnQgZGF0YS10ZXN0aWQ9XCJuZXctbG9jYXRpb24tY2xhc3NFbmVyZ3lDb25zdW1wdGlvbi1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2NsYXNzRW5lcmd5Q29uc3VtcHRpb24nXSkgfHwgIGlzRm9ybUVycm9yKGZvcm0uY29udHJvbHNbJ2NsYXNzRW5lcmd5Q29uc3VtcHRpb24nXSlcIj5cbiAgICAgICAgICAgIHt7dmFsaWRhdG9yc1NlcnZpY2UuZ2V0RXJyb3IoZm9ybS5jb250cm9sc1snY2xhc3NFbmVyZ3lDb25zdW1wdGlvbiddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snR3JlZW5ob3VzZSBnYXMgZW1pc3Npb24gQ2xhc3MnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS05XCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwidGV4dFwiIGNsYXNzPVwiZm9ybS1jb250cm9sXCIgZm9ybUNvbnRyb2xOYW1lPVwiY2xhc3NHZXNcIiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1jbGFzc0dlc1wiIChuZ01vZGVsQ2hhbmdlKT1cIm9uRm9ybUNoYW5nZSgpXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7J2lzLWludmFsaWQnIDogdmFsaWRhdG9yc1NlcnZpY2UuaXNDb250cm9sRXJyb3IoZm9ybS5jb250cm9sc1snY2xhc3NHZXMnXSl8fCAgaXNGb3JtRXJyb3IoZm9ybS5jb250cm9sc1snY2xhc3NHZXMnXSl9XCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJpbnZhbGlkLWZlZWRiYWNrXCI+XG4gICAgICAgICAgPG5nYi1hbGVydCBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1jbGFzc0dlcy1pbnZhbGlkXCIgW2Rpc21pc3NpYmxlXT1cImZhbHNlXCIgdHlwZT1cImRhbmdlclwiXG4gICAgICAgICAgICAqbmdJZj1cInZhbGlkYXRvcnNTZXJ2aWNlLmlzQ29udHJvbEVycm9yKGZvcm0uY29udHJvbHNbJ2NsYXNzR2VzJ10pIHx8ICBpc0Zvcm1FcnJvcihmb3JtLmNvbnRyb2xzWydjbGFzc0dlcyddKVwiPlxuICAgICAgICAgICAge3t2YWxpZGF0b3JzU2VydmljZS5nZXRFcnJvcihmb3JtLmNvbnRyb2xzWydjbGFzc0dlcyddKSB8IHRyYW5zbGF0ZX19XG4gICAgICAgICAgPC9uZ2ItYWxlcnQ+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwibWItMyByb3dcIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snQ292ZXIgcGljdHVyZScgfCB0cmFuc2xhdGV9fTwvbGFiZWw+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTlcIj5cbiAgICAgICAgPGltZyAjaW1hZ2VCYXNlUHJldmlldyAqbmdJZj1cImN1cnJlbnRJbWFnZVwiIGNsYXNzPVwiaW1hZ2UtcHJldmlld1wiIFtzcmNdPVwiY3VycmVudEltYWdlXCI+XG4gICAgICAgIDxsYWJlbCAjaW1hZ2VJbnB1dENvbnRhaW5lciBmb3I9XCJpbWFnZVwiXG4gICAgICAgICAgY2xhc3M9XCJidG4gYnRuLWxhYmVsLWZpbGUgYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGwgaW1hZ2VJbnB1dENvbnRhaW5lclwiPlxuICAgICAgICAgIDxpbnB1dCAjaW1hZ2VJbnB1dCB0eXBlPVwiZmlsZVwiIGlkPVwiaW1hZ2VcIiAoY2hhbmdlKT1cImhhbmRsZUltYWdlSW5wdXQoJGV2ZW50LnRhcmdldClcIiAvPlxuICAgICAgICAgIHt7IGltYWdlSW5wdXRUZXh0IHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgICA8YnV0dG9uICpuZ0lmPVwiY3VycmVudEltYWdlICYmICFpbWFnZVRvVXBsb2FkXCIgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIlxuICAgICAgICAgIChjbGljayk9XCJpbWFnZVRvQmVEZWxldGVkPXRydWU7Y2xlYXJJbWFnZUZpbGUoKVwiPnt7J0RlbGV0ZSBwaWN0dXJlJyB8IHRyYW5zbGF0ZSB9fTwvYnV0dG9uPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaW1hZ2UtbmFtZVwiICpuZ0lmPVwiaW1hZ2VUb1VwbG9hZFwiPlxuICAgICAgICAgIDxwPnt7IGltYWdlVG9VcGxvYWQubmFtZX19PC9wPlxuICAgICAgICAgIDxkaXYgKGNsaWNrKT1cImNsZWFySW1hZ2VGaWxlKClcIiBbc3R5bGUuY3Vyc29yXT1cIidwb2ludGVyJ1wiPlxuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJpY29uaWZ5XCIgZGF0YS1pY29uPVwibWRpOnRyYXNoLWNhbi1vdXRsaW5lXCI+PC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cblxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cIm1iLTMgcm93XCIgKm5nSWY9XCIhbG9jYXRpb25cIj5cbiAgICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0zIGNvbC1mb3JtLWxhYmVsXCI+e3snQ3JlYXRlIG1pc3Npb24gZm9yIHRoaXMgc3BhY2UnIHwgdHJhbnNsYXRlfX08L2xhYmVsPlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS0zXCI+XG4gICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbKG5nTW9kZWwpXT1cImFkZE1pc3Npb25Gb3JOZXdTcGFjZVwiIFtuZ01vZGVsT3B0aW9uc109XCJ7c3RhbmRhbG9uZTogdHJ1ZX1cIj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPGJ1dHRvbiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1zdWJtaXQtYnRuXCIgW25nQ2xhc3NdPVwieydpcy1pbnZhbGlkJyA6IGVycm9yRm9ybSB9XCIgdHlwZT1cInN1Ym1pdFwiXG4gICAgICBjbGFzcz1cImJ0biBidG4tb3V0bGluZS1wcmltYXJ5IHJvdW5kZWQtcGlsbCBtZS0zXCI+e3snU2F2ZScgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuXG4gICAgPGJ1dHRvbiBkYXRhLXRlc3RpZD1cIm5ldy1sb2NhdGlvbi1jbG9zZS1idG5cIiB0eXBlPVwiYnV0dG9uXCIgKGNsaWNrKT1cIm9uQ2FuY2VsKClcIlxuICAgICAgY2xhc3M9XCJidG4gYnRuLW91dGxpbmUtcHJpbWFyeSByb3VuZGVkLXBpbGxcIj57eydDYW5jZWwnIHxcbiAgICAgIHRyYW5zbGF0ZX19PC9idXR0b24+XG5cbiAgICA8ZGl2IGNsYXNzPVwiaW52YWxpZC1mZWVkYmFja1wiICpuZ0lmPVwiZXJyb3JGb3JtXCI+XG4gICAgICA8bmdiLWFsZXJ0IGRhdGEtdGVzdGlkPVwibmV3LWxvY2F0aW9uLWZvcm0taW52YWxpZFwiIFtkaXNtaXNzaWJsZV09XCJmYWxzZVwiIHR5cGU9XCJkYW5nZXJcIj5cbiAgICAgICAge3snZXJyb3JGb3JtLmluZm9CdG4nIHx0cmFuc2xhdGV9fVxuXG4gICAgICA8L25nYi1hbGVydD5cbiAgICA8L2Rpdj5cbiAgPC9mb3JtPlxuPC9kaXY+Il19
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { Component } from '@angular/core';
|
|
2
|
+
import { InventoryStatus } from '@smarterplan/ngx-smarterplan-core';
|
|
3
|
+
import { Subject, takeUntil } from 'rxjs';
|
|
4
|
+
import * as i0 from "@angular/core";
|
|
5
|
+
import * as i1 from "@angular/router";
|
|
6
|
+
import * as i2 from "@smarterplan/ngx-smarterplan-core";
|
|
7
|
+
import * as i3 from "../tab-navigation/tab-navigation.component";
|
|
8
|
+
import * as i4 from "../carousel/carousel.component";
|
|
9
|
+
import * as i5 from "@angular/common";
|
|
10
|
+
import * as i6 from "@ng-bootstrap/ng-bootstrap";
|
|
11
|
+
import * as i7 from "@ngx-translate/core";
|
|
12
|
+
export class ImagesComponent {
|
|
13
|
+
constructor(route, spaceService, visitService, nodeService, navigatorService, router) {
|
|
14
|
+
this.route = route;
|
|
15
|
+
this.spaceService = spaceService;
|
|
16
|
+
this.visitService = visitService;
|
|
17
|
+
this.nodeService = nodeService;
|
|
18
|
+
this.navigatorService = navigatorService;
|
|
19
|
+
this.router = router;
|
|
20
|
+
this.loading = false;
|
|
21
|
+
this.menuItems = [];
|
|
22
|
+
this.destroy$ = new Subject();
|
|
23
|
+
this.navigatorService.locationIDChange
|
|
24
|
+
.pipe(takeUntil(this.destroy$))
|
|
25
|
+
.subscribe((spaceID) => {
|
|
26
|
+
this.router.navigate(["dashboard/localisation", spaceID, "images"]);
|
|
27
|
+
});
|
|
28
|
+
this.route.params.subscribe((params) => {
|
|
29
|
+
this.spaceID = params.id;
|
|
30
|
+
;
|
|
31
|
+
this.loadImages();
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
ngOnInit() {
|
|
35
|
+
}
|
|
36
|
+
ngOnDestroy() {
|
|
37
|
+
this.destroy$.next(true);
|
|
38
|
+
this.destroy$.complete();
|
|
39
|
+
}
|
|
40
|
+
setupMenuItems() {
|
|
41
|
+
this.menuItems = [
|
|
42
|
+
{ label: "Locations", url: "/localisation" },
|
|
43
|
+
{
|
|
44
|
+
label: this.currentSpace.name,
|
|
45
|
+
url: `/localisation/${this.spaceID}`,
|
|
46
|
+
},
|
|
47
|
+
{ label: "360° Images" },
|
|
48
|
+
];
|
|
49
|
+
if (this.currentVisit) {
|
|
50
|
+
this.menuItems.push({ label: this.currentVisit.name });
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
onGoBack() {
|
|
54
|
+
this.currentVisit = null;
|
|
55
|
+
this.currentImages = null;
|
|
56
|
+
this.setupMenuItems();
|
|
57
|
+
}
|
|
58
|
+
async loadImages() {
|
|
59
|
+
this.loading = true;
|
|
60
|
+
this.currentSpace = await this.spaceService.getSpace(this.spaceID);
|
|
61
|
+
this.setupMenuItems();
|
|
62
|
+
this.images = await this.visitService.loadImagesForSpace(this.currentSpace);
|
|
63
|
+
if (this.currentSpace.visits.length === 1) {
|
|
64
|
+
this.setVisit(this.currentSpace.visits[0]);
|
|
65
|
+
}
|
|
66
|
+
this.loading = false;
|
|
67
|
+
}
|
|
68
|
+
setVisit(visit) {
|
|
69
|
+
this.currentVisit = visit;
|
|
70
|
+
this.currentImages = this.images.filter((im) => {
|
|
71
|
+
return im.visit === visit;
|
|
72
|
+
});
|
|
73
|
+
this.setupMenuItems();
|
|
74
|
+
}
|
|
75
|
+
setCurrentScan(id) {
|
|
76
|
+
this.currentScanID = id;
|
|
77
|
+
}
|
|
78
|
+
async onInventoryClick() {
|
|
79
|
+
const { node } = this.currentVisit;
|
|
80
|
+
const { filename } = this.currentImages[this.currentScanID]; // 110ee452_sweep.jpeg
|
|
81
|
+
// check if node has already errors of inventory
|
|
82
|
+
const missingFilesErrors = [
|
|
83
|
+
InventoryStatus.ERROR_FILE_JSON_NOT_EXIST,
|
|
84
|
+
InventoryStatus.ERROR_FILE_MODEL_NOT_EXIST,
|
|
85
|
+
InventoryStatus.ERROR_FILE_OBJ_NOT_EXIST,
|
|
86
|
+
];
|
|
87
|
+
if (node.inventoryStatus &&
|
|
88
|
+
missingFilesErrors.includes(node.inventoryStatus)) {
|
|
89
|
+
alert("Files missing for this visit's inventory. Contact your administrator.");
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
await this.nodeService.updateNode({
|
|
93
|
+
id: node.id,
|
|
94
|
+
inventoryStatus: InventoryStatus.TO_RUN_ONE_IMAGE,
|
|
95
|
+
navigationForInventory: filename.split("_")[0],
|
|
96
|
+
});
|
|
97
|
+
alert("Automatic AI Inventory started! Detected equipments will appear soon in the visit.");
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
ImagesComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.SpaceService }, { token: i2.VisitService }, { token: i2.NodeService }, { token: i2.NavigatorService }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Component });
|
|
102
|
+
ImagesComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.2.7", type: ImagesComponent, selector: "lib-images", ngImport: i0, template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""], components: [{ type: i3.TabNavigationComponent, selector: "lib-tab-navigation", inputs: ["menuItems"], outputs: ["onGoBack"] }, { type: i4.CarouselComponent, selector: "lib-carousel", inputs: ["images"], outputs: ["currentScan"] }], directives: [{ type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i6.NgbDropdown, selector: "[ngbDropdown]", inputs: ["autoClose", "dropdownClass", "open", "placement", "container", "display"], outputs: ["openChange"], exportAs: ["ngbDropdown"] }, { type: i6.NgbDropdownToggle, selector: "[ngbDropdownToggle]" }, { type: i6.NgbDropdownMenu, selector: "[ngbDropdownMenu]" }, { type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i6.NgbDropdownItem, selector: "[ngbDropdownItem]", inputs: ["disabled"] }], pipes: { "translate": i7.TranslatePipe } });
|
|
103
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: ImagesComponent, decorators: [{
|
|
104
|
+
type: Component,
|
|
105
|
+
args: [{ selector: 'lib-images', template: "<div class=\"container-fluid dashboard-tab col-sm-10 mb-3\" *ngIf=\"currentSpace\" >\n <div class=\"m-3\">\n <lib-tab-navigation [menuItems]='menuItems' (onGoBack)=\"onGoBack()\"></lib-tab-navigation>\n </div>\n <div class=\"d-flex justify-content-center\" *ngIf=\"loading\">\n <div class=\"spinner-border\" role=\"status\">\n <span class=\"visually-hidden\">{{'Loading' | translate}}...</span>\n </div>\n </div>\n <div ngbDropdown class=\"d-inline-block\" *ngIf=\"currentSpace.visits && currentSpace.visits.length > 0\">\n <button class=\"btn btn-label-file rounded-pill\" id=\"dropdownBasic1\" *ngIf=\"!currentVisit\"\n ngbDropdownToggle>{{'Choose 3D visit' | translate}}</button>\n <div ngbDropdownMenu aria-labelledby=\"dropdownBasic1\">\n <button ngbDropdownItem *ngFor=\"let visit of currentSpace.visits\" (click)=\"setVisit(visit)\"> {{ visit.name }}\n </button>\n </div>\n </div>\n <h3 *ngIf=\"currentVisit\">{{ currentVisit.name }}</h3>\n <div class=\"mt-3\" *ngIf=\"currentVisit && currentImages.length == 0 && !loading\">\n <h4>{{'No imported images' | translate }}</h4>\n <p>{{'For import: go Virtual Visits => Import Images' | translate}}</p>\n </div>\n <button *ngIf=\"currentVisit && currentImages.length > 0 && !loading\"\n class=\"btn btn-outline-primary rounded-pill no-lowercase mb-2\" (click)=\"onInventoryClick()\">\n {{'Run AI inventory on this image' | translate}}</button>\n <lib-carousel [images]=\"currentImages\" *ngIf=\"currentImages\" (currentScan)=\"setCurrentScan($event)\"></lib-carousel>\n </div>", styles: [""] }]
|
|
106
|
+
}], ctorParameters: function () { return [{ type: i1.ActivatedRoute }, { type: i2.SpaceService }, { type: i2.VisitService }, { type: i2.NodeService }, { type: i2.NavigatorService }, { type: i1.Router }]; } });
|
|
107
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW1hZ2VzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1zbWFydGVycGxhbi1sb2NhdGlvbnMvc3JjL2xpYi9jb21wb25lbnRzL2ltYWdlcy9pbWFnZXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWxvY2F0aW9ucy9zcmMvbGliL2NvbXBvbmVudHMvaW1hZ2VzL2ltYWdlcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFVLE1BQU0sZUFBZSxDQUFDO0FBRWxELE9BQU8sRUFBbUUsZUFBZSxFQUFvQixNQUFNLG1DQUFtQyxDQUFDO0FBQ3ZKLE9BQU8sRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sTUFBTSxDQUFDOzs7Ozs7Ozs7QUFPMUMsTUFBTSxPQUFPLGVBQWU7SUFvQnhCLFlBQ1ksS0FBcUIsRUFDckIsWUFBMEIsRUFDMUIsWUFBMEIsRUFDMUIsV0FBd0IsRUFDeEIsZ0JBQWtDLEVBQ2xDLE1BQWM7UUFMZCxVQUFLLEdBQUwsS0FBSyxDQUFnQjtRQUNyQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQWtCO1FBQ2xDLFdBQU0sR0FBTixNQUFNLENBQVE7UUFkMUIsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUloQixjQUFTLEdBQWUsRUFBRSxDQUFDO1FBRTNCLGFBQVEsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBVXJCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxnQkFBZ0I7YUFDakMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7YUFDOUIsU0FBUyxDQUFDLENBQUMs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LGFBQWEsQ0FBQyxDQUFDLENBQUMsc0JBQXNCO1FBQ25GLGdEQUFnRDtRQUNoRCxNQUFNLGtCQUFrQixHQUFHO1lBQ3ZCLGVBQWUsQ0FBQyx5QkFBeUI7WUFDekMsZUFBZSxDQUFDLDBCQUEwQjtZQUMxQyxlQUFlLENBQUMsd0JBQXdCO1NBQzNDLENBQUM7UUFDRixJQUNJLElBQUksQ0FBQyxlQUFlO1lBQ3BCLGtCQUFrQixDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEVBQ25EO1lBQ0UsS0FBSyxDQUNELHVFQUF1RSxDQUMxRSxDQUFDO1NBQ0w7YUFBTTtZQUNILE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxVQUFVLENBQUM7Z0JBQzlCLEVBQUUsRUFBRSxJQUFJLENBQUMsRUFBRTtnQkFDWCxlQUFlLEVBQUUsZUFBZSxDQUFDLGdCQUFnQjtnQkFDakQsc0JBQXNCLEVBQUUsUUFBUSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDakQsQ0FBQyxDQUFDO1lBQ0gsS0FBSyxDQUNELG9GQUFvRixDQUN2RixDQUFDO1NBQ0w7SUFDTCxDQUFDOzs0R0F4SFEsZUFBZTtnR0FBZixlQUFlLGtEQ1Y1QiwybURBMEJROzJGRGhCSyxlQUFlO2tCQUwzQixTQUFTOytCQUNJLFlBQVkiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQWN0aXZhdGVkUm91dGUsIFJvdXRlciB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgeyBTcGFjZSwgVmlzaXQsIE1lbnVJdGVtLCBTcGFjZVNlcnZpY2UsIFZpc2l0U2VydmljZSwgTm9kZVNlcnZpY2UsIEludmVudG9yeVN0YXR1cywgTmF2aWdhdG9yU2VydmljZSB9IGZyb20gJ0BzbWFydGVycGxhbi9uZ3gtc21hcnRlcnBsYW4tY29yZSc7XG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwgfSBmcm9tICdyeGpzJztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdsaWItaW1hZ2VzJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vaW1hZ2VzLmNvbXBvbmVudC5odG1sJyxcbiAgICBzdHlsZVVybHM6IFsnLi9pbWFnZXMuY29tcG9uZW50LnNjc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBJbWFnZXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuXG4gICAgaW1hZ2VzOiBBcnJheTxhbnk+O1xuXG4gICAgc3BhY2VJRDogc3RyaW5nO1xuXG4gICAgY3VycmVudFNwYWNlOiBTcGFjZTtcblxuICAgIGN1cnJlbnRWaXNpdDogVmlzaXQ7XG5cbiAgICBjdXJyZW50SW1hZ2VzOiBBcnJheTxhbnk+O1xuXG4gICAgbG9hZGluZyA9IGZhbHNlO1xuXG4gICAgY3VycmVudFNjYW5JRDogc3RyaW5nO1xuXG4gICAgbWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgICBkZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSByb3V0ZTogQWN0aXZhdGVkUm91dGUsXG4gICAgICAgIHByaXZhdGUgc3BhY2VTZXJ2aWNlOiBTcGFjZVNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgdmlzaXRTZXJ2aWNlOiBWaXNpdFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbm9kZVNlcnZpY2U6IE5vZGVTZXJ2aWNlLFxuICAgICAgICBwcml2YXRlIG5hdmlnYXRvclNlcnZpY2U6IE5hdmlnYXRvclNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXG4gICAgKSB7XG4gICAgICAgIHRoaXMubmF2aWdhdG9yU2VydmljZS5sb2NhdGlvbklEQ2hhbmdlXG4gICAgICAgICAgICAucGlwZSh0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpXG4gICAgICAgICAgICAuc3Vic2NyaWJlKChzcGFjZUlEKSA9PiB7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW1wiZGFzaGJvYXJkL2xvY2FsaXNhdGlvblwiLCBzcGFjZUlELCBcImltYWdlc1wiXSk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICB0aGlzLnJvdXRlLnBhcmFtcy5zdWJzY3JpYmUoKHBhcmFtcykgPT4ge1xuICAgICAgICAgICAgdGhpcy5zcGFjZUlEID0gcGFyYW1zLmlkOztcbiAgICAgICAgICAgIHRoaXMubG9hZEltYWdlcygpO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95JC5uZXh0KHRydWUpO1xuICAgICAgICB0aGlzLmRlc3Ryb3kkLmNvbXBsZXRlKCk7XG4gICAgfVxuXG4gICAgc2V0dXBNZW51SXRlbXMoKSB7XG4gICAgICAgIHRoaXMubWVudUl0ZW1zID0gW1xuICAgICAgICAgICAgeyBsYWJlbDogXCJMb2NhdGlvbnNcIiwgdXJsOiBcIi9sb2NhbGlzYXRpb25cIiB9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGxhYmVsOiB0aGlzLmN1cnJlbnRTcGFjZS5uYW1lLFxuICAgICAgICAgICAgICAgIHVybDogYC9sb2NhbGlzYXRpb24vJHt0aGlzLnNwYWNlSUR9YCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7IGxhYmVsOiBcIjM2MMKwIEltYWdlc1wiIH0sXG4gICAgICAgIF07XG5cbiAgICAgICAgaWYgKHRoaXMuY3VycmVudFZpc2l0KSB7XG4gICAgICAgICAgICB0aGlzLm1lbnVJdGVtcy5wdXNoKHsgbGFiZWw6IHRoaXMuY3VycmVudFZpc2l0Lm5hbWUgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkdvQmFjaygpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50VmlzaXQgPSBudWxsO1xuICAgICAgICB0aGlzLmN1cnJlbnRJbWFnZXMgPSBudWxsO1xuICAgICAgICB0aGlzLnNldHVwTWVudUl0ZW1zKCk7XG4gICAgfVxuXG4gICAgYXN5bmMgbG9hZEltYWdlcygpIHtcbiAgICAgICAgdGhpcy5sb2FkaW5nID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5jdXJyZW50U3BhY2UgPSBhd2FpdCB0aGlzLnNwYWNlU2VydmljZS5nZXRTcGFjZSh0aGlzLnNwYWNlSUQpO1xuICAgICAgICB0aGlzLnNldHVwTWVudUl0ZW1zKCk7XG4gICAgICAgIHRoaXMuaW1hZ2VzID0gYXdhaXQgdGhpcy52aXNpdFNlcnZpY2UubG9hZEltYWdlc0ZvclNwYWNlKFxuICAgICAgICAgICAgdGhpcy5jdXJyZW50U3BhY2UsXG4gICAgICAgICk7XG4gICAgICAgIGlmICh0aGlzLmN1cnJlbnRTcGFjZS52aXNpdHMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgICB0aGlzLnNldFZpc2l0KHRoaXMuY3VycmVudFNwYWNlLnZpc2l0c1swXSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gICAgfVxuXG4gICAgc2V0VmlzaXQodmlzaXQpIHtcbiAgICAgICAgdGhpcy5jdXJyZW50VmlzaXQgPSB2aXNpdDtcbiAgICAgICAgdGhpcy5jdXJyZW50SW1hZ2VzID0gdGhpcy5pbWFnZXMuZmlsdGVyKChpbSkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGltLnZpc2l0ID09PSB2aXNpdDtcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuc2V0dXBNZW51SXRlbXMoKTtcbiAgICB9XG5cbiAgICBzZXRDdXJyZW50U2NhbihpZCkge1xuICAgICAgICB0aGlzLmN1cnJlbnRTY2FuSUQgPSBpZDtcbiAgICB9XG5cbiAgICBhc3luYyBvbkludmVudG9yeUNsaWNrKCkge1xuICAgICAgICBjb25zdCB7IG5vZGUgfSA9IHRoaXMuY3VycmVudFZpc2l0O1xuICAgICAgICBjb25zdCB7IGZpbGVuYW1lIH0gPSB0aGlzLmN1cnJlbnRJbWFnZXNbdGhpcy5jdXJyZW50U2NhbklEXTsgLy8gMTEwZWU0NTJfc3dlZXAuanBlZ1xuICAgICAgICAvLyBjaGVjayBpZiBub2RlIGhhcyBhbHJlYWR5IGVycm9ycyBvZiBpbnZlbnRvcnlcbiAgICAgICAgY29uc3QgbWlzc2luZ0ZpbGVzRXJyb3JzID0gW1xuICAgICAgICAgICAgSW52ZW50b3J5U3RhdHVzLkVSUk9SX0ZJTEVfSlNPTl9OT1RfRVhJU1QsXG4gICAgICAgICAgICBJbnZlbnRvcnlTdGF0dXMuRVJST1JfRklMRV9NT0RFTF9OT1RfRVhJU1QsXG4gICAgICAgICAgICBJbnZlbnRvcnlTdGF0dXMuRVJST1JfRklMRV9PQkpfTk9UX0VYSVNULFxuICAgICAgICBdO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgICBub2RlLmludmVudG9yeVN0YXR1cyAmJlxuICAgICAgICAgICAgbWlzc2luZ0ZpbGVzRXJyb3JzLmluY2x1ZGVzKG5vZGUuaW52ZW50b3J5U3RhdHVzKVxuICAgICAgICApIHtcbiAgICAgICAgICAgIGFsZXJ0KFxuICAgICAgICAgICAgICAgIFwiRmlsZXMgbWlzc2luZyBmb3IgdGhpcyB2aXNpdCdzIGludmVudG9yeS4gQ29udGFjdCB5b3VyIGFkbWluaXN0cmF0b3IuXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYXdhaXQgdGhpcy5ub2RlU2VydmljZS51cGRhdGVOb2RlKHtcbiAgICAgICAgICAgICAgICBpZDogbm9kZS5pZCxcbiAgICAgICAgICAgICAgICBpbnZlbnRvcnlTdGF0dXM6IEludmVudG9yeVN0YXR1cy5UT19SVU5fT05FX0lNQUdFLFxuICAgICAgICAgICAgICAgIG5hdmlnYXRpb25Gb3JJbnZlbnRvcnk6IGZpbGVuYW1lLnNwbGl0KFwiX1wiKVswXSxcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgYWxlcnQoXG4gICAgICAgICAgICAgICAgXCJBdXRvbWF0aWMgQUkgSW52ZW50b3J5IHN0YXJ0ZWQhIERldGVjdGVkIGVxdWlwbWVudHMgd2lsbCBhcHBlYXIgc29vbiBpbiB0aGUgdmlzaXQuXCIsXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG59XG4iLCI8ZGl2IGNsYXNzPVwiY29udGFpbmVyLWZsdWlkIGRhc2hib2FyZC10YWIgY29sLXNtLTEwIG1iLTNcIiAqbmdJZj1cImN1cnJlbnRTcGFjZVwiID5cbiAgICA8ZGl2IGNsYXNzPVwibS0zXCI+XG4gICAgICA8bGliLXRhYi1uYXZpZ2F0aW9uIFttZW51SXRlbXNdPSdtZW51SXRlbXMnIChvbkdvQmFjayk9XCJvbkdvQmFjaygpXCI+PC9saWItdGFiLW5hdmlnYXRpb24+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtY2VudGVyXCIgKm5nSWY9XCJsb2FkaW5nXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lci1ib3JkZXJcIiByb2xlPVwic3RhdHVzXCI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidmlzdWFsbHktaGlkZGVuXCI+e3snTG9hZGluZycgfCB0cmFuc2xhdGV9fS4uLjwvc3Bhbj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgbmdiRHJvcGRvd24gY2xhc3M9XCJkLWlubGluZS1ibG9ja1wiICpuZ0lmPVwiY3VycmVudFNwYWNlLnZpc2l0cyAmJiBjdXJyZW50U3BhY2UudmlzaXRzLmxlbmd0aCA+IDBcIj5cbiAgICAgIDxidXR0b24gY2xhc3M9XCJidG4gYnRuLWxhYmVsLWZpbGUgcm91bmRlZC1waWxsXCIgaWQ9XCJkcm9wZG93bkJhc2ljMVwiICpuZ0lmPVwiIWN1cnJlbnRWaXNpdFwiXG4gICAgICAgIG5nYkRyb3Bkb3duVG9nZ2xlPnt7J0Nob29zZSAzRCB2aXNpdCcgfCB0cmFuc2xhdGV9fTwvYnV0dG9uPlxuICAgICAgPGRpdiBuZ2JEcm9wZG93bk1lbnUgYXJpYS1sYWJlbGxlZGJ5PVwiZHJvcGRvd25CYXNpYzFcIj5cbiAgICAgICAgPGJ1dHRvbiBuZ2JEcm9wZG93bkl0ZW0gKm5nRm9yPVwibGV0IHZpc2l0IG9mIGN1cnJlbnRTcGFjZS52aXNpdHNcIiAoY2xpY2spPVwic2V0VmlzaXQodmlzaXQpXCI+IHt7IHZpc2l0Lm5hbWUgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgICA8aDMgKm5nSWY9XCJjdXJyZW50VmlzaXRcIj57eyBjdXJyZW50VmlzaXQubmFtZSB9fTwvaDM+XG4gICAgPGRpdiBjbGFzcz1cIm10LTNcIiAqbmdJZj1cImN1cnJlbnRWaXNpdCAmJiBjdXJyZW50SW1hZ2VzLmxlbmd0aCA9PSAwICYmICFsb2FkaW5nXCI+XG4gICAgICA8aDQ+e3snTm8gaW1wb3J0ZWQgaW1hZ2VzJyB8IHRyYW5zbGF0ZSB9fTwvaDQ+XG4gICAgICA8cD57eydGb3IgaW1wb3J0OiBnbyBWaXJ0dWFsIFZpc2l0cyA9PiBJbXBvcnQgSW1hZ2VzJyB8IHRyYW5zbGF0ZX19PC9wPlxuICAgIDwvZGl2PlxuICAgIDxidXR0b24gKm5nSWY9XCJjdXJyZW50VmlzaXQgJiYgY3VycmVudEltYWdlcy5sZW5ndGggPiAwICYmICFsb2FkaW5nXCJcbiAgICAgIGNsYXNzPVwiYnRuIGJ0bi1vdXRsaW5lLXByaW1hcnkgcm91bmRlZC1waWxsIG5vLWxvd2VyY2FzZSBtYi0yXCIgKGNsaWNrKT1cIm9uSW52ZW50b3J5Q2xpY2soKVwiPlxuICAgICAge3snUnVuIEFJIGludmVudG9yeSBvbiB0aGlzIGltYWdlJyB8IHRyYW5zbGF0ZX19PC9idXR0b24+XG4gICAgPGxpYi1jYXJvdXNlbCBbaW1hZ2VzXT1cImN1cnJlbnRJbWFnZXNcIiAqbmdJZj1cImN1cnJlbnRJbWFnZXNcIiAoY3VycmVudFNjYW4pPVwic2V0Q3VycmVudFNjYW4oJGV2ZW50KVwiPjwvbGliLWNhcm91c2VsPlxuICA8L2Rpdj4iXX0=
|