@flowmap.gl/layers 8.0.0-alpha.0 → 8.0.0-alpha.12

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.
@@ -1,304 +0,0 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- /*
11
- * Copyright 2022 FlowmapBlue
12
- *
13
- * Licensed under the Apache License, Version 2.0 (the "License");
14
- * you may not use this file except in compliance with the License.
15
- * You may obtain a copy of the License at
16
- *
17
- * http://www.apache.org/licenses/LICENSE-2.0
18
- *
19
- * Unless required by applicable law or agreed to in writing, software
20
- * distributed under the License is distributed on an "AS IS" BASIS,
21
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
- * See the License for the specific language governing permissions and
23
- * limitations under the License.
24
- *
25
- */
26
- import { CompositeLayer } from '@deck.gl/core';
27
- import { ScatterplotLayer } from '@deck.gl/layers';
28
- import { colorAsRgba, getFlowLineAttributesByIndex, getFlowMapColors, getOuterCircleRadiusByIndex, getLocationCentroidByIndex, isFlowMapData, isFlowMapDataProvider, LocalFlowMapDataProvider, LocationFilterMode, FlowMapAggregateAccessors, } from '@flowmap.gl/data';
29
- import AnimatedFlowLinesLayer from './AnimatedFlowLinesLayer';
30
- import FlowCirclesLayer from './FlowCirclesLayer';
31
- import FlowLinesLayer from './FlowLinesLayer';
32
- import { PickingType, } from './types';
33
- var HighlightType;
34
- (function (HighlightType) {
35
- HighlightType["LOCATION"] = "location";
36
- HighlightType["FLOW"] = "flow";
37
- })(HighlightType || (HighlightType = {}));
38
- export default class FlowMapLayer extends CompositeLayer {
39
- constructor(props) {
40
- super(Object.assign(Object.assign({}, props), { onHover: (info, event) => {
41
- // TODO: if (lastHoverEventStartTimeRef > startTime) {
42
- // // Skipping, because this is not the latest hover event
43
- // return;
44
- // }
45
- this.setState({ highlightedObject: this._getHighlightedObject(info) });
46
- const { onHover } = props;
47
- if (onHover) {
48
- this._getFlowLayerPickingInfo(info).then((info) => onHover(info, event));
49
- }
50
- }, onClick: (info, event) => {
51
- const { onClick } = props;
52
- if (onClick) {
53
- this._getFlowLayerPickingInfo(info).then((info) => {
54
- if (info) {
55
- onClick(info, event);
56
- }
57
- });
58
- }
59
- } }));
60
- }
61
- initializeState() {
62
- this.state = {
63
- accessors: new FlowMapAggregateAccessors(this.props),
64
- dataProvider: this._makeDataProvider(),
65
- layersData: undefined,
66
- highlightedObject: undefined,
67
- };
68
- }
69
- _updateAccessors() {
70
- var _a, _b;
71
- (_b = (_a = this.state) === null || _a === void 0 ? void 0 : _a.dataProvider) === null || _b === void 0 ? void 0 : _b.setAccessors(this.props);
72
- this.setState({ accessors: new FlowMapAggregateAccessors(this.props) });
73
- }
74
- _makeDataProvider() {
75
- const { data } = this.props;
76
- if (isFlowMapDataProvider(data)) {
77
- return data;
78
- }
79
- else if (isFlowMapData(data)) {
80
- const dataProvider = new LocalFlowMapDataProvider(this.props);
81
- dataProvider.setFlowMapData(data);
82
- return dataProvider;
83
- }
84
- throw new Error('FlowMapLayer: data must be a FlowMapDataProvider or FlowMapData');
85
- }
86
- _updateDataProvider() {
87
- this.setState({ dataProvider: this._makeDataProvider() });
88
- }
89
- shouldUpdateState(params) {
90
- const { changeFlags } = params;
91
- // if (this._viewportChanged()) {
92
- // return true;
93
- // }
94
- if (changeFlags.viewportChanged) {
95
- return true;
96
- }
97
- return super.shouldUpdateState(params);
98
- // TODO: be smarter on when to update
99
- // (e.g. ignore viewport changes when adaptiveScalesEnabled and clustering are false)
100
- }
101
- updateState({ oldProps, props, changeFlags }) {
102
- const { dataProvider, highlightedObject } = this.state || {};
103
- if (!dataProvider) {
104
- return;
105
- }
106
- if (changeFlags.propsChanged) {
107
- this._updateAccessors();
108
- }
109
- if (changeFlags.dataChanged) {
110
- this._updateDataProvider();
111
- }
112
- if (changeFlags.viewportChanged || changeFlags.propsOrDataChanged) {
113
- dataProvider.setFlowMapState(this._getFlowMapState());
114
- (() => __awaiter(this, void 0, void 0, function* () {
115
- const layersData = yield dataProvider.getLayersData();
116
- this.setState({ layersData });
117
- }))();
118
- }
119
- }
120
- _getSettingsState() {
121
- const { locationTotalsEnabled, adaptiveScalesEnabled, animationEnabled, clusteringEnabled, clusteringLevel, fadeEnabled, clusteringAuto, darkMode, fadeAmount, colorScheme, } = this.props;
122
- return {
123
- locationTotalsEnabled,
124
- adaptiveScalesEnabled,
125
- animationEnabled,
126
- clusteringEnabled,
127
- clusteringLevel,
128
- fadeEnabled,
129
- clusteringAuto,
130
- darkMode,
131
- fadeAmount,
132
- colorScheme,
133
- };
134
- }
135
- _getFlowMapState() {
136
- return {
137
- viewport: asViewState(this.context.viewport),
138
- filterState: {
139
- selectedLocations: undefined,
140
- locationFilterMode: LocationFilterMode.ALL,
141
- selectedTimeRange: undefined,
142
- },
143
- settingsState: this._getSettingsState(),
144
- };
145
- }
146
- _getFlowLayerPickingInfo(info) {
147
- var _a;
148
- return __awaiter(this, void 0, void 0, function* () {
149
- const { index, sourceLayer } = info;
150
- const { dataProvider, accessors } = this.state || {};
151
- if (!dataProvider || !accessors) {
152
- return undefined;
153
- }
154
- const commonInfo = {
155
- // ...info,
156
- layer: info.layer,
157
- index: info.index,
158
- x: info.x,
159
- y: info.y,
160
- coordinate: info.coordinate,
161
- };
162
- if (sourceLayer instanceof FlowLinesLayer ||
163
- sourceLayer instanceof AnimatedFlowLinesLayer) {
164
- const flow = index === -1 ? undefined : yield dataProvider.getFlowByIndex(index);
165
- if (flow) {
166
- const origin = yield dataProvider.getLocationById(accessors.getFlowOriginId(flow));
167
- const dest = yield dataProvider.getLocationById(accessors.getFlowDestId(flow));
168
- if (origin && dest) {
169
- return Object.assign(Object.assign({}, commonInfo), { type: PickingType.FLOW, object: flow, origin: origin, dest: dest, count: accessors.getFlowMagnitude(flow) });
170
- }
171
- }
172
- }
173
- else if (sourceLayer instanceof FlowCirclesLayer) {
174
- const location = index === -1 ? undefined : yield dataProvider.getLocationByIndex(index);
175
- if (location) {
176
- const id = accessors.getLocationId(location);
177
- const name = accessors.getLocationName(location);
178
- const totals = yield dataProvider.getTotalsForLocation(id);
179
- const { circleAttributes } = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) || {};
180
- if (totals && circleAttributes) {
181
- const circleRadius = getOuterCircleRadiusByIndex(circleAttributes, info.index);
182
- return Object.assign(Object.assign({}, commonInfo), { type: PickingType.LOCATION, object: location, id,
183
- name,
184
- totals, circleRadius: circleRadius, event: undefined });
185
- }
186
- }
187
- }
188
- return undefined;
189
- });
190
- }
191
- _getHighlightedObject(info) {
192
- var _a, _b;
193
- const { index, sourceLayer } = info;
194
- if (index < 0)
195
- return undefined;
196
- if (sourceLayer instanceof FlowLinesLayer ||
197
- sourceLayer instanceof AnimatedFlowLinesLayer) {
198
- const { lineAttributes } = ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) || {};
199
- if (lineAttributes) {
200
- return {
201
- type: HighlightType.FLOW,
202
- lineAttributes: getFlowLineAttributesByIndex(lineAttributes, index),
203
- };
204
- }
205
- }
206
- else if (sourceLayer instanceof FlowCirclesLayer) {
207
- const { circleAttributes } = ((_b = this.state) === null || _b === void 0 ? void 0 : _b.layersData) || {};
208
- if (circleAttributes) {
209
- return {
210
- type: HighlightType.LOCATION,
211
- centroid: getLocationCentroidByIndex(circleAttributes, index),
212
- radius: getOuterCircleRadiusByIndex(circleAttributes, index),
213
- };
214
- }
215
- }
216
- return undefined;
217
- }
218
- renderLayers() {
219
- var _a;
220
- const layers = [];
221
- if ((_a = this.state) === null || _a === void 0 ? void 0 : _a.layersData) {
222
- const { layersData, highlightedObject } = this.state;
223
- const { circleAttributes, lineAttributes } = layersData || {};
224
- if (circleAttributes && lineAttributes) {
225
- const flowMapColors = getFlowMapColors(this._getSettingsState());
226
- const outlineColor = colorAsRgba(flowMapColors.outlineColor || (this.props.darkMode ? '#000' : '#fff'));
227
- const commonLineLayerProps = {
228
- data: lineAttributes,
229
- parameters: {
230
- // prevent z-fighting at non-zero bearing/pitch
231
- depthTest: false,
232
- },
233
- };
234
- if (this.props.animationEnabled) {
235
- layers.push(
236
- // @ts-ignore
237
- new AnimatedFlowLinesLayer(Object.assign({}, this.getSubLayerProps(Object.assign(Object.assign({}, commonLineLayerProps), { id: 'animated-flow-lines', drawOutline: false, thicknessUnit: 20 })))));
238
- }
239
- else {
240
- layers.push(new FlowLinesLayer(Object.assign({}, this.getSubLayerProps(Object.assign(Object.assign({}, commonLineLayerProps), { id: 'flow-lines', drawOutline: true, outlineColor: outlineColor })))));
241
- }
242
- layers.push(new FlowCirclesLayer(this.getSubLayerProps({
243
- id: 'circles',
244
- data: circleAttributes,
245
- emptyColor: [0, 0, 0, 255],
246
- emptyOutlineColor: [0, 0, 0, 255],
247
- })));
248
- if (highlightedObject) {
249
- switch (highlightedObject.type) {
250
- case HighlightType.LOCATION:
251
- layers.push(new ScatterplotLayer({
252
- id: 'location-highlight',
253
- data: [highlightedObject],
254
- stroked: true,
255
- filled: false,
256
- lineWidthUnits: 'pixels',
257
- getLineWidth: 2,
258
- radiusUnits: 'pixels',
259
- getRadius: (d) => d.radius,
260
- getLineColor: (d) => colorAsRgba('orange'),
261
- getPosition: (d) => d.centroid,
262
- }));
263
- break;
264
- case HighlightType.FLOW:
265
- layers.push(new FlowLinesLayer({
266
- id: 'flow-highlight',
267
- data: highlightedObject.lineAttributes,
268
- drawOutline: true,
269
- outlineColor: colorAsRgba('orange'),
270
- outlineThickness: 1,
271
- }));
272
- break;
273
- }
274
- }
275
- }
276
- }
277
- return layers;
278
- }
279
- }
280
- FlowMapLayer.defaultProps = {
281
- darkMode: true,
282
- fadeAmount: 50,
283
- locationTotalsEnabled: true,
284
- animationEnabled: false,
285
- clusteringEnabled: true,
286
- fadeEnabled: true,
287
- clusteringAuto: true,
288
- clusteringLevel: undefined,
289
- adaptiveScalesEnabled: true,
290
- colorScheme: 'Teal',
291
- };
292
- function asViewState(viewport) {
293
- const { width, height, longitude, latitude, zoom, pitch, bearing } = viewport;
294
- return {
295
- width,
296
- height,
297
- longitude,
298
- latitude,
299
- zoom,
300
- pitch,
301
- bearing,
302
- };
303
- }
304
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd01hcExheWVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL0Zsb3dNYXBMYXllci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFDSCxPQUFPLEVBQUMsY0FBYyxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQzdDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBQ2pELE9BQU8sRUFDTCxXQUFXLEVBS1gsNEJBQTRCLEVBQzVCLGdCQUFnQixFQUNoQiwyQkFBMkIsRUFDM0IsMEJBQTBCLEVBQzFCLGFBQWEsRUFDYixxQkFBcUIsRUFFckIsd0JBQXdCLEVBQ3hCLGtCQUFrQixFQUVsQix5QkFBeUIsR0FHMUIsTUFBTSxrQkFBa0IsQ0FBQztBQUMxQixPQUFPLHNCQUFzQixNQUFNLDBCQUEwQixDQUFDO0FBQzlELE9BQU8sZ0JBQWdCLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxjQUFjLE1BQU0sa0JBQWtCLENBQUM7QUFDOUMsT0FBTyxFQUlMLFdBQVcsR0FDWixNQUFNLFNBQVMsQ0FBQztBQXNCakIsSUFBSyxhQUdKO0FBSEQsV0FBSyxhQUFhO0lBQ2hCLHNDQUFxQixDQUFBO0lBQ3JCLDhCQUFhLENBQUE7QUFDZixDQUFDLEVBSEksYUFBYSxLQUFiLGFBQWEsUUFHakI7QUF3QkQsTUFBTSxDQUFDLE9BQU8sT0FBTyxZQUFtQixTQUFRLGNBQWM7SUFlNUQsWUFBbUIsS0FBOEI7UUFDL0MsS0FBSyxpQ0FDQSxLQUFLLEtBQ1IsT0FBTyxFQUFFLENBQUMsSUFBc0IsRUFBRSxLQUFrQixFQUFFLEVBQUU7Z0JBQ3RELHNEQUFzRDtnQkFDdEQsNERBQTREO2dCQUM1RCxZQUFZO2dCQUNaLElBQUk7Z0JBQ0osSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsRUFBQyxDQUFD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QztJQUNoQixDQUFDOztBQWpWTSx5QkFBWSxHQUFHO0lBQ3BCLFFBQVEsRUFBRSxJQUFJO0lBQ2QsVUFBVSxFQUFFLEVBQUU7SUFDZCxxQkFBcUIsRUFBRSxJQUFJO0lBQzNCLGdCQUFnQixFQUFFLEtBQUs7SUFDdkIsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixXQUFXLEVBQUUsSUFBSTtJQUNqQixjQUFjLEVBQUUsSUFBSTtJQUNwQixlQUFlLEVBQUUsU0FBUztJQUMxQixxQkFBcUIsRUFBRSxJQUFJO0lBQzNCLFdBQVcsRUFBRSxNQUFNO0NBQ3BCLENBQUM7QUF5VUosU0FBUyxXQUFXLENBQUMsUUFBNkI7SUFDaEQsTUFBTSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBQyxHQUFHLFFBQVEsQ0FBQztJQUM1RSxPQUFPO1FBQ0wsS0FBSztRQUNMLE1BQU07UUFDTixTQUFTO1FBQ1QsUUFBUTtRQUNSLElBQUk7UUFDSixLQUFLO1FBQ0wsT0FBTztLQUNSLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIENvcHlyaWdodCAyMDIyIEZsb3dtYXBCbHVlXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG5pbXBvcnQge0NvbXBvc2l0ZUxheWVyfSBmcm9tICdAZGVjay5nbC9jb3JlJztcbmltcG9ydCB7U2NhdHRlcnBsb3RMYXllcn0gZnJvbSAnQGRlY2suZ2wvbGF5ZXJzJztcbmltcG9ydCB7XG4gIGNvbG9yQXNSZ2JhLFxuICBGbG93TGluZXNMYXllckF0dHJpYnV0ZXMsXG4gIEZsb3dNYXBEYXRhLFxuICBGbG93TWFwRGF0YUFjY2Vzc29ycyxcbiAgRmxvd01hcERhdGFQcm92aWRlcixcbiAgZ2V0Rmxvd0xpbmVBdHRyaWJ1dGVzQnlJbmRleCxcbiAgZ2V0Rmxvd01hcENvbG9ycyxcbiAgZ2V0T3V0ZXJDaXJjbGVSYWRpdXNCeUluZGV4LFxuICBnZXRMb2NhdGlvbkNlbnRyb2lkQnlJbmRleCxcbiAgaXNGbG93TWFwRGF0YSxcbiAgaXNGbG93TWFwRGF0YVByb3ZpZGVyLFxuICBMYXllcnNEYXRhLFxuICBMb2NhbEZsb3dNYXBEYXRhUHJvdmlkZXIsXG4gIExvY2F0aW9uRmlsdGVyTW9kZSxcbiAgVmlld3BvcnRQcm9wcyxcbiAgRmxvd01hcEFnZ3JlZ2F0ZUFjY2Vzc29ycyxcbiAgQ2x1c3Rlck5vZGUsXG4gIEFnZ3JlZ2F0ZUZsb3csXG59IGZyb20gJ0BmbG93bWFwLmdsL2RhdGEnO1xuaW1wb3J0IEFuaW1hdGVkRmxvd0xpbmVzTGF5ZXIgZnJvbSAnLi9BbmltYXRlZEZsb3dMaW5lc0xheWVyJztcbmltcG9ydCBGbG93Q2lyY2xlc0xheWVyIGZyb20gJy4vRmxvd0NpcmNsZXNMYXllcic7XG5pbXBvcnQgRmxvd0xpbmVzTGF5ZXIgZnJvbSAnLi9GbG93TGluZXNMYXllcic7XG5pbXBvcnQge1xuICBGbG93TGF5ZXJQaWNraW5nSW5mbyxcbiAgTGF5ZXJQcm9wcyxcbiAgUGlja2luZ0luZm8sXG4gIFBpY2tpbmdUeXBlLFxufSBmcm9tICcuL3R5cGVzJztcblxuZXhwb3J0IHR5cGUgRmxvd01hcExheWVyUHJvcHM8TCwgRj4gPSB7XG4gIGRhdGE6IEZsb3dNYXBEYXRhPEwsIEY+IHwgRmxvd01hcERhdGFQcm92aWRlcjxMLCBGPjtcbiAgbG9jYXRpb25Ub3RhbHNFbmFibGVkPzogYm9vbGVhbjtcbiAgYWRhcHRpdmVTY2FsZXNFbmFibGVkPzogYm9vbGVhbjtcbiAgYW5pbWF0aW9uRW5hYmxlZD86IGJvb2xlYW47XG4gIGNsdXN0ZXJpbmdFbmFibGVkPzogYm9vbGVhbjtcbiAgY2x1c3RlcmluZ0xldmVsPzogbnVtYmVyO1xuICBmYWRlRW5hYmxlZD86IGJvb2xlYW47XG4gIGNsdXN0ZXJpbmdBdXRvPzogYm9vbGVhbjtcbiAgZGFya01vZGU/OiBib29sZWFuO1xuICBmYWRlQW1vdW50PzogbnVtYmVyO1xuICBjb2xvclNjaGVtZT86IHN0cmluZztcbiAgb25Ib3Zlcj86IChcbiAgICBpbmZvOiBGbG93TGF5ZXJQaWNraW5nSW5mbzxMLCBGPiB8IHVuZGVmaW5lZCxcbiAgICBldmVudDogU291cmNlRXZlbnQsXG4gICkgPT4gdm9pZDtcbiAgb25DbGljaz86IChpbmZvOiBGbG93TGF5ZXJQaWNraW5nSW5mbzxMLCBGPiwgZXZlbnQ6IFNvdXJjZUV2ZW50KSA9PiB2b2lkO1xufSAmIFBhcnRpYWw8Rmxvd01hcERhdGFBY2Nlc3NvcnM8TCwgRj4+ICZcbiAgTGF5ZXJQcm9wcztcblxuZW51bSBIaWdobGlnaHRUeXBlIHtcbiAgTE9DQVRJT04gPSAnbG9jYXRpb24nLFxuICBGTE9XID0gJ2Zsb3cnLFxufVxuXG50eXBlIEhpZ2hsaWdodGVkTG9jYXRpb25PYmplY3QgPSB7XG4gIHR5cGU6IEhpZ2hsaWdodFR5cGUuTE9DQVRJT047XG4gIGNlbnRyb2lkOiBbbnVtYmVyLCBudW1iZXJdO1xuICByYWRpdXM6IG51bWJlcjtcbn07XG5cbnR5cGUgSGlnaGxpZ2h0ZWRGbG93T2JqZWN0ID0ge1xuICB0eXBlOiBIaWdobGlnaHRUeXBlLkZMT1c7XG4gIGxpbmVBdHRyaWJ1dGVzOiBGbG93TGluZXNMYXllckF0dHJpYnV0ZXM7XG59O1xuXG50eXBlIEhpZ2hsaWdodGVkT2JqZWN0ID0gSGlnaGxpZ2h0ZWRMb2NhdGlvbk9iamVjdCB8IEhpZ2hsaWdodGVkRmxvd09iamVjdDtcblxudHlwZSBTdGF0ZTxMLCBGPiA9IHtcbiAgYWNjZXNzb3JzOiBGbG93TWFwQWdncmVnYXRlQWNjZXNzb3JzPEwsIEY+O1xuICBkYXRhUHJvdmlkZXI6IEZsb3dNYXBEYXRhUHJvdmlkZXI8TCwgRj47XG4gIGxheWVyc0RhdGE6IExheWVyc0RhdGEgfCB1bmRlZmluZWQ7XG4gIGhpZ2hsaWdodGVkT2JqZWN0OiBIaWdobGlnaHRlZE9iamVjdCB8IHVuZGVmaW5lZDtcbn07XG5cbmV4cG9ydCB0eXBlIFNvdXJjZUV2ZW50ID0ge3NyY0V2ZW50OiBNb3VzZUV2ZW50fTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRmxvd01hcExheWVyPEwsIEY+IGV4dGVuZHMgQ29tcG9zaXRlTGF5ZXIge1xuICBzdGF0aWMgZGVmYXVsdFByb3BzID0ge1xuICAgIGRhcmtNb2RlOiB0cnVlLFxuICAgIGZhZGVBbW91bnQ6IDUwLFxuICAgIGxvY2F0aW9uVG90YWxzRW5hYmxlZDogdHJ1ZSxcbiAgICBhbmltYXRpb25FbmFibGVkOiBmYWxzZSxcbiAgICBjbHVzdGVyaW5nRW5hYmxlZDogdHJ1ZSxcbiAgICBmYWRlRW5hYmxlZDogdHJ1ZSxcbiAgICBjbHVzdGVyaW5nQXV0bzogdHJ1ZSxcbiAgICBjbHVzdGVyaW5nTGV2ZWw6IHVuZGVmaW5lZCxcbiAgICBhZGFwdGl2ZVNjYWxlc0VuYWJsZWQ6IHRydWUsXG4gICAgY29sb3JTY2hlbWU6ICdUZWFsJyxcbiAgfTtcbiAgc3RhdGU6IFN0YXRlPEwsIEY+IHwgdW5kZWZpbmVkO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcm9wczogRmxvd01hcExheWVyUHJvcHM8TCwgRj4pIHtcbiAgICBzdXBlcih7XG4gICAgICAuLi5wcm9wcyxcbiAgICAgIG9uSG92ZXI6IChpbmZvOiBQaWNraW5nSW5mbzxhbnk+LCBldmVudDogU291cmNlRXZlbnQpID0+IHtcbiAgICAgICAgLy8gVE9ETzogaWYgKGxhc3RIb3ZlckV2ZW50U3RhcnRUaW1lUmVmID4gc3RhcnRUaW1lKSB7XG4gICAgICAgIC8vICAgLy8gU2tpcHBpbmcsIGJlY2F1c2UgdGhpcyBpcyBub3QgdGhlIGxhdGVzdCBob3ZlciBldmVudFxuICAgICAgICAvLyAgIHJldHVybjtcbiAgICAgICAgLy8gfVxuICAgICAgICB0aGlzLnNldFN0YXRlKHtoaWdobGlnaHRlZE9iamVjdDogdGhpcy5fZ2V0SGlnaGxpZ2h0ZWRPYmplY3QoaW5mbyl9KTtcbiAgICAgICAgY29uc3Qge29uSG92ZXJ9ID0gcHJvcHM7XG4gICAgICAgIGlmIChvbkhvdmVyKSB7XG4gICAgICAgICAgdGhpcy5fZ2V0Rmxvd0xheWVyUGlja2luZ0luZm8oaW5mbykudGhlbigoaW5mbykgPT5cbiAgICAgICAgICAgIG9uSG92ZXIoaW5mbywgZXZlbnQpLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBvbkNsaWNrOiAoaW5mbzogUGlja2luZ0luZm88YW55PiwgZXZlbnQ6IFNvdXJjZUV2ZW50KSA9PiB7XG4gICAgICAgIGNvbnN0IHtvbkNsaWNrfSA9IHByb3BzO1xuICAgICAgICBpZiAob25DbGljaykge1xuICAgICAgICAgIHRoaXMuX2dldEZsb3dMYXllclBpY2tpbmdJbmZvKGluZm8pLnRoZW4oKGluZm8pID0+IHtcbiAgICAgICAgICAgIGlmIChpbmZvKSB7XG4gICAgICAgICAgICAgIG9uQ2xpY2soaW5mbywgZXZlbnQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgaW5pdGlhbGl6ZVN0YXRlKCkge1xuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBhY2Nlc3NvcnM6IG5ldyBGbG93TWFwQWdncmVnYXRlQWNjZXNzb3JzPEwsIEY+KHRoaXMucHJvcHMpLFxuICAgICAgZGF0YVByb3ZpZGVyOiB0aGlzLl9tYWtlRGF0YVByb3ZpZGVyKCksXG4gICAgICBsYXllcnNEYXRhOiB1bmRlZmluZWQsXG4gICAgICBoaWdobGlnaHRlZE9iamVjdDogdW5kZWZpbmVkLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVBY2Nlc3NvcnMoKSB7XG4gICAgdGhpcy5zdGF0ZT8uZGF0YVByb3ZpZGVyPy5zZXRBY2Nlc3NvcnModGhpcy5wcm9wcyk7XG4gICAgdGhpcy5zZXRTdGF0ZSh7YWNjZXNzb3JzOiBuZXcgRmxvd01hcEFnZ3JlZ2F0ZUFjY2Vzc29ycyh0aGlzLnByb3BzKX0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfbWFrZURhdGFQcm92aWRlcigpIHtcbiAgICBjb25zdCB7ZGF0YX0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChpc0Zsb3dNYXBEYXRhUHJvdmlkZXI8TCwgRj4oZGF0YSkpIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH0gZWxzZSBpZiAoaXNGbG93TWFwRGF0YTxMLCBGPihkYXRhKSkge1xuICAgICAgY29uc3QgZGF0YVByb3ZpZGVyID0gbmV3IExvY2FsRmxvd01hcERhdGFQcm92aWRlcjxMLCBGPih0aGlzLnByb3BzKTtcbiAgICAgIGRhdGFQcm92aWRlci5zZXRGbG93TWFwRGF0YShkYXRhKTtcbiAgICAgIHJldHVybiBkYXRhUHJvdmlkZXI7XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdGbG93TWFwTGF5ZXI6IGRhdGEgbXVzdCBiZSBhIEZsb3dNYXBEYXRhUHJvdmlkZXIgb3IgRmxvd01hcERhdGEnLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIF91cGRhdGVEYXRhUHJvdmlkZXIoKSB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7ZGF0YVByb3ZpZGVyOiB0aGlzLl9tYWtlRGF0YVByb3ZpZGVyKCl9KTtcbiAgfVxuXG4gIHNob3VsZFVwZGF0ZVN0YXRlKHBhcmFtczogUmVjb3JkPHN0cmluZywgYW55Pik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHtjaGFuZ2VGbGFnc30gPSBwYXJhbXM7XG4gICAgLy8gaWYgKHRoaXMuX3ZpZXdwb3J0Q2hhbmdlZCgpKSB7XG4gICAgLy8gICByZXR1cm4gdHJ1ZTtcbiAgICAvLyB9XG4gICAgaWYgKGNoYW5nZUZsYWdzLnZpZXdwb3J0Q2hhbmdlZCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBzdXBlci5zaG91bGRVcGRhdGVTdGF0ZShwYXJhbXMpO1xuICAgIC8vIFRPRE86IGJlIHNtYXJ0ZXIgb24gd2hlbiB0byB1cGRhdGVcbiAgICAvLyAoZS5nLiBpZ25vcmUgdmlld3BvcnQgY2hhbmdlcyB3aGVuIGFkYXB0aXZlU2NhbGVzRW5hYmxlZCBhbmQgY2x1c3RlcmluZyBhcmUgZmFsc2UpXG4gIH1cblxuICB1cGRhdGVTdGF0ZSh7b2xkUHJvcHMsIHByb3BzLCBjaGFuZ2VGbGFnc306IFJlY29yZDxzdHJpbmcsIGFueT4pOiB2b2lkIHtcbiAgICBjb25zdCB7ZGF0YVByb3ZpZGVyLCBoaWdobGlnaHRlZE9iamVjdH0gPSB0aGlzLnN0YXRlIHx8IHt9O1xuICAgIGlmICghZGF0YVByb3ZpZGVyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZUZsYWdzLnByb3BzQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fdXBkYXRlQWNjZXNzb3JzKCk7XG4gICAgfVxuICAgIGlmIChjaGFuZ2VGbGFncy5kYXRhQ2hhbmdlZCkge1xuICAgICAgdGhpcy5fdXBkYXRlRGF0YVByb3ZpZGVyKCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZUZsYWdzLnZpZXdwb3J0Q2hhbmdlZCB8fCBjaGFuZ2VGbGFncy5wcm9wc09yRGF0YUNoYW5nZWQpIHtcbiAgICAgIGRhdGFQcm92aWRlci5zZXRGbG93TWFwU3RhdGUodGhpcy5fZ2V0Rmxvd01hcFN0YXRlKCkpO1xuXG4gICAgICAoYXN5bmMgKCkgPT4ge1xuICAgICAgICBjb25zdCBsYXllcnNEYXRhID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExheWVyc0RhdGEoKTtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7bGF5ZXJzRGF0YX0pO1xuICAgICAgfSkoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIF9nZXRTZXR0aW5nc1N0YXRlKCkge1xuICAgIGNvbnN0IHtcbiAgICAgIGxvY2F0aW9uVG90YWxzRW5hYmxlZCxcbiAgICAgIGFkYXB0aXZlU2NhbGVzRW5hYmxlZCxcbiAgICAgIGFuaW1hdGlvbkVuYWJsZWQsXG4gICAgICBjbHVzdGVyaW5nRW5hYmxlZCxcbiAgICAgIGNsdXN0ZXJpbmdMZXZlbCxcbiAgICAgIGZhZGVFbmFibGVkLFxuICAgICAgY2x1c3RlcmluZ0F1dG8sXG4gICAgICBkYXJrTW9kZSxcbiAgICAgIGZhZGVBbW91bnQsXG4gICAgICBjb2xvclNjaGVtZSxcbiAgICB9ID0gdGhpcy5wcm9wcztcbiAgICByZXR1cm4ge1xuICAgICAgbG9jYXRpb25Ub3RhbHNFbmFibGVkLFxuICAgICAgYWRhcHRpdmVTY2FsZXNFbmFibGVkLFxuICAgICAgYW5pbWF0aW9uRW5hYmxlZCxcbiAgICAgIGNsdXN0ZXJpbmdFbmFibGVkLFxuICAgICAgY2x1c3RlcmluZ0xldmVsLFxuICAgICAgZmFkZUVuYWJsZWQsXG4gICAgICBjbHVzdGVyaW5nQXV0byxcbiAgICAgIGRhcmtNb2RlLFxuICAgICAgZmFkZUFtb3VudCxcbiAgICAgIGNvbG9yU2NoZW1lLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9nZXRGbG93TWFwU3RhdGUoKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHZpZXdwb3J0OiBhc1ZpZXdTdGF0ZSh0aGlzLmNvbnRleHQudmlld3BvcnQpLFxuICAgICAgZmlsdGVyU3RhdGU6IHtcbiAgICAgICAgc2VsZWN0ZWRMb2NhdGlvbnM6IHVuZGVmaW5lZCxcbiAgICAgICAgbG9jYXRpb25GaWx0ZXJNb2RlOiBMb2NhdGlvbkZpbHRlck1vZGUuQUxMLFxuICAgICAgICBzZWxlY3RlZFRpbWVSYW5nZTogdW5kZWZpbmVkLFxuICAgICAgfSxcbiAgICAgIHNldHRpbmdzU3RhdGU6IHRoaXMuX2dldFNldHRpbmdzU3RhdGUoKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfZ2V0Rmxvd0xheWVyUGlja2luZ0luZm8oXG4gICAgaW5mbzogUmVjb3JkPHN0cmluZywgYW55PixcbiAgKTogUHJvbWlzZTxGbG93TGF5ZXJQaWNraW5nSW5mbzxMLCBGPiB8IHVuZGVmaW5lZD4ge1xuICAgIGNvbnN0IHtpbmRleCwgc291cmNlTGF5ZXJ9ID0gaW5mbztcbiAgICBjb25zdCB7ZGF0YVByb3ZpZGVyLCBhY2Nlc3NvcnN9ID0gdGhpcy5zdGF0ZSB8fCB7fTtcbiAgICBpZiAoIWRhdGFQcm92aWRlciB8fCAhYWNjZXNzb3JzKSB7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbiAgICBjb25zdCBjb21tb25JbmZvID0ge1xuICAgICAgLy8gLi4uaW5mbyxcbiAgICAgIGxheWVyOiBpbmZvLmxheWVyLFxuICAgICAgaW5kZXg6IGluZm8uaW5kZXgsXG4gICAgICB4OiBpbmZvLngsXG4gICAgICB5OiBpbmZvLnksXG4gICAgICBjb29yZGluYXRlOiBpbmZvLmNvb3JkaW5hdGUsXG4gICAgfTtcbiAgICBpZiAoXG4gICAgICBzb3VyY2VMYXllciBpbnN0YW5jZW9mIEZsb3dMaW5lc0xheWVyIHx8XG4gICAgICBzb3VyY2VMYXllciBpbnN0YW5jZW9mIEFuaW1hdGVkRmxvd0xpbmVzTGF5ZXJcbiAgICApIHtcbiAgICAgIGNvbnN0IGZsb3cgPVxuICAgICAgICBpbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiBhd2FpdCBkYXRhUHJvdmlkZXIuZ2V0Rmxvd0J5SW5kZXgoaW5kZXgpO1xuICAgICAgaWYgKGZsb3cpIHtcbiAgICAgICAgY29uc3Qgb3JpZ2luID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExvY2F0aW9uQnlJZChcbiAgICAgICAgICBhY2Nlc3NvcnMuZ2V0Rmxvd09yaWdpbklkKGZsb3cpLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBkZXN0ID0gYXdhaXQgZGF0YVByb3ZpZGVyLmdldExvY2F0aW9uQnlJZChcbiAgICAgICAgICBhY2Nlc3NvcnMuZ2V0Rmxvd0Rlc3RJZChmbG93KSxcbiAgICAgICAgKTtcbiAgICAgICAgaWYgKG9yaWdpbiAmJiBkZXN0KSB7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vbkluZm8sXG4gICAgICAgICAgICB0eXBlOiBQaWNraW5nVHlwZS5GTE9XLFxuICAgICAgICAgICAgb2JqZWN0OiBmbG93LFxuICAgICAgICAgICAgb3JpZ2luOiBvcmlnaW4sXG4gICAgICAgICAgICBkZXN0OiBkZXN0LFxuICAgICAgICAgICAgY291bnQ6IGFjY2Vzc29ycy5nZXRGbG93TWFnbml0dWRlKGZsb3cpLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHNvdXJjZUxheWVyIGluc3RhbmNlb2YgRmxvd0NpcmNsZXNMYXllcikge1xuICAgICAgY29uc3QgbG9jYXRpb24gPVxuICAgICAgICBpbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiBhd2FpdCBkYXRhUHJvdmlkZXIuZ2V0TG9jYXRpb25CeUluZGV4KGluZGV4KTtcblxuICAgICAgaWYgKGxvY2F0aW9uKSB7XG4gICAgICAgIGNvbnN0IGlkID0gYWNjZXNzb3JzLmdldExvY2F0aW9uSWQobG9jYXRpb24pO1xuICAgICAgICBjb25zdCBuYW1lID0gYWNjZXNzb3JzLmdldExvY2F0aW9uTmFtZShsb2NhdGlvbik7XG4gICAgICAgIGNvbnN0IHRvdGFscyA9IGF3YWl0IGRhdGFQcm92aWRlci5nZXRUb3RhbHNGb3JMb2NhdGlvbihpZCk7XG4gICAgICAgIGNvbnN0IHtjaXJjbGVBdHRyaWJ1dGVzfSA9IHRoaXMuc3RhdGU/LmxheWVyc0RhdGEgfHwge307XG4gICAgICAgIGlmICh0b3RhbHMgJiYgY2lyY2xlQXR0cmlidXRlcykge1xuICAgICAgICAgIGNvbnN0IGNpcmNsZVJhZGl1cyA9IGdldE91dGVyQ2lyY2xlUmFkaXVzQnlJbmRleChcbiAgICAgICAgICAgIGNpcmNsZUF0dHJpYnV0ZXMsXG4gICAgICAgICAgICBpbmZvLmluZGV4LFxuICAgICAgICAgICk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmNvbW1vbkluZm8sXG4gICAgICAgICAgICB0eXBlOiBQaWNraW5nVHlwZS5MT0NBVElPTixcbiAgICAgICAgICAgIG9iamVjdDogbG9jYXRpb24sXG4gICAgICAgICAgICBpZCxcbiAgICAgICAgICAgIG5hbWUsXG4gICAgICAgICAgICB0b3RhbHMsXG4gICAgICAgICAgICBjaXJjbGVSYWRpdXM6IGNpcmNsZVJhZGl1cyxcbiAgICAgICAgICAgIGV2ZW50OiB1bmRlZmluZWQsXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBwcml2YXRlIF9nZXRIaWdobGlnaHRlZE9iamVjdChcbiAgICBpbmZvOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICApOiBIaWdobGlnaHRlZE9iamVjdCB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3Qge2luZGV4LCBzb3VyY2VMYXllcn0gPSBpbmZvO1xuICAgIGlmIChpbmRleCA8IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKFxuICAgICAgc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBGbG93TGluZXNMYXllciB8fFxuICAgICAgc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBBbmltYXRlZEZsb3dMaW5lc0xheWVyXG4gICAgKSB7XG4gICAgICBjb25zdCB7bGluZUF0dHJpYnV0ZXN9ID0gdGhpcy5zdGF0ZT8ubGF5ZXJzRGF0YSB8fCB7fTtcbiAgICAgIGlmIChsaW5lQXR0cmlidXRlcykge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHR5cGU6IEhpZ2hsaWdodFR5cGUuRkxPVyxcbiAgICAgICAgICBsaW5lQXR0cmlidXRlczogZ2V0Rmxvd0xpbmVBdHRyaWJ1dGVzQnlJbmRleChsaW5lQXR0cmlidXRlcywgaW5kZXgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoc291cmNlTGF5ZXIgaW5zdGFuY2VvZiBGbG93Q2lyY2xlc0xheWVyKSB7XG4gICAgICBjb25zdCB7Y2lyY2xlQXR0cmlidXRlc30gPSB0aGlzLnN0YXRlPy5sYXllcnNEYXRhIHx8IHt9O1xuICAgICAgaWYgKGNpcmNsZUF0dHJpYnV0ZXMpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICB0eXBlOiBIaWdobGlnaHRUeXBlLkxPQ0FUSU9OLFxuICAgICAgICAgIGNlbnRyb2lkOiBnZXRMb2NhdGlvbkNlbnRyb2lkQnlJbmRleChjaXJjbGVBdHRyaWJ1dGVzLCBpbmRleCksXG4gICAgICAgICAgcmFkaXVzOiBnZXRPdXRlckNpcmNsZVJhZGl1c0J5SW5kZXgoY2lyY2xlQXR0cmlidXRlcywgaW5kZXgpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcmVuZGVyTGF5ZXJzKCk6IEFycmF5PGFueT4ge1xuICAgIGNvbnN0IGxheWVycyA9IFtdO1xuICAgIGlmICh0aGlzLnN0YXRlPy5sYXllcnNEYXRhKSB7XG4gICAgICBjb25zdCB7bGF5ZXJzRGF0YSwgaGlnaGxpZ2h0ZWRPYmplY3R9ID0gdGhpcy5zdGF0ZTtcbiAgICAgIGNvbnN0IHtjaXJjbGVBdHRyaWJ1dGVzLCBsaW5lQXR0cmlidXRlc30gPSBsYXllcnNEYXRhIHx8IHt9O1xuICAgICAgaWYgKGNpcmNsZUF0dHJpYnV0ZXMgJiYgbGluZUF0dHJpYnV0ZXMpIHtcbiAgICAgICAgY29uc3QgZmxvd01hcENvbG9ycyA9IGdldEZsb3dNYXBDb2xvcnModGhpcy5fZ2V0U2V0dGluZ3NTdGF0ZSgpKTtcbiAgICAgICAgY29uc3Qgb3V0bGluZUNvbG9yID0gY29sb3JBc1JnYmEoXG4gICAgICAgICAgZmxvd01hcENvbG9ycy5vdXRsaW5lQ29sb3IgfHwgKHRoaXMucHJvcHMuZGFya01vZGUgPyAnIzAwMCcgOiAnI2ZmZicpLFxuICAgICAgICApO1xuICAgICAgICBjb25zdCBjb21tb25MaW5lTGF5ZXJQcm9wcyA9IHtcbiAgICAgICAgICBkYXRhOiBsaW5lQXR0cmlidXRlcyxcbiAgICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAvLyBwcmV2ZW50IHotZmlnaHRpbmcgYXQgbm9uLXplcm8gYmVhcmluZy9waXRjaFxuICAgICAgICAgICAgZGVwdGhUZXN0OiBmYWxzZSxcbiAgICAgICAgICB9LFxuICAgICAgICB9O1xuICAgICAgICBpZiAodGhpcy5wcm9wcy5hbmltYXRpb25FbmFibGVkKSB7XG4gICAgICAgICAgbGF5ZXJzLnB1c2goXG4gICAgICAgICAgICAvLyBAdHMtaWdub3JlXG4gICAgICAgICAgICBuZXcgQW5pbWF0ZWRGbG93TGluZXNMYXllcih7XG4gICAgICAgICAgICAgIC4uLnRoaXMuZ2V0U3ViTGF5ZXJQcm9wcyh7XG4gICAgICAgICAgICAgICAgLi4uY29tbW9uTGluZUxheWVyUHJvcHMsXG4gICAgICAgICAgICAgICAgaWQ6ICdhbmltYXRlZC1mbG93LWxpbmVzJyxcbiAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogZmFsc2UsXG4gICAgICAgICAgICAgICAgdGhpY2tuZXNzVW5pdDogMjAsXG4gICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsYXllcnMucHVzaChcbiAgICAgICAgICAgIG5ldyBGbG93TGluZXNMYXllcih7XG4gICAgICAgICAgICAgIC4uLnRoaXMuZ2V0U3ViTGF5ZXJQcm9wcyh7XG4gICAgICAgICAgICAgICAgLi4uY29tbW9uTGluZUxheWVyUHJvcHMsXG4gICAgICAgICAgICAgICAgaWQ6ICdmbG93LWxpbmVzJyxcbiAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICBvdXRsaW5lQ29sb3I6IG91dGxpbmVDb2xvcixcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgICAgIGxheWVycy5wdXNoKFxuICAgICAgICAgIG5ldyBGbG93Q2lyY2xlc0xheWVyKFxuICAgICAgICAgICAgdGhpcy5nZXRTdWJMYXllclByb3BzKHtcbiAgICAgICAgICAgICAgaWQ6ICdjaXJjbGVzJyxcbiAgICAgICAgICAgICAgZGF0YTogY2lyY2xlQXR0cmlidXRlcyxcbiAgICAgICAgICAgICAgZW1wdHlDb2xvcjogWzAsIDAsIDAsIDI1NV0sXG4gICAgICAgICAgICAgIGVtcHR5T3V0bGluZUNvbG9yOiBbMCwgMCwgMCwgMjU1XSxcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIGlmIChoaWdobGlnaHRlZE9iamVjdCkge1xuICAgICAgICAgIHN3aXRjaCAoaGlnaGxpZ2h0ZWRPYmplY3QudHlwZSkge1xuICAgICAgICAgICAgY2FzZSBIaWdobGlnaHRUeXBlLkxPQ0FUSU9OOlxuICAgICAgICAgICAgICBsYXllcnMucHVzaChcbiAgICAgICAgICAgICAgICBuZXcgU2NhdHRlcnBsb3RMYXllcih7XG4gICAgICAgICAgICAgICAgICBpZDogJ2xvY2F0aW9uLWhpZ2hsaWdodCcsXG4gICAgICAgICAgICAgICAgICBkYXRhOiBbaGlnaGxpZ2h0ZWRPYmplY3RdLFxuICAgICAgICAgICAgICAgICAgc3Ryb2tlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIGZpbGxlZDogZmFsc2UsXG4gICAgICAgICAgICAgICAgICBsaW5lV2lkdGhVbml0czogJ3BpeGVscycsXG4gICAgICAgICAgICAgICAgICBnZXRMaW5lV2lkdGg6IDIsXG4gICAgICAgICAgICAgICAgICByYWRpdXNVbml0czogJ3BpeGVscycsXG4gICAgICAgICAgICAgICAgICBnZXRSYWRpdXM6IChkOiBIaWdobGlnaHRlZExvY2F0aW9uT2JqZWN0KSA9PiBkLnJhZGl1cyxcbiAgICAgICAgICAgICAgICAgIGdldExpbmVDb2xvcjogKGQ6IEhpZ2hsaWdodGVkTG9jYXRpb25PYmplY3QpID0+XG4gICAgICAgICAgICAgICAgICAgIGNvbG9yQXNSZ2JhKCdvcmFuZ2UnKSxcbiAgICAgICAgICAgICAgICAgIGdldFBvc2l0aW9uOiAoZDogSGlnaGxpZ2h0ZWRMb2NhdGlvbk9iamVjdCkgPT4gZC5jZW50cm9pZCxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBjYXNlIEhpZ2hsaWdodFR5cGUuRkxPVzpcbiAgICAgICAgICAgICAgbGF5ZXJzLnB1c2goXG4gICAgICAgICAgICAgICAgbmV3IEZsb3dMaW5lc0xheWVyKHtcbiAgICAgICAgICAgICAgICAgIGlkOiAnZmxvdy1oaWdobGlnaHQnLFxuICAgICAgICAgICAgICAgICAgZGF0YTogaGlnaGxpZ2h0ZWRPYmplY3QubGluZUF0dHJpYnV0ZXMsXG4gICAgICAgICAgICAgICAgICBkcmF3T3V0bGluZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgIG91dGxpbmVDb2xvcjogY29sb3JBc1JnYmEoJ29yYW5nZScpLFxuICAgICAgICAgICAgICAgICAgb3V0bGluZVRoaWNrbmVzczogMSxcbiAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGxheWVycztcbiAgfVxufVxuXG5mdW5jdGlvbiBhc1ZpZXdTdGF0ZSh2aWV3cG9ydDogUmVjb3JkPHN0cmluZywgYW55Pik6IFZpZXdwb3J0UHJvcHMge1xuICBjb25zdCB7d2lkdGgsIGhlaWdodCwgbG9uZ2l0dWRlLCBsYXRpdHVkZSwgem9vbSwgcGl0Y2gsIGJlYXJpbmd9ID0gdmlld3BvcnQ7XG4gIHJldHVybiB7XG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0LFxuICAgIGxvbmdpdHVkZSxcbiAgICBsYXRpdHVkZSxcbiAgICB6b29tLFxuICAgIHBpdGNoLFxuICAgIGJlYXJpbmcsXG4gIH07XG59XG4iXX0=