UNPKG

61.1 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports["default"] = void 0;
7
8var _reactMapGl = require("react-map-gl");
9
10var _react = _interopRequireWildcard(require("react"));
11
12var _editModes = require("@nebula.gl/edit-modes");
13
14var _memoize = _interopRequireDefault(require("./memoize"));
15
16var _constants = require("./constants");
17
18var _utils = require("./edit-modes/utils");
19
20var _editModes2 = require("./edit-modes");
21
22var _Object$freeze;
23
24function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
25
26function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
27
28function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; if (obj != null) { var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
29
30function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
31
32function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
33
34function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
35
36function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
37
38function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }
39
40function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
41
42function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
43
44function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
45
46function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
47
48function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); }
49
50function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); }
51
52function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
53
54var MODE_TO_HANDLER = Object.freeze((_Object$freeze = {}, _defineProperty(_Object$freeze, _constants.MODES.READ_ONLY, null), _defineProperty(_Object$freeze, _constants.MODES.SELECT, _editModes2.SelectMode), _defineProperty(_Object$freeze, _constants.MODES.EDITING, _editModes2.EditingMode), _defineProperty(_Object$freeze, _constants.MODES.DRAW_POINT, _editModes2.DrawPointMode), _defineProperty(_Object$freeze, _constants.MODES.DRAW_PATH, _editModes2.DrawLineStringMode), _defineProperty(_Object$freeze, _constants.MODES.DRAW_RECTANGLE, _editModes2.DrawRectangleMode), _defineProperty(_Object$freeze, _constants.MODES.DRAW_POLYGON, _editModes2.DrawPolygonMode), _Object$freeze));
55var defaultProps = {
56 mode: _constants.MODES.READ_ONLY,
57 features: null,
58 onSelect: null,
59 onUpdate: null
60};
61var defaultState = {
62 featureCollection: new _editModes.ImmutableFeatureCollection({
63 type: 'FeatureCollection',
64 features: []
65 }),
66 selectedFeatureIndex: null,
67 // index, isGuide, mapCoords, screenCoords
68 hovered: null,
69 isDragging: false,
70 didDrag: false,
71 lastPointerMoveEvent: null,
72 pointerDownPicks: null,
73 pointerDownScreenCoords: null,
74 pointerDownMapCoords: null
75};
76
77var ModeHandler =
78/*#__PURE__*/
79function (_PureComponent) {
80 _inherits(ModeHandler, _PureComponent);
81
82 function ModeHandler() {
83 var _this;
84
85 _classCallCheck(this, ModeHandler);
86
87 _this = _possibleConstructorReturn(this, _getPrototypeOf(ModeHandler).call(this));
88
89 _defineProperty(_assertThisInitialized(_this), "_events", void 0);
90
91 _defineProperty(_assertThisInitialized(_this), "_eventsRegistered", void 0);
92
93 _defineProperty(_assertThisInitialized(_this), "_modeHandler", void 0);
94
95 _defineProperty(_assertThisInitialized(_this), "_context", void 0);
96
97 _defineProperty(_assertThisInitialized(_this), "_containerRef", void 0);
98
99 _defineProperty(_assertThisInitialized(_this), "getFeatures", function () {
100 var featureCollection = _this._getFeatureCollection();
101
102 featureCollection = featureCollection && featureCollection.getObject();
103 return featureCollection && featureCollection.features;
104 });
105
106 _defineProperty(_assertThisInitialized(_this), "addFeatures", function (features) {
107 var featureCollection = _this._getFeatureCollection();
108
109 if (featureCollection) {
110 if (!Array.isArray(features)) {
111 features = [features];
112 }
113
114 featureCollection = featureCollection.addFeatures(features);
115
116 _this.setState({
117 featureCollection: featureCollection
118 });
119 }
120 });
121
122 _defineProperty(_assertThisInitialized(_this), "deleteFeatures", function (featureIndexes) {
123 var featureCollection = _this._getFeatureCollection();
124
125 var selectedFeatureIndex = _this._getSelectedFeatureIndex();
126
127 if (featureCollection) {
128 if (!Array.isArray(featureIndexes)) {
129 featureIndexes = [featureIndexes];
130 }
131
132 featureCollection = featureCollection.deleteFeatures(featureIndexes);
133 var newState = {
134 featureCollection: featureCollection
135 };
136
137 if (featureIndexes.findIndex(function (index) {
138 return selectedFeatureIndex === index;
139 }) >= 0) {
140 newState.selectedFeatureIndex = null;
141 }
142
143 _this.setState(newState);
144 }
145 });
146
147 _defineProperty(_assertThisInitialized(_this), "_getMemorizedFeatureCollection", (0, _memoize["default"])(function (_ref) {
148 var propsFeatures = _ref.propsFeatures,
149 stateFeatures = _ref.stateFeatures;
150 var features = propsFeatures || stateFeatures; // Any changes in ImmutableFeatureCollection will create a new object
151
152 if (features instanceof _editModes.ImmutableFeatureCollection) {
153 return features;
154 }
155
156 if (features && features.type === 'FeatureCollection') {
157 return new _editModes.ImmutableFeatureCollection({
158 type: 'FeatureCollection',
159 features: features.features
160 });
161 }
162
163 return new _editModes.ImmutableFeatureCollection({
164 type: 'FeatureCollection',
165 features: features || []
166 });
167 }));
168
169 _defineProperty(_assertThisInitialized(_this), "_getFeatureCollection", function () {
170 return _this._getMemorizedFeatureCollection({
171 propsFeatures: _this.props.features,
172 stateFeatures: _this.state.featureCollection
173 });
174 });
175
176 _defineProperty(_assertThisInitialized(_this), "_setupModeHandler", function () {
177 var mode = _this.props.mode;
178
179 if (!mode || mode === _constants.MODES.READ_ONLY) {
180 _this._degregisterEvents();
181
182 _this._modeHandler = null;
183 return;
184 }
185
186 _this._registerEvents();
187
188 var HandlerClass = MODE_TO_HANDLER[mode];
189 _this._modeHandler = HandlerClass ? new HandlerClass() : null;
190 });
191
192 _defineProperty(_assertThisInitialized(_this), "_clearEditingState", function () {
193 _this.setState({
194 selectedFeatureIndex: null,
195 hovered: null,
196 pointerDownPicks: null,
197 pointerDownScreenCoords: null,
198 pointerDownMapCoords: null,
199 isDragging: false,
200 didDrag: false
201 });
202 });
203
204 _defineProperty(_assertThisInitialized(_this), "_getSelectedFeatureIndex", function () {
205 if ('selectedFeatureIndex' in _this.props) {
206 return _this.props.selectedFeatureIndex;
207 }
208
209 return _this.state.selectedFeatureIndex;
210 });
211
212 _defineProperty(_assertThisInitialized(_this), "_getSelectedFeature", function (featureIndex) {
213 var features = _this.getFeatures();
214
215 featureIndex = (0, _utils.isNumeric)(featureIndex) ? featureIndex : _this._getSelectedFeatureIndex();
216 return features[featureIndex];
217 });
218
219 _defineProperty(_assertThisInitialized(_this), "_onSelect", function (selected) {
220 _this.setState({
221 selectedFeatureIndex: selected && selected.selectedFeatureIndex
222 });
223
224 if (_this.props.onSelect) {
225 _this.props.onSelect(selected);
226 }
227 });
228
229 _defineProperty(_assertThisInitialized(_this), "_onUpdate", function (editAction, isInternal) {
230 var editType = editAction.editType,
231 updatedData = editAction.updatedData,
232 editContext = editAction.editContext;
233
234 _this.setState({
235 featureCollection: new _editModes.ImmutableFeatureCollection(updatedData)
236 });
237
238 console.log('______ONUPDATE', _this.props.onUpdate, isInternal);
239
240 if (_this.props.onUpdate && !isInternal) {
241 _this.props.onUpdate({
242 data: updatedData && updatedData.features,
243 editType: editType,
244 editContext: editContext
245 });
246 }
247 });
248
249 _defineProperty(_assertThisInitialized(_this), "_onEdit", function (editAction) {
250 var mode = _this.props.mode;
251 var editType = editAction.editType,
252 updatedData = editAction.updatedData;
253
254 switch (editType) {
255 case _constants.EDIT_TYPE.MOVE_POSITION:
256 // intermediate feature, do not need forward to application
257 // only need update editor internal state
258 _this._onUpdate(editAction, Boolean(_this.props.features));
259
260 break;
261
262 case _constants.EDIT_TYPE.ADD_FEATURE:
263 _this._onUpdate(editAction);
264
265 if (mode === _constants.MODES.DRAW_PATH) {
266 var context = editAction.editContext && editAction.editContext[0] || {};
267 var screenCoords = context.screenCoords,
268 mapCoords = context.mapCoords;
269 var featureIndex = updatedData.features.length - 1;
270
271 var selectedFeature = _this._getSelectedFeature(featureIndex);
272
273 _this._onSelect({
274 selectedFeature: selectedFeature,
275 selectedFeatureIndex: featureIndex,
276 selectedEditHandleIndex: null,
277 screenCoords: screenCoords,
278 mapCoords: mapCoords
279 });
280 }
281
282 break;
283
284 case _constants.EDIT_TYPE.ADD_POSITION:
285 case _constants.EDIT_TYPE.REMOVE_POSITION:
286 case _constants.EDIT_TYPE.FINISH_MOVE_POSITION:
287 _this._onUpdate(editAction);
288
289 break;
290
291 default:
292 }
293 });
294
295 _defineProperty(_assertThisInitialized(_this), "_degregisterEvents", function () {
296 var eventManager = _this._context && _this._context.eventManager;
297
298 if (!_this._events || !eventManager) {
299 return;
300 }
301
302 if (_this._eventsRegistered) {
303 eventManager.off(_this._events);
304 _this._eventsRegistered = false;
305 }
306 });
307
308 _defineProperty(_assertThisInitialized(_this), "_registerEvents", function () {
309 var ref = _this._containerRef;
310 var eventManager = _this._context && _this._context.eventManager;
311
312 if (!_this._events || !ref || !eventManager) {
313 return;
314 }
315
316 if (_this._eventsRegistered) {
317 return;
318 }
319
320 eventManager.on(_this._events, ref);
321 _this._eventsRegistered = true;
322 });
323
324 _defineProperty(_assertThisInitialized(_this), "_onEvent", function (handler, evt, stopPropagation) {
325 var event = _this._getEvent(evt);
326
327 handler(event);
328
329 if (stopPropagation) {
330 evt.stopImmediatePropagation();
331 }
332 });
333
334 _defineProperty(_assertThisInitialized(_this), "_onClick", function (event) {
335 var mode = _this.props.mode;
336
337 if (mode === _constants.MODES.SELECT || mode === _constants.MODES.EDITING) {
338 var mapCoords = event.mapCoords,
339 screenCoords = event.screenCoords;
340 var pickedObject = event.picks && event.picks[0] && event.picks[0].object;
341
342 if (pickedObject && (0, _utils.isNumeric)(pickedObject.featureIndex)) {
343 var selectedFeatureIndex = pickedObject.featureIndex;
344
345 var selectedFeature = _this._getSelectedFeature(selectedFeatureIndex);
346
347 _this._onSelect({
348 selectedFeature: selectedFeature,
349 selectedFeatureIndex: selectedFeatureIndex,
350 selectedEditHandleIndex: pickedObject.type === _constants.ELEMENT_TYPE.EDIT_HANDLE ? pickedObject.index : null,
351 mapCoords: mapCoords,
352 screenCoords: screenCoords
353 });
354 } else {
355 _this._onSelect({
356 selectedFeature: null,
357 selectedFeatureIndex: null,
358 selectedEditHandleIndex: null,
359 mapCoords: mapCoords,
360 screenCoords: screenCoords
361 });
362 }
363 }
364
365 var modeProps = _this.getModeProps();
366
367 _this._modeHandler.handleClick(event, modeProps);
368 });
369
370 _defineProperty(_assertThisInitialized(_this), "_onPointerMove", function (event) {
371 // hovering
372 var hovered = _this._getHoverState(event);
373
374 var _this$state = _this.state,
375 isDragging = _this$state.isDragging,
376 didDrag = _this$state.didDrag,
377 pointerDownPicks = _this$state.pointerDownPicks,
378 pointerDownScreenCoords = _this$state.pointerDownScreenCoords,
379 pointerDownMapCoords = _this$state.pointerDownMapCoords;
380
381 if (isDragging && !didDrag && pointerDownScreenCoords) {
382 var dx = event.screenCoords[0] - pointerDownScreenCoords[0];
383 var dy = event.screenCoords[1] - pointerDownScreenCoords[1];
384
385 if (dx * dx + dy * dy > 5) {
386 _this.setState({
387 didDrag: true
388 });
389 }
390 }
391
392 var pointerMoveEvent = _objectSpread({}, event, {
393 isDragging: isDragging,
394 pointerDownPicks: pointerDownPicks,
395 pointerDownScreenCoords: pointerDownScreenCoords,
396 pointerDownMapCoords: pointerDownMapCoords
397 });
398
399 if (_this.state.didDrag) {
400 var modeProps = _this.getModeProps();
401
402 _this._modeHandler.handlePointerMove(pointerMoveEvent, modeProps);
403 }
404
405 _this.setState({
406 hovered: hovered,
407 lastPointerMoveEvent: pointerMoveEvent
408 });
409 });
410
411 _defineProperty(_assertThisInitialized(_this), "_onPointerDown", function (event) {
412 var pickedObject = event.picks && event.picks[0] && event.picks[0].object;
413
414 var startDraggingEvent = _objectSpread({}, event, {
415 pointerDownScreenCoords: event.screenCoords,
416 pointerDownMapCoords: event.mapCoords
417 });
418
419 var newState = {
420 isDragging: pickedObject && (0, _utils.isNumeric)(pickedObject.featureIndex),
421 pointerDownPicks: event.picks,
422 pointerDownScreenCoords: event.screenCoords,
423 pointerDownMapCoords: event.mapCoords
424 };
425
426 _this.setState(newState);
427
428 var modeProps = _this.getModeProps();
429
430 _this._modeHandler.handleStartDragging(startDraggingEvent, modeProps);
431 });
432
433 _defineProperty(_assertThisInitialized(_this), "_onPointerUp", function (event) {
434 var stopDraggingEvent = _objectSpread({}, event, {
435 pointerDownScreenCoords: _this.state.pointerDownScreenCoords,
436 pointerDownMapCoords: _this.state.pointerDownMapCoords
437 });
438
439 var newState = {
440 isDragging: false,
441 didDrag: false,
442 pointerDownPicks: null,
443 pointerDownScreenCoords: null,
444 pointerDownMapCoords: null
445 };
446
447 _this.setState(newState);
448
449 var modeProps = _this.getModeProps();
450
451 _this._modeHandler.handleStopDragging(stopDraggingEvent, modeProps);
452 });
453
454 _defineProperty(_assertThisInitialized(_this), "_onPan", function (event) {
455 var isDragging = _this.state.isDragging;
456
457 if (isDragging) {
458 event.sourceEvent.stopImmediatePropagation();
459 }
460 });
461
462 _defineProperty(_assertThisInitialized(_this), "project", function (pt) {
463 var viewport = _this._context && _this._context.viewport;
464 return viewport && viewport.project(pt);
465 });
466
467 _defineProperty(_assertThisInitialized(_this), "unproject", function (pt) {
468 var viewport = _this._context && _this._context.viewport;
469 return viewport && viewport.unproject(pt);
470 });
471
472 _defineProperty(_assertThisInitialized(_this), "_getHoverState", function (event) {
473 var object = event.picks && event.picks[0] && event.picks[0].object;
474
475 if (!object) {
476 return null;
477 }
478
479 return _objectSpread({
480 screenCoords: event.screenCoords,
481 mapCoords: event.mapCoords
482 }, object);
483 });
484
485 _this.state = defaultState;
486 _this._eventsRegistered = false;
487 _this._events = {
488 anyclick: function anyclick(evt) {
489 return _this._onEvent(_this._onClick, evt, true);
490 },
491 click: function click(evt) {
492 return evt.stopImmediatePropagation();
493 },
494 pointermove: function pointermove(evt) {
495 return _this._onEvent(_this._onPointerMove, evt, true);
496 },
497 pointerdown: function pointerdown(evt) {
498 return _this._onEvent(_this._onPointerDown, evt, true);
499 },
500 pointerup: function pointerup(evt) {
501 return _this._onEvent(_this._onPointerUp, evt, true);
502 },
503 panmove: function panmove(evt) {
504 return _this._onEvent(_this._onPan, evt, false);
505 },
506 panstart: function panstart(evt) {
507 return _this._onEvent(_this._onPan, evt, false);
508 },
509 panend: function panend(evt) {
510 return _this._onEvent(_this._onPan, evt, false);
511 }
512 };
513 return _this;
514 }
515
516 _createClass(ModeHandler, [{
517 key: "componentDidMount",
518 value: function componentDidMount() {
519 this._setupModeHandler();
520 }
521 }, {
522 key: "componentDidUpdate",
523 value: function componentDidUpdate(prevProps) {
524 if (prevProps.mode !== this.props.mode) {
525 this._clearEditingState();
526
527 this._setupModeHandler();
528 }
529 }
530 }, {
531 key: "componentWillUnmount",
532 value: function componentWillUnmount() {
533 this._degregisterEvents();
534 }
535 }, {
536 key: "getModeProps",
537 value: function getModeProps() {
538 var featureCollection = this._getFeatureCollection();
539
540 var lastPointerMoveEvent = this.state.lastPointerMoveEvent;
541
542 var selectedFeatureIndex = this._getSelectedFeatureIndex();
543
544 var viewport = this._context && this._context.viewport;
545 return {
546 data: featureCollection,
547 selectedIndexes: [selectedFeatureIndex],
548 lastPointerMoveEvent: lastPointerMoveEvent,
549 viewport: viewport,
550 onEdit: this._onEdit
551 };
552 }
553 /* MEMORIZERS */
554
555 }, {
556 key: "_getEvent",
557 value: function _getEvent(evt) {
558 var picked = (0, _utils.parseEventElement)(evt);
559 var screenCoords = (0, _utils.getScreenCoords)(evt);
560 var mapCoords = this.unproject(screenCoords);
561 return {
562 picks: picked ? [picked] : null,
563 screenCoords: screenCoords,
564 mapCoords: mapCoords,
565 sourceEvent: evt
566 };
567 }
568 }, {
569 key: "_isDrawing",
570 value: function _isDrawing() {
571 var mode = this.props.mode;
572 return _constants.DRAWING_MODE.findIndex(function (m) {
573 return m === mode;
574 }) >= 0;
575 }
576 }, {
577 key: "render",
578 value: function render(child) {
579 var _this2 = this;
580
581 return _react["default"].createElement(_reactMapGl._MapContext.Consumer, null, function (context) {
582 _this2._context = context;
583 var viewport = context && context.viewport;
584
585 if (!viewport || viewport.height <= 0 || viewport.width <= 0) {
586 return null;
587 }
588
589 return child;
590 });
591 }
592 }]);
593
594 return ModeHandler;
595}(_react.PureComponent);
596
597exports["default"] = ModeHandler;
598
599_defineProperty(ModeHandler, "defaultProps", defaultProps);
600
601ModeHandler.displayName = 'ModeHandler';
602//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9tb2RlLWhhbmRsZXIuanMiXSwibmFtZXMiOlsiTU9ERV9UT19IQU5ETEVSIiwiT2JqZWN0IiwiZnJlZXplIiwiTU9ERVMiLCJSRUFEX09OTFkiLCJTRUxFQ1QiLCJTZWxlY3RNb2RlIiwiRURJVElORyIsIkVkaXRpbmdNb2RlIiwiRFJBV19QT0lOVCIsIkRyYXdQb2ludE1vZGUiLCJEUkFXX1BBVEgiLCJEcmF3TGluZVN0cmluZ01vZGUiLCJEUkFXX1JFQ1RBTkdMRSIsIkRyYXdSZWN0YW5nbGVNb2RlIiwiRFJBV19QT0xZR09OIiwiRHJhd1BvbHlnb25Nb2RlIiwiZGVmYXVsdFByb3BzIiwibW9kZSIsImZlYXR1cmVzIiwib25TZWxlY3QiLCJvblVwZGF0ZSIsImRlZmF1bHRTdGF0ZSIsImZlYXR1cmVDb2xsZWN0aW9uIiwiSW1tdXRhYmxlRmVhdHVyZUNvbGxlY3Rpb24iLCJ0eXBlIiwic2VsZWN0ZWRGZWF0dXJlSW5kZXgiLCJob3ZlcmVkIiwiaXNEcmFnZ2luZyIsImRpZERyYWciLCJsYXN0UG9pbnRlck1vdmVFdmVudCIsInBvaW50ZXJEb3duUGlja3MiLCJwb2ludGVyRG93blNjcmVlbkNvb3JkcyIsInBvaW50ZXJEb3duTWFwQ29vcmRzIiwiTW9kZUhhbmRsZXIiLCJfZ2V0RmVhdHVyZUNvbGxlY3Rpb24iLCJnZXRPYmplY3QiLCJBcnJheSIsImlzQXJyYXkiLCJhZGRGZWF0dXJlcyIsInNldFN0YXRlIiwiZmVhdHVyZUluZGV4ZXMiLCJfZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXgiLCJkZWxldGVGZWF0dXJlcyIsIm5ld1N0YXRlIiwiZmluZEluZGV4IiwiaW5kZXgiLCJwcm9wc0ZlYXR1cmVzIiwic3RhdGVGZWF0dXJlcyIsIl9nZXRNZW1vcml6ZWRGZWF0dXJlQ29sbGVjdGlvbiIsInByb3BzIiwic3RhdGUiLCJfZGVncmVnaXN0ZXJFdmVudHMiLCJfbW9kZUhhbmRsZXIiLCJfcmVnaXN0ZXJFdmVudHMiLCJIYW5kbGVyQ2xhc3MiLCJmZWF0dXJlSW5kZXgiLCJnZXRGZWF0dXJlcyIsInNlbGVjdGVkIiwiZWRpdEFjdGlvbiIsImlzSW50ZXJuYWwiLCJlZGl0VHlwZSIsInVwZGF0ZWREYXRhIiwiZWRpdENvbnRleHQiLCJjb25zb2xlIiwibG9nIiwiZGF0YSIsIkVESVRfVFlQRSIsIk1PVkVfUE9TSVRJT04iLCJfb25VcGRhdGUiLCJCb29sZWFuIiwiQUREX0ZFQVRVUkUiLCJjb250ZXh0Iiwic2NyZWVuQ29vcmRzIiwibWFwQ29vcmRzIiwibGVuZ3RoIiwic2VsZWN0ZWRGZWF0dXJlIiwiX2dldFNlbGVjdGVkRmVhdHVyZSIsIl9vblNlbGVjdCIsInNlbGVjdGVkRWRpdEhhbmRsZUluZGV4IiwiQUREX1BPU0lUSU9OIiwiUkVNT1ZFX1BPU0lUSU9OIiwiRklOSVNIX01PVkVfUE9TSVRJT04iLCJldmVudE1hbmFnZXIiLCJfY29udGV4dCIsIl9ldmVudHMiLCJfZXZlbnRzUmVnaXN0ZXJlZCIsIm9mZiIsInJlZiIsIl9jb250YWluZXJSZWYiLCJvbiIsImhhbmRsZXIiLCJldnQiLCJzdG9wUHJvcGFnYXRpb24iLCJldmVudCIsIl9nZXRFdmVudCIsInN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiIsInBpY2tlZE9iamVjdCIsInBpY2tzIiwib2JqZWN0IiwiRUxFTUVOVF9UWVBFIiwiRURJVF9IQU5ETEUiLCJtb2RlUHJvcHMiLCJnZXRNb2RlUHJvcHMiLCJoYW5kbGVDbGljayIsIl9nZXRIb3ZlclN0YXRlIiwiZHgiLCJkeSIsInBvaW50ZXJNb3ZlRXZlbnQiLCJoYW5kbGVQb2ludGVyTW92ZSIsInN0YXJ0RHJhZ2dpbmdFdmVudCIsImhhbmRsZVN0YXJ0RHJhZ2dpbmciLCJzdG9wRHJhZ2dpbmdFdmVudCIsImhhbmRsZVN0b3BEcmFnZ2luZyIsInNvdXJjZUV2ZW50IiwicHQiLCJ2aWV3cG9ydCIsInByb2plY3QiLCJ1bnByb2plY3QiLCJhbnljbGljayIsIl9vbkV2ZW50IiwiX29uQ2xpY2siLCJjbGljayIsInBvaW50ZXJtb3ZlIiwiX29uUG9pbnRlck1vdmUiLCJwb2ludGVyZG93biIsIl9vblBvaW50ZXJEb3duIiwicG9pbnRlcnVwIiwiX29uUG9pbnRlclVwIiwicGFubW92ZSIsIl9vblBhbiIsInBhbnN0YXJ0IiwicGFuZW5kIiwiX3NldHVwTW9kZUhhbmRsZXIiLCJwcmV2UHJvcHMiLCJfY2xlYXJFZGl0aW5nU3RhdGUiLCJzZWxlY3RlZEluZGV4ZXMiLCJvbkVkaXQiLCJfb25FZGl0IiwicGlja2VkIiwiRFJBV0lOR19NT0RFIiwibSIsImNoaWxkIiwiaGVpZ2h0Iiwid2lkdGgiLCJQdXJlQ29tcG9uZW50IiwiZGlzcGxheU5hbWUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFDQTs7QUFDQTs7QUFDQTs7QUFLQTs7QUFFQTs7QUFDQTs7QUFDQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVNBLElBQU1BLGVBQWUsR0FBR0MsTUFBTSxDQUFDQyxNQUFQLHVEQUNyQkMsaUJBQU1DLFNBRGUsRUFDSCxJQURHLG1DQUVyQkQsaUJBQU1FLE1BRmUsRUFFTkMsc0JBRk0sbUNBR3JCSCxpQkFBTUksT0FIZSxFQUdMQyx1QkFISyxtQ0FJckJMLGlCQUFNTSxVQUplLEVBSUZDLHlCQUpFLG1DQUtyQlAsaUJBQU1RLFNBTGUsRUFLSEMsOEJBTEcsbUNBTXJCVCxpQkFBTVUsY0FOZSxFQU1FQyw2QkFORixtQ0FPckJYLGlCQUFNWSxZQVBlLEVBT0FDLDJCQVBBLG1CQUF4QjtBQVVBLElBQU1DLFlBQVksR0FBRztBQUNuQkMsRUFBQUEsSUFBSSxFQUFFZixpQkFBTUMsU0FETztBQUVuQmUsRUFBQUEsUUFBUSxFQUFFLElBRlM7QUFHbkJDLEVBQUFBLFFBQVEsRUFBRSxJQUhTO0FBSW5CQyxFQUFBQSxRQUFRLEVBQUU7QUFKUyxDQUFyQjtBQU9BLElBQU1DLFlBQVksR0FBRztBQUNuQkMsRUFBQUEsaUJBQWlCLEVBQUUsSUFBSUMscUNBQUosQ0FBK0I7QUFDaERDLElBQUFBLElBQUksRUFBRSxtQkFEMEM7QUFFaEROLElB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VjtBQUFBLE9BQXhCLEtBQTJDLENBQWxEO0FBQ0Q7OzsyQkFFTTRILEssRUFBWTtBQUFBOztBQUNqQixhQUNFLGdDQUFDLHVCQUFELENBQVksUUFBWixRQUNHLFVBQUF0RSxPQUFPLEVBQUk7QUFDVixRQUFBLE1BQUksQ0FBQ1ksUUFBTCxHQUFnQlosT0FBaEI7QUFDQSxZQUFNNEMsUUFBUSxHQUFHNUMsT0FBTyxJQUFJQSxPQUFPLENBQUM0QyxRQUFwQzs7QUFFQSxZQUFJLENBQUNBLFFBQUQsSUFBYUEsUUFBUSxDQUFDMkIsTUFBVCxJQUFtQixDQUFoQyxJQUFxQzNCLFFBQVEsQ0FBQzRCLEtBQVQsSUFBa0IsQ0FBM0QsRUFBOEQ7QUFDNUQsaUJBQU8sSUFBUDtBQUNEOztBQUVELGVBQU9GLEtBQVA7QUFDRCxPQVZILENBREY7QUFjRDs7OztFQS9hc0NHLG9COzs7O2dCQUFwQi9HLFcsa0JBQ0dqQixZOztBQWlieEJpQixXQUFXLENBQUNnSCxXQUFaLEdBQTBCLGFBQTFCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQGZsb3dcbmltcG9ydCB7IF9NYXBDb250ZXh0IGFzIE1hcENvbnRleHQgfSBmcm9tICdyZWFjdC1tYXAtZ2wnO1xuaW1wb3J0IFJlYWN0LCB7IFB1cmVDb21wb25lbnQgfSBmcm9tICdyZWFjdCc7XG5pbXBvcnQgeyBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbiB9IGZyb20gJ0BuZWJ1bGEuZ2wvZWRpdC1tb2Rlcyc7XG5cbmltcG9ydCB0eXBlIHsgRmVhdHVyZSwgUG9zaXRpb24sIEVkaXRBY3Rpb24gfSBmcm9tICdAbmVidWxhLmdsL2VkaXQtbW9kZXMnO1xuaW1wb3J0IHR5cGUgeyBNam9sbmlyRXZlbnQgfSBmcm9tICdtam9sbmlyLmpzJztcbmltcG9ydCB0eXBlIHsgQmFzZUV2ZW50LCBFZGl0b3JQcm9wcywgRWRpdG9yU3RhdGUsIFNlbGVjdEFjdGlvbiB9IGZyb20gJy4vdHlwZXMnO1xuaW1wb3J0IG1lbW9pemUgZnJvbSAnLi9tZW1vaXplJztcblxuaW1wb3J0IHsgRFJBV0lOR19NT0RFLCBFRElUX1RZUEUsIEVMRU1FTlRfVFlQRSwgTU9ERVMgfSBmcm9tICcuL2NvbnN0YW50cyc7XG5pbXBvcnQgeyBnZXRTY3JlZW5Db29yZHMsIGlzTnVtZXJpYywgcGFyc2VFdmVudEVsZW1lbnQgfSBmcm9tICcuL2VkaXQtbW9kZXMvdXRpbHMnO1xuaW1wb3J0IHtcbiAgU2VsZWN0TW9kZSxcbiAgRWRpdGluZ01vZGUsXG4gIERyYXdQb2ludE1vZGUsXG4gIERyYXdMaW5lU3RyaW5nTW9kZSxcbiAgRHJhd1JlY3RhbmdsZU1vZGUsXG4gIERyYXdQb2x5Z29uTW9kZVxufSBmcm9tICcuL2VkaXQtbW9kZXMnO1xuXG5jb25zdCBNT0RFX1RPX0hBTkRMRVIgPSBPYmplY3QuZnJlZXplKHtcbiAgW01PREVTLlJFQURfT05MWV06IG51bGwsXG4gIFtNT0RFUy5TRUxFQ1RdOiBTZWxlY3RNb2RlLFxuICBbTU9ERVMuRURJVElOR106IEVkaXRpbmdNb2RlLFxuICBbTU9ERVMuRFJBV19QT0lOVF06IERyYXdQb2ludE1vZGUsXG4gIFtNT0RFUy5EUkFXX1BBVEhdOiBEcmF3TGluZVN0cmluZ01vZGUsXG4gIFtNT0RFUy5EUkFXX1JFQ1RBTkdMRV06IERyYXdSZWN0YW5nbGVNb2RlLFxuICBbTU9ERVMuRFJBV19QT0xZR09OXTogRHJhd1BvbHlnb25Nb2RlXG59KTtcblxuY29uc3QgZGVmYXVsdFByb3BzID0ge1xuICBtb2RlOiBNT0RFUy5SRUFEX09OTFksXG4gIGZlYXR1cmVzOiBudWxsLFxuICBvblNlbGVjdDogbnVsbCxcbiAgb25VcGRhdGU6IG51bGxcbn07XG5cbmNvbnN0IGRlZmF1bHRTdGF0ZSA9IHtcbiAgZmVhdHVyZUNvbGxlY3Rpb246IG5ldyBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbih7XG4gICAgdHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJyxcbiAgICBmZWF0dXJlczogW11cbiAgfSksXG5cbiAgc2VsZWN0ZWRGZWF0dXJlSW5kZXg6IG51bGwsXG5cbiAgLy8gaW5kZXgsIGlzR3VpZGUsIG1hcENvb3Jkcywgc2NyZWVuQ29vcmRzXG4gIGhvdmVyZWQ6IG51bGwsXG5cbiAgaXNEcmFnZ2luZzogZmFsc2UsXG4gIGRpZERyYWc6IGZhbHNlLFxuXG4gIGxhc3RQb2ludGVyTW92ZUV2ZW50OiBudWxsLFxuXG4gIHBvaW50ZXJEb3duUGlja3M6IG51bGwsXG4gIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzOiBudWxsLFxuICBwb2ludGVyRG93bk1hcENvb3JkczogbnVsbFxufTtcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgTW9kZUhhbmRsZXIgZXh0ZW5kcyBQdXJlQ29tcG9uZW50PEVkaXRvclByb3BzLCBFZGl0b3JTdGF0ZT4ge1xuICBzdGF0aWMgZGVmYXVsdFByb3BzID0gZGVmYXVsdFByb3BzO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5zdGF0ZSA9IGRlZmF1bHRTdGF0ZTtcbiAgICB0aGlzLl9ldmVudHNSZWdpc3RlcmVkID0gZmFsc2U7XG5cbiAgICB0aGlzLl9ldmVudHMgPSB7XG4gICAgICBhbnljbGljazogZXZ0ID0+IHRoaXMuX29uRXZlbnQodGhpcy5fb25DbGljaywgZXZ0LCB0cnVlKSxcbiAgICAgIGNsaWNrOiBldnQgPT4gZXZ0LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpLFxuICAgICAgcG9pbnRlcm1vdmU6IGV2dCA9PiB0aGlzLl9vbkV2ZW50KHRoaXMuX29uUG9pbnRlck1vdmUsIGV2dCwgdHJ1ZSksXG4gICAgICBwb2ludGVyZG93bjogZXZ0ID0+IHRoaXMuX29uRXZlbnQodGhpcy5fb25Qb2ludGVyRG93biwgZXZ0LCB0cnVlKSxcbiAgICAgIHBvaW50ZXJ1cDogZXZ0ID0+IHRoaXMuX29uRXZlbnQodGhpcy5fb25Qb2ludGVyVXAsIGV2dCwgdHJ1ZSksXG4gICAgICBwYW5tb3ZlOiBldnQgPT4gdGhpcy5fb25FdmVudCh0aGlzLl9vblBhbiwgZXZ0LCBmYWxzZSksXG4gICAgICBwYW5zdGFydDogZXZ0ID0+IHRoaXMuX29uRXZlbnQodGhpcy5fb25QYW4sIGV2dCwgZmFsc2UpLFxuICAgICAgcGFuZW5kOiBldnQgPT4gdGhpcy5fb25FdmVudCh0aGlzLl9vblBhbiwgZXZ0LCBmYWxzZSlcbiAgICB9O1xuICB9XG5cbiAgY29tcG9uZW50RGlkTW91bnQoKSB7XG4gICAgdGhpcy5fc2V0dXBNb2RlSGFuZGxlcigpO1xuICB9XG5cbiAgY29tcG9uZW50RGlkVXBkYXRlKHByZXZQcm9wczogRWRpdG9yUHJvcHMpIHtcbiAgICBpZiAocHJldlByb3BzLm1vZGUgIT09IHRoaXMucHJvcHMubW9kZSkge1xuICAgICAgdGhpcy5fY2xlYXJFZGl0aW5nU3RhdGUoKTtcbiAgICAgIHRoaXMuX3NldHVwTW9kZUhhbmRsZXIoKTtcbiAgICB9XG4gIH1cblxuICBjb21wb25lbnRXaWxsVW5tb3VudCgpIHtcbiAgICB0aGlzLl9kZWdyZWdpc3RlckV2ZW50cygpO1xuICB9XG5cbiAgX2V2ZW50czogYW55O1xuICBfZXZlbnRzUmVnaXN0ZXJlZDogYm9vbGVhbjtcbiAgX21vZGVIYW5kbGVyOiBhbnk7XG4gIF9jb250ZXh0OiA/TWFwQ29udGV4dDtcbiAgX2NvbnRhaW5lclJlZjogP0hUTUxFbGVtZW50O1xuXG4gIGdldEZlYXR1cmVzID0gKCkgPT4ge1xuICAgIGxldCBmZWF0dXJlQ29sbGVjdGlvbiA9IHRoaXMuX2dldEZlYXR1cmVDb2xsZWN0aW9uKCk7XG4gICAgZmVhdHVyZUNvbGxlY3Rpb24gPSBmZWF0dXJlQ29sbGVjdGlvbiAmJiBmZWF0dXJlQ29sbGVjdGlvbi5nZXRPYmplY3QoKTtcbiAgICByZXR1cm4gZmVhdHVyZUNvbGxlY3Rpb24gJiYgZmVhdHVyZUNvbGxlY3Rpb24uZmVhdHVyZXM7XG4gIH07XG5cbiAgYWRkRmVhdHVyZXMgPSAoZmVhdHVyZXM6IEZlYXR1cmUgfCBGZWF0dXJlW10pID0+IHtcbiAgICBsZXQgZmVhdHVyZUNvbGxlY3Rpb24gPSB0aGlzLl9nZXRGZWF0dXJlQ29sbGVjdGlvbigpO1xuICAgIGlmIChmZWF0dXJlQ29sbGVjdGlvbikge1xuICAgICAgaWYgKCFBcnJheS5pc0FycmF5KGZlYXR1cmVzKSkge1xuICAgICAgICBmZWF0dXJlcyA9IFtmZWF0dXJlc107XG4gICAgICB9XG5cbiAgICAgIGZlYXR1cmVDb2xsZWN0aW9uID0gZmVhdHVyZUNvbGxlY3Rpb24uYWRkRmVhdHVyZXMoZmVhdHVyZXMpO1xuICAgICAgdGhpcy5zZXRTdGF0ZSh7IGZlYXR1cmVDb2xsZWN0aW9uIH0pO1xuICAgIH1cbiAgfTtcblxuICBkZWxldGVGZWF0dXJlcyA9IChmZWF0dXJlSW5kZXhlczogbnVtYmVyIHwgbnVtYmVyW10pID0+IHtcbiAgICBsZXQgZmVhdHVyZUNvbGxlY3Rpb24gPSB0aGlzLl9nZXRGZWF0dXJlQ29sbGVjdGlvbigpO1xuICAgIGNvbnN0IHNlbGVjdGVkRmVhdHVyZUluZGV4ID0gdGhpcy5fZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXgoKTtcbiAgICBpZiAoZmVhdHVyZUNvbGxlY3Rpb24pIHtcbiAgICAgIGlmICghQXJyYXkuaXNBcnJheShmZWF0dXJlSW5kZXhlcykpIHtcbiAgICAgICAgZmVhdHVyZUluZGV4ZXMgPSBbZmVhdHVyZUluZGV4ZXNdO1xuICAgICAgfVxuICAgICAgZmVhdHVyZUNvbGxlY3Rpb24gPSBmZWF0dXJlQ29sbGVjdGlvbi5kZWxldGVGZWF0dXJlcyhmZWF0dXJlSW5kZXhlcyk7XG4gICAgICBjb25zdCBuZXdTdGF0ZTogYW55ID0geyBmZWF0dXJlQ29sbGVjdGlvbiB9O1xuICAgICAgaWYgKGZlYXR1cmVJbmRleGVzLmZpbmRJbmRleChpbmRleCA9PiBzZWxlY3RlZEZlYXR1cmVJbmRleCA9PT0gaW5kZXgpID49IDApIHtcbiAgICAgICAgbmV3U3RhdGUuc2VsZWN0ZWRGZWF0dXJlSW5kZXggPSBudWxsO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXRTdGF0ZShuZXdTdGF0ZSk7XG4gICAgfVxuICB9O1xuXG4gIGdldE1vZGVQcm9wcygpIHtcbiAgICBjb25zdCBmZWF0dXJlQ29sbGVjdGlvbiA9IHRoaXMuX2dldEZlYXR1cmVDb2xsZWN0aW9uKCk7XG5cbiAgICBjb25zdCB7IGxhc3RQb2ludGVyTW92ZUV2ZW50IH0gPSB0aGlzLnN0YXRlO1xuICAgIGNvbnN0IHNlbGVjdGVkRmVhdHVyZUluZGV4ID0gdGhpcy5fZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXgoKTtcbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuX2NvbnRleHQgJiYgdGhpcy5fY29udGV4dC52aWV3cG9ydDtcblxuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBmZWF0dXJlQ29sbGVjdGlvbixcbiAgICAgIHNlbGVjdGVkSW5kZXhlczogW3NlbGVjdGVkRmVhdHVyZUluZGV4XSxcbiAgICAgIGxhc3RQb2ludGVyTW92ZUV2ZW50LFxuICAgICAgdmlld3BvcnQsXG4gICAgICBvbkVkaXQ6IHRoaXMuX29uRWRpdFxuICAgIH07XG4gIH1cblxuICAvKiBNRU1PUklaRVJTICovXG4gIF9nZXRNZW1vcml6ZWRGZWF0dXJlQ29sbGVjdGlvbiA9IG1lbW9pemUoKHsgcHJvcHNGZWF0dXJlcywgc3RhdGVGZWF0dXJlcyB9OiBhbnkpID0+IHtcbiAgICBjb25zdCBmZWF0dXJlcyA9IHByb3BzRmVhdHVyZXMgfHwgc3RhdGVGZWF0dXJlcztcbiAgICAvLyBBbnkgY2hhbmdlcyBpbiBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbiB3aWxsIGNyZWF0ZSBhIG5ldyBvYmplY3RcbiAgICBpZiAoZmVhdHVyZXMgaW5zdGFuY2VvZiBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbikge1xuICAgICAgcmV0dXJuIGZlYXR1cmVzO1xuICAgIH1cblxuICAgIGlmIChmZWF0dXJlcyAmJiBmZWF0dXJlcy50eXBlID09PSAnRmVhdHVyZUNvbGxlY3Rpb24nKSB7XG4gICAgICByZXR1cm4gbmV3IEltbXV0YWJsZUZlYXR1cmVDb2xsZWN0aW9uKHtcbiAgICAgICAgdHlwZTogJ0ZlYXR1cmVDb2xsZWN0aW9uJyxcbiAgICAgICAgZmVhdHVyZXM6IGZlYXR1cmVzLmZlYXR1cmVzXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IEltbXV0YWJsZUZlYXR1cmVDb2xsZWN0aW9uKHtcbiAgICAgIHR5cGU6ICdGZWF0dXJlQ29sbGVjdGlvbicsXG4gICAgICBmZWF0dXJlczogZmVhdHVyZXMgfHwgW11cbiAgICB9KTtcbiAgfSk7XG5cbiAgX2dldEZlYXR1cmVDb2xsZWN0aW9uID0gKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLl9nZXRNZW1vcml6ZWRGZWF0dXJlQ29sbGVjdGlvbih7XG4gICAgICBwcm9wc0ZlYXR1cmVzOiB0aGlzLnByb3BzLmZlYXR1cmVzLFxuICAgICAgc3RhdGVGZWF0dXJlczogdGhpcy5zdGF0ZS5mZWF0dXJlQ29sbGVjdGlvblxuICAgIH0pO1xuICB9O1xuXG4gIF9zZXR1cE1vZGVIYW5kbGVyID0gKCkgPT4ge1xuICAgIGNvbnN0IG1vZGUgPSB0aGlzLnByb3BzLm1vZGU7XG5cbiAgICBpZiAoIW1vZGUgfHwgbW9kZSA9PT0gTU9ERVMuUkVBRF9PTkxZKSB7XG4gICAgICB0aGlzLl9kZWdyZWdpc3RlckV2ZW50cygpO1xuICAgICAgdGhpcy5fbW9kZUhhbmRsZXIgPSBudWxsO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlZ2lzdGVyRXZlbnRzKCk7XG5cbiAgICBjb25zdCBIYW5kbGVyQ2xhc3MgPSBNT0RFX1RPX0hBTkRMRVJbbW9kZV07XG4gICAgdGhpcy5fbW9kZUhhbmRsZXIgPSBIYW5kbGVyQ2xhc3MgPyBuZXcgSGFuZGxlckNsYXNzKCkgOiBudWxsO1xuICB9O1xuXG4gIC8qIEVESVRJTkcgT1BFUkFUSU9OUyAqL1xuICBfY2xlYXJFZGl0aW5nU3RhdGUgPSAoKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7XG4gICAgICBzZWxlY3RlZEZlYXR1cmVJbmRleDogbnVsbCxcblxuICAgICAgaG92ZXJlZDogbnVsbCxcblxuICAgICAgcG9pbnRlckRvd25QaWNrczogbnVsbCxcbiAgICAgIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzOiBudWxsLFxuICAgICAgcG9pbnRlckRvd25NYXBDb29yZHM6IG51bGwsXG5cbiAgICAgIGlzRHJhZ2dpbmc6IGZhbHNlLFxuICAgICAgZGlkRHJhZzogZmFsc2VcbiAgICB9KTtcbiAgfTtcblxuICBfZ2V0U2VsZWN0ZWRGZWF0dXJlSW5kZXggPSAoKSA9PiB7XG4gICAgaWYgKCdzZWxlY3RlZEZlYXR1cmVJbmRleCcgaW4gdGhpcy5wcm9wcykge1xuICAgICAgcmV0dXJuIHRoaXMucHJvcHMuc2VsZWN0ZWRGZWF0dXJlSW5kZXg7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnN0YXRlLnNlbGVjdGVkRmVhdHVyZUluZGV4O1xuICB9O1xuXG4gIF9nZXRTZWxlY3RlZEZlYXR1cmUgPSAoZmVhdHVyZUluZGV4OiA/bnVtYmVyKSA9PiB7XG4gICAgY29uc3QgZmVhdHVyZXMgPSB0aGlzLmdldEZlYXR1cmVzKCk7XG4gICAgZmVhdHVyZUluZGV4ID0gaXNOdW1lcmljKGZlYXR1cmVJbmRleCkgPyBmZWF0dXJlSW5kZXggOiB0aGlzLl9nZXRTZWxlY3RlZEZlYXR1cmVJbmRleCgpO1xuICAgIHJldHVybiBmZWF0dXJlc1tmZWF0dXJlSW5kZXhdO1xuICB9O1xuXG4gIF9vblNlbGVjdCA9IChzZWxlY3RlZDogU2VsZWN0QWN0aW9uKSA9PiB7XG4gICAgdGhpcy5zZXRTdGF0ZSh7IHNlbGVjdGVkRmVhdHVyZUluZGV4OiBzZWxlY3RlZCAmJiBzZWxlY3RlZC5zZWxlY3RlZEZlYXR1cmVJbmRleCB9KTtcbiAgICBpZiAodGhpcy5wcm9wcy5vblNlbGVjdCkge1xuICAgICAgdGhpcy5wcm9wcy5vblNlbGVjdChzZWxlY3RlZCk7XG4gICAgfVxuICB9O1xuXG4gIF9vblVwZGF0ZSA9IChlZGl0QWN0aW9uOiBFZGl0QWN0aW9uLCBpc0ludGVybmFsOiA/Ym9vbGVhbikgPT4ge1xuICAgIGNvbnN0IHsgZWRpdFR5cGUsIHVwZGF0ZWREYXRhLCBlZGl0Q29udGV4dCB9ID0gZWRpdEFjdGlvbjtcbiAgICB0aGlzLnNldFN0YXRlKHsgZmVhdHVyZUNvbGxlY3Rpb246IG5ldyBJbW11dGFibGVGZWF0dXJlQ29sbGVjdGlvbih1cGRhdGVkRGF0YSkgfSk7XG4gICAgY29uc29sZS5sb2coJ19fX19fX09OVVBEQVRFJywgdGhpcy5wcm9wcy5vblVwZGF0ZSwgaXNJbnRlcm5hbClcbiAgICBpZiAodGhpcy5wcm9wcy5vblVwZGF0ZSAmJiAhaXNJbnRlcm5hbCkge1xuICAgICAgdGhpcy5wcm9wcy5vblVwZGF0ZSh7XG4gICAgICAgIGRhdGE6IHVwZGF0ZWREYXRhICYmIHVwZGF0ZWREYXRhLmZlYXR1cmVzLFxuICAgICAgICBlZGl0VHlwZSxcbiAgICAgICAgZWRpdENvbnRleHRcbiAgICAgIH0pO1xuICAgIH1cbiAgfTtcblxuICBfb25FZGl0ID0gKGVkaXRBY3Rpb246IEVkaXRBY3Rpb24pID0+IHtcbiAgICBjb25zdCB7IG1vZGUgfSA9IHRoaXMucHJvcHM7XG4gICAgY29uc3QgeyBlZGl0VHlwZSwgdXBkYXRlZERhdGEgfSA9IGVkaXRBY3Rpb247XG5cbiAgICBzd2l0Y2ggKGVkaXRUeXBlKSB7XG4gICAgICBjYXNlIEVESVRfVFlQRS5NT1ZFX1BPU0lUSU9OOlxuICAgICAgICAvLyBpbnRlcm1lZGlhdGUgZmVhdHVyZSwgZG8gbm90IG5lZWQgZm9yd2FyZCB0byBhcHBsaWNhdGlvblxuICAgICAgICAvLyBvbmx5IG5lZWQgdXBkYXRlIGVkaXRvciBpbnRlcm5hbCBzdGF0ZVxuICAgICAgICB0aGlzLl9vblVwZGF0ZShlZGl0QWN0aW9uLCBCb29sZWFuKHRoaXMucHJvcHMuZmVhdHVyZXMpKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIEVESVRfVFlQRS5BRERfRkVBVFVSRTpcbiAgICAgICAgdGhpcy5fb25VcGRhdGUoZWRpdEFjdGlvbik7XG4gICAgICAgIGlmIChtb2RlID09PSBNT0RFUy5EUkFXX1BBVEgpIHtcbiAgICAgICAgICBjb25zdCBjb250ZXh0ID0gKGVkaXRBY3Rpb24uZWRpdENvbnRleHQgJiYgZWRpdEFjdGlvbi5lZGl0Q29udGV4dFswXSkgfHwge307XG4gICAgICAgICAgY29uc3QgeyBzY3JlZW5Db29yZHMsIG1hcENvb3JkcyB9ID0gY29udGV4dDtcbiAgICAgICAgICBjb25zdCBmZWF0dXJlSW5kZXggPSB1cGRhdGVkRGF0YS5mZWF0dXJlcy5sZW5ndGggLSAxO1xuICAgICAgICAgIGNvbnN0IHNlbGVjdGVkRmVhdHVyZSA9IHRoaXMuX2dldFNlbGVjdGVkRmVhdHVyZShmZWF0dXJlSW5kZXgpO1xuICAgICAgICAgIHRoaXMuX29uU2VsZWN0KHtcbiAgICAgICAgICAgIHNlbGVjdGVkRmVhdHVyZSxcbiAgICAgICAgICAgIHNlbGVjdGVkRmVhdHVyZUluZGV4OiBmZWF0dXJlSW5kZXgsXG4gICAgICAgICAgICBzZWxlY3RlZEVkaXRIYW5kbGVJbmRleDogbnVsbCxcbiAgICAgICAgICAgIHNjcmVlbkNvb3JkcyxcbiAgICAgICAgICAgIG1hcENvb3Jkc1xuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBFRElUX1RZUEUuQUREX1BPU0lUSU9OOlxuICAgICAgY2FzZSBFRElUX1RZUEUuUkVNT1ZFX1BPU0lUSU9OOlxuICAgICAgY2FzZSBFRElUX1RZUEUuRklOSVNIX01PVkVfUE9TSVRJT046XG4gICAgICAgIHRoaXMuX29uVXBkYXRlKGVkaXRBY3Rpb24pO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICB9XG4gIH07XG5cbiAgLyogRVZFTlRTICovXG4gIF9kZWdyZWdpc3RlckV2ZW50cyA9ICgpID0+IHtcbiAgICBjb25zdCBldmVudE1hbmFnZXIgPSB0aGlzLl9jb250ZXh0ICYmIHRoaXMuX2NvbnRleHQuZXZlbnRNYW5hZ2VyO1xuICAgIGlmICghdGhpcy5fZXZlbnRzIHx8ICFldmVudE1hbmFnZXIpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZXZlbnRzUmVnaXN0ZXJlZCkge1xuICAgICAgZXZlbnRNYW5hZ2VyLm9mZih0aGlzLl9ldmVudHMpO1xuICAgICAgdGhpcy5fZXZlbnRzUmVnaXN0ZXJlZCA9IGZhbHNlO1xuICAgIH1cbiAgfTtcblxuICBfcmVnaXN0ZXJFdmVudHMgPSAoKSA9PiB7XG4gICAgY29uc3QgcmVmID0gdGhpcy5fY29udGFpbmVyUmVmO1xuICAgIGNvbnN0IGV2ZW50TWFuYWdlciA9IHRoaXMuX2NvbnRleHQgJiYgdGhpcy5fY29udGV4dC5ldmVudE1hbmFnZXI7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXJlZiB8fCAhZXZlbnRNYW5hZ2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2V2ZW50c1JlZ2lzdGVyZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBldmVudE1hbmFnZXIub24odGhpcy5fZXZlbnRzLCByZWYpO1xuICAgIHRoaXMuX2V2ZW50c1JlZ2lzdGVyZWQgPSB0cnVlO1xuICB9O1xuXG4gIF9vbkV2ZW50ID0gKGhhbmRsZXI6IEZ1bmN0aW9uLCBldnQ6IE1qb2xuaXJFdmVudCwgc3RvcFByb3BhZ2F0aW9uOiBib29sZWFuKSA9PiB7XG4gICAgY29uc3QgZXZlbnQgPSB0aGlzLl9nZXRFdmVudChldnQpO1xuICAgIGhhbmRsZXIoZXZlbnQpO1xuXG4gICAgaWYgKHN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgZXZ0LnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgfTtcblxuICBfb25DbGljayA9IChldmVudDogQmFzZUV2ZW50KSA9PiB7XG4gICAgY29uc3QgeyBtb2RlIH0gPSB0aGlzLnByb3BzO1xuICAgIGlmIChtb2RlID09PSBNT0RFUy5TRUxFQ1QgfHwgbW9kZSA9PT0gTU9ERVMuRURJVElORykge1xuICAgICAgY29uc3QgeyBtYXBDb29yZHMsIHNjcmVlbkNvb3JkcyB9ID0gZXZlbnQ7XG4gICAgICBjb25zdCBwaWNrZWRPYmplY3QgPSBldmVudC5waWNrcyAmJiBldmVudC5waWNrc1swXSAmJiBldmVudC5waWNrc1swXS5vYmplY3Q7XG4gICAgICBpZiAocGlja2VkT2JqZWN0ICYmIGlzTnVtZXJpYyhwaWNrZWRPYmplY3QuZmVhdHVyZUluZGV4KSkge1xuICAgICAgICBjb25zdCBzZWxlY3RlZEZlYXR1cmVJbmRleCA9IHBpY2tlZE9iamVjdC5mZWF0dXJlSW5kZXg7XG4gICAgICAgIGNvbnN0IHNlbGVjdGVkRmVhdHVyZSA9IHRoaXMuX2dldFNlbGVjdGVkRmVhdHVyZShzZWxlY3RlZEZlYXR1cmVJbmRleCk7XG4gICAgICAgIHRoaXMuX29uU2VsZWN0KHtcbiAgICAgICAgICBzZWxlY3RlZEZlYXR1cmUsXG4gICAgICAgICAgc2VsZWN0ZWRGZWF0dXJlSW5kZXgsXG4gICAgICAgICAgc2VsZWN0ZWRFZGl0SGFuZGxlSW5kZXg6XG4gICAgICAgICAgICBwaWNrZWRPYmplY3QudHlwZSA9PT0gRUxFTUVOVF9UWVBFLkVESVRfSEFORExFID8gcGlja2VkT2JqZWN0LmluZGV4IDogbnVsbCxcbiAgICAgICAgICBtYXBDb29yZHMsXG4gICAgICAgICAgc2NyZWVuQ29vcmRzXG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5fb25TZWxlY3Qoe1xuICAgICAgICAgIHNlbGVjdGVkRmVhdHVyZTogbnVsbCxcbiAgICAgICAgICBzZWxlY3RlZEZlYXR1cmVJbmRleDogbnVsbCxcbiAgICAgICAgICBzZWxlY3RlZEVkaXRIYW5kbGVJbmRleDogbnVsbCxcbiAgICAgICAgICBtYXBDb29yZHMsXG4gICAgICAgICAgc2NyZWVuQ29vcmRzXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IG1vZGVQcm9wcyA9IHRoaXMuZ2V0TW9kZVByb3BzKCk7XG4gICAgdGhpcy5fbW9kZUhhbmRsZXIuaGFuZGxlQ2xpY2soZXZlbnQsIG1vZGVQcm9wcyk7XG4gIH07XG5cbiAgX29uUG9pbnRlck1vdmUgPSAoZXZlbnQ6IEJhc2VFdmVudCkgPT4ge1xuICAgIC8vIGhvdmVyaW5nXG4gICAgY29uc3QgaG92ZXJlZCA9IHRoaXMuX2dldEhvdmVyU3RhdGUoZXZlbnQpO1xuICAgIGNvbnN0IHtcbiAgICAgIGlzRHJhZ2dpbmcsXG4gICAgICBkaWREcmFnLFxuICAgICAgcG9pbnRlckRvd25QaWNrcyxcbiAgICAgIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzLFxuICAgICAgcG9pbnRlckRvd25NYXBDb29yZHNcbiAgICB9ID0gdGhpcy5zdGF0ZTtcblxuICAgIGlmIChpc0RyYWdnaW5nICYmICFkaWREcmFnICYmIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzKSB7XG4gICAgICBjb25zdCBkeCA9IGV2ZW50LnNjcmVlbkNvb3Jkc1swXSAtIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzWzBdO1xuICAgICAgY29uc3QgZHkgPSBldmVudC5zY3JlZW5Db29yZHNbMV0gLSBwb2ludGVyRG93blNjcmVlbkNvb3Jkc1sxXTtcbiAgICAgIGlmIChkeCAqIGR4ICsgZHkgKiBkeSA+IDUpIHtcbiAgICAgICAgdGhpcy5zZXRTdGF0ZSh7IGRpZERyYWc6IHRydWUgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcG9pbnRlck1vdmVFdmVudCA9IHtcbiAgICAgIC4uLmV2ZW50LFxuICAgICAgaXNEcmFnZ2luZyxcbiAgICAgIHBvaW50ZXJEb3duUGlja3MsXG4gICAgICBwb2ludGVyRG93blNjcmVlbkNvb3JkcyxcbiAgICAgIHBvaW50ZXJEb3duTWFwQ29vcmRzXG4gICAgfTtcblxuICAgIGlmICh0aGlzLnN0YXRlLmRpZERyYWcpIHtcbiAgICAgIGNvbnN0IG1vZGVQcm9wcyA9IHRoaXMuZ2V0TW9kZVByb3BzKCk7XG4gICAgICB0aGlzLl9tb2RlSGFuZGxlci5oYW5kbGVQb2ludGVyTW92ZShwb2ludGVyTW92ZUV2ZW50LCBtb2RlUHJvcHMpO1xuICAgIH1cblxuICAgIHRoaXMuc2V0U3RhdGUoe1xuICAgICAgaG92ZXJlZCxcbiAgICAgIGxhc3RQb2ludGVyTW92ZUV2ZW50OiBwb2ludGVyTW92ZUV2ZW50XG4gICAgfSk7XG4gIH07XG5cbiAgX29uUG9pbnRlckRvd24gPSAoZXZlbnQ6IEJhc2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IHBpY2tlZE9iamVjdCA9IGV2ZW50LnBpY2tzICYmIGV2ZW50LnBpY2tzWzBdICYmIGV2ZW50LnBpY2tzWzBdLm9iamVjdDtcbiAgICBjb25zdCBzdGFydERyYWdnaW5nRXZlbnQgPSB7XG4gICAgICAuLi5ldmVudCxcbiAgICAgIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzOiBldmVudC5zY3JlZW5Db29yZHMsXG4gICAgICBwb2ludGVyRG93bk1hcENvb3JkczogZXZlbnQubWFwQ29vcmRzXG4gICAgfTtcblxuICAgIGNvbnN0IG5ld1N0YXRlID0ge1xuICAgICAgaXNEcmFnZ2luZzogcGlja2VkT2JqZWN0ICYmIGlzTnVtZXJpYyhwaWNrZWRPYmplY3QuZmVhdHVyZUluZGV4KSxcbiAgICAgIHBvaW50ZXJEb3duUGlja3M6IGV2ZW50LnBpY2tzLFxuICAgICAgcG9pbnRlckRvd25TY3JlZW5Db29yZHM6IGV2ZW50LnNjcmVlbkNvb3JkcyxcbiAgICAgIHBvaW50ZXJEb3duTWFwQ29vcmRzOiBldmVudC5tYXBDb29yZHNcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRTdGF0ZShuZXdTdGF0ZSk7XG5cbiAgICBjb25zdCBtb2RlUHJvcHMgPSB0aGlzLmdldE1vZGVQcm9wcygpO1xuICAgIHRoaXMuX21vZGVIYW5kbGVyLmhhbmRsZVN0YXJ0RHJhZ2dpbmcoc3RhcnREcmFnZ2luZ0V2ZW50LCBtb2RlUHJvcHMpO1xuICB9O1xuXG4gIF9vblBvaW50ZXJVcCA9IChldmVudDogTWpvbG5pckV2ZW50KSA9PiB7XG4gICAgY29uc3Qgc3RvcERyYWdnaW5nRXZlbnQgPSB7XG4gICAgICAuLi5ldmVudCxcbiAgICAgIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzOiB0aGlzLnN0YXRlLnBvaW50ZXJEb3duU2NyZWVuQ29vcmRzLFxuICAgICAgcG9pbnRlckRvd25NYXBDb29yZHM6IHRoaXMuc3RhdGUucG9pbnRlckRvd25NYXBDb29yZHNcbiAgICB9O1xuXG4gICAgY29uc3QgbmV3U3RhdGUgPSB7XG4gICAgICBpc0RyYWdnaW5nOiBmYWxzZSxcbiAgICAgIGRpZERyYWc6IGZhbHNlLFxuICAgICAgcG9pbnRlckRvd25QaWNrczogbnVsbCxcbiAgICAgIHBvaW50ZXJEb3duU2NyZWVuQ29vcmRzOiBudWxsLFxuICAgICAgcG9pbnRlckRvd25NYXBDb29yZHM6IG51bGxcbiAgICB9O1xuXG4gICAgdGhpcy5zZXRTdGF0ZShuZXdTdGF0ZSk7XG5cbiAgICBjb25zdCBtb2RlUHJvcHMgPSB0aGlzLmdldE1vZGVQcm9wcygpO1xuICAgIHRoaXMuX21vZGVIYW5kbGVyLmhhbmRsZVN0b3BEcmFnZ2luZyhzdG9wRHJhZ2dpbmdFdmVudCwgbW9kZVByb3BzKTtcbiAgfTtcblxuICBfb25QYW4gPSAoZXZlbnQ6IEJhc2VFdmVudCkgPT4ge1xuICAgIGNvbnN0IHsgaXNEcmFnZ2luZyB9ID0gdGhpcy5zdGF0ZTtcbiAgICBpZiAoaXNEcmFnZ2luZykge1xuICAgICAgZXZlbnQuc291cmNlRXZlbnQuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICB9O1xuXG4gIC8qIEhFTFBFUlMgKi9cbiAgcHJvamVjdCA9IChwdDogUG9zaXRpb24pID0+IHtcbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuX2NvbnRleHQgJiYgdGhpcy5fY29udGV4dC52aWV3cG9ydDtcbiAgICByZXR1cm4gdmlld3BvcnQgJiYgdmlld3BvcnQucHJvamVjdChwdCk7XG4gIH07XG5cbiAgdW5wcm9qZWN0ID0gKHB0OiBQb3NpdGlvbikgPT4ge1xuICAgIGNvbnN0IHZpZXdwb3J0ID0gdGhpcy5fY29udGV4dCAmJiB0aGlzLl9jb250ZXh0LnZpZXdwb3J0O1xuICAgIHJldHVybiB2aWV3cG9ydCAmJiB2aWV3cG9ydC51bnByb2plY3QocHQpO1xuICB9O1xuXG4gIF9nZXRFdmVudChldnQ6IE1qb2xuaXJFdmVudCkge1xuICAgIGNvbnN0IHBpY2tlZCA9IHBhcnNlRXZlbnRFbGVtZW50KGV2dCk7XG4gICAgY29uc3Qgc2NyZWVuQ29vcmRzID0gZ2V0U2NyZWVuQ29vcmRzKGV2dCk7XG4gICAgY29uc3QgbWFwQ29vcmRzID0gdGhpcy51bnByb2plY3Qoc2NyZWVuQ29vcmRzKTtcblxuICAgIHJldHVybiB7XG4gICAgICBwaWNrczogcGlja2VkID8gW3BpY2tlZF0gOiBudWxsLFxuICAgICAgc2NyZWVuQ29vcmRzLFxuICAgICAgbWFwQ29vcmRzLFxuICAgICAgc291cmNlRXZlbnQ6IGV2dFxuICAgIH07XG4gIH1cblxuICBfZ2V0SG92ZXJTdGF0ZSA9IChldmVudDogQmFzZUV2ZW50KSA9PiB7XG4gICAgY29uc3Qgb2JqZWN0ID0gZXZlbnQucGlja3MgJiYgZXZlbnQucGlja3NbMF0gJiYgZXZlbnQucGlja3NbMF0ub2JqZWN0O1xuICAgIGlmICghb2JqZWN0KSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgc2NyZWVuQ29vcmRzOiBldmVudC5zY3JlZW5Db29yZHMsXG4gICAgICBtYXBDb29yZHM6IGV2ZW50Lm1hcENvb3JkcyxcbiAgICAgIC4uLm9iamVjdFxuICAgIH07XG4gIH07XG5cbiAgX2lzRHJhd2luZygpIHtcbiAgICBjb25zdCB7IG1vZGUgfSA9IHRoaXMucHJvcHM7XG4gICAgcmV0dXJuIERSQVdJTkdfTU9ERS5maW5kSW5kZXgobSA9PiBtID09PSBtb2RlKSA+PSAwO1xuICB9XG5cbiAgcmVuZGVyKGNoaWxkOiBhbnkpIHtcbiAgICByZXR1cm4gKFxuICAgICAgPE1hcENvbnRleHQuQ29uc3VtZXI+XG4gICAgICAgIHtjb250ZXh0ID0+IHtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbiAgICAgICAgICBjb25zdCB2aWV3cG9ydCA9IGNvbnRleHQgJiYgY29udGV4dC52aWV3cG9ydDtcblxuICAgICAgICAgIGlmICghdmlld3BvcnQgfHwgdmlld3BvcnQuaGVpZ2h0IDw9IDAgfHwgdmlld3BvcnQud2lkdGggPD0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgICB9fVxuICAgICAgPC9NYXBDb250ZXh0LkNvbnN1bWVyPlxuICAgICk7XG4gIH1cbn1cblxuTW9kZUhhbmRsZXIuZGlzcGxheU5hbWUgPSAnTW9kZUhhbmRsZXInO1xuIl19
\No newline at end of file