@smarterplan/ngx-smarterplan-core 0.3.11
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/README.md +24 -0
- package/esm2020/lib/components/csv-export/csv-export.component.mjs +59 -0
- package/esm2020/lib/components/loader/loader.component.mjs +14 -0
- package/esm2020/lib/components/menu-bar/avatar/avatar.component.mjs +75 -0
- package/esm2020/lib/components/menu-bar/menu-bar.component.mjs +115 -0
- package/esm2020/lib/components/menu-bar/navigation-bar/navigation-bar.component.mjs +254 -0
- package/esm2020/lib/components/menu-bar/range-date-picker/range-date-picker.component.mjs +81 -0
- package/esm2020/lib/components/modal-switch-visit/modal-switch-visit.component.mjs +39 -0
- package/esm2020/lib/components/search-bar/search-bar.component.mjs +63 -0
- package/esm2020/lib/components/support-modal/support-modal.component.mjs +59 -0
- package/esm2020/lib/config.mjs +4 -0
- package/esm2020/lib/helpers.service.mjs +468 -0
- package/esm2020/lib/mattertagData.mjs +177 -0
- package/esm2020/lib/ngx-smarterplan-core.module.mjs +117 -0
- package/esm2020/lib/ngx-smarterplan-core.service.mjs +14 -0
- package/esm2020/lib/pipes/duration-to-string.pipe.mjs +66 -0
- package/esm2020/lib/pipes/hashtag-from-id.pipe.mjs +26 -0
- package/esm2020/lib/pipes/safe-url.pipe.mjs +20 -0
- package/esm2020/lib/pipes/time-date-to-local-string.pipe.mjs +104 -0
- package/esm2020/lib/pipes/username-from-id.pipe.mjs +29 -0
- package/esm2020/lib/services/base-tab.service.mjs +24 -0
- package/esm2020/lib/services/baseVisibility.service.mjs +17 -0
- package/esm2020/lib/services/booking.service.mjs +161 -0
- package/esm2020/lib/services/content.service.mjs +135 -0
- package/esm2020/lib/services/filter.service.mjs +560 -0
- package/esm2020/lib/services/intervention.service.mjs +236 -0
- package/esm2020/lib/services/locale.service.mjs +45 -0
- package/esm2020/lib/services/matterport-import.service.mjs +339 -0
- package/esm2020/lib/services/matterport.service.mjs +876 -0
- package/esm2020/lib/services/models/affectation.service.mjs +60 -0
- package/esm2020/lib/services/models/base-object.service.mjs +70 -0
- package/esm2020/lib/services/models/capture.service.mjs +34 -0
- package/esm2020/lib/services/models/comment.service.mjs +98 -0
- package/esm2020/lib/services/models/domain.service.mjs +77 -0
- package/esm2020/lib/services/models/equipment.service.mjs +629 -0
- package/esm2020/lib/services/models/event.service.mjs +128 -0
- package/esm2020/lib/services/models/feature.service.mjs +339 -0
- package/esm2020/lib/services/models/hashtag.service.mjs +38 -0
- package/esm2020/lib/services/models/layer.service.mjs +33 -0
- package/esm2020/lib/services/models/measurement.service.mjs +158 -0
- package/esm2020/lib/services/models/mission.service.mjs +185 -0
- package/esm2020/lib/services/models/navigation.service.mjs +76 -0
- package/esm2020/lib/services/models/node.service.mjs +31 -0
- package/esm2020/lib/services/models/operation.service.mjs +59 -0
- package/esm2020/lib/services/models/organisation.service.mjs +73 -0
- package/esm2020/lib/services/models/plan.service.mjs +573 -0
- package/esm2020/lib/services/models/poi.service.mjs +48 -0
- package/esm2020/lib/services/models/profile.service.mjs +54 -0
- package/esm2020/lib/services/models/property.service.mjs +34 -0
- package/esm2020/lib/services/models/space.service.mjs +184 -0
- package/esm2020/lib/services/models/template.service.mjs +41 -0
- package/esm2020/lib/services/models/ticket.service.mjs +454 -0
- package/esm2020/lib/services/models/visit.service.mjs +130 -0
- package/esm2020/lib/services/models/zone.service.mjs +184 -0
- package/esm2020/lib/services/navigator.service.mjs +165 -0
- package/esm2020/lib/services/s3.service.mjs +124 -0
- package/esm2020/lib/services/search.service.mjs +124 -0
- package/esm2020/lib/services/support.service.mjs +42 -0
- package/esm2020/lib/services/tag.service.mjs +101 -0
- package/esm2020/lib/services/user.service.mjs +444 -0
- package/esm2020/lib/services/viewer.service.mjs +395 -0
- package/esm2020/lib/services/zone-drawer.service.mjs +76 -0
- package/esm2020/lib/types.service.mjs +266 -0
- package/esm2020/public-api.mjs +63 -0
- package/esm2020/smarterplan-ngx-smarterplan-core.mjs +5 -0
- package/fesm2015/smarterplan-ngx-smarterplan-core.mjs +10057 -0
- package/fesm2015/smarterplan-ngx-smarterplan-core.mjs.map +1 -0
- package/fesm2020/smarterplan-ngx-smarterplan-core.mjs +9371 -0
- package/fesm2020/smarterplan-ngx-smarterplan-core.mjs.map +1 -0
- package/lib/components/csv-export/csv-export.component.d.ts +18 -0
- package/lib/components/loader/loader.component.d.ts +8 -0
- package/lib/components/menu-bar/avatar/avatar.component.d.ts +18 -0
- package/lib/components/menu-bar/menu-bar.component.d.ts +35 -0
- package/lib/components/menu-bar/navigation-bar/navigation-bar.component.d.ts +66 -0
- package/lib/components/menu-bar/range-date-picker/range-date-picker.component.d.ts +24 -0
- package/lib/components/modal-switch-visit/modal-switch-visit.component.d.ts +22 -0
- package/lib/components/search-bar/search-bar.component.d.ts +16 -0
- package/lib/components/support-modal/support-modal.component.d.ts +24 -0
- package/lib/config.d.ts +17 -0
- package/lib/helpers.service.d.ts +79 -0
- package/lib/mattertagData.d.ts +65 -0
- package/lib/ngx-smarterplan-core.module.d.ts +28 -0
- package/lib/ngx-smarterplan-core.service.d.ts +6 -0
- package/lib/pipes/duration-to-string.pipe.d.ts +12 -0
- package/lib/pipes/hashtag-from-id.pipe.d.ts +10 -0
- package/lib/pipes/safe-url.pipe.d.ts +10 -0
- package/lib/pipes/time-date-to-local-string.pipe.d.ts +16 -0
- package/lib/pipes/username-from-id.pipe.d.ts +11 -0
- package/lib/services/base-tab.service.d.ts +10 -0
- package/lib/services/baseVisibility.service.d.ts +8 -0
- package/lib/services/booking.service.d.ts +21 -0
- package/lib/services/content.service.d.ts +28 -0
- package/lib/services/filter.service.d.ts +58 -0
- package/lib/services/intervention.service.d.ts +25 -0
- package/lib/services/locale.service.d.ts +23 -0
- package/lib/services/matterport-import.service.d.ts +46 -0
- package/lib/services/matterport.service.d.ts +141 -0
- package/lib/services/models/affectation.service.d.ts +14 -0
- package/lib/services/models/base-object.service.d.ts +20 -0
- package/lib/services/models/capture.service.d.ts +13 -0
- package/lib/services/models/comment.service.d.ts +26 -0
- package/lib/services/models/domain.service.d.ts +19 -0
- package/lib/services/models/equipment.service.d.ts +88 -0
- package/lib/services/models/event.service.d.ts +43 -0
- package/lib/services/models/feature.service.d.ts +71 -0
- package/lib/services/models/hashtag.service.d.ts +13 -0
- package/lib/services/models/layer.service.d.ts +11 -0
- package/lib/services/models/measurement.service.d.ts +43 -0
- package/lib/services/models/mission.service.d.ts +32 -0
- package/lib/services/models/navigation.service.d.ts +22 -0
- package/lib/services/models/node.service.d.ts +12 -0
- package/lib/services/models/operation.service.d.ts +15 -0
- package/lib/services/models/organisation.service.d.ts +19 -0
- package/lib/services/models/plan.service.d.ts +117 -0
- package/lib/services/models/poi.service.d.ts +15 -0
- package/lib/services/models/profile.service.d.ts +15 -0
- package/lib/services/models/property.service.d.ts +13 -0
- package/lib/services/models/space.service.d.ts +38 -0
- package/lib/services/models/template.service.d.ts +15 -0
- package/lib/services/models/ticket.service.d.ts +86 -0
- package/lib/services/models/visit.service.d.ts +24 -0
- package/lib/services/models/zone.service.d.ts +25 -0
- package/lib/services/navigator.service.d.ts +55 -0
- package/lib/services/s3.service.d.ts +13 -0
- package/lib/services/search.service.d.ts +20 -0
- package/lib/services/support.service.d.ts +17 -0
- package/lib/services/tag.service.d.ts +45 -0
- package/lib/services/user.service.d.ts +104 -0
- package/lib/services/viewer.service.d.ts +113 -0
- package/lib/services/zone-drawer.service.d.ts +7 -0
- package/lib/types.service.d.ts +723 -0
- package/package.json +41 -0
- package/public-api.d.ts +56 -0
- package/smarterplan-ngx-smarterplan-core.d.ts +5 -0
|
@@ -0,0 +1,876 @@
|
|
|
1
|
+
import { Inject, Injectable } from '@angular/core';
|
|
2
|
+
import { Subject } from 'rxjs';
|
|
3
|
+
import { getDistanceBetweenTwoPoints, poiTypeToString, wait } from '../helpers.service';
|
|
4
|
+
import { MattertagData } from '../mattertagData';
|
|
5
|
+
import { PoiType, TagAction, ViewerInteractions } from '../types.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
import * as i1 from "@angular/router";
|
|
8
|
+
import * as i2 from "./baseVisibility.service";
|
|
9
|
+
import * as i3 from "../config";
|
|
10
|
+
export class MatterportService {
|
|
11
|
+
constructor(config, router, visibilityService) {
|
|
12
|
+
this.router = router;
|
|
13
|
+
this.visibilityService = visibilityService;
|
|
14
|
+
// Measure mode
|
|
15
|
+
this.isMeasureModeOn = false;
|
|
16
|
+
// Timers
|
|
17
|
+
this.lastActionTime = -1;
|
|
18
|
+
this.interactionMode = ViewerInteractions.DEFAULT;
|
|
19
|
+
this.mattertags = [];
|
|
20
|
+
this.dictionnaryTags = new Map;
|
|
21
|
+
this.lastMeasure = [];
|
|
22
|
+
this.distancesLastMeasure = [];
|
|
23
|
+
this.resolution = {
|
|
24
|
+
width: 500,
|
|
25
|
+
height: 600,
|
|
26
|
+
};
|
|
27
|
+
this.visibility = {
|
|
28
|
+
mattertags: false,
|
|
29
|
+
sweeps: true,
|
|
30
|
+
};
|
|
31
|
+
this.currentSweep = new Subject();
|
|
32
|
+
this.forbiddenSweeps = [];
|
|
33
|
+
this.tagAction = new Subject();
|
|
34
|
+
this.inTransitionMode = false;
|
|
35
|
+
this.inTransitionSweep = false;
|
|
36
|
+
this.config = config;
|
|
37
|
+
}
|
|
38
|
+
get currentSpaceID() {
|
|
39
|
+
return this._currentSpaceID;
|
|
40
|
+
}
|
|
41
|
+
set currentSpaceID(value) {
|
|
42
|
+
this._currentSpaceID = value;
|
|
43
|
+
}
|
|
44
|
+
/*-----------------------------------------------------------------------------
|
|
45
|
+
Utils async
|
|
46
|
+
------------------------------------------------------------------------------*/
|
|
47
|
+
async initSdk(tagService, isMuseum = false) {
|
|
48
|
+
if (this.sdk) {
|
|
49
|
+
await this.action_delete_all_mattertags();
|
|
50
|
+
}
|
|
51
|
+
this.tagService = tagService;
|
|
52
|
+
return new Promise((resolve, reject) => {
|
|
53
|
+
// Retrieve DOM elements
|
|
54
|
+
this.pointerButton = document.querySelector("#viewer-pointer-trick");
|
|
55
|
+
this.container = document.querySelector("#viewer-module");
|
|
56
|
+
const iframe = document.querySelector("#viewer-module");
|
|
57
|
+
if (!iframe) {
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
// Add listeners
|
|
61
|
+
if (this.pointerButton) {
|
|
62
|
+
this.pointerButton.addEventListener("click", function (e) {
|
|
63
|
+
this.addMattertag();
|
|
64
|
+
this.updatePositionInTagData();
|
|
65
|
+
}.bind(this));
|
|
66
|
+
// cancel on right click
|
|
67
|
+
this.pointerButton.addEventListener("contextmenu", function (e) {
|
|
68
|
+
console.log("cancel on right click");
|
|
69
|
+
e.preventDefault();
|
|
70
|
+
this.action_canceled();
|
|
71
|
+
alert("action cancelled");
|
|
72
|
+
}.bind(this));
|
|
73
|
+
}
|
|
74
|
+
// Load SDK
|
|
75
|
+
console.log("Loading Matterport SDK");
|
|
76
|
+
// @ts-ignore
|
|
77
|
+
window.MP_SDK.connect(iframe, "qn9wsasuy5h2fzrbrn1nzr0id", "3.11").then(async (sdk) => {
|
|
78
|
+
// Instanciate sdk
|
|
79
|
+
this.sdk = sdk;
|
|
80
|
+
// Load Mattertag icons
|
|
81
|
+
this.sdk.Mattertag.registerIcon("icon-ticket", this.config.my_config.icon_ticket);
|
|
82
|
+
this.sdk.Mattertag.registerIcon("icon-equipment", this.config.my_config.icon_equipment);
|
|
83
|
+
this.sdk.Mattertag.registerIcon("icon-measure", this.config.my_config.icon_measure);
|
|
84
|
+
this.sdk.Mattertag.registerIcon("icon-data", this.config.my_config.icon_data);
|
|
85
|
+
this.sdk.Mattertag.registerIcon("icon-position", this.config.my_config.icon_position);
|
|
86
|
+
// 3D position's pointer
|
|
87
|
+
this.sdk.Pointer.intersection.subscribe(function (intersection) {
|
|
88
|
+
this.poseMatterport = intersection;
|
|
89
|
+
if (!this.oldPoseMatterportPosition) {
|
|
90
|
+
this.oldPoseMatterportPosition = {
|
|
91
|
+
x: 0,
|
|
92
|
+
y: 0,
|
|
93
|
+
z: 0,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (this.interactionMode !==
|
|
97
|
+
ViewerInteractions.DEFAULT &&
|
|
98
|
+
this.mattertagToFollow) {
|
|
99
|
+
// follow the pointer and changes the position of the last tag
|
|
100
|
+
// (we are about to validate, but it exists in sdk already)
|
|
101
|
+
this.enable_following_tag(this.mattertagToFollow);
|
|
102
|
+
}
|
|
103
|
+
}.bind(this));
|
|
104
|
+
// subscribe to measurements
|
|
105
|
+
if (!isMuseum) {
|
|
106
|
+
this.sdk.Measurements.data.subscribe({
|
|
107
|
+
onAdded: function (index, item, collection) {
|
|
108
|
+
// console.log(
|
|
109
|
+
// "item added to the collection",
|
|
110
|
+
// index,
|
|
111
|
+
// item,
|
|
112
|
+
// );
|
|
113
|
+
// this.measurements[index] = item;
|
|
114
|
+
this.lastMeasure = item.points;
|
|
115
|
+
}.bind(this),
|
|
116
|
+
onCollectionUpdated: function (collection) {
|
|
117
|
+
// console.log('the entire up-to-date collection', collection);
|
|
118
|
+
this.getDistanceForLastMeasurement();
|
|
119
|
+
}.bind(this),
|
|
120
|
+
});
|
|
121
|
+
this.sdk.Measurements.mode.subscribe(function (measurementModeState) {
|
|
122
|
+
// measurement mode state has changed
|
|
123
|
+
this.isMeasureModeOn = measurementModeState.active;
|
|
124
|
+
// console.log('Is measurement mode currently active? ', measurementModeState.active);
|
|
125
|
+
}.bind(this));
|
|
126
|
+
}
|
|
127
|
+
// Camera's viewpoint
|
|
128
|
+
this.sdk.Camera.pose.subscribe(function subscr(pose) {
|
|
129
|
+
this.poseCamera = pose;
|
|
130
|
+
// console.log('Current position is ', pose.position);
|
|
131
|
+
// console.log('Rotation angle is ', pose.rotation);
|
|
132
|
+
// console.log("Sweep UUID is", pose.sweep);
|
|
133
|
+
}.bind(this));
|
|
134
|
+
// subscribe to sweeps
|
|
135
|
+
this.sdk.Sweep.data.subscribe({
|
|
136
|
+
onCollectionUpdated: function subscr(collection) {
|
|
137
|
+
// console.log(collection);
|
|
138
|
+
this.sweeps = Object.keys(collection);
|
|
139
|
+
}.bind(this),
|
|
140
|
+
});
|
|
141
|
+
// subscribe to current sweep
|
|
142
|
+
this.sdk.Sweep.current.subscribe(function subscr(currentSweep) {
|
|
143
|
+
// Change to the current sweep has occurred.
|
|
144
|
+
if (currentSweep.sid === "") {
|
|
145
|
+
// console.log('Not currently stationed at a sweep position');
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
// console.log("emmiting sweep", currentSweep.sid);
|
|
149
|
+
this.currentSweep.next(currentSweep.sid);
|
|
150
|
+
}
|
|
151
|
+
}.bind(this));
|
|
152
|
+
// Subscribe to Floor data
|
|
153
|
+
this.sdk.Floor.data.subscribe({
|
|
154
|
+
onCollectionUpdated: function upd(collection) {
|
|
155
|
+
this.floors = Object.values(collection);
|
|
156
|
+
}.bind(this),
|
|
157
|
+
});
|
|
158
|
+
// on tag click open details page
|
|
159
|
+
this.sdk.on("tag.click", (sid) => {
|
|
160
|
+
// get object of this tag
|
|
161
|
+
try {
|
|
162
|
+
const mattertagData = this.dictionnaryTags.get(sid)?.mattertagData;
|
|
163
|
+
const url = tagService.getUrlForSeeDetails(mattertagData.getObject(), mattertagData.getType());
|
|
164
|
+
if (url !== "") {
|
|
165
|
+
this.visibilityService.detailShowing.next(true);
|
|
166
|
+
this.router.navigate([url]);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
catch {
|
|
170
|
+
console.log("Cannot show details for tag");
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
// Pointer trick
|
|
174
|
+
// Create a div that will appear when the cursor is still
|
|
175
|
+
// It will intercept the click of the mouse before it trigerring the Matterport's tour navigation
|
|
176
|
+
this.timerPointer = setInterval(this.updatePointerTrick.bind(this), 50);
|
|
177
|
+
/**
|
|
178
|
+
* Transitions
|
|
179
|
+
*/
|
|
180
|
+
this.sdk.on("viewmode.changestart", function (to, from) {
|
|
181
|
+
// console.log('Starting to move to ' + to + ' from ' + from);
|
|
182
|
+
this.inTransitionMode = true;
|
|
183
|
+
}.bind(this));
|
|
184
|
+
this.sdk.on("viewmode.changeend", function (oldMode, newMode) {
|
|
185
|
+
// console.log('Ended to move to ' + newMode + ' from ' + oldMode);
|
|
186
|
+
if (newMode !== "mode.transitioning") {
|
|
187
|
+
this.inTransitionMode = false;
|
|
188
|
+
}
|
|
189
|
+
}.bind(this));
|
|
190
|
+
this.sdk.on(sdk.Sweep.Event.ENTER, function (oldSweep, newSweep) {
|
|
191
|
+
// console.log('Leaving sweep ' + oldSweep);
|
|
192
|
+
// console.log('Entering sweep ' + newSweep);
|
|
193
|
+
this.inTransitionSweep = false;
|
|
194
|
+
}.bind(this));
|
|
195
|
+
this.sdk.on(sdk.Sweep.Event.EXIT, function (fromSweep, toSweep) {
|
|
196
|
+
// console.log('Leaving sweep ' + fromSweep);
|
|
197
|
+
// console.log('Transitioning to sweep ' + toSweep);
|
|
198
|
+
this.inTransitionSweep = true;
|
|
199
|
+
}.bind(this));
|
|
200
|
+
resolve(true);
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Add Mattertag to the dictionnary of the current tags
|
|
206
|
+
* @param mattertagID
|
|
207
|
+
* @param mattertagData
|
|
208
|
+
* @param tagType
|
|
209
|
+
* @param ticketID
|
|
210
|
+
*/
|
|
211
|
+
addMattertagToObject(mattertagID, mattertagData) {
|
|
212
|
+
if (this.sdk) {
|
|
213
|
+
this.mattertags.push(mattertagID);
|
|
214
|
+
this.dictionnaryTags.set(mattertagID, {
|
|
215
|
+
mattertagData,
|
|
216
|
+
elementID: mattertagData.elementID,
|
|
217
|
+
});
|
|
218
|
+
this.editTagStyle(mattertagID, mattertagData);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
getDistanceForLastMeasurement() {
|
|
222
|
+
if (this.lastMeasure.length > 0) {
|
|
223
|
+
const numberPoints = this.lastMeasure.length;
|
|
224
|
+
this.distancesLastMeasure = [];
|
|
225
|
+
for (let index = 1; index < numberPoints; index += 1) {
|
|
226
|
+
const distance = getDistanceBetweenTwoPoints(this.lastMeasure[index - 1], this.lastMeasure[index]);
|
|
227
|
+
this.distancesLastMeasure.push(distance);
|
|
228
|
+
}
|
|
229
|
+
this.takeScreenShot().then((res) => {
|
|
230
|
+
this.goToMenu(`visit/${this.currentSpaceID}/add_measurement`);
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Init the Mattertag that will follow the cursor
|
|
236
|
+
* @param tagType
|
|
237
|
+
*/
|
|
238
|
+
async add_cursor_mattertag(tagType, element, positioning = false) {
|
|
239
|
+
if (!this.poseMatterport)
|
|
240
|
+
return;
|
|
241
|
+
const mattertagData = new MattertagData(tagType);
|
|
242
|
+
if (positioning) {
|
|
243
|
+
// set the coordinates of the existing tag
|
|
244
|
+
const [poi] = element.pois.items;
|
|
245
|
+
if (poi && poi.coordinate) {
|
|
246
|
+
mattertagData.setPosition(JSON.parse(poi.coordinate));
|
|
247
|
+
mattertagData.setPoi(poi); // to keep custom tagIon and opacity
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
mattertagData.setSweepID(this.poseCamera.sweep);
|
|
251
|
+
mattertagData.setRotation(this.poseCamera.rotation);
|
|
252
|
+
if (element) {
|
|
253
|
+
switch (tagType) {
|
|
254
|
+
case PoiType.TICKET:
|
|
255
|
+
mattertagData.setTicket(element);
|
|
256
|
+
break;
|
|
257
|
+
case PoiType.EQUIPMENT:
|
|
258
|
+
mattertagData.setEquipment(element);
|
|
259
|
+
break;
|
|
260
|
+
case PoiType.DATA:
|
|
261
|
+
mattertagData.setFeature(element);
|
|
262
|
+
break;
|
|
263
|
+
case PoiType.DESK:
|
|
264
|
+
mattertagData.setDesk(element);
|
|
265
|
+
break;
|
|
266
|
+
default:
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
this.mattertagToFollow = await this.add_mattertag_to_viewer(mattertagData);
|
|
271
|
+
if (positioning) {
|
|
272
|
+
this.sdk.Mattertag.editIcon(this.mattertagToFollow, "icon-position");
|
|
273
|
+
this.sdk.Mattertag.editOpacity(this.mattertagToFollow, 1);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Add Mattertag from its data
|
|
278
|
+
* @param tagID
|
|
279
|
+
* @param tagType
|
|
280
|
+
* @param mattertagData
|
|
281
|
+
*/
|
|
282
|
+
async add_mattertag_to_viewer(mattertagData) {
|
|
283
|
+
let sidList;
|
|
284
|
+
if (!this.sdk) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
try {
|
|
288
|
+
sidList = await this.sdk.Mattertag.add(mattertagData.getData());
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
console.log("Tag does not belong to the visit", error, mattertagData.getData());
|
|
292
|
+
}
|
|
293
|
+
if (sidList) {
|
|
294
|
+
const mattertagID = sidList[0];
|
|
295
|
+
// console.log("added tag", mattertagData.getType(), mattertagID);
|
|
296
|
+
this.addMattertagToObject(mattertagID, mattertagData);
|
|
297
|
+
return mattertagID;
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
/*-----------------------------------------------------------------------------
|
|
302
|
+
Utils - Mattertag
|
|
303
|
+
------------------------------------------------------------------------------*/
|
|
304
|
+
addMattertag() {
|
|
305
|
+
this.setInteractionMode(ViewerInteractions.DEFAULT);
|
|
306
|
+
this.action_open_menu(this.getMenuToOpenForLastTag());
|
|
307
|
+
this.resetActionTime();
|
|
308
|
+
}
|
|
309
|
+
updatePointerTrick() {
|
|
310
|
+
if (this.interactionMode !== ViewerInteractions.DEFAULT &&
|
|
311
|
+
this.mattertagToFollow &&
|
|
312
|
+
this.poseMatterport &&
|
|
313
|
+
this.getDistPosition(this.poseMatterport.position, this.oldPoseMatterportPosition) > 25) {
|
|
314
|
+
this.pointerButton.style.display = "none";
|
|
315
|
+
const size = {
|
|
316
|
+
w: this.container.clientWidth,
|
|
317
|
+
h: this.container.clientHeight,
|
|
318
|
+
};
|
|
319
|
+
const coords = this.sdk.Conversion.worldToScreen(this.poseMatterport.position, this.poseCamera, size);
|
|
320
|
+
this.pointerButton.style.left = `${coords.x * Math.sign(coords.x) - 25}px`;
|
|
321
|
+
this.pointerButton.style.top = `${coords.y * Math.sign(coords.x) - 25}px`;
|
|
322
|
+
this.oldPoseMatterportPosition = {
|
|
323
|
+
...this.poseMatterport.position,
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
this.pointerButton.style.display = "block";
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
async editTagStyle(mattertagID, mattertagData) {
|
|
331
|
+
const stringTagType = poiTypeToString(mattertagData.getType());
|
|
332
|
+
let opacity = this.config.my_config.DEFAULT_OPACITY_TAG;
|
|
333
|
+
let iconName = `icon-${stringTagType}`;
|
|
334
|
+
const poi = mattertagData.getPoi();
|
|
335
|
+
if (poi && poi.tagIcon) {
|
|
336
|
+
const tagIcon = JSON.parse(poi.tagIcon);
|
|
337
|
+
// TODO for indicators
|
|
338
|
+
// if (mattertagData.getType() === PoiType.DATA) {
|
|
339
|
+
// const feature = mattertagData.getObject();
|
|
340
|
+
// tagIcon.src = this.tagService.getIconTagImageForFeature(
|
|
341
|
+
// feature,
|
|
342
|
+
// poi,
|
|
343
|
+
// );
|
|
344
|
+
// poi.tagIcon = tagIcon;
|
|
345
|
+
// }
|
|
346
|
+
if (tagIcon.src) {
|
|
347
|
+
const pathSigned = await this.tagService.getSignedTagIconSource(tagIcon.src);
|
|
348
|
+
if (pathSigned) {
|
|
349
|
+
try {
|
|
350
|
+
iconName = `icon-${stringTagType}-${mattertagID}-${mattertagData.customIconIndex}`;
|
|
351
|
+
await this.sdk.Mattertag.registerIcon(iconName, pathSigned);
|
|
352
|
+
mattertagData.customIconIndex += 1;
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
console.log("error registerIcon");
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
if (tagIcon.opacity) {
|
|
360
|
+
opacity = tagIcon.opacity;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
try {
|
|
364
|
+
this.sdk.Mattertag.editIcon(mattertagID, iconName);
|
|
365
|
+
this.sdk.Mattertag.editOpacity(mattertagID, opacity);
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
console.log("Error editIcon or opacity", error);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
enable_following_tag(mattertag) {
|
|
372
|
+
this.sdk.Mattertag.editPosition(mattertag, {
|
|
373
|
+
anchorPosition: {
|
|
374
|
+
x: this.poseMatterport.position.x * 1,
|
|
375
|
+
y: this.poseMatterport.position.y * 1,
|
|
376
|
+
z: this.poseMatterport.position.z * 1,
|
|
377
|
+
},
|
|
378
|
+
stemVector: {
|
|
379
|
+
x: this.poseMatterport.normal.x * 0.3,
|
|
380
|
+
y: this.poseMatterport.normal.y * 0.3,
|
|
381
|
+
z: this.poseMatterport.normal.z * 0.3,
|
|
382
|
+
},
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
resetActionTime() {
|
|
386
|
+
this.lastActionTime = -1;
|
|
387
|
+
}
|
|
388
|
+
goToLastTag() {
|
|
389
|
+
setTimeout(() => {
|
|
390
|
+
this.goToTag(this.mattertags[this.mattertags.length - 1]);
|
|
391
|
+
}, 2000);
|
|
392
|
+
}
|
|
393
|
+
async goToTag(mattertagID) {
|
|
394
|
+
if (mattertagID === "")
|
|
395
|
+
return;
|
|
396
|
+
try {
|
|
397
|
+
await this.sdk.Mattertag.navigateToTag(mattertagID, this.sdk.Mattertag.Transition.FLY);
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
console.log("cannot navigate to tag", error);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
goToMenu(menuUrl) {
|
|
404
|
+
this.router.navigate([menuUrl]);
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Get the distance betwween two 3D positions
|
|
408
|
+
* Used in order to see how much the cursor has moved from the previous position
|
|
409
|
+
* @param pos1
|
|
410
|
+
* @param pos2
|
|
411
|
+
*/
|
|
412
|
+
getDistPosition(pos1, pos2) {
|
|
413
|
+
const size = {
|
|
414
|
+
w: this.container.clientWidth,
|
|
415
|
+
h: this.container.clientHeight,
|
|
416
|
+
};
|
|
417
|
+
const coords1 = this.sdk.Conversion.worldToScreen(pos1, this.poseCamera, size);
|
|
418
|
+
const coords2 = this.sdk.Conversion.worldToScreen(pos2, this.poseCamera, size);
|
|
419
|
+
return Math.sqrt((coords1.x - coords2.x) ** 2 + (coords1.y - coords2.y) ** 2);
|
|
420
|
+
}
|
|
421
|
+
updatePositionInTagData() {
|
|
422
|
+
const lastTag = this.getLastTag();
|
|
423
|
+
if (lastTag) {
|
|
424
|
+
this.dictionnaryTags.get(lastTag).mattertagData.setPosition(this.poseMatterport.position);
|
|
425
|
+
this.dictionnaryTags.get(lastTag).mattertagData.setNormal(this.poseMatterport.normal);
|
|
426
|
+
this.updateMatterTagFromId(lastTag);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
async updateMatterTagFromId(mattertagID, object = null, tagType = null) {
|
|
430
|
+
this.sdk.Mattertag.editBillboard(mattertagID, this.dictionnaryTags.get(mattertagID).mattertagData.getData());
|
|
431
|
+
if (object && tagType) {
|
|
432
|
+
this.injectHtmlInTag(tagType, object, mattertagID);
|
|
433
|
+
}
|
|
434
|
+
this.editTagStyle(mattertagID, this.dictionnaryTags.get(mattertagID).mattertagData);
|
|
435
|
+
}
|
|
436
|
+
deleteMattertagFromId(mattertagID) {
|
|
437
|
+
this.sdk.Mattertag.remove(mattertagID);
|
|
438
|
+
this.dictionnaryTags.delete(mattertagID);
|
|
439
|
+
}
|
|
440
|
+
deleteLastMattertag() {
|
|
441
|
+
const mattertagID = this.mattertags.pop();
|
|
442
|
+
if (mattertagID) {
|
|
443
|
+
this.deleteMattertagFromId(mattertagID);
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
/*-----------------------------------------------------------------------------
|
|
447
|
+
Utils - Toolbar
|
|
448
|
+
------------------------------------------------------------------------------*/
|
|
449
|
+
action_toolbox_floorplan() {
|
|
450
|
+
this.sdk.Mode.moveTo("mode.floorplan");
|
|
451
|
+
}
|
|
452
|
+
action_toolbox_inside_view() {
|
|
453
|
+
this.sdk.Mode.moveTo("mode.inside");
|
|
454
|
+
}
|
|
455
|
+
async action_toolbox_dollhouse() {
|
|
456
|
+
setTimeout(async () => {
|
|
457
|
+
console.log("mode: ", this.inTransitionMode, " sweep: ", this.inTransitionSweep);
|
|
458
|
+
if (this.inTransitionMode || this.inTransitionSweep) {
|
|
459
|
+
console.log("viewer is in transition, cannot go dollhouse");
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
try {
|
|
463
|
+
await this.sdk.Mode.moveTo("mode.dollhouse");
|
|
464
|
+
}
|
|
465
|
+
catch (e) {
|
|
466
|
+
console.log("cannot go to dollhouse", e);
|
|
467
|
+
}
|
|
468
|
+
}, 1200);
|
|
469
|
+
}
|
|
470
|
+
action_toolbox_mesure() {
|
|
471
|
+
const newState = !this.isMeasureModeOn;
|
|
472
|
+
this.sdk.Measurements.toggleMode(newState).then(() => {
|
|
473
|
+
console.log(`Measurement mode is now ${newState ? "enabled" : "disabled"}`);
|
|
474
|
+
});
|
|
475
|
+
}
|
|
476
|
+
action_toolbox_cancel_mesure() {
|
|
477
|
+
if (this.isMeasureModeOn) {
|
|
478
|
+
this.action_toolbox_mesure();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
/*-----------------------------------------------------------------------------
|
|
482
|
+
Actions
|
|
483
|
+
------------------------------------------------------------------------------*/
|
|
484
|
+
async action_add_mattertag_from_POI(tagType, object, poi) {
|
|
485
|
+
// check if tag exists already
|
|
486
|
+
const { tag, sweep } = this.getTagFromElementId(object.id);
|
|
487
|
+
if (tag) {
|
|
488
|
+
// console.log("tag exists", object)
|
|
489
|
+
return;
|
|
490
|
+
}
|
|
491
|
+
const mattertagData = new MattertagData(tagType);
|
|
492
|
+
switch (tagType) {
|
|
493
|
+
case PoiType.TICKET:
|
|
494
|
+
mattertagData.setTicket(object);
|
|
495
|
+
break;
|
|
496
|
+
case PoiType.EQUIPMENT:
|
|
497
|
+
mattertagData.setEquipment(object);
|
|
498
|
+
break;
|
|
499
|
+
case PoiType.MEASURE:
|
|
500
|
+
mattertagData.setComment(object);
|
|
501
|
+
break;
|
|
502
|
+
case PoiType.DATA:
|
|
503
|
+
mattertagData.setFeature(object);
|
|
504
|
+
break;
|
|
505
|
+
case PoiType.DESK:
|
|
506
|
+
mattertagData.setFeature(object);
|
|
507
|
+
break;
|
|
508
|
+
default:
|
|
509
|
+
break;
|
|
510
|
+
}
|
|
511
|
+
if (poi.coordinate) {
|
|
512
|
+
mattertagData.setPosition(JSON.parse(poi.coordinate));
|
|
513
|
+
}
|
|
514
|
+
if (poi.metadata) {
|
|
515
|
+
const tagMetadata = JSON.parse(poi.metadata);
|
|
516
|
+
if (tagMetadata.normal) {
|
|
517
|
+
mattertagData.setNormal(tagMetadata.normal);
|
|
518
|
+
}
|
|
519
|
+
else {
|
|
520
|
+
mattertagData.setNormal({ x: 0, y: -0.15, z: 0 });
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
if (poi.matterportSweepID) {
|
|
524
|
+
mattertagData.setSweepID(poi.matterportSweepID);
|
|
525
|
+
}
|
|
526
|
+
mattertagData.setPoi(poi);
|
|
527
|
+
const createdTag = await this.add_mattertag_to_viewer(mattertagData);
|
|
528
|
+
if (createdTag && this.sdk) {
|
|
529
|
+
await this.injectHtmlInTag(tagType, object, createdTag);
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
async injectHtmlInTag(tagType, object, tagID) {
|
|
533
|
+
let { html, height } = await this.tagService.getHtmlToInject(tagType, object, this.config.my_config.DEFAULT_HEIGHT_HTML_TAG);
|
|
534
|
+
if (html !== "" && this.sdk) {
|
|
535
|
+
const scriptTag = this.tagService.getScriptForTag(object, tagType);
|
|
536
|
+
html += `${scriptTag}`;
|
|
537
|
+
this.sdk.Mattertag.injectHTML(tagID, html, {
|
|
538
|
+
size: {
|
|
539
|
+
w: this.config.my_config.DEFAULT_WIDTH_HTML_TAG,
|
|
540
|
+
h: height,
|
|
541
|
+
},
|
|
542
|
+
})
|
|
543
|
+
.then((messenger) => {
|
|
544
|
+
messenger.on(TagAction.DETAIL_CLICK, this.tagService.onActionDetailClick.bind(this.tagService));
|
|
545
|
+
messenger.on(TagAction.TICKET_CLICK, this.tagService.onActionDetailClick.bind(this.tagService));
|
|
546
|
+
messenger.on(TagAction.AUDIO_CLICK, this.tagService.onActionAudioClick.bind(this.tagService));
|
|
547
|
+
messenger.on(TagAction.IMAGE_CLICK, this.tagService.onActionImageClick.bind(this.tagService));
|
|
548
|
+
messenger.on(TagAction.VIDEO_CLICK, this.tagService.onActionVideoClick.bind(this.tagService));
|
|
549
|
+
messenger.on(TagAction.DOC_CLICK, this.tagService.onActionDocClick.bind(this.tagService));
|
|
550
|
+
messenger.on(TagAction.YOUTUBE_CLICK, this.tagService.onActionYoutubeClick.bind(this.tagService));
|
|
551
|
+
})
|
|
552
|
+
.catch((error) => console.log("Cannot inject html for tag", tagID, error));
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async action_delete_all_mattertags() {
|
|
556
|
+
// await Promise.all(
|
|
557
|
+
this.mattertags.map(async (tag) => {
|
|
558
|
+
await this.sdk.Mattertag.remove(tag);
|
|
559
|
+
});
|
|
560
|
+
// );
|
|
561
|
+
this.mattertags = [];
|
|
562
|
+
this.dictionnaryTags.clear();
|
|
563
|
+
}
|
|
564
|
+
async action_delete_element(element) {
|
|
565
|
+
const sidTag = this.getTagFromElementId(element.id).tag;
|
|
566
|
+
if (sidTag) {
|
|
567
|
+
let resp;
|
|
568
|
+
try {
|
|
569
|
+
resp = await this.sdk.Mattertag.remove(sidTag);
|
|
570
|
+
}
|
|
571
|
+
catch (error) {
|
|
572
|
+
console.log("Cannot delete tag", sidTag, error);
|
|
573
|
+
}
|
|
574
|
+
if (resp) {
|
|
575
|
+
this.dictionnaryTags.delete(sidTag);
|
|
576
|
+
const index = this.mattertags.indexOf(sidTag);
|
|
577
|
+
this.mattertags.splice(index, 1);
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
async action_add_ticket() {
|
|
582
|
+
await this.add_cursor_mattertag(PoiType.TICKET);
|
|
583
|
+
this.setInteractionMode(ViewerInteractions.ADDING_TICKET);
|
|
584
|
+
}
|
|
585
|
+
async action_position_element(poiType, element) {
|
|
586
|
+
await this.add_cursor_mattertag(poiType, element, true);
|
|
587
|
+
this.setInteractionMode(ViewerInteractions.POSITIONING);
|
|
588
|
+
}
|
|
589
|
+
async action_add_equip() {
|
|
590
|
+
await this.add_cursor_mattertag(PoiType.EQUIPMENT);
|
|
591
|
+
this.setInteractionMode(ViewerInteractions.ADDING_EQUIPMENT);
|
|
592
|
+
}
|
|
593
|
+
async action_add_measurement() {
|
|
594
|
+
await this.add_cursor_mattertag(PoiType.MEASURE);
|
|
595
|
+
this.setInteractionMode(ViewerInteractions.ADDING_MEASURE);
|
|
596
|
+
}
|
|
597
|
+
async action_add_feature() {
|
|
598
|
+
await this.add_cursor_mattertag(PoiType.DATA);
|
|
599
|
+
this.setInteractionMode(ViewerInteractions.ADDING_FEATURE);
|
|
600
|
+
}
|
|
601
|
+
async action_add_desk() {
|
|
602
|
+
await this.add_cursor_mattertag(PoiType.DESK);
|
|
603
|
+
this.setInteractionMode(ViewerInteractions.ADDING_FEATURE);
|
|
604
|
+
}
|
|
605
|
+
action_completed() {
|
|
606
|
+
return (Date.now() - this.lastActionTime > 2000 &&
|
|
607
|
+
this.lastActionTime !== -1);
|
|
608
|
+
}
|
|
609
|
+
action_canceled() {
|
|
610
|
+
this.setInteractionMode(ViewerInteractions.DEFAULT);
|
|
611
|
+
this.deleteLastMattertag();
|
|
612
|
+
}
|
|
613
|
+
action_open_menu(menu) {
|
|
614
|
+
this.visibilityService.detailShowing.next(true);
|
|
615
|
+
const lastTag = this.getLastTag();
|
|
616
|
+
switch (menu) {
|
|
617
|
+
case "add_equip":
|
|
618
|
+
this.goToLastTag();
|
|
619
|
+
this.goToMenu(`visit/${this.currentSpaceID}/add_equip`);
|
|
620
|
+
break;
|
|
621
|
+
case "add_ticket":
|
|
622
|
+
this.goToLastTag();
|
|
623
|
+
this.goToMenu(`visit/${this.currentSpaceID}/add_ticket`);
|
|
624
|
+
break;
|
|
625
|
+
case "add_feature":
|
|
626
|
+
this.goToLastTag();
|
|
627
|
+
let url;
|
|
628
|
+
if (this.router.url.includes("?")) {
|
|
629
|
+
url = this.router.url.substring(0, this.router.url.indexOf("?"));
|
|
630
|
+
}
|
|
631
|
+
else {
|
|
632
|
+
url = this.router.url;
|
|
633
|
+
}
|
|
634
|
+
this.goToMenu(`${url}/add_feature`);
|
|
635
|
+
break;
|
|
636
|
+
case "add_desk":
|
|
637
|
+
this.goToLastTag();
|
|
638
|
+
this.router.navigate([`visit/${this.currentSpaceID}/add_feature`], { queryParams: { isDesk: true } });
|
|
639
|
+
break;
|
|
640
|
+
case "positioning_ticket":
|
|
641
|
+
console.log("positioning_ticket");
|
|
642
|
+
if (lastTag) {
|
|
643
|
+
this.router.navigate([
|
|
644
|
+
`visit/${this.currentSpaceID}/detail/${this.dictionnaryTags.get(lastTag).elementID}`,
|
|
645
|
+
], { queryParams: { positioning: true } });
|
|
646
|
+
}
|
|
647
|
+
break;
|
|
648
|
+
case "positioning_equip":
|
|
649
|
+
if (lastTag) {
|
|
650
|
+
this.router.navigate([
|
|
651
|
+
`visit/${this.currentSpaceID}/equip/${this.dictionnaryTags.get(lastTag).elementID}`,
|
|
652
|
+
], { queryParams: { positioning: true } });
|
|
653
|
+
}
|
|
654
|
+
break;
|
|
655
|
+
case "positioning_feature":
|
|
656
|
+
if (lastTag) {
|
|
657
|
+
this.router.navigate([`${this.router.url}`], {
|
|
658
|
+
queryParams: { positioning: true },
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
break;
|
|
662
|
+
default:
|
|
663
|
+
break;
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
async action_go_to_floor(floorName, matterportFloorSequence = null) {
|
|
667
|
+
if (!this.floors) {
|
|
668
|
+
console.log("Floor are not loaded yet");
|
|
669
|
+
return;
|
|
670
|
+
}
|
|
671
|
+
// console.log(this.floors);
|
|
672
|
+
// look up for sequence number (the safest method)
|
|
673
|
+
let floorMatterport = this.floors.find((floor) => floor.sequence === matterportFloorSequence);
|
|
674
|
+
if (!floorMatterport) {
|
|
675
|
+
floorMatterport = this.floors.find((floor) => floorName.includes(floor.name) && floor.name != "");
|
|
676
|
+
}
|
|
677
|
+
if (!floorMatterport) {
|
|
678
|
+
floorMatterport = this.floors.find((floor) => floorName.includes(floor.id));
|
|
679
|
+
}
|
|
680
|
+
// console.log(floorMatterport)
|
|
681
|
+
if (floorMatterport) {
|
|
682
|
+
let retry = true;
|
|
683
|
+
while (retry) {
|
|
684
|
+
try {
|
|
685
|
+
const floorIndex = await this.sdk.Floor.moveTo(floorMatterport.sequence);
|
|
686
|
+
// console.log("moved to floorIndex", floorIndex);
|
|
687
|
+
retry = false;
|
|
688
|
+
}
|
|
689
|
+
catch (error) {
|
|
690
|
+
console.log("Cannot move to Floor", error);
|
|
691
|
+
await wait(100);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
console.warn("No matterport floor found to move to");
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
async action_go_to_sweep(sweep, rotation = null) {
|
|
700
|
+
if (this.forbiddenSweeps.includes(sweep)) {
|
|
701
|
+
console.log("user is not allowed to go to this sweep");
|
|
702
|
+
return;
|
|
703
|
+
}
|
|
704
|
+
// console.log("going to sweep", sweep, "with rotation:", rotation);
|
|
705
|
+
setTimeout(async () => {
|
|
706
|
+
if (this.inTransitionMode || this.inTransitionSweep) {
|
|
707
|
+
console.log("Cannot go to sweep, in transition");
|
|
708
|
+
return;
|
|
709
|
+
}
|
|
710
|
+
try {
|
|
711
|
+
this.inTransitionSweep = true;
|
|
712
|
+
await this.sdk.Sweep.moveTo(sweep, {
|
|
713
|
+
transition: "transition.fly",
|
|
714
|
+
transitionTime: 1500,
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
catch (error) {
|
|
718
|
+
this.inTransitionSweep = false;
|
|
719
|
+
console.log("Cannot move to sweep", error);
|
|
720
|
+
}
|
|
721
|
+
if (rotation) {
|
|
722
|
+
await this.sdk.Camera.setRotation(rotation, { speed: 100 }); // speed is degrees per second
|
|
723
|
+
}
|
|
724
|
+
}, 1000);
|
|
725
|
+
}
|
|
726
|
+
getCurrentSweep() {
|
|
727
|
+
if (this.poseCamera) {
|
|
728
|
+
return this.poseCamera.sweep;
|
|
729
|
+
}
|
|
730
|
+
return null;
|
|
731
|
+
}
|
|
732
|
+
getCurrentCameraPosition() {
|
|
733
|
+
if (this.poseCamera) {
|
|
734
|
+
return this.poseCamera;
|
|
735
|
+
}
|
|
736
|
+
return null;
|
|
737
|
+
}
|
|
738
|
+
/*-----------------------------------------------------------------------------
|
|
739
|
+
Setters
|
|
740
|
+
------------------------------------------------------------------------------*/
|
|
741
|
+
setInteractionMode(interactionMode) {
|
|
742
|
+
this.interactionMode = interactionMode;
|
|
743
|
+
}
|
|
744
|
+
setTicketAndPoiInTag(mattertagID, ticket, poi = null) {
|
|
745
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setTicket(ticket);
|
|
746
|
+
if (poi) {
|
|
747
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setPoi(poi);
|
|
748
|
+
}
|
|
749
|
+
this.dictionnaryTags.get(mattertagID).elementID = ticket.id;
|
|
750
|
+
this.updateMatterTagFromId(mattertagID, ticket, PoiType.TICKET);
|
|
751
|
+
}
|
|
752
|
+
setEquipmentAndPoiInTag(mattertagID, equip, poi = null) {
|
|
753
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setEquipment(equip);
|
|
754
|
+
if (poi) {
|
|
755
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setPoi(poi);
|
|
756
|
+
}
|
|
757
|
+
this.dictionnaryTags.get(mattertagID).elementID = equip.id;
|
|
758
|
+
this.updateMatterTagFromId(mattertagID, equip, PoiType.EQUIPMENT);
|
|
759
|
+
}
|
|
760
|
+
setFeatureAndPoiInTag(mattertagID, feature, poi = null) {
|
|
761
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setFeature(feature);
|
|
762
|
+
if (poi) {
|
|
763
|
+
this.dictionnaryTags.get(mattertagID).mattertagData.setPoi(poi);
|
|
764
|
+
}
|
|
765
|
+
this.dictionnaryTags.get(mattertagID).elementID = feature.id;
|
|
766
|
+
const tagType = feature.isBookingPlace ? PoiType.DESK : PoiType.DATA;
|
|
767
|
+
this.updateMatterTagFromId(mattertagID, feature, tagType);
|
|
768
|
+
}
|
|
769
|
+
/*-----------------------------------------------------------------------------
|
|
770
|
+
Getters
|
|
771
|
+
------------------------------------------------------------------------------*/
|
|
772
|
+
getInteractionMode() {
|
|
773
|
+
return this.interactionMode;
|
|
774
|
+
}
|
|
775
|
+
getTagFromElementId(elementID) {
|
|
776
|
+
for (let index = 0; index < this.mattertags.length; index += 1) {
|
|
777
|
+
if (this.dictionnaryTags.get(this.mattertags[index]).elementID ===
|
|
778
|
+
elementID) {
|
|
779
|
+
const { mattertagData } = this.dictionnaryTags.get(this.mattertags[index]);
|
|
780
|
+
const sweep = mattertagData.getSweepID();
|
|
781
|
+
if (!sweep) {
|
|
782
|
+
return { tag: this.mattertags[index], sweep: null };
|
|
783
|
+
}
|
|
784
|
+
if (this.sweeps && this.sweeps.includes(sweep)) {
|
|
785
|
+
return { tag: this.mattertags[index], sweep };
|
|
786
|
+
}
|
|
787
|
+
return { tag: null, sweep };
|
|
788
|
+
}
|
|
789
|
+
}
|
|
790
|
+
return { tag: null, sweep: null };
|
|
791
|
+
}
|
|
792
|
+
getTags() {
|
|
793
|
+
return this.mattertags;
|
|
794
|
+
}
|
|
795
|
+
getLastTag() {
|
|
796
|
+
if (this.mattertagToFollow) {
|
|
797
|
+
return this.mattertagToFollow;
|
|
798
|
+
}
|
|
799
|
+
else {
|
|
800
|
+
return this.mattertags.length === 0
|
|
801
|
+
? null
|
|
802
|
+
: this.mattertags[this.mattertags.length - 1];
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
getMenuToOpenForLastTag() {
|
|
806
|
+
const lastTag = this.getLastTag();
|
|
807
|
+
if (lastTag) {
|
|
808
|
+
return this.dictionnaryTags.get(lastTag).mattertagData.getMenuToOpen();
|
|
809
|
+
}
|
|
810
|
+
return null;
|
|
811
|
+
}
|
|
812
|
+
getTagDataFromId(mattertagID) {
|
|
813
|
+
try {
|
|
814
|
+
return this.dictionnaryTags.get(mattertagID).mattertagData;
|
|
815
|
+
}
|
|
816
|
+
catch {
|
|
817
|
+
console.log("cannot retrieve mattertagData for tag", mattertagID);
|
|
818
|
+
}
|
|
819
|
+
return null;
|
|
820
|
+
}
|
|
821
|
+
getLastDistances() {
|
|
822
|
+
return this.distancesLastMeasure;
|
|
823
|
+
}
|
|
824
|
+
takeScreenShot() {
|
|
825
|
+
return this.sdk.Renderer.takeScreenShot(this.resolution, this.visibility).then(function (screenShotUri) {
|
|
826
|
+
// base64 string
|
|
827
|
+
this.lastScreenshotUri = screenShotUri;
|
|
828
|
+
return Promise.resolve();
|
|
829
|
+
}.bind(this));
|
|
830
|
+
}
|
|
831
|
+
getScreenShotUri() {
|
|
832
|
+
return this.lastScreenshotUri;
|
|
833
|
+
}
|
|
834
|
+
getLastMeasurement() {
|
|
835
|
+
const data = {
|
|
836
|
+
measure: this.lastMeasure,
|
|
837
|
+
sweep: this.poseCamera.sweep,
|
|
838
|
+
};
|
|
839
|
+
return data;
|
|
840
|
+
}
|
|
841
|
+
async clearAll() {
|
|
842
|
+
console.log("removing viewer");
|
|
843
|
+
this.action_delete_all_mattertags();
|
|
844
|
+
this.floors = null;
|
|
845
|
+
this.sweeps = null;
|
|
846
|
+
this.sdk = null;
|
|
847
|
+
clearInterval(this.timerPointer);
|
|
848
|
+
this.forbiddenSweeps = [];
|
|
849
|
+
}
|
|
850
|
+
async removeForbiddenSweeps(forbiddenSweeps) {
|
|
851
|
+
this.forbiddenSweeps = [...forbiddenSweeps];
|
|
852
|
+
let removed = 0;
|
|
853
|
+
await Promise.all(forbiddenSweeps.map(async (sweep) => {
|
|
854
|
+
try {
|
|
855
|
+
await this.sdk.Sweep.disable(sweep);
|
|
856
|
+
removed += 1;
|
|
857
|
+
}
|
|
858
|
+
catch (error) {
|
|
859
|
+
console.log(error);
|
|
860
|
+
}
|
|
861
|
+
}));
|
|
862
|
+
console.log("removed sweeps:", removed);
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
MatterportService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MatterportService, deps: [{ token: 'config' }, { token: i1.Router }, { token: i2.BaseVisibilityService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
866
|
+
MatterportService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MatterportService, providedIn: 'root' });
|
|
867
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.2.7", ngImport: i0, type: MatterportService, decorators: [{
|
|
868
|
+
type: Injectable,
|
|
869
|
+
args: [{
|
|
870
|
+
providedIn: 'root'
|
|
871
|
+
}]
|
|
872
|
+
}], ctorParameters: function () { return [{ type: i3.Config, decorators: [{
|
|
873
|
+
type: Inject,
|
|
874
|
+
args: ['config']
|
|
875
|
+
}] }, { type: i1.Router }, { type: i2.BaseVisibilityService }]; } });
|
|
876
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWF0dGVycG9ydC5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LXNtYXJ0ZXJwbGFuLWNvcmUvc3JjL2xpYi9zZXJ2aWNlcy9tYXR0ZXJwb3J0LnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE1BQU0sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFbkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMvQixPQUFPLEVBQUUsMkJBQTJCLEVBQUUsZUFBZSxFQUFFLElBQUksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3hGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNqRCxPQUFPLEVBQWtELE9BQU8sRUFBRSxTQUFTLEVBQTBCLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7Ozs7O0FBU2xKLE1BQU0sT0FBTyxpQkFBaUI7SUEyRTFCLFlBQzBCLE1BQWMsRUFDeEIsTUFBYyxFQUNkLGlCQUF3QztRQUR4QyxXQUFNLEdBQU4sTUFBTSxDQUFRO1FBQ2Qsc0JBQWlCLEdBQWpCLGlCQUFpQixDQUF1QjtRQS9EMUQsZUFBZTtRQUNQLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBRWhDLFNBQVM7UUFDRCxtQkFBYyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRXBCLG9CQUFlLEdBQVcsa0JBQWtCLENBQUMsT0FBTyxDQUFDO1FBRXJELGVBQVUsR0FBa0IsRUFBRSxDQUFDO1FBRS9CLG9CQUFlLEdBQW1FLElBQUksR0FBRyxDQUFDO1FBRTFGLGdCQUFXLEdBQUcsRUFBRSxDQUFDO1FBRWpCLHlCQUFvQixHQUFZLEVBQUUsQ0FBQztRQUVuQyxlQUFVLEdBQUc7WUFDakIsS0FBSyxFQUFFLEdBQUc7WUFDVixNQUFNLEVBQUUsR0FBRztTQUNkLENBQUM7UUFFTSxlQUFVLEdBQUc7WUFDakIsVUFBVSxF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QUMsZUFBZSxHQUFHLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQztRQUM1QyxJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsTUFBTSxPQUFPLENBQUMsR0FBRyxDQUNiLGVBQWUsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO1lBQ2hDLElBQUk7Z0JBQ0EsTUFBTSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3BDLE9BQU8sSUFBSSxDQUFDLENBQUM7YUFDaEI7WUFBQyxPQUFPLEtBQUssRUFBRTtnQkFDWixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3RCO1FBQ0wsQ0FBQyxDQUFDLENBQ0wsQ0FBQztRQUNGLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDNUMsQ0FBQzs7OEdBNW9DVSxpQkFBaUIsa0JBNEVWLFFBQVE7a0hBNUVmLGlCQUFpQixjQUZoQixNQUFNOzJGQUVQLGlCQUFpQjtrQkFIN0IsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkI7OzBCQTZFWSxNQUFNOzJCQUFDLFFBQVEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgUm91dGVyIH0gZnJvbSAnQGFuZ3VsYXIvcm91dGVyJztcclxuaW1wb3J0IHsgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBnZXREaXN0YW5jZUJldHdlZW5Ud29Qb2ludHMsIHBvaVR5cGVUb1N0cmluZywgd2FpdCB9IGZyb20gJy4uL2hlbHBlcnMuc2VydmljZSc7XHJcbmltcG9ydCB7IE1hdHRlcnRhZ0RhdGEgfSBmcm9tICcuLi9tYXR0ZXJ0YWdEYXRhJztcclxuaW1wb3J0IHsgQ29tbWVudCwgRGJPYmplY3RUeXBlLCBFcXVpcG1lbnQsIEZlYXR1cmUsIFBPSSwgUG9pVHlwZSwgVGFnQWN0aW9uLCBUaWNrZXQsIFRpY2tldFByaW9yaXR5LCBWaWV3ZXJJbnRlcmFjdGlvbnMgfSBmcm9tICcuLi90eXBlcy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQmFzZVRhZ1NlcnZpY2UgfSBmcm9tICcuL3RhZy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQmFzZVZpc2liaWxpdHlTZXJ2aWNlIH0gZnJvbSAnLi9iYXNlVmlzaWJpbGl0eS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgQ29uZmlnIH0gZnJvbSAnLi4vY29uZmlnJztcclxuXHJcblxyXG5ASW5qZWN0YWJsZSh7XHJcbiAgcHJvdmlkZWRJbjogJ3Jvb3QnXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNYXR0ZXJwb3J0U2VydmljZSB7XHJcbiAgICBwdWJsaWMgc2RrOiBhbnk7XHJcblxyXG4gIHByaXZhdGUgY29udGFpbmVyOiBhbnk7XHJcblxyXG4gIC8vIFBvc2l0aW9uIGNhbWVyYVxyXG4gIHByaXZhdGUgcG9zZU1hdHRlcnBvcnQ6IGFueTtcclxuXHJcbiAgcHVibGljIHBvc2VDYW1lcmE6IHsgcm90YXRpb246IGFueTsgcG9zaXRpb246IGFueTsgc3dlZXA6IGFueSB9O1xyXG5cclxuICAvLyBQb2ludGVyIHRyaWNrXHJcbiAgcHJpdmF0ZSBwb2ludGVyQnV0dG9uOiBhbnk7XHJcblxyXG4gIHByaXZhdGUgb2xkUG9zZU1hdHRlcnBvcnRQb3NpdGlvbjogYW55O1xyXG5cclxuICAvLyBNZWFzdXJlIG1vZGVcclxuICBwcml2YXRlIGlzTWVhc3VyZU1vZGVPbiA9IGZhbHNlO1xyXG5cclxuICAvLyBUaW1lcnNcclxuICBwcml2YXRlIGxhc3RBY3Rpb25UaW1lID0gLTE7XHJcblxyXG4gIHByaXZhdGUgaW50ZXJhY3Rpb25Nb2RlOiBudW1iZXIgPSBWaWV3ZXJJbnRlcmFjdGlvbnMuREVGQVVMVDtcclxuXHJcbiAgcHJpdmF0ZSBtYXR0ZXJ0YWdzOiBBcnJheTxzdHJpbmc+ID0gW107XHJcblxyXG4gIHByaXZhdGUgZGljdGlvbm5hcnlUYWdzOiBNYXA8c3RyaW5nLCB7bWF0dGVydGFnRGF0YTogTWF0dGVydGFnRGF0YTsgZWxlbWVudElEOiBzdHJpbmd9PiA9IG5ldyBNYXA7XHJcblxyXG4gIHByaXZhdGUgbGFzdE1lYXN1cmUgPSBbXTtcclxuXHJcbiAgcHJpdmF0ZSBkaXN0YW5jZXNMYXN0TWVhc3VyZTpudW1iZXJbXSA9IFtdO1xyXG5cclxuICBwcml2YXRlIHJlc29sdXRpb24gPSB7XHJcbiAgICAgIHdpZHRoOiA1MDAsXHJcbiAgICAgIGhlaWdodDogNjAwLFxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgdmlzaWJpbGl0eSA9IHtcclxuICAgICAgbWF0dGVydGFnczogZmFsc2UsXHJcbiAgICAgIHN3ZWVwczogdHJ1ZSxcclxuICB9O1xyXG5cclxuICBwcml2YXRlIGxhc3RTY3JlZW5zaG90VXJpOiBhbnk7XHJcblxyXG4gIHB1YmxpYyBzd2VlcHM6IEFycmF5PHN0cmluZz4gfCBudWxsO1xyXG5cclxuICBwdWJsaWMgY3VycmVudFN3ZWVwOiBTdWJqZWN0PHN0cmluZz4gPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICBwcml2YXRlIGZsb29ycz86IEFycmF5PHsgaWQ6IHN0cmluZzsgbmFtZTogc3RyaW5nOyBzZXF1ZW5jZTogbnVtYmVyIH0+IHwgbnVsbDtcclxuXHJcbiAgcHJpdmF0ZSBfY3VycmVudFNwYWNlSUQ6IHN0cmluZztcclxuXHJcbiAgcHVibGljIGdldCBjdXJyZW50U3BhY2VJRCgpOiBzdHJpbmcge1xyXG4gICAgICByZXR1cm4gdGhpcy5fY3VycmVudFNwYWNlSUQ7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgc2V0IGN1cnJlbnRTcGFjZUlEKHZhbHVlOiBzdHJpbmcpIHtcclxuICAgICAgdGhpcy5fY3VycmVudFNwYWNlSUQgPSB2YWx1ZTtcclxuICB9XHJcblxyXG4gIHRpbWVyUG9pbnRlcjogYW55O1xyXG5cclxuICBmb3JiaWRkZW5Td2VlcHM6IHN0cmluZ1tdID0gW107XHJcblxyXG4gIHB1YmxpYyB0YWdBY3Rpb246IFN1YmplY3Q8eyBhY3Rpb246IHN0cmluZzsgZGF0YTogc3RyaW5nIH0+ID0gbmV3IFN1YmplY3QoKTtcclxuXHJcbiAgcHVibGljIG1hdHRlcnRhZ1RvRm9sbG93OiBzdHJpbmcgfCBudWxsO1xyXG5cclxuICB0YWdTZXJ2aWNlOiBCYXNlVGFnU2VydmljZTtcclxuXHJcbiAgY29uZmlnOiBDb25maWc7XHJcblxyXG4gICAgcHVibGljIGluVHJhbnNpdGlvbk1vZGUgPSBmYWxzZTtcclxuXHJcbiAgICBwdWJsaWMgaW5UcmFuc2l0aW9uU3dlZXAgPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICAgICAgQEluamVjdCgnY29uZmlnJykgY29uZmlnOiBDb25maWcsXHJcbiAgICAgICAgICAgIHByaXZhdGUgcm91dGVyOiBSb3V0ZXIsXHJcbiAgICAgICAgICAgIHByaXZhdGUgdmlzaWJpbGl0eVNlcnZpY2U6IEJhc2VWaXNpYmlsaXR5U2VydmljZVxyXG4gICAgKSB7XHJcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XHJcbiAgICB9XHJcblxyXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuVXRpbHMgYXN5bmNcclxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cclxuXHJcbiAgYXN5bmMgaW5pdFNkayh0YWdTZXJ2aWNlOiBCYXNlVGFnU2VydmljZSwgaXNNdXNldW06IGJvb2xlYW4gPSBmYWxzZSk6IFByb21pc2U8Ym9vbGVhbj4ge1xyXG4gICAgICBpZiAodGhpcy5zZGspIHtcclxuICAgICAgICAgIGF3YWl0IHRoaXMuYWN0aW9uX2RlbGV0ZV9hbGxfbWF0dGVydGFncygpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMudGFnU2VydmljZSA9IHRhZ1NlcnZpY2U7XHJcbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XHJcbiAgICAgICAgICAvLyBSZXRyaWV2ZSBET00gZWxlbWVudHNcclxuICAgICAgICAgIHRoaXMucG9pbnRlckJ1dHRvbiA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgICAgICAgXCIjdmlld2VyLXBvaW50ZXItdHJpY2tcIixcclxuICAgICAgICAgICkgYXMgSFRNTEVsZW1lbnQ7XHJcbiAgICAgICAgICB0aGlzLmNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgICAgICAgXCIjdmlld2VyLW1vZHVsZVwiLFxyXG4gICAgICAgICAgKSBhcyBIVE1MRWxlbWVudDtcclxuICAgICAgICAgIGNvbnN0IGlmcmFtZSA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICAgICAgICAgXCIjdmlld2VyLW1vZHVsZVwiLFxyXG4gICAgICAgICAgKSBhcyBIVE1MSUZyYW1lRWxlbWVudDtcclxuICAgICAgICAgIGlmICghaWZyYW1lKSB7XHJcbiAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIC8vIEFkZCBsaXN0ZW5lcnNcclxuICAgICAgICAgIGlmICh0aGlzLnBvaW50ZXJCdXR0b24pIHtcclxuICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICAgICAgICAgICAgXCJjbGlja1wiLFxyXG4gICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZTogYW55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFkZE1hdHRlcnRhZygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVQb3NpdGlvbkluVGFnRGF0YSgpO1xyXG4gICAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAvLyBjYW5jZWwgb24gcmlnaHQgY2xpY2tcclxuICAgICAgICAgICAgICB0aGlzLnBvaW50ZXJCdXR0b24uYWRkRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICAgICAgICAgICAgXCJjb250ZXh0bWVudVwiLFxyXG4gICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZTogeyBwcmV2ZW50RGVmYXVsdDogKCkgPT4gdm9pZDsgfSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJjYW5jZWwgb24gcmlnaHQgY2xpY2tcIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmFjdGlvbl9jYW5jZWxlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgYWxlcnQoXCJhY3Rpb24gY2FuY2VsbGVkXCIpO1xyXG4gICAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAvLyBMb2FkIFNES1xyXG4gICAgICAgICAgY29uc29sZS5sb2coXCJMb2FkaW5nIE1hdHRlcnBvcnQgU0RLXCIpO1xyXG4gICAgICAgICAgLy8gQHRzLWlnbm9yZVxyXG4gICAgICAgICAgd2luZG93Lk1QX1NESy5jb25uZWN0KFxyXG4gICAgICAgICAgICAgIGlmcmFtZSxcclxuICAgICAgICAgICAgICBcInFuOXdzYXN1eTVoMmZ6cmJybjFuenIwaWRcIixcclxuICAgICAgICAgICAgICBcIjMuMTFcIixcclxuICAgICAgICAgICkudGhlbihhc3luYyAoc2RrOmFueSkgPT4ge1xyXG4gICAgICAgICAgICAgIC8vIEluc3RhbmNpYXRlIHNka1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RrID0gc2RrO1xyXG5cclxuICAgICAgICAgICAgICAvLyBMb2FkIE1hdHRlcnRhZyBpY29uc1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5yZWdpc3Rlckljb24oXHJcbiAgICAgICAgICAgICAgICAgIFwiaWNvbi10aWNrZXRcIixcclxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcubXlfY29uZmlnLmljb25fdGlja2V0LFxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgdGhpcy5zZGsuTWF0dGVydGFnLnJlZ2lzdGVySWNvbihcclxuICAgICAgICAgICAgICAgICAgXCJpY29uLWVxdWlwbWVudFwiLFxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5teV9jb25maWcuaWNvbl9lcXVpcG1lbnQsXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICB0aGlzLnNkay5NYXR0ZXJ0YWcucmVnaXN0ZXJJY29uKFxyXG4gICAgICAgICAgICAgICAgICBcImljb24tbWVhc3VyZVwiLFxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5teV9jb25maWcuaWNvbl9tZWFzdXJlLFxyXG4gICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgdGhpcy5zZGsuTWF0dGVydGFnLnJlZ2lzdGVySWNvbihcclxuICAgICAgICAgICAgICAgICAgXCJpY29uLWRhdGFcIixcclxuICAgICAgICAgICAgICAgICAgdGhpcy5jb25maWcubXlfY29uZmlnLmljb25fZGF0YSxcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5yZWdpc3Rlckljb24oXHJcbiAgICAgICAgICAgICAgICAgIFwiaWNvbi1wb3NpdGlvblwiLFxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmNvbmZpZy5teV9jb25maWcuaWNvbl9wb3NpdGlvbixcclxuICAgICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgICAvLyAzRCBwb3NpdGlvbidzIHBvaW50ZXJcclxuICAgICAgICAgICAgICB0aGlzLnNkay5Qb2ludGVyLmludGVyc2VjdGlvbi5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChpbnRlcnNlY3Rpb246IGFueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NlTWF0dGVycG9ydCA9IGludGVyc2VjdGlvbjtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoIXRoaXMub2xkUG9zZU1hdHRlcnBvcnRQb3NpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMub2xkUG9zZU1hdHRlcnBvcnRQb3NpdGlvbiA9IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeDogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeTogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgejogMCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmludGVyYWN0aW9uTW9kZSAhPT1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVmlld2VySW50ZXJhY3Rpb25zLkRFRkFVTFQgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLm1hdHRlcnRhZ1RvRm9sbG93XHJcbiAgICAgICAgICAgICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb2xsb3cgdGhlIHBvaW50ZXIgYW5kIGNoYW5nZXMgdGhlIHBvc2l0aW9uIG9mIHRoZSBsYXN0IHRhZ1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vICh3ZSBhcmUgYWJvdXQgdG8gdmFsaWRhdGUsIGJ1dCBpdCBleGlzdHMgaW4gc2RrIGFscmVhZHkpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5lbmFibGVfZm9sbG93aW5nX3RhZyh0aGlzLm1hdHRlcnRhZ1RvRm9sbG93KTtcclxuICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgIC8vIHN1YnNjcmliZSB0byBtZWFzdXJlbWVudHNcclxuICAgICAgICAgICAgICBpZiAoIWlzTXVzZXVtKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNkay5NZWFzdXJlbWVudHMuZGF0YS5zdWJzY3JpYmUoe1xyXG4gICAgICAgICAgICAgICAgICAgIG9uQWRkZWQ6IGZ1bmN0aW9uIChpbmRleDogYW55LCBpdGVtOiB7IHBvaW50czogYW55OyB9LCBjb2xsZWN0aW9uOiBhbnkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vICAgICBcIml0ZW0gYWRkZWQgdG8gdGhlIGNvbGxlY3Rpb25cIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGluZGV4LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyAgICAgaXRlbSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy5tZWFzdXJlbWVudHNbaW5kZXhdID0gaXRlbTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0TWVhc3VyZSA9IGl0ZW0ucG9pbnRzO1xyXG4gICAgICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSxcclxuICAgICAgICAgICAgICAgICAgICBvbkNvbGxlY3Rpb25VcGRhdGVkOiBmdW5jdGlvbiAoY29sbGVjdGlvbjogYW55KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCd0aGUgZW50aXJlIHVwLXRvLWRhdGUgY29sbGVjdGlvbicsIGNvbGxlY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdldERpc3RhbmNlRm9yTGFzdE1lYXN1cmVtZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNkay5NZWFzdXJlbWVudHMubW9kZS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKG1lYXN1cmVtZW50TW9kZVN0YXRlOiB7IGFjdGl2ZTogYW55OyB9KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG1lYXN1cmVtZW50IG1vZGUgc3RhdGUgaGFzIGNoYW5nZWRcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc01lYXN1cmVNb2RlT24gPSBtZWFzdXJlbWVudE1vZGVTdGF0ZS5hY3RpdmU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdJcyBtZWFzdXJlbWVudCBtb2RlIGN1cnJlbnRseSBhY3RpdmU/ICcsIG1lYXN1cmVtZW50TW9kZVN0YXRlLmFjdGl2ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgXHJcblxyXG4gICAgICAgICAgICAgIC8vIENhbWVyYSdzIHZpZXdwb2ludFxyXG4gICAgICAgICAgICAgIHRoaXMuc2RrLkNhbWVyYS5wb3NlLnN1YnNjcmliZShcclxuICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc3Vic2NyKHBvc2U6IGFueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5wb3NlQ2FtZXJhID0gcG9zZTtcclxuICAgICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdDdXJyZW50IHBvc2l0aW9uIGlzICcsIHBvc2UucG9zaXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ1JvdGF0aW9uIGFuZ2xlIGlzICcsIHBvc2Uucm90YXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJTd2VlcCBVVUlEIGlzXCIsIHBvc2Uuc3dlZXApO1xyXG4gICAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgLy8gc3Vic2NyaWJlIHRvIHN3ZWVwc1xyXG4gICAgICAgICAgICAgIHRoaXMuc2RrLlN3ZWVwLmRhdGEuc3Vic2NyaWJlKHtcclxuICAgICAgICAgICAgICAgICAgb25Db2xsZWN0aW9uVXBkYXRlZDogZnVuY3Rpb24gc3Vic2NyKGNvbGxlY3Rpb246IHt9KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhjb2xsZWN0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3dlZXBzID0gT2JqZWN0LmtleXMoY29sbGVjdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgIH0uYmluZCh0aGlzKSxcclxuICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgLy8gc3Vic2NyaWJlIHRvIGN1cnJlbnQgc3dlZXBcclxuICAgICAgICAgICAgICB0aGlzLnNkay5Td2VlcC5jdXJyZW50LnN1YnNjcmliZShcclxuICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gc3Vic2NyKGN1cnJlbnRTd2VlcDogeyBzaWQ6IHN0cmluZzsgfSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgLy8gQ2hhbmdlIHRvIHRoZSBjdXJyZW50IHN3ZWVwIGhhcyBvY2N1cnJlZC5cclxuICAgICAgICAgICAgICAgICAgICAgIGlmIChjdXJyZW50U3dlZXAuc2lkID09PSBcIlwiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ05vdCBjdXJyZW50bHkgc3RhdGlvbmVkIGF0IGEgc3dlZXAgcG9zaXRpb24nKTtcclxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coXCJlbW1pdGluZyBzd2VlcFwiLCBjdXJyZW50U3dlZXAuc2lkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1cnJlbnRTd2VlcC5uZXh0KGN1cnJlbnRTd2VlcC5zaWQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgKTtcclxuXHJcbiAgICAgICAgICAgICAgLy8gU3Vic2NyaWJlIHRvIEZsb29yIGRhdGFcclxuICAgICAgICAgICAgICB0aGlzLnNkay5GbG9vci5kYXRhLnN1YnNjcmliZSh7XHJcbiAgICAgICAgICAgICAgICAgIG9uQ29sbGVjdGlvblVwZGF0ZWQ6IGZ1bmN0aW9uIHVwZCh0aGlzOiBhbnksIGNvbGxlY3Rpb246IGFueSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy5mbG9vcnMgPSBPYmplY3QudmFsdWVzKGNvbGxlY3Rpb24pO1xyXG4gICAgICAgICAgICAgICAgICB9LmJpbmQodGhpcyksXHJcbiAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgIC8vIG9uIHRhZyBjbGljayBvcGVuIGRldGFpbHMgcGFnZVxyXG4gICAgICAgICAgICAgIHRoaXMuc2RrLm9uKFwidGFnLmNsaWNrXCIsIChzaWQ6IHN0cmluZykgPT4ge1xyXG4gICAgICAgICAgICAgICAgICAvLyBnZXQgb2JqZWN0IG9mIHRoaXMgdGFnXHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbWF0dGVydGFnRGF0YSA9IHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChzaWQpPy5tYXR0ZXJ0YWdEYXRhITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdXJsPSB0YWdTZXJ2aWNlLmdldFVybEZvclNlZURldGFpbHMoXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuZ2V0T2JqZWN0KCksXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuZ2V0VHlwZSgpLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh1cmwgIT09IFwiXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuZGV0YWlsU2hvd2luZy5uZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoW3VybF0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ2Fubm90IHNob3cgZGV0YWlscyBmb3IgdGFnXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgLy8gUG9pbnRlciB0cmlja1xyXG4gICAgICAgICAgICAgIC8vIENyZWF0ZSBhIGRpdiB0aGF0IHdpbGwgYXBwZWFyIHdoZW4gdGhlIGN1cnNvciBpcyBzdGlsbFxyXG4gICAgICAgICAgICAgIC8vIEl0IHdpbGwgaW50ZXJjZXB0IHRoZSBjbGljayBvZiB0aGUgbW91c2UgYmVmb3JlIGl0IHRyaWdlcnJpbmcgdGhlIE1hdHRlcnBvcnQncyB0b3VyIG5hdmlnYXRpb25cclxuICAgICAgICAgICAgICB0aGlzLnRpbWVyUG9pbnRlciA9IHNldEludGVydmFsKFxyXG4gICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVBvaW50ZXJUcmljay5iaW5kKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgICA1MCxcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVHJhbnNpdGlvbnNcclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICB0aGlzLnNkay5vbihcInZpZXdtb2RlLmNoYW5nZXN0YXJ0XCIsZnVuY3Rpb24odG8sIGZyb20pIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdTdGFydGluZyB0byBtb3ZlIHRvICcgKyB0byArICcgZnJvbSAnICsgZnJvbSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmluVHJhbnNpdGlvbk1vZGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9LmJpbmQodGhpcykpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5zZGsub24oXCJ2aWV3bW9kZS5jaGFuZ2VlbmRcIixmdW5jdGlvbihvbGRNb2RlLCBuZXdNb2RlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnRW5kZWQgdG8gbW92ZSB0byAnICsgbmV3TW9kZSArICcgZnJvbSAnICsgb2xkTW9kZSk7XHJcbiAgICAgICAgICAgICAgICBpZihuZXdNb2RlICE9PSBcIm1vZGUudHJhbnNpdGlvbmluZ1wiKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pblRyYW5zaXRpb25Nb2RlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0uYmluZCh0aGlzKSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLnNkay5vbihzZGsuU3dlZXAuRXZlbnQuRU5URVIsXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbihvbGRTd2VlcCwgbmV3U3dlZXApe1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdMZWF2aW5nIHN3ZWVwICcgKyBvbGRTd2VlcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0VudGVyaW5nIHN3ZWVwICcgKyBuZXdTd2VlcCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pblRyYW5zaXRpb25Td2VlcCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfS5iaW5kKHRoaXMpXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIHRoaXMuc2RrLm9uKHNkay5Td2VlcC5FdmVudC5FWElULFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24oZnJvbVN3ZWVwLCB0b1N3ZWVwKXtcclxuICAgICAgICAgICAgICAgIC8vICAgY29uc29sZS5sb2coJ0xlYXZpbmcgc3dlZXAgJyArIGZyb21Td2VlcCk7XHJcbiAgICAgICAgICAgICAgICAvLyAgIGNvbnNvbGUubG9nKCdUcmFuc2l0aW9uaW5nIHRvIHN3ZWVwICcgKyB0b1N3ZWVwKTtcclxuICAgICAgICAgICAgICAgICAgdGhpcy5pblRyYW5zaXRpb25Td2VlcCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9LmJpbmQodGhpcylcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgcmVzb2x2ZSh0cnVlKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCBNYXR0ZXJ0YWcgdG8gdGhlIGRpY3Rpb25uYXJ5IG9mIHRoZSBjdXJyZW50IHRhZ3NcclxuICAgKiBAcGFyYW0gbWF0dGVydGFnSURcclxuICAgKiBAcGFyYW0gbWF0dGVydGFnRGF0YVxyXG4gICAqIEBwYXJhbSB0YWdUeXBlXHJcbiAgICogQHBhcmFtIHRpY2tldElEXHJcbiAgICovXHJcbiAgYWRkTWF0dGVydGFnVG9PYmplY3QobWF0dGVydGFnSUQ6IHN0cmluZywgbWF0dGVydGFnRGF0YTogTWF0dGVydGFnRGF0YSkge1xyXG4gICAgICBpZiAodGhpcy5zZGspIHtcclxuICAgICAgICAgIHRoaXMubWF0dGVydGFncy5wdXNoKG1hdHRlcnRhZ0lEKTtcclxuICAgICAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLnNldChtYXR0ZXJ0YWdJRCx7XHJcbiAgICAgICAgICAgICAgbWF0dGVydGFnRGF0YSxcclxuICAgICAgICAgICAgICBlbGVtZW50SUQ6IG1hdHRlcnRhZ0RhdGEuZWxlbWVudElELFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICB0aGlzLmVkaXRUYWdTdHlsZShtYXR0ZXJ0YWdJRCwgbWF0dGVydGFnRGF0YSk7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGdldERpc3RhbmNlRm9yTGFzdE1lYXN1cmVtZW50KCkge1xyXG4gICAgICBpZiAodGhpcy5sYXN0TWVhc3VyZS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICBjb25zdCBudW1iZXJQb2ludHMgPSB0aGlzLmxhc3RNZWFzdXJlLmxlbmd0aDtcclxuICAgICAgICAgIHRoaXMuZGlzdGFuY2VzTGFzdE1lYXN1cmUgPSBbXTtcclxuICAgICAgICAgIGZvciAobGV0IGluZGV4ID0gMTsgaW5kZXggPCBudW1iZXJQb2ludHM7IGluZGV4ICs9IDEpIHtcclxuICAgICAgICAgICAgICBjb25zdCBkaXN0YW5jZSA9IGdldERpc3RhbmNlQmV0d2VlblR3b1BvaW50cyhcclxuICAgICAgICAgICAgICAgICAgdGhpcy5sYXN0TWVhc3VyZVtpbmRleCAtIDFdLFxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmxhc3RNZWFzdXJlW2luZGV4XSxcclxuICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIHRoaXMuZGlzdGFuY2VzTGFzdE1lYXN1cmUucHVzaChkaXN0YW5jZSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICB0aGlzLnRha2VTY3JlZW5TaG90KCkudGhlbigocmVzKSA9PiB7XHJcbiAgICAgICAgICAgICAgdGhpcy5nb1RvTWVudShgdmlzaXQvJHt0aGlzLmN1cnJlbnRTcGFjZUlEfS9hZGRfbWVhc3VyZW1lbnRgKTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0IHRoZSBNYXR0ZXJ0YWcgdGhhdCB3aWxsIGZvbGxvdyB0aGUgY3Vyc29yXHJcbiAgICogQHBhcmFtIHRhZ1R5cGVcclxuICAgKi9cclxuICBhc3luYyBhZGRfY3Vyc29yX21hdHRlcnRhZyhcclxuICAgICAgdGFnVHlwZTogUG9pVHlwZSxcclxuICAgICAgZWxlbWVudD86IGFueSxcclxuICAgICAgcG9zaXRpb25pbmc6IGJvb2xlYW4gPSBmYWxzZSxcclxuICApIHtcclxuICAgICAgaWYgKCF0aGlzLnBvc2VNYXR0ZXJwb3J0KSByZXR1cm47XHJcbiAgICAgIGNvbnN0IG1hdHRlcnRhZ0RhdGEgPSBuZXcgTWF0dGVydGFnRGF0YSh0YWdUeXBlKTtcclxuICAgICAgaWYgKHBvc2l0aW9uaW5nKSB7XHJcbiAgICAgICAgICAvLyBzZXQgdGhlIGNvb3JkaW5hdGVzIG9mIHRoZSBleGlzdGluZyB0YWdcclxuICAgICAgICAgIGNvbnN0IFtwb2ldID0gZWxlbWVudC5wb2lzLml0ZW1zO1xyXG4gICAgICAgICAgaWYgKHBvaSAmJiBwb2kuY29vcmRpbmF0ZSkge1xyXG4gICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0UG9zaXRpb24oSlNPTi5wYXJzZShwb2kuY29vcmRpbmF0ZSkpO1xyXG4gICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0UG9pKHBvaSk7IC8vIHRvIGtlZXAgY3VzdG9tIHRhZ0lvbiBhbmQgb3BhY2l0eVxyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0U3dlZXBJRCh0aGlzLnBvc2VDYW1lcmEuc3dlZXApO1xyXG4gICAgICBtYXR0ZXJ0YWdEYXRhLnNldFJvdGF0aW9uKHRoaXMucG9zZUNhbWVyYS5yb3RhdGlvbik7XHJcbiAgICAgIGlmIChlbGVtZW50KSB7XHJcbiAgICAgICAgICBzd2l0Y2ggKHRhZ1R5cGUpIHtcclxuICAgICAgICAgICAgICBjYXNlIFBvaVR5cGUuVElDS0VUOlxyXG4gICAgICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldFRpY2tldChlbGVtZW50KTtcclxuICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgY2FzZSBQb2lUeXBlLkVRVUlQTUVOVDpcclxuICAgICAgICAgICAgICAgICAgbWF0dGVydGFnRGF0YS5zZXRFcXVpcG1lbnQoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5EQVRBOlxyXG4gICAgICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldEZlYXR1cmUoZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGNhc2UgUG9pVHlwZS5ERVNLOlxyXG4gICAgICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldERlc2soZWxlbWVudCk7XHJcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMubWF0dGVydGFnVG9Gb2xsb3cgPSBhd2FpdCB0aGlzLmFkZF9tYXR0ZXJ0YWdfdG9fdmlld2VyKFxyXG4gICAgICAgICAgbWF0dGVydGFnRGF0YSxcclxuICAgICAgKTtcclxuICAgICAgaWYgKHBvc2l0aW9uaW5nKSB7XHJcbiAgICAgICAgICB0aGlzLnNkay5NYXR0ZXJ0YWcuZWRpdEljb24oXHJcbiAgICAgICAgICAgICAgdGhpcy5tYXR0ZXJ0YWdUb0ZvbGxvdyxcclxuICAgICAgICAgICAgICBcImljb24tcG9zaXRpb25cIixcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgICB0aGlzLnNkay5NYXR0ZXJ0YWcuZWRpdE9wYWNpdHkodGhpcy5tYXR0ZXJ0YWdUb0ZvbGxvdywgMSk7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZCBNYXR0ZXJ0YWcgZnJvbSBpdHMgZGF0YVxyXG4gICAqIEBwYXJhbSB0YWdJRFxyXG4gICAqIEBwYXJhbSB0YWdUeXBlXHJcbiAgICogQHBhcmFtIG1hdHRlcnRhZ0RhdGFcclxuICAgKi9cclxuICBhc3luYyBhZGRfbWF0dGVydGFnX3RvX3ZpZXdlcihcclxuICAgICAgbWF0dGVydGFnRGF0YTogTWF0dGVydGFnRGF0YSxcclxuICApOiBQcm9taXNlPHN0cmluZyB8IG51bGw+IHtcclxuICAgICAgbGV0IHNpZExpc3Q7XHJcbiAgICAgIGlmICghdGhpcy5zZGspIHtcclxuICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICB9XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgICBzaWRMaXN0ID0gYXdhaXQgdGhpcy5zZGsuTWF0dGVydGFnLmFkZChtYXR0ZXJ0YWdEYXRhLmdldERhdGEoKSk7XHJcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICBjb25zb2xlLmxvZyhcclxuICAgICAgICAgICAgICBcIlRhZyBkb2VzIG5vdCBiZWxvbmcgdG8gdGhlIHZpc2l0XCIsXHJcbiAgICAgICAgICAgICAgZXJyb3IsXHJcbiAgICAgICAgICAgICAgbWF0dGVydGFnRGF0YS5nZXREYXRhKCksXHJcbiAgICAgICAgICApO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChzaWRMaXN0KSB7XHJcbiAgICAgICAgICBjb25zdCBtYXR0ZXJ0YWdJRCA9IHNpZExpc3RbMF07XHJcbiAgICAgICAgLy8gICBjb25zb2xlLmxvZyhcImFkZGVkIHRhZ1wiLCBtYXR0ZXJ0YWdEYXRhLmdldFR5cGUoKSwgbWF0dGVydGFnSUQpO1xyXG4gICAgICAgICAgdGhpcy5hZGRNYXR0ZXJ0YWdUb09iamVjdChtYXR0ZXJ0YWdJRCwgbWF0dGVydGFnRGF0YSk7XHJcbiAgICAgICAgICByZXR1cm4gbWF0dGVydGFnSUQ7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblV0aWxzIC0gTWF0dGVydGFnXHJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcblxyXG4gIGFkZE1hdHRlcnRhZygpIHtcclxuICAgICAgdGhpcy5zZXRJbnRlcmFjdGlvbk1vZGUoVmlld2VySW50ZXJhY3Rpb25zLkRFRkFVTFQpO1xyXG4gICAgICB0aGlzLmFjdGlvbl9vcGVuX21lbnUodGhpcy5nZXRNZW51VG9PcGVuRm9yTGFzdFRhZygpKTtcclxuICAgICAgdGhpcy5yZXNldEFjdGlvblRpbWUoKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVBvaW50ZXJUcmljaygpIHtcclxuICAgICAgaWYgKFxyXG4gICAgICAgICAgdGhpcy5pbnRlcmFjdGlvbk1vZGUgIT09IFZpZXdlckludGVyYWN0aW9ucy5ERUZBVUxUICYmXHJcbiAgICAgICAgICB0aGlzLm1hdHRlcnRhZ1RvRm9sbG93ICYmXHJcbiAgICAgICAgICB0aGlzLnBvc2VNYXR0ZXJwb3J0ICYmXHJcbiAgICAgICAgICB0aGlzLmdldERpc3RQb3NpdGlvbihcclxuICAgICAgICAgICAgICB0aGlzLnBvc2VNYXR0ZXJwb3J0LnBvc2l0aW9uLFxyXG4gICAgICAgICAgICAgIHRoaXMub2xkUG9zZU1hdHRlcnBvcnRQb3NpdGlvbixcclxuICAgICAgICAgICkgPiAyNVxyXG4gICAgICApIHtcclxuICAgICAgICAgIHRoaXMucG9pbnRlckJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XHJcblxyXG4gICAgICAgICAgY29uc3Qgc2l6ZSA9IHtcclxuICAgICAgICAgICAgICB3OiB0aGlzLmNvbnRhaW5lci5jbGllbnRXaWR0aCxcclxuICAgICAgICAgICAgICBoOiB0aGlzLmNvbnRhaW5lci5jbGllbnRIZWlnaHQsXHJcbiAgICAgICAgICB9O1xyXG4gICAgICAgICAgY29uc3QgY29vcmRzID0gdGhpcy5zZGsuQ29udmVyc2lvbi53b3JsZFRvU2NyZWVuKFxyXG4gICAgICAgICAgICAgIHRoaXMucG9zZU1hdHRlcnBvcnQucG9zaXRpb24sXHJcbiAgICAgICAgICAgICAgdGhpcy5wb3NlQ2FtZXJhLFxyXG4gICAgICAgICAgICAgIHNpemUsXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5wb2ludGVyQnV0dG9uLnN0eWxlLmxlZnQgPSBgJHtcclxuICAgICAgICAgICAgICBjb29yZHMueCAqIE1hdGguc2lnbihjb29yZHMueCkgLSAyNVxyXG4gICAgICAgICAgfXB4YDtcclxuICAgICAgICAgIHRoaXMucG9pbnRlckJ1dHRvbi5zdHlsZS50b3AgPSBgJHtcclxuICAgICAgICAgICAgICBjb29yZHMueSAqIE1hdGguc2lnbihjb29yZHMueCkgLSAyNVxyXG4gICAgICAgICAgfXB4YDtcclxuICAgICAgICAgIHRoaXMub2xkUG9zZU1hdHRlcnBvcnRQb3NpdGlvbiA9IHtcclxuICAgICAgICAgICAgICAuLi50aGlzLnBvc2VNYXR0ZXJwb3J0LnBvc2l0aW9uLFxyXG4gICAgICAgICAgfTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHRoaXMucG9pbnRlckJ1dHRvbi5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICBhc3luYyBlZGl0VGFnU3R5bGUobWF0dGVydGFnSUQ6IHN0cmluZywgbWF0dGVydGFnRGF0YTogTWF0dGVydGFnRGF0YSkge1xyXG4gICAgICBjb25zdCBzdHJpbmdUYWdUeXBlID0gcG9pVHlwZVRvU3RyaW5nKG1hdHRlcnRhZ0RhdGEuZ2V0VHlwZSgpKTtcclxuICAgICAgbGV0IG9wYWNpdHkgPSB0aGlzLmNvbmZpZy5teV9jb25maWcuREVGQVVMVF9PUEFDSVRZX1RBRztcclxuICAgICAgbGV0IGljb25OYW1lID0gYGljb24tJHtzdHJpbmdUYWdUeXBlfWA7XHJcbiAgICAgIGNvbnN0IHBvaSA9IG1hdHRlcnRhZ0RhdGEuZ2V0UG9pKCk7XHJcbiAgICAgIGlmIChwb2kgJiYgcG9pLnRhZ0ljb24pIHtcclxuICAgICAgICAgIGNvbnN0IHRhZ0ljb24gPSBKU09OLnBhcnNlKHBvaS50YWdJY29uKTtcclxuICAgICAgICAgIC8vIFRPRE8gZm9yIGluZGljYXRvcnNcclxuICAgICAgICAvLyAgIGlmIChtYXR0ZXJ0YWdEYXRhLmdldFR5cGUoKSA9PT0gUG9pVHlwZS5EQVRBKSB7XHJcbiAgICAgICAgLy8gICAgICAgY29uc3QgZmVhdHVyZSA9IG1hdHRlcnRhZ0RhdGEuZ2V0T2JqZWN0KCk7XHJcbiAgICAgICAgLy8gICAgICAgdGFnSWNvbi5zcmMgPSB0aGlzLnRhZ1NlcnZpY2UuZ2V0SWNvblRhZ0ltYWdlRm9yRmVhdHVyZShcclxuICAgICAgICAvLyAgICAgICAgICAgZmVhdHVyZSxcclxuICAgICAgICAvLyAgICAgICAgICAgcG9pLFxyXG4gICAgICAgIC8vICAgICAgICk7XHJcbiAgICAgICAgLy8gICAgICAgcG9pLnRhZ0ljb24gPSB0YWdJY29uO1xyXG4gICAgICAgIC8vICAgfVxyXG4gICAgICAgICAgaWYgKHRhZ0ljb24uc3JjKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgcGF0aFNpZ25lZCA9IGF3YWl0IHRoaXMudGFnU2VydmljZS5nZXRTaWduZWRUYWdJY29uU291cmNlKHRhZ0ljb24uc3JjKTtcclxuICAgICAgICAgICAgICBpZiAocGF0aFNpZ25lZCkge1xyXG4gICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgaWNvbk5hbWUgPSBgaWNvbi0ke3N0cmluZ1RhZ1R5cGV9LSR7bWF0dGVydGFnSUR9LSR7bWF0dGVydGFnRGF0YS5jdXN0b21JY29uSW5kZXh9YDtcclxuICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IHRoaXMuc2RrLk1hdHRlcnRhZy5yZWdpc3Rlckljb24oXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWNvbk5hbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0aFNpZ25lZCxcclxuICAgICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLmN1c3RvbUljb25JbmRleCArPSAxO1xyXG4gICAgICAgICAgICAgICAgICB9IGNhdGNoIHtcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiZXJyb3IgcmVnaXN0ZXJJY29uXCIpO1xyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHRhZ0ljb24ub3BhY2l0eSkge1xyXG4gICAgICAgICAgICAgIG9wYWNpdHkgPSB0YWdJY29uLm9wYWNpdHk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgICAgdHJ5IHtcclxuICAgICAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5lZGl0SWNvbihtYXR0ZXJ0YWdJRCwgaWNvbk5hbWUpO1xyXG4gICAgICAgICAgdGhpcy5zZGsuTWF0dGVydGFnLmVkaXRPcGFjaXR5KG1hdHRlcnRhZ0lELCBvcGFjaXR5KTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiRXJyb3IgZWRpdEljb24gb3Igb3BhY2l0eVwiLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGVuYWJsZV9mb2xsb3dpbmdfdGFnKG1hdHRlcnRhZzogYW55KSB7XHJcbiAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5lZGl0UG9zaXRpb24obWF0dGVydGFnLCB7XHJcbiAgICAgICAgICBhbmNob3JQb3NpdGlvbjoge1xyXG4gICAgICAgICAgICAgIHg6IHRoaXMucG9zZU1hdHRlcnBvcnQucG9zaXRpb24ueCAqIDEsXHJcbiAgICAgICAgICAgICAgeTogdGhpcy5wb3NlTWF0dGVycG9ydC5wb3NpdGlvbi55ICogMSxcclxuICAgICAgICAgICAgICB6OiB0aGlzLnBvc2VNYXR0ZXJwb3J0LnBvc2l0aW9uLnogKiAxLFxyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIHN0ZW1WZWN0b3I6IHtcclxuICAgICAgICAgICAgICB4OiB0aGlzLnBvc2VNYXR0ZXJwb3J0Lm5vcm1hbC54ICogMC4zLFxyXG4gICAgICAgICAgICAgIHk6IHRoaXMucG9zZU1hdHRlcnBvcnQubm9ybWFsLnkgKiAwLjMsXHJcbiAgICAgICAgICAgICAgejogdGhpcy5wb3NlTWF0dGVycG9ydC5ub3JtYWwueiAqIDAuMyxcclxuICAgICAgICAgIH0sXHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcmVzZXRBY3Rpb25UaW1lKCkge1xyXG4gICAgICB0aGlzLmxhc3RBY3Rpb25UaW1lID0gLTE7XHJcbiAgfVxyXG5cclxuICBnb1RvTGFzdFRhZygpIHtcclxuICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLmdvVG9UYWcodGhpcy5tYXR0ZXJ0YWdzW3RoaXMubWF0dGVydGFncy5sZW5ndGggLSAxXSk7XHJcbiAgICAgIH0sIDIwMDApO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgZ29Ub1RhZyhtYXR0ZXJ0YWdJRDogc3RyaW5nKSB7XHJcbiAgICAgIGlmIChtYXR0ZXJ0YWdJRCA9PT0gXCJcIikgcmV0dXJuO1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgICAgYXdhaXQgdGhpcy5zZGsuTWF0dGVydGFnLm5hdmlnYXRlVG9UYWcoXHJcbiAgICAgICAgICAgICAgbWF0dGVydGFnSUQsXHJcbiAgICAgICAgICAgICAgdGhpcy5zZGsuTWF0dGVydGFnLlRyYW5zaXRpb24uRkxZLFxyXG4gICAgICAgICAgKTtcclxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKFwiY2Fubm90IG5hdmlnYXRlIHRvIHRhZ1wiLCBlcnJvcik7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGdvVG9NZW51KG1lbnVVcmw6IGFueSkge1xyXG4gICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShbbWVudVVybF0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IHRoZSBkaXN0YW5jZSBiZXR3d2VlbiB0d28gM0QgcG9zaXRpb25zXHJcbiAgICogVXNlZCBpbiBvcmRlciB0byBzZWUgaG93IG11Y2ggdGhlIGN1cnNvciBoYXMgbW92ZWQgZnJvbSB0aGUgcHJldmlvdXMgcG9zaXRpb25cclxuICAgKiBAcGFyYW0gcG9zMVxyXG4gICAqIEBwYXJhbSBwb3MyXHJcbiAgICovXHJcbiAgZ2V0RGlzdFBvc2l0aW9uKHBvczE6IGFueSwgcG9zMjogYW55KSB7XHJcbiAgICAgIGNvbnN0IHNpemUgPSB7XHJcbiAgICAgICAgICB3OiB0aGlzLmNvbnRhaW5lci5jbGllbnRXaWR0aCxcclxuICAgICAgICAgIGg6IHRoaXMuY29udGFpbmVyLmNsaWVudEhlaWdodCxcclxuICAgICAgfTtcclxuICAgICAgY29uc3QgY29vcmRzMSA9IHRoaXMuc2RrLkNvbnZlcnNpb24ud29ybGRUb1NjcmVlbihcclxuICAgICAgICAgIHBvczEsXHJcbiAgICAgICAgICB0aGlzLnBvc2VDYW1lcmEsXHJcbiAgICAgICAgICBzaXplLFxyXG4gICAgICApO1xyXG4gICAgICBjb25zdCBjb29yZHMyID0gdGhpcy5zZGsuQ29udmVyc2lvbi53b3JsZFRvU2NyZWVuKFxyXG4gICAgICAgICAgcG9zMixcclxuICAgICAgICAgIHRoaXMucG9zZUNhbWVyYSxcclxuICAgICAgICAgIHNpemUsXHJcbiAgICAgICk7XHJcbiAgICAgIHJldHVybiBNYXRoLnNxcnQoXHJcbiAgICAgICAgICAoY29vcmRzMS54IC0gY29vcmRzMi54KSAqKiAyICsgKGNvb3JkczEueSAtIGNvb3JkczIueSkgKiogMixcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIHVwZGF0ZVBvc2l0aW9uSW5UYWdEYXRhKCkge1xyXG4gICAgICAgIGNvbnN0IGxhc3RUYWcgPSB0aGlzLmdldExhc3RUYWcoKTtcclxuICAgICAgICBpZiAobGFzdFRhZykge1xyXG4gICAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobGFzdFRhZykhLm1hdHRlcnRhZ0RhdGEuc2V0UG9zaXRpb24oXHJcbiAgICAgICAgICAgICAgICB0aGlzLnBvc2VNYXR0ZXJwb3J0LnBvc2l0aW9uLFxyXG4gICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobGFzdFRhZykhLm1hdHRlcnRhZ0RhdGEuc2V0Tm9ybWFsKFxyXG4gICAgICAgICAgICAgICAgdGhpcy5wb3NlTWF0dGVycG9ydC5ub3JtYWwsXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlTWF0dGVyVGFnRnJvbUlkKGxhc3RUYWcpO1xyXG4gICAgICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIHVwZGF0ZU1hdHRlclRhZ0Zyb21JZChcclxuICAgICAgbWF0dGVydGFnSUQ6IHN0cmluZyxcclxuICAgICAgb2JqZWN0OiBhbnkgPSBudWxsLFxyXG4gICAgICB0YWdUeXBlOiBQb2lUeXBlIHwgbnVsbCA9IG51bGwsXHJcbiAgKSB7XHJcbiAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5lZGl0QmlsbGJvYXJkKFxyXG4gICAgICAgICAgbWF0dGVydGFnSUQsXHJcbiAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobWF0dGVydGFnSUQpIS5tYXR0ZXJ0YWdEYXRhLmdldERhdGEoKSxcclxuICAgICAgKTtcclxuICAgICAgaWYgKG9iamVjdCAmJiB0YWdUeXBlKSB7XHJcbiAgICAgICAgICB0aGlzLmluamVjdEh0bWxJblRhZyh0YWdUeXBlLCBvYmplY3QsIG1hdHRlcnRhZ0lEKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmVkaXRUYWdTdHlsZShcclxuICAgICAgICAgIG1hdHRlcnRhZ0lELFxyXG4gICAgICAgICAgdGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KG1hdHRlcnRhZ0lEKSEubWF0dGVydGFnRGF0YSxcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIGRlbGV0ZU1hdHRlcnRhZ0Zyb21JZChtYXR0ZXJ0YWdJRDogc3RyaW5nKSB7XHJcbiAgICAgIHRoaXMuc2RrLk1hdHRlcnRhZy5yZW1vdmUobWF0dGVydGFnSUQpO1xyXG4gICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5kZWxldGUobWF0dGVydGFnSUQpO1xyXG4gIH1cclxuXHJcbiAgZGVsZXRlTGFzdE1hdHRlcnRhZygpIHtcclxuICAgICAgY29uc3QgbWF0dGVydGFnSUQgPSB0aGlzLm1hdHRlcnRhZ3MucG9wKCk7XHJcbiAgICAgIGlmIChtYXR0ZXJ0YWdJRCkge1xyXG4gICAgICAgIHRoaXMuZGVsZXRlTWF0dGVydGFnRnJvbUlkKG1hdHRlcnRhZ0lEKTtcclxuICAgICAgfVxyXG4gICAgICBcclxuICB9XHJcblxyXG4gIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuVXRpbHMgLSBUb29sYmFyXHJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcblxyXG4gIGFjdGlvbl90b29sYm94X2Zsb29ycGxhbigpIHtcclxuICAgICAgdGhpcy5zZGsuTW9kZS5tb3ZlVG8oXCJtb2RlLmZsb29ycGxhblwiKTtcclxuICB9XHJcblxyXG4gIGFjdGlvbl90b29sYm94X2luc2lkZV92aWV3KCkge1xyXG4gICAgICB0aGlzLnNkay5Nb2RlLm1vdmVUbyhcIm1vZGUuaW5zaWRlXCIpO1xyXG4gIH1cclxuXHJcbiAgICBhc3luYyBhY3Rpb25fdG9vbGJveF9kb2xsaG91c2UoKSB7XHJcbiAgICAgICAgc2V0VGltZW91dChhc3luYyAoKSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwibW9kZTogXCIsdGhpcy5pblRyYW5zaXRpb25Nb2RlLCBcIiBzd2VlcDogXCIsIHRoaXMuaW5UcmFuc2l0aW9uU3dlZXApXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmluVHJhbnNpdGlvbk1vZGUgfHwgdGhpcy5pblRyYW5zaXRpb25Td2VlcCkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS5sb2coXCJ2aWV3ZXIgaXMgaW4gdHJhbnNpdGlvbiwgY2Fubm90IGdvIGRvbGxob3VzZVwiKVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNkay5Nb2RlLm1vdmVUbyhcIm1vZGUuZG9sbGhvdXNlXCIpO1xyXG4gICAgICAgICAgICB9IGNhdGNoKGUpIHtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiY2Fubm90IGdvIHRvIGRvbGxob3VzZVwiLCBlKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgMTIwMCk7XHJcbiAgICB9XHJcblxyXG4gIGFjdGlvbl90b29sYm94X21lc3VyZSgpIHtcclxuICAgICAgY29uc3QgbmV3U3RhdGUgPSAhdGhpcy5pc01lYXN1cmVNb2RlT247XHJcbiAgICAgIHRoaXMuc2RrLk1lYXN1cmVtZW50cy50b2dnbGVNb2RlKG5ld1N0YXRlKS50aGVuKCgpID0+IHtcclxuICAgICAgICAgIGNvbnNvbGUubG9nKFxyXG4gICAgICAgICAgICAgIGBNZWFzdXJlbWVudCBtb2RlIGlzIG5vdyAke25ld1N0YXRlID8gXCJlbmFibGVkXCIgOiBcImRpc2FibGVkXCJ9YCxcclxuICAgICAgICAgICk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgYWN0aW9uX3Rvb2xib3hfY2FuY2VsX21lc3VyZSgpIHtcclxuICAgICAgaWYgKHRoaXMuaXNNZWFzdXJlTW9kZU9uKSB7XHJcbiAgICAgICAgICB0aGlzLmFjdGlvbl90b29sYm94X21lc3VyZSgpO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbkFjdGlvbnNcclxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cclxuXHJcbiAgYXN5bmMgYWN0aW9uX2FkZF9tYXR0ZXJ0YWdfZnJvbV9QT0koXHJcbiAgICAgIHRhZ1R5cGU6IFBvaVR5cGUsXHJcbiAgICAgIG9iamVjdDogVGlja2V0IHwgRXF1aXBtZW50IHwgQ29tbWVudCB8IEZlYXR1cmUsXHJcbiAgICAgIHBvaTogUE9JLFxyXG4gICk6IFByb21pc2U8YW55PiB7XHJcbiAgICAgICAgLy8gY2hlY2sgaWYgdGFnIGV4aXN0cyBhbHJlYWR5XHJcbiAgICAgICAgY29uc3Qge3RhZywgc3dlZXB9ID0gdGhpcy5nZXRUYWdGcm9tRWxlbWVudElkKG9iamVjdC5pZClcclxuICAgICAgICBpZiAodGFnKSB7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwidGFnIGV4aXN0c1wiLCBvYmplY3QpXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgIGNvbnN0IG1hdHRlcnRhZ0RhdGE6IE1hdHRlcnRhZ0RhdGEgPSBuZXcgTWF0dGVydGFnRGF0YSh0YWdUeXBlKTtcclxuICAgICAgc3dpdGNoICh0YWdUeXBlKSB7XHJcbiAgICAgICAgICBjYXNlIFBvaVR5cGUuVElDS0VUOlxyXG4gICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0VGlja2V0KG9iamVjdCBhcyBUaWNrZXQpO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBQb2lUeXBlLkVRVUlQTUVOVDpcclxuICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldEVxdWlwbWVudChvYmplY3QgYXMgRXF1aXBtZW50KTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgUG9pVHlwZS5NRUFTVVJFOlxyXG4gICAgICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0Q29tbWVudChvYmplY3QgYXMgQ29tbWVudCk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFBvaVR5cGUuREFUQTpcclxuICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldEZlYXR1cmUob2JqZWN0IGFzIEZlYXR1cmUpO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBQb2lUeXBlLkRFU0s6XHJcbiAgICAgICAgICAgICAgbWF0dGVydGFnRGF0YS5zZXRGZWF0dXJlKG9iamVjdCBhcyBGZWF0dXJlKTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHBvaS5jb29yZGluYXRlKSB7XHJcbiAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldFBvc2l0aW9uKEpTT04ucGFyc2UocG9pLmNvb3JkaW5hdGUpKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAocG9pLm1ldGFkYXRhKSB7XHJcbiAgICAgICAgICBjb25zdCB0YWdNZXRhZGF0YSA9IEpTT04ucGFyc2UocG9pLm1ldGFkYXRhKTtcclxuICAgICAgICAgIGlmICh0YWdNZXRhZGF0YS5ub3JtYWwpIHtcclxuICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldE5vcm1hbCh0YWdNZXRhZGF0YS5ub3JtYWwpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBtYXR0ZXJ0YWdEYXRhLnNldE5vcm1hbCh7IHg6IDAsIHk6IC0wLjE1LCB6OiAwIH0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChwb2kubWF0dGVycG9ydFN3ZWVwSUQpIHtcclxuICAgICAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0U3dlZXBJRChwb2kubWF0dGVycG9ydFN3ZWVwSUQpO1xyXG4gICAgICB9XHJcbiAgICAgIG1hdHRlcnRhZ0RhdGEuc2V0UG9pKHBvaSk7XHJcblxyXG4gICAgICBjb25zdCBjcmVhdGVkVGFnID0gYXdhaXQgdGhpcy5hZGRfbWF0dGVydGFnX3RvX3ZpZXdlcihtYXR0ZXJ0YWdEYXRhKTtcclxuICAgICAgaWYgKGNyZWF0ZWRUYWcgJiYgdGhpcy5zZGspIHtcclxuICAgICAgICAgIGF3YWl0IHRoaXMuaW5qZWN0SHRtbEluVGFnKHRhZ1R5cGUsIG9iamVjdCwgY3JlYXRlZFRhZyk7XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGluamVjdEh0bWxJblRhZyhcclxuICAgICAgdGFnVHlwZTogUG9pVHlwZSxcclxuICAgICAgb2JqZWN0OiBEYk9iamVjdFR5cGUsXHJcbiAgICAgIHRhZ0lEOiBzdHJpbmcsXHJcbiAgKSB7XHJcbiAgICAgIGxldCB7IGh0bWwsIGhlaWdodCB9ID0gYXdhaXQgdGhpcy50YWdTZXJ2aWNlLmdldEh0bWxUb0luamVjdChcclxuICAgICAgICAgIHRhZ1R5cGUsXHJcbiAgICAgICAgICBvYmplY3QsXHJcbiAgICAgICAgICB0aGlzLmNvbmZpZy5teV9jb25maWcuREVGQVVMVF9IRUlHSFRfSFRNTF9UQUdcclxuICAgICAgKTtcclxuICAgICAgaWYgKGh0bWwgIT09IFwiXCIgJiYgdGhpcy5zZGspIHtcclxuICAgICAgICAgIGNvbnN0IHNjcmlwdFRhZyA9IHRoaXMudGFnU2VydmljZS5nZXRTY3JpcHRGb3JUYWcob2JqZWN0LCB0YWdUeXBlKTtcclxuICAgICAgICAgIGh0bWwgKz0gYCR7c2NyaXB0VGFnfWA7XHJcbiAgICAgICAgICB0aGlzLnNkay5NYXR0ZXJ0YWcuaW5qZWN0SFRNTCh0YWdJRCwgaHRtbCwge1xyXG4gICAgICAgICAgICAgIHNpemU6IHtcclxuICAgICAgICAgICAgICAgICAgdzogdGhpcy5jb25maWcubXlfY29uZmlnLkRFRkFVTFRfV0lEVEhfSFRNTF9UQUcsXHJcbiAgICAgICAgICAgICAgICAgIGg6IGhlaWdodCxcclxuICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAudGhlbigobWVzc2VuZ2VyKSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgIG1lc3Nlbmdlci5vbihcclxuICAgICAgICAgICAgICAgICAgICAgIFRhZ0FjdGlvbi5ERVRBSUxfQ0xJQ0ssXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ1NlcnZpY2Uub25BY3Rpb25EZXRhaWxDbGljay5iaW5kKHRoaXMudGFnU2VydmljZSlcclxuICAgICAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICAgICAgbWVzc2VuZ2VyLm9uKFxyXG4gICAgICAgICAgICAgICAgICAgICAgVGFnQWN0aW9uLlRJQ0tFVF9DTElDSyxcclxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMudGFnU2VydmljZS5vbkFjdGlvbkRldGFpbENsaWNrLmJpbmQodGhpcy50YWdTZXJ2aWNlKVxyXG4gICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICBtZXNzZW5nZXIub24oXHJcbiAgICAgICAgICAgICAgICAgICAgICBUYWdBY3Rpb24uQVVESU9fQ0xJQ0ssXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ1NlcnZpY2Uub25BY3Rpb25BdWRpb0NsaWNrLmJpbmQodGhpcy50YWdTZXJ2aWNlKVxyXG4gICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICBtZXNzZW5nZXIub24oXHJcbiAgICAgICAgICAgICAgICAgICAgICBUYWdBY3Rpb24uSU1BR0VfQ0xJQ0ssXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ1NlcnZpY2Uub25BY3Rpb25JbWFnZUNsaWNrLmJpbmQodGhpcy50YWdTZXJ2aWNlKVxyXG4gICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICBtZXNzZW5nZXIub24oXHJcbiAgICAgICAgICAgICAgICAgICAgICBUYWdBY3Rpb24uVklERU9fQ0xJQ0ssXHJcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ1NlcnZpY2Uub25BY3Rpb25WaWRlb0NsaWNrLmJpbmQodGhpcy50YWdTZXJ2aWNlKVxyXG4gICAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgICAgICBtZXNzZW5nZXIub24oXHJcbiAgICAgICAgICAgICAgICAgICAgICBUYWdBY3Rpb24uRE9DX0NMSUNLLFxyXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy50YWdTZXJ2aWNlLm9uQWN0aW9uRG9jQ2xpY2suYmluZCh0aGlzLnRhZ1NlcnZpY2UpXHJcbiAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICAgIG1lc3Nlbmdlci5vbihcclxuICAgICAgICAgICAgICAgICAgICBUYWdBY3Rpb24uWU9VVFVCRV9DTElDSyxcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnRhZ1NlcnZpY2Uub25BY3Rpb25Zb3V0dWJlQ2xpY2suYmluZCh0aGlzLnRhZ1NlcnZpY2UpXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgLmNhdGNoKChlcnJvcjogYW55KSA9PlxyXG4gICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkNhbm5vdCBpbmplY3QgaHRtbCBmb3IgdGFnXCIsIHRhZ0lELCBlcnJvciksXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgfVxyXG4gIH1cclxuXHJcbiAgYXN5bmMgYWN0aW9uX2RlbGV0ZV9hbGxfbWF0dGVydGFncygpIHtcclxuICAgICAgLy8gYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgIHRoaXMubWF0dGVydGFncy5tYXAoYXN5bmMgKHRhZykgPT4ge1xyXG4gICAgICAgICAgYXdhaXQgdGhpcy5zZGsuTWF0dGVydGFnLnJlbW92ZSh0YWcpO1xyXG4gICAgICB9KTtcclxuICAgICAgLy8gKTtcclxuICAgICAgdGhpcy5tYXR0ZXJ0YWdzID0gW107XHJcbiAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLmNsZWFyKCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBhY3Rpb25fZGVsZXRlX2VsZW1lbnQoXHJcbiAgICAgIGVsZW1lbnQ6IERiT2JqZWN0VHlwZSxcclxuICApIHtcclxuICAgICAgY29uc3Qgc2lkVGFnID0gdGhpcy5nZXRUYWdGcm9tRWxlbWVudElkKGVsZW1lbnQuaWQhKS50YWc7XHJcbiAgICAgIGlmIChzaWRUYWcpIHtcclxuICAgICAgICAgIGxldCByZXNwO1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICByZXNwID0gYXdhaXQgdGhpcy5zZGsuTWF0dGVydGFnLnJlbW92ZShzaWRUYWcpO1xyXG4gICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkNhbm5vdCBkZWxldGUgdGFnXCIsIHNpZFRhZywgZXJyb3IpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgaWYgKHJlc3ApIHtcclxuICAgICAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5kZWxldGUoc2lkVGFnKTtcclxuICAgICAgICAgICAgICBjb25zdCBpbmRleCA9IHRoaXMubWF0dGVydGFncy5pbmRleE9mKHNpZFRhZyk7XHJcbiAgICAgICAgICAgICAgdGhpcy5tYXR0ZXJ0YWdzLnNwbGljZShpbmRleCwgMSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgIH1cclxuICB9XHJcblxyXG4gIGFzeW5jIGFjdGlvbl9hZGRfdGlja2V0KCkge1xyXG4gICAgICBhd2FpdCB0aGlzLmFkZF9jdXJzb3JfbWF0dGVydGFnKFBvaVR5cGUuVElDS0VUKTtcclxuICAgICAgdGhpcy5zZXRJbnRlcmFjdGlvbk1vZGUoVmlld2VySW50ZXJhY3Rpb25zLkFERElOR19USUNLRVQpO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgYWN0aW9uX3Bvc2l0aW9uX2VsZW1lbnQoXHJcbiAgICAgIHBvaVR5cGU6IFBvaVR5cGUsXHJcbiAgICAgIGVsZW1lbnQ6IERiT2JqZWN0VHlwZSxcclxuICApIHtcclxuICAgICAgYXdhaXQgdGhpcy5hZGRfY3Vyc29yX21hdHRlcnRhZyhwb2lUeXBlLCBlbGVtZW50LCB0cnVlKTtcclxuICAgICAgdGhpcy5zZXRJbnRlcmFjdGlvbk1vZGUoVmlld2VySW50ZXJhY3Rpb25zLlBPU0lUSU9OSU5HKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGFjdGlvbl9hZGRfZXF1aXAoKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuYWRkX2N1cnNvcl9tYXR0ZXJ0YWcoUG9pVHlwZS5FUVVJUE1FTlQpO1xyXG4gICAgICB0aGlzLnNldEludGVyYWN0aW9uTW9kZShWaWV3ZXJJbnRlcmFjdGlvbnMuQURESU5HX0VRVUlQTUVOVCk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBhY3Rpb25fYWRkX21lYXN1cmVtZW50KCkge1xyXG4gICAgICBhd2FpdCB0aGlzLmFkZF9jdXJzb3JfbWF0dGVydGFnKFBvaVR5cGUuTUVBU1VSRSk7XHJcbiAgICAgIHRoaXMuc2V0SW50ZXJhY3Rpb25Nb2RlKFZpZXdlckludGVyYWN0aW9ucy5BRERJTkdfTUVBU1VSRSk7XHJcbiAgfVxyXG5cclxuICBhc3luYyBhY3Rpb25fYWRkX2ZlYXR1cmUoKSB7XHJcbiAgICAgIGF3YWl0IHRoaXMuYWRkX2N1cnNvcl9tYXR0ZXJ0YWcoUG9pVHlwZS5EQVRBKTtcclxuICAgICAgdGhpcy5zZXRJbnRlcmFjdGlvbk1vZGUoVmlld2VySW50ZXJhY3Rpb25zLkFERElOR19GRUFUVVJFKTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGFjdGlvbl9hZGRfZGVzaygpIHtcclxuICAgICAgYXdhaXQgdGhpcy5hZGRfY3Vyc29yX21hdHRlcnRhZyhQb2lUeXBlLkRFU0spO1xyXG4gICAgICB0aGlzLnNldEludGVyYWN0aW9uTW9kZShWaWV3ZXJJbnRlcmFjdGlvbnMuQURESU5HX0ZFQVRVUkUpO1xyXG4gIH1cclxuXHJcbiAgYWN0aW9uX2NvbXBsZXRlZCgpIHtcclxuICAgICAgcmV0dXJuIChcclxuICAgICAgICAgIERhdGUubm93KCkgLSB0aGlzLmxhc3RBY3Rpb25UaW1lID4gMjAwMCAmJlxyXG4gICAgICAgICAgdGhpcy5sYXN0QWN0aW9uVGltZSAhPT0gLTFcclxuICAgICAgKTtcclxuICB9XHJcblxyXG4gIGFjdGlvbl9jYW5jZWxlZCgpIHtcclxuICAgICAgdGhpcy5zZXRJbnRlcmFjdGlvbk1vZGUoVmlld2VySW50ZXJhY3Rpb25zLkRFRkFVTFQpO1xyXG4gICAgICB0aGlzLmRlbGV0ZUxhc3RNYXR0ZXJ0YWcoKTtcclxuICB9XHJcblxyXG4gIGFjdGlvbl9vcGVuX21lbnUobWVudTogc3RyaW5nKSB7XHJcbiAgICAgIHRoaXMudmlzaWJpbGl0eVNlcnZpY2UuZGV0YWlsU2hvd2luZy5uZXh0KHRydWUpO1xyXG4gICAgICBjb25zdCBsYXN0VGFnID0gdGhpcy5nZXRMYXN0VGFnKCk7XHJcbiAgICAgIHN3aXRjaCAobWVudSkge1xyXG4gICAgICAgICAgY2FzZSBcImFkZF9lcXVpcFwiOlxyXG4gICAgICAgICAgICAgIHRoaXMuZ29Ub0xhc3RUYWcoKTtcclxuICAgICAgICAgICAgICB0aGlzLmdvVG9NZW51KGB2aXNpdC8ke3RoaXMuY3VycmVudFNwYWNlSUR9L2FkZF9lcXVpcGApO1xyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcImFkZF90aWNrZXRcIjpcclxuICAgICAgICAgICAgICB0aGlzLmdvVG9MYXN0VGFnKCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5nb1RvTWVudShgdmlzaXQvJHt0aGlzLmN1cnJlbnRTcGFjZUlEfS9hZGRfdGlja2V0YCk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiYWRkX2ZlYXR1cmVcIjpcclxuICAgICAgICAgICAgICB0aGlzLmdvVG9MYXN0VGFnKCk7XHJcbiAgICAgICAgICAgICAgbGV0IHVybDogc3RyaW5nO1xyXG4gICAgICAgICAgICAgIGlmICh0aGlzLnJvdXRlci51cmwuaW5jbHVkZXMoXCI/XCIpKSB7XHJcbiAgICAgICAgICAgICAgICB1cmwgPSB0aGlzLnJvdXRlci51cmwuc3Vic3RyaW5nKDAsIHRoaXMucm91dGVyLnVybC5pbmRleE9mKFwiP1wiKSk7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHVybCA9IHRoaXMucm91dGVyLnVybDtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgdGhpcy5nb1RvTWVudShgJHt1cmx9L2FkZF9mZWF0dXJlYCk7XHJcbiAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBjYXNlIFwiYWRkX2Rlc2tcIjpcclxuICAgICAgICAgICAgICB0aGlzLmdvVG9MYXN0VGFnKCk7XHJcbiAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoXHJcbiAgICAgICAgICAgICAgICAgIFtgdmlzaXQvJHt0aGlzLmN1cnJlbnRTcGFjZUlEfS9hZGRfZmVhdHVyZWBdLFxyXG4gICAgICAgICAgICAgICAgICB7IHF1ZXJ5UGFyYW1zOiB7IGlzRGVzazogdHJ1ZSB9IH0sXHJcbiAgICAgICAgICAgICAgKTtcclxuICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIGNhc2UgXCJwb3NpdGlvbmluZ190aWNrZXRcIjpcclxuICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcInBvc2l0aW9uaW5nX3RpY2tldFwiKTtcclxuICAgICAgICAgICAgICBpZiAobGFzdFRhZykge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yb3V0ZXIubmF2aWdhdGUoXHJcbiAgICAgICAgICAgICAgICAgICAgW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBgdmlzaXQvJHt0aGlzLmN1cnJlbnRTcGFjZUlEfS9kZXRhaWwvJHt0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobGFzdFRhZykuZWxlbWVudElEfWAsXHJcbiAgICAgICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgICAgICAgICB7IHF1ZXJ5UGFyYW1zOiB7IHBvc2l0aW9uaW5nOiB0cnVlIH0gfSxcclxuICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcInBvc2l0aW9uaW5nX2VxdWlwXCI6XHJcbiAgICAgICAgICAgIGlmIChsYXN0VGFnKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvdXRlci5uYXZpZ2F0ZShcclxuICAgICAgICAgICAgICAgICAgICBbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGB2aXNpdC8ke3RoaXMuY3VycmVudFNwYWNlSUR9L2VxdWlwLyR7dGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KGxhc3RUYWcpLmVsZW1lbnRJRH1gLFxyXG4gICAgICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICAgICAgeyBxdWVyeVBhcmFtczogeyBwb3NpdGlvbmluZzogdHJ1ZSB9IH0sXHJcbiAgICAgICAgICAgICAgICApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgY2FzZSBcInBvc2l0aW9uaW5nX2ZlYXR1cmVcIjpcclxuICAgICAgICAgICAgaWYgKGxhc3RUYWcpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMucm91dGVyLm5hdmlnYXRlKFtgJHt0aGlzLnJvdXRlci51cmx9YF0sIHtcclxuICAgICAgICAgICAgICAgICAgICBxdWVyeVBhcmFtczogeyBwb3NpdGlvbmluZzogdHJ1ZSB9LFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgfVxyXG5cclxuICAgIGFzeW5jIGFjdGlvbl9nb190b19mbG9vcihmbG9vck5hbWU6IHN0cmluZywgbWF0dGVycG9ydEZsb29yU2VxdWVuY2U6IG51bWJlciA9IG51bGwpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZmxvb3JzKSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiRmxvb3IgYXJlIG5vdCBsb2FkZWQgeWV0XCIpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGNvbnNvbGUubG9nKHRoaXMuZmxvb3JzKTtcclxuICAgICAgICAvLyBsb29rIHVwIGZvciBzZXF1ZW5jZSBudW1iZXIgKHRoZSBzYWZlc3QgbWV0aG9kKVxyXG4gICAgICAgIGxldCBmbG9vck1hdHRlcnBvcnQgPSB0aGlzLmZsb29ycy5maW5kKFxyXG4gICAgICAgICAgICAoZmxvb3IpID0+IGZsb29yLnNlcXVlbmNlID09PSBtYXR0ZXJwb3J0Rmxvb3JTZXF1ZW5jZSxcclxuICAgICAgICApO1xyXG4gICAgICAgIGlmICghZmxvb3JNYXR0ZXJwb3J0KSB7XHJcbiAgICAgICAgICAgIGZsb29yTWF0dGVycG9ydCA9IHRoaXMuZmxvb3JzLmZpbmQoXHJcbiAgICAgICAgICAgICAgICAoZmxvb3IpID0+IGZsb29yTmFtZS5pbmNsdWRlcyhmbG9vci5uYW1lKSAmJiBmbG9vci5uYW1lICE9IFwiXCIsXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICghZmxvb3JNYXR0ZXJwb3J0KSB7XHJcbiAgICAgICAgICAgIGZsb29yTWF0dGVycG9ydCA9IHRoaXMuZmxvb3JzLmZpbmQoKGZsb29yKSA9PlxyXG4gICAgICAgICAgICAgICAgZmxvb3JOYW1lLmluY2x1ZGVzKGZsb29yLmlkKSxcclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coZmxvb3JNYXR0ZXJwb3J0KVxyXG4gICAgICAgIGlmIChmbG9vck1hdHRlcnBvcnQpIHtcclxuICAgICAgICAgICAgbGV0IHJldHJ5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgd2hpbGUocmV0cnkpIHtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmxvb3JJbmRleCA9IGF3YWl0IHRoaXMuc2RrLkZsb29yLm1vdmVUbyhmbG9vck1hdHRlcnBvcnQuc2VxdWVuY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKFwibW92ZWQgdG8gZmxvb3JJbmRleFwiLCBmbG9vckluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICByZXRyeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkNhbm5vdCBtb3ZlIHRvIEZsb29yXCIsIGVycm9yKTtcclxuICAgICAgICAgICAgICAgICAgICBhd2FpdCB3YWl0KDEwMCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zb2xlLndhcm4oXCJObyBtYXR0ZXJwb3J0IGZsb29yIGZvdW5kIHRvIG1vdmUgdG9cIilcclxuICAgICAgICB9XHJcbiAgfVxyXG5cclxuICAgIGFzeW5jIGFjdGlvbl9nb190b19zd2VlcChcclxuICAgICAgICBzd2VlcDogc3RyaW5nLFxyXG4gICAgICAgIHJvdGF0aW9uOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH0gPSBudWxsLFxyXG4gICAgKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuZm9yYmlkZGVuU3dlZXBzLmluY2x1ZGVzKHN3ZWVwKSkge1xyXG4gICAgICAgICAgICBjb25zb2xlLmxvZyhcInVzZXIgaXMgbm90IGFsbG93ZWQgdG8gZ28gdG8gdGhpcyBzd2VlcFwiKTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhcImdvaW5nIHRvIHN3ZWVwXCIsIHN3ZWVwLCBcIndpdGggcm90YXRpb246XCIsIHJvdGF0aW9uKTtcclxuICAgICAgICBzZXRUaW1lb3V0KGFzeW5jICgpID0+IHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuaW5UcmFuc2l0aW9uTW9kZSB8fCB0aGlzLmluVHJhbnNpdGlvblN3ZWVwKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhcIkNhbm5vdCBnbyB0byBzd2VlcCwgaW4gdHJhbnNpdGlvblwiKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pblRyYW5zaXRpb25Td2VlcCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBhd2FpdCB0aGlzLnNkay5Td2VlcC5tb3ZlVG8oc3dlZXAsIHtcclxuICAgICAgICAgICAgICAgICAgICB0cmFuc2l0aW9uOiBcInRyYW5zaXRpb24uZmx5XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgdHJhbnNpdGlvblRpbWU6IDE1MDAsXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaW5UcmFuc2l0aW9uU3dlZXAgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKFwiQ2Fubm90IG1vdmUgdG8gc3dlZXBcIiwgZXJyb3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChyb3RhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZGsuQ2FtZXJhLnNldFJvdGF0aW9uKHJvdGF0aW9uLCB7IHNwZWVkOiAxMDAgfSk7IC8vIHNwZWVkIGlzIGRlZ3JlZXMgcGVyIHNlY29uZFxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgMTAwMCk7XHJcbiAgICB9XHJcblxyXG4gIGdldEN1cnJlbnRTd2VlcCgpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgICAgaWYgKHRoaXMucG9zZUNhbWVyYSkge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMucG9zZUNhbWVyYS5zd2VlcDtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gbnVsbDtcclxuICB9XHJcblxyXG4gIGdldEN1cnJlbnRDYW1lcmFQb3NpdGlvbigpOiB7XHJcbiAgICAgIHJvdGF0aW9uOiBhbnk7XHJcbiAgICAgIHBvc2l0aW9uOiBhbnk7XHJcbiAgICAgIHN3ZWVwOiBhbnk7XHJcbiAgfSB8IG51bGwge1xyXG4gICAgICBpZiAodGhpcy5wb3NlQ2FtZXJhKSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5wb3NlQ2FtZXJhO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5TZXR0ZXJzXHJcbi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXHJcblxyXG4gIHNldEludGVyYWN0aW9uTW9kZShpbnRlcmFjdGlvbk1vZGU6IG51bWJlcikge1xyXG4gICAgICB0aGlzLmludGVyYWN0aW9uTW9kZSA9IGludGVyYWN0aW9uTW9kZTtcclxuICB9XHJcblxyXG4gIHNldFRpY2tldEFuZFBvaUluVGFnKG1hdHRlcnRhZ0lEOiBzdHJpbmcsIHRpY2tldDogVGlja2V0LCBwb2k6IFBPSSB8IG51bGwgPSBudWxsKSB7XHJcbiAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChtYXR0ZXJ0YWdJRCkubWF0dGVydGFnRGF0YS5zZXRUaWNrZXQodGlja2V0KTtcclxuICAgICAgaWYgKHBvaSkge1xyXG4gICAgICAgICAgdGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KG1hdHRlcnRhZ0lEKS5tYXR0ZXJ0YWdEYXRhLnNldFBvaShwb2kpO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChtYXR0ZXJ0YWdJRCkuZWxlbWVudElEID0gdGlja2V0LmlkO1xyXG4gICAgICB0aGlzLnVwZGF0ZU1hdHRlclRhZ0Zyb21JZChtYXR0ZXJ0YWdJRCwgdGlja2V0LCBQb2lUeXBlLlRJQ0tFVCk7XHJcbiAgfVxyXG5cclxuICBzZXRFcXVpcG1lbnRBbmRQb2lJblRhZyhcclxuICAgICAgbWF0dGVydGFnSUQ6IHN0cmluZyxcclxuICAgICAgZXF1aXA6IEVxdWlwbWVudCxcclxuICAgICAgcG9pOiBQT0kgfCBudWxsID0gbnVsbCxcclxuICApIHtcclxuICAgICAgdGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KG1hdHRlcnRhZ0lEKS5tYXR0ZXJ0YWdEYXRhLnNldEVxdWlwbWVudChlcXVpcCk7XHJcbiAgICAgIGlmIChwb2kpIHtcclxuICAgICAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChtYXR0ZXJ0YWdJRCkubWF0dGVydGFnRGF0YS5zZXRQb2kocG9pKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobWF0dGVydGFnSUQpLmVsZW1lbnRJRCA9IGVxdWlwLmlkO1xyXG4gICAgICB0aGlzLnVwZGF0ZU1hdHRlclRhZ0Zyb21JZChtYXR0ZXJ0YWdJRCwgZXF1aXAsIFBvaVR5cGUuRVFVSVBNRU5UKTtcclxuICB9XHJcblxyXG4gIHNldEZlYXR1cmVBbmRQb2lJblRhZyhcclxuICAgICAgbWF0dGVydGFnSUQ6IHN0cmluZyxcclxuICAgICAgZmVhdHVyZTogRmVhdHVyZSxcclxuICAgICAgcG9pOiBQT0kgfCBudWxsID0gbnVsbCxcclxuICApIHtcclxuICAgICAgdGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KG1hdHRlcnRhZ0lEKS5tYXR0ZXJ0YWdEYXRhLnNldEZlYXR1cmUoZmVhdHVyZSk7XHJcbiAgICAgIGlmIChwb2kpIHtcclxuICAgICAgICAgIHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChtYXR0ZXJ0YWdJRCkubWF0dGVydGFnRGF0YS5zZXRQb2kocG9pKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQobWF0dGVydGFnSUQpLmVsZW1lbnRJRCA9IGZlYXR1cmUuaWQ7XHJcbiAgICAgIGNvbnN0IHRhZ1R5cGUgPSBmZWF0dXJlLmlzQm9va2luZ1BsYWNlID8gUG9pVHlwZS5ERVNLIDogUG9pVHlwZS5EQVRBO1xyXG4gICAgICB0aGlzLnVwZGF0ZU1hdHRlclRhZ0Zyb21JZChtYXR0ZXJ0YWdJRCwgZmVhdHVyZSwgdGFnVHlwZSk7XHJcbiAgfVxyXG5cclxuICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcbkdldHRlcnNcclxuLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cclxuXHJcbiAgZ2V0SW50ZXJhY3Rpb25Nb2RlKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5pbnRlcmFjdGlvbk1vZGU7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0VGFnRnJvbUVsZW1lbnRJZChlbGVtZW50SUQ6IHN0cmluZyk6IHtcclxuICAgICAgdGFnOiBzdHJpbmcgfCBudWxsO1xyXG4gICAgICBzd2VlcDogc3RyaW5nIHwgbnVsbDtcclxuICB9IHtcclxuICAgICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHRoaXMubWF0dGVydGFncy5sZW5ndGg7IGluZGV4ICs9IDEpIHtcclxuICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQodGhpcy5tYXR0ZXJ0YWdzW2luZGV4XSkuZWxlbWVudElEID09PVxyXG4gICAgICAgICAgICAgIGVsZW1lbnRJRFxyXG4gICAgICAgICAgKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgeyBtYXR0ZXJ0YWdEYXRhIH0gPVxyXG4gICAgICAgICAgICAgICAgICB0aGlzLmRpY3Rpb25uYXJ5VGFncy5nZXQodGhpcy5tYXR0ZXJ0YWdzW2luZGV4XSk7XHJcbiAgICAgICAgICAgICAgY29uc3Qgc3dlZXAgPSBtYXR0ZXJ0YWdEYXRhLmdldFN3ZWVwSUQoKTtcclxuICAgICAgICAgICAgICBpZiAoIXN3ZWVwKSB7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybiB7IHRhZzogdGhpcy5tYXR0ZXJ0YWdzW2luZGV4XSwgc3dlZXA6IG51bGwgfTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgaWYgKHRoaXMuc3dlZXBzICYmIHRoaXMuc3dlZXBzLmluY2x1ZGVzKHN3ZWVwKSkge1xyXG4gICAgICAgICAgICAgICAgICByZXR1cm4geyB0YWc6IHRoaXMubWF0dGVydGFnc1tpbmRleF0sIHN3ZWVwIH07XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIHJldHVybiB7IHRhZzogbnVsbCwgc3dlZXAgfTtcclxuICAgICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4geyB0YWc6IG51bGwsIHN3ZWVwOiBudWxsIH07XHJcbiAgfVxyXG5cclxuICBnZXRUYWdzKCkge1xyXG4gICAgICByZXR1cm4gdGhpcy5tYXR0ZXJ0YWdzO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGFzdFRhZygpOiBzdHJpbmcgfCBudWxsIHtcclxuICAgIGlmICh0aGlzLm1hdHRlcnRhZ1RvRm9sbG93KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0dGVydGFnVG9Gb2xsb3dcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubWF0dGVydGFncy5sZW5ndGggPT09IDBcclxuICAgICAgICA/IG51bGxcclxuICAgICAgICA6IHRoaXMubWF0dGVydGFnc1t0aGlzLm1hdHRlcnRhZ3MubGVuZ3RoIC0gMV07XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBnZXRNZW51VG9PcGVuRm9yTGFzdFRhZygpIHtcclxuICAgIGNvbnN0IGxhc3RUYWcgPSB0aGlzLmdldExhc3RUYWcoKTtcclxuICAgIGlmIChsYXN0VGFnKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGljdGlvbm5hcnlUYWdzLmdldChsYXN0VGFnKS5tYXR0ZXJ0YWdEYXRhLmdldE1lbnVUb09wZW4oKVxyXG4gICAgfVxyXG4gICAgcmV0dXJuIG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRUYWdEYXRhRnJvbUlkKG1hdHRlcnRhZ0lEOiBzdHJpbmcpOiBNYXR0ZXJ0YWdEYXRhIHwgbnVsbCB7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgICByZXR1cm4gdGhpcy5kaWN0aW9ubmFyeVRhZ3MuZ2V0KG1hdHRlcnRhZ0lEKSEubWF0dGVydGFnRGF0YTtcclxuICAgICAgfSBjYXRjaCB7XHJcbiAgICAgICAgICBjb25zb2xlLmxvZyhcImNhbm5vdCByZXRyaWV2ZSBtYXR0ZXJ0YWdEYXRhIGZvciB0YWdcIiwgbWF0dGVydGFnSUQpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxuXHJcbiAgZ2V0TGFzdERpc3RhbmNlcygpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuZGlzdGFuY2VzTGFzdE1lYXN1cmU7XHJcbiAgfVxyXG5cclxuICB0YWtlU2NyZWVuU2hvdCgpOiBQcm9taXNlPGFueT4ge1xyXG4gICAgICByZXR1cm4gdGhpcy5zZGsuUmVuZGVyZXIudGFrZVNjcmVlblNob3QoXHJcbiAgICAgICAgICB0aGlzLnJlc29sdXRpb24sXHJcbiAgICAgICAgICB0aGlzLnZpc2liaWxpdHksXHJcbiAgICAgICkudGhlbihcclxuICAgICAgICAgIGZ1bmN0aW9uIChzY3JlZW5TaG90VXJpOiBhbnkpIHtcclxuICAgICAgICAgICAgICAvLyBiYXNlNjQgc3RyaW5nXHJcbiAgICAgICAgICAgICAgdGhpcy5sYXN0U2NyZWVuc2hvdFVyaSA9IHNjcmVlblNob3RVcmk7XHJcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xyXG4gICAgICAgICAgfS5iaW5kKHRoaXMpLFxyXG4gICAgICApO1xyXG4gIH1cclxuXHJcbiAgZ2V0U2NyZWVuU2hvdFVyaSgpIHtcclxuICAgICAgcmV0dXJuIHRoaXMubGFzdFNjcmVlbnNob3RVcmk7XHJcbiAgfVxyXG5cclxuICBnZXRMYXN0TWVhc3VyZW1lbnQoKTogT2JqZWN0IHtcclxuICAgICAgY29uc3QgZGF0YSA9IHtcclxuICAgICAgICAgIG1lYXN1cmU6IHRoaXMubGFzdE1lYXN1cmUsXHJcbiAgICAgICAgICBzd2VlcDogdGhpcy5wb3NlQ2FtZXJhLnN3ZWVwLFxyXG4gICAgICB9O1xyXG4gICAgICByZXR1cm4gZGF0YTtcclxuICB9XHJcblxyXG4gIGFzeW5jIGNsZWFyQWxsKCkge1xyXG4gICAgICBjb25zb2xlLmxvZyhcInJlbW92aW5nIHZpZXdlclwiKTtcclxuICAgICAgdGhpcy5hY3Rpb25fZGVsZXRlX2FsbF9tYXR0ZXJ0YWdzKCk7XHJcbiAgICAgIHRoaXMuZmxvb3JzID0gbnVsbDtcclxuICAgICAgdGhpcy5zd2VlcHMgPSBudWxsO1xyXG4gICAgICB0aGlzLnNkayA9IG51bGw7XHJcbiAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aW1lclBvaW50ZXIpO1xyXG4gICAgICB0aGlzLmZvcmJpZGRlblN3ZWVwcyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgYXN5bmMgcmVtb3ZlRm9yYmlkZGVuU3dlZXBzKGZvcmJpZGRlblN3ZWVwczogc3RyaW5nW10pIHtcclxuICAgICAgdGhpcy5mb3JiaWRkZW5Td2VlcHMgPSBbLi4uZm9yYmlkZGVuU3dlZXBzXTtcclxuICAgICAgbGV0IHJlbW92ZWQgPSAwO1xyXG4gICAgICBhd2FpdCBQcm9taXNlLmFsbChcclxuICAgICAgICAgIGZvcmJpZGRlblN3ZWVwcy5tYXAoYXN5bmMgKHN3ZWVwKSA9PiB7XHJcbiAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgYXdhaXQgdGhpcy5zZGsuU3dlZXAuZGlzYWJsZShzd2VlcCk7XHJcbiAgICAgICAgICAgICAgICAgIHJlbW92ZWQgKz0gMTtcclxuICAgICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnJvcik7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSksXHJcbiAgICAgICk7XHJcbiAgICAgIGNvbnNvbGUubG9nKFwicmVtb3ZlZCBzd2VlcHM6XCIsIHJlbW92ZWQpO1xyXG4gIH1cclxufVxyXG4iXX0=
|