@sapui5/sap.fe.core 1.102.4 → 1.102.6
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/package.json +1 -1
- package/src/sap/fe/core/.library +1 -1
- package/src/sap/fe/core/CommonUtils.js +30 -15
- package/src/sap/fe/core/CommonUtils.ts +27 -12
- package/src/sap/fe/core/ExtensionAPI.js +34 -1
- package/src/sap/fe/core/ExtensionAPI.ts +30 -0
- package/src/sap/fe/core/PageController.js +9 -7
- package/src/sap/fe/core/PageController.ts +10 -1
- package/src/sap/fe/core/controllerextensions/PageReady.js +85 -176
- package/src/sap/fe/core/controllerextensions/PageReady.ts +86 -168
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.js +397 -0
- package/src/sap/fe/core/controllerextensions/pageReady/DataQueryWatcher.ts +295 -0
- package/src/sap/fe/core/converters/annotations/DataField.js +9 -7
- package/src/sap/fe/core/converters/annotations/DataField.ts +10 -7
- package/src/sap/fe/core/converters/controls/Common/Table.js +1 -2
- package/src/sap/fe/core/converters/controls/Common/Table.ts +0 -2
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.js +12 -2
- package/src/sap/fe/core/converters/controls/ListReport/FilterBar.ts +14 -1
- package/src/sap/fe/core/library.js +1 -1
- package/src/sap/fe/core/templating/DataModelPathHelper.js +3 -3
- package/src/sap/fe/core/templating/DataModelPathHelper.ts +3 -0
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* SAP UI development toolkit for HTML5 (SAPUI5)
|
|
3
|
+
* (c) Copyright 2009-2021 SAP SE. All rights reserved
|
|
4
|
+
*/
|
|
5
|
+
sap.ui.define(["sap/base/Log"], function (Log) {
|
|
6
|
+
"use strict";
|
|
7
|
+
|
|
8
|
+
function _catch(body, recover) {
|
|
9
|
+
try {
|
|
10
|
+
var result = body();
|
|
11
|
+
} catch (e) {
|
|
12
|
+
return recover(e);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (result && result.then) {
|
|
16
|
+
return result.then(void 0, recover);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return result;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var DataQueryWatcher = /*#__PURE__*/function () {
|
|
23
|
+
function DataQueryWatcher(_oEventProvider, _fnOnFinished) {
|
|
24
|
+
this._aBindingRegistrations = [];
|
|
25
|
+
this._aOtherEventSources = [];
|
|
26
|
+
this._isSearchPending = false;
|
|
27
|
+
this._aMDCTables = [];
|
|
28
|
+
this._aMDCCharts = [];
|
|
29
|
+
this._oEventProvider = _oEventProvider;
|
|
30
|
+
this._fnOnFinished = _fnOnFinished;
|
|
31
|
+
} // Accessors
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
var _proto = DataQueryWatcher.prototype;
|
|
35
|
+
|
|
36
|
+
_proto.isSearchPending = function isSearchPending() {
|
|
37
|
+
return this._isSearchPending;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
_proto.isDataReceived = function isDataReceived() {
|
|
41
|
+
return this._isDataReceived;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
_proto.resetDataReceived = function resetDataReceived() {
|
|
45
|
+
this._isDataReceived = undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Reset the state: unsubscribe to all data events and remove all registered objects.
|
|
49
|
+
*/
|
|
50
|
+
;
|
|
51
|
+
|
|
52
|
+
_proto.reset = function reset() {
|
|
53
|
+
var _this = this;
|
|
54
|
+
|
|
55
|
+
// Remove all remaining callbacks
|
|
56
|
+
this._aBindingRegistrations.forEach(function (reg) {
|
|
57
|
+
reg.binding.detachEvent("dataRequested", _this.onDataRequested, _this);
|
|
58
|
+
reg.binding.detachEvent("dataReceived", _this.onDataReceived, _this);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
this._aOtherEventSources.forEach(function (oElement) {
|
|
62
|
+
oElement.detachEvent("search", _this.onSearch, _this);
|
|
63
|
+
oElement.detachEvent("bindingUpdated", _this.register, _this);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
this._aBindingRegistrations = [];
|
|
67
|
+
this._aOtherEventSources = [];
|
|
68
|
+
this._aMDCTables = [];
|
|
69
|
+
this._aMDCCharts = [];
|
|
70
|
+
this._isSearchPending = false;
|
|
71
|
+
this._isDataReceived = undefined;
|
|
72
|
+
} // //////////////////////////////////////////////////
|
|
73
|
+
// Callback when data is received on a binding.
|
|
74
|
+
;
|
|
75
|
+
|
|
76
|
+
_proto.onDataReceived = function onDataReceived(oEvent, params) {
|
|
77
|
+
// Look for the corresponding binding registration
|
|
78
|
+
var binding = oEvent.getSource();
|
|
79
|
+
|
|
80
|
+
var bindingRegistration = this._aBindingRegistrations.find(function (reg) {
|
|
81
|
+
return reg.binding === binding;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
if (!bindingRegistration) {
|
|
85
|
+
Log.error("PageReady - data received on an unregistered binding");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
switch (binding.getGroupId()) {
|
|
90
|
+
case "$auto.Workers":
|
|
91
|
+
this._oEventProvider.fireEvent("workersBatchReceived");
|
|
92
|
+
|
|
93
|
+
break;
|
|
94
|
+
|
|
95
|
+
case "$auto.Heroes":
|
|
96
|
+
this._oEventProvider.fireEvent("heroesBatchReceived");
|
|
97
|
+
|
|
98
|
+
break;
|
|
99
|
+
|
|
100
|
+
default:
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
bindingRegistration.receivedCount++;
|
|
104
|
+
|
|
105
|
+
if (bindingRegistration.receivedCount < bindingRegistration.requestedCount) {
|
|
106
|
+
// There are other request pending --> resubscribe to wait until they return
|
|
107
|
+
binding.attachEventOnce("dataReceived", {
|
|
108
|
+
triggeredBySearch: params.triggeredBySearch
|
|
109
|
+
}, this.onDataReceived, this);
|
|
110
|
+
return;
|
|
111
|
+
} // Check if at least one binding has requested data, and all bindings that have requested data have received it
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
var bAllDone = this._aBindingRegistrations.some(function (reg) {
|
|
115
|
+
return reg.requestedCount !== 0;
|
|
116
|
+
}) && this._aBindingRegistrations.every(function (reg) {
|
|
117
|
+
return reg.requestedCount === 0 || reg.receivedCount >= reg.requestedCount;
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
if (params.triggeredBySearch || bindingRegistration.receivedCount >= bindingRegistration.requestedCount) {
|
|
121
|
+
this._isSearchPending = false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (bAllDone) {
|
|
125
|
+
this._isDataReceived = true;
|
|
126
|
+
|
|
127
|
+
this._fnOnFinished();
|
|
128
|
+
}
|
|
129
|
+
} // //////////////////////////////////////////////////
|
|
130
|
+
// Callback when data is requested on a binding.
|
|
131
|
+
;
|
|
132
|
+
|
|
133
|
+
_proto.onDataRequested = function onDataRequested(oEvent, params) {
|
|
134
|
+
// Look for the corresponding binding registration
|
|
135
|
+
var binding = oEvent.getSource();
|
|
136
|
+
|
|
137
|
+
var bindingRegistration = this._aBindingRegistrations.find(function (reg) {
|
|
138
|
+
return reg.binding === binding;
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
if (!bindingRegistration) {
|
|
142
|
+
Log.error("PageReady - data requested on an unregistered binding");
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
bindingRegistration.requestedCount++;
|
|
147
|
+
this._isDataReceived = false;
|
|
148
|
+
|
|
149
|
+
if (bindingRegistration.requestedCount - bindingRegistration.receivedCount === 1) {
|
|
150
|
+
// Listen to dataReceived only if there's no other request pending
|
|
151
|
+
// Otherwise the 'dataReceived' handler would be called several times when the first query returns
|
|
152
|
+
// and we wouldn't wait for all queries to be finished
|
|
153
|
+
// (we will resubscribe to the dataReceived event in onDataReceived if necessary)
|
|
154
|
+
binding.attachEventOnce("dataReceived", {
|
|
155
|
+
triggeredBySearch: params.triggeredBySearch
|
|
156
|
+
}, this.onDataReceived, this);
|
|
157
|
+
}
|
|
158
|
+
} // //////////////////////////////////////////////////
|
|
159
|
+
// Callback when a search is triggered from a filterbar
|
|
160
|
+
;
|
|
161
|
+
|
|
162
|
+
_proto.onSearch = function onSearch(oEvent) {
|
|
163
|
+
var _this3 = this;
|
|
164
|
+
|
|
165
|
+
var _this2 = this;
|
|
166
|
+
|
|
167
|
+
var aMDCTableLinkedToFilterBar = this._aMDCTables.filter(function (oTable) {
|
|
168
|
+
return oEvent.getSource().sId === oTable.getFilter() && oTable.getVisible();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
var aMDCChartsLinkedToFilterBar = this._aMDCCharts.filter(function (oChart) {
|
|
172
|
+
return oEvent.getSource().sId === oChart.getFilter() && oChart.getVisible();
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
if (aMDCTableLinkedToFilterBar.length > 0 || aMDCChartsLinkedToFilterBar.length > 0) {
|
|
176
|
+
this._isSearchPending = true;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
aMDCTableLinkedToFilterBar.forEach(function (oTable) {
|
|
180
|
+
_this2.registerTable(oTable, true);
|
|
181
|
+
});
|
|
182
|
+
aMDCChartsLinkedToFilterBar.forEach(function (oChart) {
|
|
183
|
+
try {
|
|
184
|
+
var _temp4 = _catch(function () {
|
|
185
|
+
function _temp2() {
|
|
186
|
+
_this3.registerChart(oChart, true);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
var _temp = function () {
|
|
190
|
+
if (oChart.innerChartBoundPromise) {
|
|
191
|
+
return Promise.resolve(oChart.innerChartBoundPromise).then(function () {});
|
|
192
|
+
}
|
|
193
|
+
}();
|
|
194
|
+
|
|
195
|
+
return _temp && _temp.then ? _temp.then(_temp2) : _temp2(_temp);
|
|
196
|
+
}, function (oError) {
|
|
197
|
+
Log.error("Cannot find a inner bound chart", oError);
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
return Promise.resolve(_temp4 && _temp4.then ? _temp4.then(function () {}) : void 0);
|
|
201
|
+
} catch (e) {
|
|
202
|
+
return Promise.reject(e);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
} // //////////////////////////////////////////////////
|
|
206
|
+
// Register a binding (with an optional table/chart)
|
|
207
|
+
// and attach callbacks on dateRequested/dataReceived events
|
|
208
|
+
;
|
|
209
|
+
|
|
210
|
+
_proto.register = function register(_event, data) {
|
|
211
|
+
var _data$table, _data$chart;
|
|
212
|
+
|
|
213
|
+
var binding = data.binding || ((_data$table = data.table) === null || _data$table === void 0 ? void 0 : _data$table.getRowBinding()) || ((_data$chart = data.chart) === null || _data$chart === void 0 ? void 0 : _data$chart.getControlDelegate().getInnerChart(data.chart).getBinding("data"));
|
|
214
|
+
var boundControl = data.table || data.chart;
|
|
215
|
+
|
|
216
|
+
if (!binding) {
|
|
217
|
+
return;
|
|
218
|
+
} // Check if the binding is already registered
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
var bindingRegistration = this._aBindingRegistrations.find(function (reg) {
|
|
222
|
+
return reg.binding === binding;
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
if (bindingRegistration) {
|
|
226
|
+
if (boundControl) {
|
|
227
|
+
// The binding was already registerd without boundControl information --> update boundControl
|
|
228
|
+
bindingRegistration.boundControl = boundControl;
|
|
229
|
+
} // This binding has already requested data, but we're registering it again (on search) --> attach to dataRequested again
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
if (bindingRegistration.requestedCount > 0) {
|
|
233
|
+
binding.attachEventOnce("dataRequested", {
|
|
234
|
+
triggeredBySearch: data.triggeredBySearch
|
|
235
|
+
}, this.onDataRequested, this);
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
if (boundControl) {
|
|
242
|
+
// Check if there's a different binding registered for the bound control
|
|
243
|
+
bindingRegistration = this._aBindingRegistrations.find(function (reg) {
|
|
244
|
+
return reg.boundControl === boundControl;
|
|
245
|
+
});
|
|
246
|
+
|
|
247
|
+
if (bindingRegistration && bindingRegistration.binding !== binding) {
|
|
248
|
+
// The control had a different binding. This can happen in case of MDC charts who recreated their binding after search
|
|
249
|
+
// The previous binding is destroyed, we can replace it with the new and reset counters
|
|
250
|
+
bindingRegistration.binding = binding;
|
|
251
|
+
bindingRegistration.requestedCount = 0;
|
|
252
|
+
bindingRegistration.receivedCount = 0;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (!bindingRegistration) {
|
|
257
|
+
bindingRegistration = {
|
|
258
|
+
binding: binding,
|
|
259
|
+
boundControl: boundControl,
|
|
260
|
+
requestedCount: 0,
|
|
261
|
+
receivedCount: 0
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
this._aBindingRegistrations.push(bindingRegistration);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
binding.attachEventOnce("dataRequested", {
|
|
268
|
+
triggeredBySearch: data.triggeredBySearch
|
|
269
|
+
}, this.onDataRequested, this);
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Registers a binding for watching its data events (dataRequested and dataReceived).
|
|
273
|
+
*
|
|
274
|
+
* @param binding The binding
|
|
275
|
+
*/
|
|
276
|
+
;
|
|
277
|
+
|
|
278
|
+
_proto.registerBinding = function registerBinding(binding) {
|
|
279
|
+
this.register(null, {
|
|
280
|
+
binding: binding,
|
|
281
|
+
triggeredBySearch: false
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Registers an MDCTable for watching the data events on its row binding (dataRequested and dataReceived).
|
|
286
|
+
*
|
|
287
|
+
* @param table The table
|
|
288
|
+
* @param triggeredBySearch True if this registration is triggered by a filterBar search
|
|
289
|
+
*/
|
|
290
|
+
;
|
|
291
|
+
|
|
292
|
+
_proto.registerTable = function registerTable(table) {
|
|
293
|
+
var triggeredBySearch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
294
|
+
|
|
295
|
+
if (this._aMDCTables.indexOf(table) < 0) {
|
|
296
|
+
this._aMDCTables.push(table);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
var oRowBinding = table.getRowBinding();
|
|
300
|
+
|
|
301
|
+
if (oRowBinding) {
|
|
302
|
+
this.register(null, {
|
|
303
|
+
table: table,
|
|
304
|
+
triggeredBySearch: triggeredBySearch
|
|
305
|
+
});
|
|
306
|
+
} else {
|
|
307
|
+
table.attachEventOnce("bindingUpdated", {
|
|
308
|
+
table: table,
|
|
309
|
+
triggeredBySearch: triggeredBySearch
|
|
310
|
+
}, this.register, this);
|
|
311
|
+
|
|
312
|
+
this._aOtherEventSources.push(table);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Registers an MDCChart for watching the data events on its inner data binding (dataRequested and dataReceived).
|
|
317
|
+
*
|
|
318
|
+
* @param chart The chart
|
|
319
|
+
* @param triggeredBySearch True if this registration is triggered by a filter bar search
|
|
320
|
+
*/
|
|
321
|
+
;
|
|
322
|
+
|
|
323
|
+
_proto.registerChart = function registerChart(chart) {
|
|
324
|
+
var triggeredBySearch = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
325
|
+
|
|
326
|
+
if (this._aMDCCharts.indexOf(chart) < 0) {
|
|
327
|
+
this._aMDCCharts.push(chart);
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
var oInnerChart = chart.getControlDelegate().getInnerChart(chart);
|
|
331
|
+
var binding = oInnerChart === null || oInnerChart === void 0 ? void 0 : oInnerChart.getBinding("data");
|
|
332
|
+
|
|
333
|
+
if (binding) {
|
|
334
|
+
this.register(null, {
|
|
335
|
+
chart: chart,
|
|
336
|
+
triggeredBySearch: triggeredBySearch
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
chart.attachEventOnce("bindingUpdated", {
|
|
340
|
+
chart: chart,
|
|
341
|
+
triggeredBySearch: triggeredBySearch
|
|
342
|
+
}, this.register, this);
|
|
343
|
+
|
|
344
|
+
this._aOtherEventSources.push(chart);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Registers an MDCTable or MDCChart for watching the data events on its inner data binding (dataRequested and dataReceived).
|
|
349
|
+
*
|
|
350
|
+
* @param element The table or cchart
|
|
351
|
+
*/
|
|
352
|
+
;
|
|
353
|
+
|
|
354
|
+
_proto.registerTableOrChart = function registerTableOrChart(element) {
|
|
355
|
+
try {
|
|
356
|
+
var _this5 = this;
|
|
357
|
+
|
|
358
|
+
if (!element.isA("sap.ui.mdc.Table") && !element.isA("sap.ui.mdc.Chart")) {
|
|
359
|
+
return Promise.resolve();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
var _temp6 = _catch(function () {
|
|
363
|
+
return Promise.resolve(element.initialized()).then(function () {
|
|
364
|
+
if (element.isA("sap.ui.mdc.Table")) {
|
|
365
|
+
_this5.registerTable(element);
|
|
366
|
+
} else {
|
|
367
|
+
_this5.registerChart(element);
|
|
368
|
+
}
|
|
369
|
+
}); // access binding only after table/chart is bound
|
|
370
|
+
}, function (oError) {
|
|
371
|
+
Log.error("PageReady - Cannot register a table or a chart", oError);
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
return Promise.resolve(_temp6 && _temp6.then ? _temp6.then(function () {}) : void 0);
|
|
375
|
+
} catch (e) {
|
|
376
|
+
return Promise.reject(e);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Registers an MDCFilterBar for watching its search event.
|
|
381
|
+
*
|
|
382
|
+
* @param filterBar The filter bar
|
|
383
|
+
*/
|
|
384
|
+
;
|
|
385
|
+
|
|
386
|
+
_proto.registerFilterBar = function registerFilterBar(filterBar) {
|
|
387
|
+
filterBar.attachEvent("search", this.onSearch, this);
|
|
388
|
+
|
|
389
|
+
this._aOtherEventSources.push(filterBar);
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
return DataQueryWatcher;
|
|
393
|
+
}();
|
|
394
|
+
|
|
395
|
+
return DataQueryWatcher;
|
|
396
|
+
}, false);
|
|
397
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIkRhdGFRdWVyeVdhdGNoZXIudHMiXSwibmFtZXMiOlsiYm9keSIsInJlY292ZXIiLCJyZXN1bHQiLCJlIiwidGhlbiIsIkRhdGFRdWVyeVdhdGNoZXIiLCJfb0V2ZW50UHJvdmlkZXIiLCJfZm5PbkZpbmlzaGVkIiwiX2FCaW5kaW5nUmVnaXN0cmF0aW9ucyIsIl9hT3RoZXJFdmVudFNvdXJjZXMiLCJfaXNTZWFyY2hQZW5kaW5nIiwiX2FNRENUYWJsZXMiLCJfYU1EQ0NoYXJ0cyIsImlzU2VhcmNoUGVuZGluZyIsImlzRGF0YVJlY2VpdmVkIiwiX2lzRGF0YVJlY2VpdmVkIiwicmVzZXREYXRhUmVjZWl2ZWQiLCJ1bmRlZmluZWQiLCJyZXNldCIsImZvckVhY2giLCJyZWciLCJiaW5kaW5nIiwiZGV0YWNoRXZlbnQiLCJvbkRhdGFSZXF1ZXN0ZWQiLCJvbkRhdGFSZWNlaXZlZCIsIm9FbGVtZW50Iiwib25TZWFyY2giLCJyZWdpc3RlciIsIm9FdmVudCIsInBhcmFtcyIsImdldFNvdXJjZSIsImJpbmRpbmdSZWdpc3RyYXRpb24iLCJmaW5kIiwiTG9nIiwiZXJyb3IiLCJnZXRHcm91cElkIiwiZmlyZUV2ZW50IiwicmVjZWl2ZWRDb3VudCIsInJlcXVlc3RlZENvdW50IiwiYXR0YWNoRXZlbnRPbmNlIiwidHJpZ2dlcmVkQnlTZWFyY2giLCJiQWxsRG9uZSIsInNvbWUiLCJldmVyeSIsImFNRENUYWJsZUxpbmtlZFRvRmlsdGVyQmFyIiwiZmlsdGVyIiwib1RhYmxlIiwic0lkIiwiZ2V0RmlsdGVyIiwiZ2V0VmlzaWJsZSIsImFNRENDaGFydHNMaW5rZWRUb0ZpbHRlckJhciIsIm9DaGFydCIsImxlbmd0aCIsInJlZ2lzdGVyVGFibGUiLCJyZWdpc3RlckNoYXJ0IiwiaW5uZXJDaGFydEJvdW5kUHJvbWlzZSIsIm9FcnJvciIsIl9ldmVudCIsImRhdGEiLCJ0YWJsZSIsImdldFJvd0JpbmRpbmciLCJjaGFydCIsImdldENvbnRyb2xEZWxlZ2F0ZSIsImdldElubmVyQ2hhcnQiLCJnZXRCaW5kaW5nIiwiYm91bmRDb250cm9sIiwicHVzaCIsInJlZ2lzdGVyQmluZGluZyIsImluZGV4T2YiLCJvUm93QmluZGluZyIsIm9Jbm5lckNoYXJ0IiwicmVnaXN0ZXJUYWJsZU9yQ2hhcnQiLCJlbGVtZW50IiwiaXNBIiwiaW5pdGlhbGl6ZWQiLCJyZWdpc3RlckZpbHRlckJhciIsImZpbHRlckJhciIsImF0dGFjaEV2ZW50Il0sIm1hcHBpbmdzIjoiO0FBQUE7QUFDQTtBQUNBOzs7O0FBZ2pCTyxrQkFBZ0JBLElBQWhCLEVBQXNCQyxPQUF0QixFQUErQjtBQUNyQyxRQUFJO0FBQ0gsVUFBSUMsTUFBTSxHQUFHRixJQUFJLEVBQWpCO0FBQ0EsS0FGRCxDQUVFLE9BQU1HLENBQU4sRUFBUztBQUNWLGFBQU9GLE9BQU8sQ0FBQ0UsQ0FBRCxDQUFkO0FBQ0E7O0FBQ0QsUUFBSUQsTUFBTSxJQUFJQSxNQUFNLENBQUNFLElBQXJCLEVBQTJCO0FBQzFCLGFBQU9GLE1BQU0sQ0FBQ0UsSUFBUCxDQUFZLEtBQUssQ0FBakIsRUFBb0JILE9BQXBCLENBQVA7QUFDQTs7QUFDRCxXQUFPQyxNQUFQO0FBQ0E7O01BbmpCS0csZ0I7QUFRTCw4QkFBNkJDLGVBQTdCLEVBQXVFQyxhQUF2RSxFQUFrRztBQUFBLFdBUHhGQyxzQkFPd0YsR0FQZ0MsRUFPaEM7QUFBQSxXQU54RkMsbUJBTXdGLEdBTmpELEVBTWlEO0FBQUEsV0FMeEZDLGdCQUt3RixHQUxyRSxLQUtxRTtBQUFBLFdBSHhGQyxXQUd3RixHQUhqRSxFQUdpRTtBQUFBLFdBRnhGQyxXQUV3RixHQUZqRSxFQUVpRTtBQUFBLFdBQXJFTixlQUFxRSxHQUFyRUEsZUFBcUU7QUFBQSxXQUEzQkMsYUFBMkIsR0FBM0JBLGFBQTJCO0FBQUUsSyxDQUVwRzs7Ozs7V0FDT00sZSxHQUFQLDJCQUF5QjtBQUN4QixhQUFPLEtBQUtILGdCQUFaO0FBQ0EsSzs7V0FDTUksYyxHQUFQLDBCQUF3QjtBQUN2QixhQUFPLEtBQUtDLGVBQVo7QUFD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MkJBQXlCQyxTQUF6QixFQUErQztBQUM5Q0EsTUFBQUEsU0FBUyxDQUFDQyxXQUFWLENBQXNCLFFBQXRCLEVBQWdDLEtBQUtuRCxRQUFyQyxFQUErQyxJQUEvQzs7QUFDQSxXQUFLakIsbUJBQUwsQ0FBeUJ5RCxJQUF6QixDQUE4QlUsU0FBOUI7QUFDQSxLOzs7OztTQUdhdkUsZ0IiLCJzb3VyY2VSb290IjoiLiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBMb2cgZnJvbSBcInNhcC9iYXNlL0xvZ1wiO1xuaW1wb3J0IHR5cGUgRXZlbnQgZnJvbSBcInNhcC91aS9iYXNlL0V2ZW50XCI7XG5pbXBvcnQgRXZlbnRQcm92aWRlciBmcm9tIFwic2FwL3VpL2Jhc2UvRXZlbnRQcm92aWRlclwiO1xuaW1wb3J0IENvbnRyb2wgZnJvbSBcInNhcC91aS9jb3JlL0NvbnRyb2xcIjtcbmltcG9ydCBDaGFydCBmcm9tIFwic2FwL3VpL21kYy9DaGFydFwiO1xuaW1wb3J0IEZpbHRlckJhciBmcm9tIFwic2FwL3VpL21kYy9GaWx0ZXJCYXJcIjtcbmltcG9ydCBUYWJsZSBmcm9tIFwic2FwL3VpL21kYy9UYWJsZVwiO1xuaW1wb3J0IEJpbmRpbmcgZnJvbSBcInNhcC91aS9tb2RlbC9CaW5kaW5nXCI7XG5cbmNsYXNzIERhdGFRdWVyeVdhdGNoZXIge1xuXHRwcm90ZWN0ZWQgX2FCaW5kaW5nUmVnaXN0cmF0aW9uczogeyBiaW5kaW5nOiBCaW5kaW5nOyBib3VuZENvbnRyb2w/OiBDb250cm9sOyByZXF1ZXN0ZWRDb3VudDogbnVtYmVyOyByZWNlaXZlZENvdW50OiBudW1iZXIgfVtdID0gW107XG5cdHByb3RlY3RlZCBfYU90aGVyRXZlbnRTb3VyY2VzOiBFdmVudFByb3ZpZGVyW10gPSBbXTtcblx0cHJvdGVjdGVkIF9pc1NlYXJjaFBlbmRpbmcgPSBmYWxzZTtcblx0cHJvdGVjdGVkIF9pc0RhdGFSZWNlaXZlZD86IGJvb2xlYW47XG5cdHByb3RlY3RlZCBfYU1EQ1RhYmxlczogVGFibGVbXSA9IFtdO1xuXHRwcm90ZWN0ZWQgX2FNRENDaGFydHM6IENoYXJ0W10gPSBbXTtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IocHJvdGVjdGVkIF9vRXZlbnRQcm92aWRlcjogRXZlbnRQcm92aWRlciwgcHJvdGVjdGVkIF9mbk9uRmluaXNoZWQ6ICgpID0+IHZvaWQpIHt9XG5cblx0Ly8gQWNjZXNzb3JzXG5cdHB1YmxpYyBpc1NlYXJjaFBlbmRpbmcoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2lzU2VhcmNoUGVuZGluZztcblx0fVxuXHRwdWJsaWMgaXNEYXRhUmVjZWl2ZWQoKSB7XG5cdFx0cmV0dXJuIHRoaXMuX2lzRGF0YVJlY2VpdmVkO1xuXHR9XG5cdHB1YmxpYyByZXNldERhdGFSZWNlaXZlZCgpIHtcblx0XHR0aGlzLl9pc0RhdGFSZWNlaXZlZCA9IHVuZGVmaW5lZDtcblx0fVxuXG5cdC8qKlxuXHQgKiBSZXNldCB0aGUgc3RhdGU6IHVuc3Vic2NyaWJlIHRvIGFsbCBkYXRhIGV2ZW50cyBhbmQgcmVtb3ZlIGFsbCByZWdpc3RlcmVkIG9iamVjdHMuXG5cdCAqL1xuXHRwdWJsaWMgcmVzZXQoKTogdm9pZCB7XG5cdFx0Ly8gUmVtb3ZlIGFsbCByZW1haW5pbmcgY2FsbGJhY2tzXG5cdFx0dGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLmZvckVhY2goKHJlZykgPT4ge1xuXHRcdFx0cmVnLmJpbmRpbmcuZGV0YWNoRXZlbnQoXCJkYXRhUmVxdWVzdGVkXCIsIHRoaXMub25EYXRhUmVxdWVzdGVkLCB0aGlzKTtcblx0XHRcdHJlZy5iaW5kaW5nLmRldGFjaEV2ZW50KFwiZGF0YVJlY2VpdmVkXCIsIHRoaXMub25EYXRhUmVjZWl2ZWQsIHRoaXMpO1xuXHRcdH0pO1xuXHRcdHRoaXMuX2FPdGhlckV2ZW50U291cmNlcy5mb3JFYWNoKChvRWxlbWVudDogYW55KSA9PiB7XG5cdFx0XHRvRWxlbWVudC5kZXRhY2hFdmVudChcInNlYXJjaFwiLCB0aGlzLm9uU2VhcmNoLCB0aGlzKTtcblx0XHRcdG9FbGVtZW50LmRldGFjaEV2ZW50KFwiYmluZGluZ1VwZGF0ZWRcIiwgdGhpcy5yZWdpc3RlciwgdGhpcyk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLl9hQmluZGluZ1JlZ2lzdHJhdGlvbnMgPSBbXTtcblx0XHR0aGlzLl9hT3RoZXJFdmVudFNvdXJjZXMgPSBbXTtcblx0XHR0aGlzLl9hTURDVGFibGVzID0gW107XG5cdFx0dGhpcy5fYU1EQ0NoYXJ0cyA9IFtdO1xuXHRcdHRoaXMuX2lzU2VhcmNoUGVuZGluZyA9IGZhbHNlO1xuXHRcdHRoaXMuX2lzRGF0YVJlY2VpdmVkID0gdW5kZWZpbmVkO1xuXHR9XG5cblx0Ly8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gQ2FsbGJhY2sgd2hlbiBkYXRhIGlzIHJlY2VpdmVkIG9uIGEgYmluZGluZy5cblx0cHJvdGVjdGVkIG9uRGF0YVJlY2VpdmVkKG9FdmVudDogRXZlbnQsIHBhcmFtczogeyB0cmlnZ2VyZWRCeVNlYXJjaDogYm9vbGVhbiB9KTogdm9pZCB7XG5cdFx0Ly8gTG9vayBmb3IgdGhlIGNvcnJlc3BvbmRpbmcgYmluZGluZyByZWdpc3RyYXRpb25cblx0XHRjb25zdCBiaW5kaW5nID0gb0V2ZW50LmdldFNvdXJjZSgpIGFzIEJpbmRpbmc7XG5cdFx0Y29uc3QgYmluZGluZ1JlZ2lzdHJhdGlvbiA9IHRoaXMuX2FCaW5kaW5nUmVnaXN0cmF0aW9ucy5maW5kKChyZWcpID0+IHtcblx0XHRcdHJldHVybiByZWcuYmluZGluZyA9PT0gYmluZGluZztcblx0XHR9KTtcblx0XHRpZiAoIWJpbmRpbmdSZWdpc3RyYXRpb24pIHtcblx0XHRcdExvZy5lcnJvcihcIlBhZ2VSZWFkeSAtIGRhdGEgcmVjZWl2ZWQgb24gYW4gdW5yZWdpc3RlcmVkIGJpbmRpbmdcIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0c3dpdGNoICgoYmluZGluZyBhcyBhbnkpLmdldEdyb3VwSWQoKSkge1xuXHRcdFx0Y2FzZSBcIiRhdXRvLldvcmtlcnNcIjpcblx0XHRcdFx0dGhpcy5fb0V2ZW50UHJvdmlkZXIuZmlyZUV2ZW50KFwid29ya2Vyc0JhdGNoUmVjZWl2ZWRcIik7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0Y2FzZSBcIiRhdXRvLkhlcm9lc1wiOlxuXHRcdFx0XHR0aGlzLl9vRXZlbnRQcm92aWRlci5maXJlRXZlbnQoXCJoZXJvZXNCYXRjaFJlY2VpdmVkXCIpO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdGRlZmF1bHQ6XG5cdFx0fVxuXHRcdGJpbmRpbmdSZWdpc3RyYXRpb24ucmVjZWl2ZWRDb3VudCsrO1xuXG5cdFx0aWYgKGJpbmRpbmdSZWdpc3RyYXRpb24ucmVjZWl2ZWRDb3VudCA8IGJpbmRpbmdSZWdpc3RyYXRpb24ucmVxdWVzdGVkQ291bnQpIHtcblx0XHRcdC8vIFRoZXJlIGFyZSBvdGhlciByZXF1ZXN0IHBlbmRpbmcgLS0+IHJlc3Vic2NyaWJlIHRvIHdhaXQgdW50aWwgdGhleSByZXR1cm5cblx0XHRcdGJpbmRpbmcuYXR0YWNoRXZlbnRPbmNlKFwiZGF0YVJlY2VpdmVkXCIsIHsgdHJpZ2dlcmVkQnlTZWFyY2g6IHBhcmFtcy50cmlnZ2VyZWRCeVNlYXJjaCB9LCB0aGlzLm9uRGF0YVJlY2VpdmVkLCB0aGlzKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDaGVjayBpZiBhdCBsZWFzdCBvbmUgYmluZGluZyBoYXMgcmVxdWVzdGVkIGRhdGEsIGFuZCBhbGwgYmluZGluZ3MgdGhhdCBoYXZlIHJlcXVlc3RlZCBkYXRhIGhhdmUgcmVjZWl2ZWQgaXRcblx0XHRjb25zdCBiQWxsRG9uZSA9XG5cdFx0XHR0aGlzLl9hQmluZGluZ1JlZ2lzdHJhdGlvbnMuc29tZSgocmVnKSA9PiB7XG5cdFx0XHRcdHJldHVybiByZWcucmVxdWVzdGVkQ291bnQgIT09IDA7XG5cdFx0XHR9KSAmJlxuXHRcdFx0dGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLmV2ZXJ5KChyZWcpID0+IHtcblx0XHRcdFx0cmV0dXJuIHJlZy5yZXF1ZXN0ZWRDb3VudCA9PT0gMCB8fCByZWcucmVjZWl2ZWRDb3VudCA+PSByZWcucmVxdWVzdGVkQ291bnQ7XG5cdFx0XHR9KTtcblxuXHRcdGlmIChwYXJhbXMudHJpZ2dlcmVkQnlTZWFyY2ggfHwgYmluZGluZ1JlZ2lzdHJhdGlvbi5yZWNlaXZlZENvdW50ID49IGJpbmRpbmdSZWdpc3RyYXRpb24ucmVxdWVzdGVkQ291bnQpIHtcblx0XHRcdHRoaXMuX2lzU2VhcmNoUGVuZGluZyA9IGZhbHNlO1xuXHRcdH1cblxuXHRcdGlmIChiQWxsRG9uZSkge1xuXHRcdFx0dGhpcy5faXNEYXRhUmVjZWl2ZWQgPSB0cnVlO1xuXHRcdFx0dGhpcy5fZm5PbkZpbmlzaGVkKCk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblx0Ly8gQ2FsbGJhY2sgd2hlbiBkYXRhIGlzIHJlcXVlc3RlZCBvbiBhIGJpbmRpbmcuXG5cdHByb3RlY3RlZCBvbkRhdGFSZXF1ZXN0ZWQob0V2ZW50OiBFdmVudCwgcGFyYW1zOiB7IHRyaWdnZXJlZEJ5U2VhcmNoOiBib29sZWFuIH0pOiB2b2lkIHtcblx0XHQvLyBMb29rIGZvciB0aGUgY29ycmVzcG9uZGluZyBiaW5kaW5nIHJlZ2lzdHJhdGlvblxuXHRcdGNvbnN0IGJpbmRpbmcgPSBvRXZlbnQuZ2V0U291cmNlKCkgYXMgQmluZGluZztcblx0XHRjb25zdCBiaW5kaW5nUmVnaXN0cmF0aW9uID0gdGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLmZpbmQoKHJlZykgPT4ge1xuXHRcdFx0cmV0dXJuIHJlZy5iaW5kaW5nID09PSBiaW5kaW5nO1xuXHRcdH0pO1xuXHRcdGlmICghYmluZGluZ1JlZ2lzdHJhdGlvbikge1xuXHRcdFx0TG9nLmVycm9yKFwiUGFnZVJlYWR5IC0gZGF0YSByZXF1ZXN0ZWQgb24gYW4gdW5yZWdpc3RlcmVkIGJpbmRpbmdcIik7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0YmluZGluZ1JlZ2lzdHJhdGlvbi5yZXF1ZXN0ZWRDb3VudCsrO1xuXHRcdHRoaXMuX2lzRGF0YVJlY2VpdmVkID0gZmFsc2U7XG5cblx0XHRpZiAoYmluZGluZ1JlZ2lzdHJhdGlvbi5yZXF1ZXN0ZWRDb3VudCAtIGJpbmRpbmdSZWdpc3RyYXRpb24ucmVjZWl2ZWRDb3VudCA9PT0gMSkge1xuXHRcdFx0Ly8gTGlzdGVuIHRvIGRhdGFSZWNlaXZlZCBvbmx5IGlmIHRoZXJlJ3Mgbm8gb3RoZXIgcmVxdWVzdCBwZW5kaW5nXG5cdFx0XHQvLyBPdGhlcndpc2UgdGhlICdkYXRhUmVjZWl2ZWQnIGhhbmRsZXIgd291bGQgYmUgY2FsbGVkIHNldmVyYWwgdGltZXMgd2hlbiB0aGUgZmlyc3QgcXVlcnkgcmV0dXJuc1xuXHRcdFx0Ly8gYW5kIHdlIHdvdWxkbid0IHdhaXQgZm9yIGFsbCBxdWVyaWVzIHRvIGJlIGZpbmlzaGVkXG5cdFx0XHQvLyAod2Ugd2lsbCByZXN1YnNjcmliZSB0byB0aGUgZGF0YVJlY2VpdmVkIGV2ZW50IGluIG9uRGF0YVJlY2VpdmVkIGlmIG5lY2Vzc2FyeSlcblx0XHRcdGJpbmRpbmcuYXR0YWNoRXZlbnRPbmNlKFwiZGF0YVJlY2VpdmVkXCIsIHsgdHJpZ2dlcmVkQnlTZWFyY2g6IHBhcmFtcy50cmlnZ2VyZWRCeVNlYXJjaCB9LCB0aGlzLm9uRGF0YVJlY2VpdmVkLCB0aGlzKTtcblx0XHR9XG5cdH1cblxuXHQvLyAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXHQvLyBDYWxsYmFjayB3aGVuIGEgc2VhcmNoIGlzIHRyaWdnZXJlZCBmcm9tIGEgZmlsdGVyYmFyXG5cdHByb3RlY3RlZCBvblNlYXJjaChvRXZlbnQ6IEV2ZW50KTogdm9pZCB7XG5cdFx0Y29uc3QgYU1EQ1RhYmxlTGlua2VkVG9GaWx0ZXJCYXIgPSB0aGlzLl9hTURDVGFibGVzLmZpbHRlcigob1RhYmxlKSA9PiB7XG5cdFx0XHRyZXR1cm4gKG9FdmVudC5nZXRTb3VyY2UoKSBhcyBhbnkpLnNJZCA9PT0gb1RhYmxlLmdldEZpbHRlcigpICYmIG9UYWJsZS5nZXRWaXNpYmxlKCk7XG5cdFx0fSk7XG5cdFx0Y29uc3QgYU1EQ0NoYXJ0c0xpbmtlZFRvRmlsdGVyQmFyID0gdGhpcy5fYU1EQ0NoYXJ0cy5maWx0ZXIoKG9DaGFydCkgPT4ge1xuXHRcdFx0cmV0dXJuIChvRXZlbnQuZ2V0U291cmNlKCkgYXMgYW55KS5zSWQgPT09IG9DaGFydC5nZXRGaWx0ZXIoKSAmJiBvQ2hhcnQuZ2V0VmlzaWJsZSgpO1xuXHRcdH0pO1xuXG5cdFx0aWYgKGFNRENUYWJsZUxpbmtlZFRvRmlsdGVyQmFyLmxlbmd0aCA+IDAgfHwgYU1EQ0NoYXJ0c0xpbmtlZFRvRmlsdGVyQmFyLmxlbmd0aCA+IDApIHtcblx0XHRcdHRoaXMuX2lzU2VhcmNoUGVuZGluZyA9IHRydWU7XG5cdFx0fVxuXHRcdGFNRENUYWJsZUxpbmtlZFRvRmlsdGVyQmFyLmZvckVhY2goKG9UYWJsZSkgPT4ge1xuXHRcdFx0dGhpcy5yZWdpc3RlclRhYmxlKG9UYWJsZSwgdHJ1ZSk7XG5cdFx0fSk7XG5cdFx0YU1EQ0NoYXJ0c0xpbmtlZFRvRmlsdGVyQmFyLmZvckVhY2goYXN5bmMgKG9DaGFydDogYW55KSA9PiB7XG5cdFx0XHR0cnkge1xuXHRcdFx0XHRpZiAob0NoYXJ0LmlubmVyQ2hhcnRCb3VuZFByb21pc2UpIHtcblx0XHRcdFx0XHRhd2FpdCBvQ2hhcnQuaW5uZXJDaGFydEJvdW5kUHJvbWlzZTtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnJlZ2lzdGVyQ2hhcnQob0NoYXJ0LCB0cnVlKTtcblx0XHRcdH0gY2F0Y2ggKG9FcnJvcjogYW55KSB7XG5cdFx0XHRcdExvZy5lcnJvcihcIkNhbm5vdCBmaW5kIGEgaW5uZXIgYm91bmQgY2hhcnRcIiwgb0Vycm9yKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8vIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cdC8vIFJlZ2lzdGVyIGEgYmluZGluZyAod2l0aCBhbiBvcHRpb25hbCB0YWJsZS9jaGFydClcblx0Ly8gYW5kIGF0dGFjaCBjYWxsYmFja3Mgb24gZGF0ZVJlcXVlc3RlZC9kYXRhUmVjZWl2ZWQgZXZlbnRzXG5cdHByb3RlY3RlZCByZWdpc3RlcihfZXZlbnQ6IEV2ZW50IHwgbnVsbCwgZGF0YTogeyBiaW5kaW5nPzogQmluZGluZzsgdGFibGU/OiBUYWJsZTsgY2hhcnQ/OiBDaGFydDsgdHJpZ2dlcmVkQnlTZWFyY2g6IGJvb2xlYW4gfSk6IHZvaWQge1xuXHRcdGNvbnN0IGJpbmRpbmc6IEJpbmRpbmcgfCB1bmRlZmluZWQgPVxuXHRcdFx0ZGF0YS5iaW5kaW5nIHx8XG5cdFx0XHRkYXRhLnRhYmxlPy5nZXRSb3dCaW5kaW5nKCkgfHxcblx0XHRcdChkYXRhLmNoYXJ0IGFzIGFueSk/LmdldENvbnRyb2xEZWxlZ2F0ZSgpLmdldElubmVyQ2hhcnQoZGF0YS5jaGFydCkuZ2V0QmluZGluZyhcImRhdGFcIik7XG5cdFx0Y29uc3QgYm91bmRDb250cm9sID0gKGRhdGEudGFibGUgfHwgZGF0YS5jaGFydCkgYXMgQ29udHJvbCB8IHVuZGVmaW5lZDtcblxuXHRcdGlmICghYmluZGluZykge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIENoZWNrIGlmIHRoZSBiaW5kaW5nIGlzIGFscmVhZHkgcmVnaXN0ZXJlZFxuXHRcdGxldCBiaW5kaW5nUmVnaXN0cmF0aW9uID0gdGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLmZpbmQoKHJlZykgPT4ge1xuXHRcdFx0cmV0dXJuIHJlZy5iaW5kaW5nID09PSBiaW5kaW5nO1xuXHRcdH0pO1xuXHRcdGlmIChiaW5kaW5nUmVnaXN0cmF0aW9uKSB7XG5cdFx0XHRpZiAoYm91bmRDb250cm9sKSB7XG5cdFx0XHRcdC8vIFRoZSBiaW5kaW5nIHdhcyBhbHJlYWR5IHJlZ2lzdGVyZCB3aXRob3V0IGJvdW5kQ29udHJvbCBpbmZvcm1hdGlvbiAtLT4gdXBkYXRlIGJvdW5kQ29udHJvbFxuXHRcdFx0XHRiaW5kaW5nUmVnaXN0cmF0aW9uLmJvdW5kQ29udHJvbCA9IGJvdW5kQ29udHJvbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVGhpcyBiaW5kaW5nIGhhcyBhbHJlYWR5IHJlcXVlc3RlZCBkYXRhLCBidXQgd2UncmUgcmVnaXN0ZXJpbmcgaXQgYWdhaW4gKG9uIHNlYXJjaCkgLS0+IGF0dGFjaCB0byBkYXRhUmVxdWVzdGVkIGFnYWluXG5cdFx0XHRpZiAoYmluZGluZ1JlZ2lzdHJhdGlvbi5yZXF1ZXN0ZWRDb3VudCA+IDApIHtcblx0XHRcdFx0YmluZGluZy5hdHRhY2hFdmVudE9uY2UoXCJkYXRhUmVxdWVzdGVkXCIsIHsgdHJpZ2dlcmVkQnlTZWFyY2g6IGRhdGEudHJpZ2dlcmVkQnlTZWFyY2ggfSwgdGhpcy5vbkRhdGFSZXF1ZXN0ZWQsIHRoaXMpO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aWYgKGJvdW5kQ29udHJvbCkge1xuXHRcdFx0Ly8gQ2hlY2sgaWYgdGhlcmUncyBhIGRpZmZlcmVudCBiaW5kaW5nIHJlZ2lzdGVyZWQgZm9yIHRoZSBib3VuZCBjb250cm9sXG5cdFx0XHRiaW5kaW5nUmVnaXN0cmF0aW9uID0gdGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLmZpbmQoKHJlZykgPT4ge1xuXHRcdFx0XHRyZXR1cm4gcmVnLmJvdW5kQ29udHJvbCA9PT0gYm91bmRDb250cm9sO1xuXHRcdFx0fSk7XG5cdFx0XHRpZiAoYmluZGluZ1JlZ2lzdHJhdGlvbiAmJiBiaW5kaW5nUmVnaXN0cmF0aW9uLmJpbmRpbmcgIT09IGJpbmRpbmcpIHtcblx0XHRcdFx0Ly8gVGhlIGNvbnRyb2wgaGFkIGEgZGlmZmVyZW50IGJpbmRpbmcuIFRoaXMgY2FuIGhhcHBlbiBpbiBjYXNlIG9mIE1EQyBjaGFydHMgd2hvIHJlY3JlYXRlZCB0aGVpciBiaW5kaW5nIGFmdGVyIHNlYXJjaFxuXHRcdFx0XHQvLyBUaGUgcHJldmlvdXMgYmluZGluZyBpcyBkZXN0cm95ZWQsIHdlIGNhbiByZXBsYWNlIGl0IHdpdGggdGhlIG5ldyBhbmQgcmVzZXQgY291bnRlcnNcblx0XHRcdFx0YmluZGluZ1JlZ2lzdHJhdGlvbi5iaW5kaW5nID0gYmluZGluZztcblx0XHRcdFx0YmluZGluZ1JlZ2lzdHJhdGlvbi5yZXF1ZXN0ZWRDb3VudCA9IDA7XG5cdFx0XHRcdGJpbmRpbmdSZWdpc3RyYXRpb24ucmVjZWl2ZWRDb3VudCA9IDA7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlmICghYmluZGluZ1JlZ2lzdHJhdGlvbikge1xuXHRcdFx0YmluZGluZ1JlZ2lzdHJhdGlvbiA9IHtcblx0XHRcdFx0YmluZGluZzogYmluZGluZyxcblx0XHRcdFx0Ym91bmRDb250cm9sOiBib3VuZENvbnRyb2wsXG5cdFx0XHRcdHJlcXVlc3RlZENvdW50OiAwLFxuXHRcdFx0XHRyZWNlaXZlZENvdW50OiAwXG5cdFx0XHR9O1xuXHRcdFx0dGhpcy5fYUJpbmRpbmdSZWdpc3RyYXRpb25zLnB1c2goYmluZGluZ1JlZ2lzdHJhdGlvbik7XG5cdFx0fVxuXG5cdFx0YmluZGluZy5hdHRhY2hFdmVudE9uY2UoXCJkYXRhUmVxdWVzdGVkXCIsIHsgdHJpZ2dlcmVkQnlTZWFyY2g6IGRhdGEudHJpZ2dlcmVkQnlTZWFyY2ggfSwgdGhpcy5vbkRhdGFSZXF1ZXN0ZWQsIHRoaXMpO1xuXHR9XG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyBhIGJpbmRpbmcgZm9yIHdhdGNoaW5nIGl0cyBkYXRhIGV2ZW50cyAoZGF0YVJlcXVlc3RlZCBhbmQgZGF0YVJlY2VpdmVkKS5cblx0ICpcblx0ICogQHBhcmFtIGJpbmRpbmcgVGhlIGJpbmRpbmdcblx0ICovXG5cdHB1YmxpYyByZWdpc3RlckJpbmRpbmcoYmluZGluZzogQmluZGluZykge1xuXHRcdHRoaXMucmVnaXN0ZXIobnVsbCwgeyBiaW5kaW5nLCB0cmlnZ2VyZWRCeVNlYXJjaDogZmFsc2UgfSk7XG5cdH1cblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIGFuIE1EQ1RhYmxlIGZvciB3YXRjaGluZyB0aGUgZGF0YSBldmVudHMgb24gaXRzIHJvdyBiaW5kaW5nIChkYXRhUmVxdWVzdGVkIGFuZCBkYXRhUmVjZWl2ZWQpLlxuXHQgKlxuXHQgKiBAcGFyYW0gdGFibGUgVGhlIHRhYmxlXG5cdCAqIEBwYXJhbSB0cmlnZ2VyZWRCeVNlYXJjaCBUcnVlIGlmIHRoaXMgcmVnaXN0cmF0aW9uIGlzIHRyaWdnZXJlZCBieSBhIGZpbHRlckJhciBzZWFyY2hcblx0ICovXG5cdHByb3RlY3RlZCByZWdpc3RlclRhYmxlKHRhYmxlOiBUYWJsZSwgdHJpZ2dlcmVkQnlTZWFyY2ggPSBmYWxzZSkge1xuXHRcdGlmICh0aGlzLl9hTURDVGFibGVzLmluZGV4T2YodGFibGUpIDwgMCkge1xuXHRcdFx0dGhpcy5fYU1EQ1RhYmxlcy5wdXNoKHRhYmxlKTtcblx0XHR9XG5cdFx0Y29uc3Qgb1Jvd0JpbmRpbmcgPSB0YWJsZS5nZXRSb3dCaW5kaW5nKCk7XG5cdFx0aWYgKG9Sb3dCaW5kaW5nKSB7XG5cdFx0XHR0aGlzLnJlZ2lzdGVyKG51bGwsIHsgdGFibGUsIHRyaWdnZXJlZEJ5U2VhcmNoIH0pO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0YWJsZS5hdHRhY2hFdmVudE9uY2UoXCJiaW5kaW5nVXBkYXRlZFwiLCB7IHRhYmxlLCB0cmlnZ2VyZWRCeVNlYXJjaCB9LCB0aGlzLnJlZ2lzdGVyLCB0aGlzKTtcblx0XHRcdHRoaXMuX2FPdGhlckV2ZW50U291cmNlcy5wdXNoKHRhYmxlKTtcblx0XHR9XG5cdH1cblxuXHQvKipcblx0ICogUmVnaXN0ZXJzIGFuIE1EQ0NoYXJ0IGZvciB3YXRjaGluZyB0aGUgZGF0YSBldmVudHMgb24gaXRzIGlubmVyIGRhdGEgYmluZGluZyAoZGF0YVJlcXVlc3RlZCBhbmQgZGF0YVJlY2VpdmVkKS5cblx0ICpcblx0ICogQHBhcmFtIGNoYXJ0IFRoZSBjaGFydFxuXHQgKiBAcGFyYW0gdHJpZ2dlcmVkQnlTZWFyY2ggVHJ1ZSBpZiB0aGlzIHJlZ2lzdHJhdGlvbiBpcyB0cmlnZ2VyZWQgYnkgYSBmaWx0ZXIgYmFyIHNlYXJjaFxuXHQgKi9cblx0cHJvdGVjdGVkIHJlZ2lzdGVyQ2hhcnQoY2hhcnQ6IENoYXJ0LCB0cmlnZ2VyZWRCeVNlYXJjaCA9IGZhbHNlKSB7XG5cdFx0aWYgKHRoaXMuX2FNRENDaGFydHMuaW5kZXhPZihjaGFydCkgPCAwKSB7XG5cdFx0XHR0aGlzLl9hTURDQ2hhcnRzLnB1c2goY2hhcnQpO1xuXHRcdH1cblxuXHRcdGNvbnN0IG9Jbm5lckNoYXJ0ID0gKGNoYXJ0IGFzIGFueSkuZ2V0Q29udHJvbERlbGVnYXRlKCkuZ2V0SW5uZXJDaGFydChjaGFydCk7XG5cdFx0Y29uc3QgYmluZGluZyA9IG9Jbm5lckNoYXJ0Py5nZXRCaW5kaW5nKFwiZGF0YVwiKTtcblx0XHRpZiAoYmluZGluZykge1xuXHRcdFx0dGhpcy5yZWdpc3RlcihudWxsLCB7IGNoYXJ0LCB0cmlnZ2VyZWRCeVNlYXJjaCB9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Y2hhcnQuYXR0YWNoRXZlbnRPbmNlKFwiYmluZGluZ1VwZGF0ZWRcIiwgeyBjaGFydCwgdHJpZ2dlcmVkQnlTZWFyY2ggfSwgdGhpcy5yZWdpc3RlciwgdGhpcyk7XG5cdFx0XHR0aGlzLl9hT3RoZXJFdmVudFNvdXJjZXMucHVzaChjaGFydCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIFJlZ2lzdGVycyBhbiBNRENUYWJsZSBvciBNRENDaGFydCBmb3Igd2F0Y2hpbmcgdGhlIGRhdGEgZXZlbnRzIG9uIGl0cyBpbm5lciBkYXRhIGJpbmRpbmcgKGRhdGFSZXF1ZXN0ZWQgYW5kIGRhdGFSZWNlaXZlZCkuXG5cdCAqXG5cdCAqIEBwYXJhbSBlbGVtZW50ICBUaGUgdGFibGUgb3IgY2NoYXJ0XG5cdCAqL1xuXHRwdWJsaWMgYXN5bmMgcmVnaXN0ZXJUYWJsZU9yQ2hhcnQoZWxlbWVudDogVGFibGUgfCBDaGFydCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGlmICghZWxlbWVudC5pc0EoXCJzYXAudWkubWRjLlRhYmxlXCIpICYmICFlbGVtZW50LmlzQShcInNhcC51aS5tZGMuQ2hhcnRcIikpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgZWxlbWVudC5pbml0aWFsaXplZCgpOyAvLyBhY2Nlc3MgYmluZGluZyBvbmx5IGFmdGVyIHRhYmxlL2NoYXJ0IGlzIGJvdW5kXG5cdFx0XHRpZiAoZWxlbWVudC5pc0EoXCJzYXAudWkubWRjLlRhYmxlXCIpKSB7XG5cdFx0XHRcdHRoaXMucmVnaXN0ZXJUYWJsZShlbGVtZW50IGFzIFRhYmxlKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMucmVnaXN0ZXJDaGFydChlbGVtZW50IGFzIENoYXJ0KTtcblx0XHRcdH1cblx0XHR9IGNhdGNoIChvRXJyb3I6IGFueSkge1xuXHRcdFx0TG9nLmVycm9yKFwiUGFnZVJlYWR5IC0gQ2Fubm90IHJlZ2lzdGVyIGEgdGFibGUgb3IgYSBjaGFydFwiLCBvRXJyb3IpO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBSZWdpc3RlcnMgYW4gTURDRmlsdGVyQmFyIGZvciB3YXRjaGluZyBpdHMgc2VhcmNoIGV2ZW50LlxuXHQgKlxuXHQgKiBAcGFyYW0gZmlsdGVyQmFyIFRoZSBmaWx0ZXIgYmFyXG5cdCAqL1xuXHRwdWJsaWMgcmVnaXN0ZXJGaWx0ZXJCYXIoZmlsdGVyQmFyOiBGaWx0ZXJCYXIpIHtcblx0XHRmaWx0ZXJCYXIuYXR0YWNoRXZlbnQoXCJzZWFyY2hcIiwgdGhpcy5vblNlYXJjaCwgdGhpcyk7XG5cdFx0dGhpcy5fYU90aGVyRXZlbnRTb3VyY2VzLnB1c2goZmlsdGVyQmFyKTtcblx0fVxufVxuXG5leHBvcnQgZGVmYXVsdCBEYXRhUXVlcnlXYXRjaGVyO1xuIl19
|