react-planner-viewer
Version:
react-planner-viewer is a React Component for view plans builded with react-planner in 2D mode
412 lines (331 loc) • 47.6 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = function (state, action) {
switch (action.type) {
case _constants.SELECT_TOOL_DRAWING_LINE:
return selectToolDrawingLine(state, action.sceneComponentType);
case _constants.BEGIN_DRAWING_LINE:
return beginDrawingLine(state, action.layerID, action.x, action.y);
case _constants.UPDATE_DRAWING_LINE:
return updateDrawingLine(state, action.x, action.y);
case _constants.END_DRAWING_LINE:
return endDrawingLine(state, action.x, action.y);
case _constants.BEGIN_DRAGGING_LINE:
return beginDraggingLine(state, action.layerID, action.lineID, action.x, action.y);
case _constants.UPDATE_DRAGGING_LINE:
return updateDraggingLine(state, action.x, action.y);
case _constants.END_DRAGGING_LINE:
return endDraggingLine(state, action.x, action.y);
case _constants.SELECT_LINE:
return selectLine(state, action.layerID, action.lineID);
default:
return state;
}
};
var _immutable = require('immutable');
var _constants = require('../constants');
var _geometry = require('../utils/geometry');
var Geometry = _interopRequireWildcard(_geometry);
var _layerOperations = require('../utils/layer-operations');
var _snap = require('../utils/snap');
var _snapScene = require('../utils/snap-scene');
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function selectToolDrawingLine(state, sceneComponentType) {
return state.merge({
mode: _constants.MODE_WAITING_DRAWING_LINE,
drawingSupport: (0, _immutable.Map)({
type: sceneComponentType
})
});
}
/** lines operations **/
function beginDrawingLine(state, layerID, x, y) {
var catalog = state.catalog;
var snapElements = (0, _snapScene.sceneSnapElements)(state.scene, new _immutable.List(), state.snapMask);
var snap = null;
if (state.snapMask && !state.snapMask.isEmpty()) {
snap = (0, _snap.nearestSnap)(snapElements, x, y, state.snapMask);
if (snap) {
;
var _snap$point = snap.point;
x = _snap$point.x;
y = _snap$point.y;
}snapElements = snapElements.withMutations(function (snapElements) {
var a = void 0,
b = void 0,
c = void 0;
var _Geometry$horizontalL = Geometry.horizontalLine(y);
a = _Geometry$horizontalL.a;
b = _Geometry$horizontalL.b;
c = _Geometry$horizontalL.c;
(0, _snap.addLineSnap)(snapElements, a, b, c, 10, 3, null);
var _Geometry$verticalLin = Geometry.verticalLine(x);
a = _Geometry$verticalLin.a;
b = _Geometry$verticalLin.b;
c = _Geometry$verticalLin.c;
(0, _snap.addLineSnap)(snapElements, a, b, c, 10, 3, null);
});
}
var drawingSupport = state.get('drawingSupport').set('layerID', layerID);
var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
(0, _layerOperations.unselectAll)(layer);
var _addLine = (0, _layerOperations.addLine)(layer, drawingSupport.get('type'), x, y, x, y, catalog),
line = _addLine.line;
(0, _layerOperations.select)(layer, 'lines', line.id);
(0, _layerOperations.select)(layer, 'vertices', line.vertices.get(0));
(0, _layerOperations.select)(layer, 'vertices', line.vertices.get(1));
});
});
return state.merge({
mode: _constants.MODE_DRAWING_LINE,
scene: scene,
snapElements: snapElements,
activeSnapElement: snap ? snap.snap : null,
drawingSupport: drawingSupport
});
}
function updateDrawingLine(state, x, y) {
var snap = null;
if (state.snapMask && !state.snapMask.isEmpty()) {
snap = (0, _snap.nearestSnap)(state.snapElements, x, y, state.snapMask);
if (snap) {
;
var _snap$point2 = snap.point;
x = _snap$point2.x;
y = _snap$point2.y;
}
}
var layerID = state.getIn(['drawingSupport', 'layerID']);
var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var lineID = layer.getIn(['selected', 'lines']).first();
var vertex = void 0;
var _replaceLineVertex = (0, _layerOperations.replaceLineVertex)(layer, lineID, 1, x, y);
layer = _replaceLineVertex.layer;
vertex = _replaceLineVertex.vertex;
(0, _layerOperations.select)(layer, 'vertices', vertex.id);
return layer;
});
});
return state.merge({
scene: scene,
activeSnapElement: snap ? snap.snap : null
});
}
function endDrawingLine(state, x, y) {
var catalog = state.catalog;
if (state.snapMask && !state.snapMask.isEmpty()) {
var snap = (0, _snap.nearestSnap)(state.snapElements, x, y, state.snapMask);
if (snap) {
;
var _snap$point3 = snap.point;
x = _snap$point3.x;
y = _snap$point3.y;
}
}
var layerID = state.getIn(['drawingSupport', 'layerID']);
var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var lineID = layer.getIn(['selected', 'lines']).first();
var line = layer.getIn(['lines', lineID]);
var v0 = layer.vertices.get(line.vertices.get(0));
(0, _layerOperations.unselect)(layer, 'lines', lineID);
(0, _layerOperations.unselect)(layer, 'vertices', line.vertices.get(0));
(0, _layerOperations.unselect)(layer, 'vertices', line.vertices.get(1));
(0, _layerOperations.removeLine)(layer, lineID);
(0, _layerOperations.addLineAvoidingIntersections)(layer, line.type, v0.x, v0.y, x, y, catalog);
(0, _layerOperations.detectAndUpdateAreas)(layer, catalog);
});
});
return state.merge({
mode: _constants.MODE_WAITING_DRAWING_LINE,
scene: scene,
snapElements: new _immutable.List(),
activeSnapElement: null,
sceneHistory: state.sceneHistory.push(scene)
});
}
function beginDraggingLine(state, layerID, lineID, x, y) {
var snapElements = (0, _snapScene.sceneSnapElements)(state.scene, new _immutable.List(), state.snapMask);
var layer = state.scene.layers.get(layerID);
var line = layer.lines.get(lineID);
var vertex0 = layer.vertices.get(line.vertices.get(0));
var vertex1 = layer.vertices.get(line.vertices.get(1));
return state.merge({
mode: _constants.MODE_DRAGGING_LINE,
snapElements: snapElements,
draggingSupport: (0, _immutable.Map)({
layerID: layerID, lineID: lineID,
startPointX: x,
startPointY: y,
startVertex0X: vertex0.x,
startVertex0Y: vertex0.y,
startVertex1X: vertex1.x,
startVertex1Y: vertex1.y
})
});
}
function updateDraggingLine(state, x, y) {
var draggingSupport = state.draggingSupport;
var snapElements = state.snapElements;
var layerID = draggingSupport.get('layerID');
var lineID = draggingSupport.get('lineID');
var diffX = x - draggingSupport.get('startPointX');
var diffY = y - draggingSupport.get('startPointY');
var newVertex0X = draggingSupport.get('startVertex0X') + diffX;
var newVertex0Y = draggingSupport.get('startVertex0Y') + diffY;
var newVertex1X = draggingSupport.get('startVertex1X') + diffX;
var newVertex1Y = draggingSupport.get('startVertex1Y') + diffY;
var activeSnapElement = null;
var curSnap0 = null,
curSnap1 = null;
if (state.snapMask && !state.snapMask.isEmpty()) {
curSnap0 = (0, _snap.nearestSnap)(snapElements, newVertex0X, newVertex0Y, state.snapMask);
curSnap1 = (0, _snap.nearestSnap)(snapElements, newVertex1X, newVertex1Y, state.snapMask);
}
var deltaX = 0,
deltaY = 0;
if (curSnap0 && curSnap1) {
if (curSnap0.point.distance < curSnap1.point.distance) {
deltaX = curSnap0.point.x - newVertex0X;
deltaY = curSnap0.point.y - newVertex0Y;
activeSnapElement = curSnap0.snap;
} else {
deltaX = curSnap1.point.x - newVertex1X;
deltaY = curSnap1.point.y - newVertex1Y;
activeSnapElement = curSnap1.snap;
}
} else {
if (curSnap0) {
deltaX = curSnap0.point.x - newVertex0X;
deltaY = curSnap0.point.y - newVertex0Y;
activeSnapElement = curSnap0.snap;
}
if (curSnap1) {
deltaX = curSnap1.point.x - newVertex1X;
deltaY = curSnap1.point.y - newVertex1Y;
activeSnapElement = curSnap1.snap;
}
}
newVertex0X += deltaX;
newVertex0Y += deltaY;
newVertex1X += deltaX;
newVertex1Y += deltaY;
return state.merge({
activeSnapElement: activeSnapElement,
scene: state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var lineVertices = layer.getIn(['lines', lineID, 'vertices']);
layer.updateIn(['vertices', lineVertices.get(0)], function (vertex) {
return vertex.merge({ x: newVertex0X, y: newVertex0Y });
});
layer.updateIn(['vertices', lineVertices.get(1)], function (vertex) {
return vertex.merge({ x: newVertex1X, y: newVertex1Y });
});
return layer;
});
})
});
}
function endDraggingLine(state, x, y) {
var catalog = state.catalog;
var draggingSupport = state.draggingSupport;
var layerID = draggingSupport.get('layerID');
var layer = state.scene.layers.get(layerID);
var lineID = draggingSupport.get('lineID');
var line = layer.lines.get(lineID);
var vertex0 = layer.vertices.get(line.vertices.get(0));
var vertex1 = layer.vertices.get(line.vertices.get(1));
var maxV = Geometry.maxVertex(vertex0, vertex1);
var minV = Geometry.minVertex(vertex0, vertex1);
var lineLength = Geometry.verticesDistance(minV, maxV);
var alpha = Math.atan2(maxV.y - minV.y, maxV.x - minV.x);
var holesWithOffsetPosition = [];
layer.lines.get(lineID).holes.forEach(function (holeID) {
var hole = layer.holes.get(holeID);
var pointOnLine = lineLength * hole.offset;
var offsetPosition = {
x: pointOnLine * Math.cos(alpha) + minV.x,
y: pointOnLine * Math.sin(alpha) + minV.y
};
holesWithOffsetPosition.push({ hole: hole, offsetPosition: offsetPosition });
});
return state.withMutations(function (state) {
var scene = state.scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var diffX = x - draggingSupport.get('startPointX');
var diffY = y - draggingSupport.get('startPointY');
var newVertex0X = draggingSupport.get('startVertex0X') + diffX;
var newVertex0Y = draggingSupport.get('startVertex0Y') + diffY;
var newVertex1X = draggingSupport.get('startVertex1X') + diffX;
var newVertex1Y = draggingSupport.get('startVertex1Y') + diffY;
if (state.snapMask && !state.snapMask.isEmpty()) {
var curSnap0 = (0, _snap.nearestSnap)(state.snapElements, newVertex0X, newVertex0Y, state.snapMask);
var curSnap1 = (0, _snap.nearestSnap)(state.snapElements, newVertex1X, newVertex1Y, state.snapMask);
var deltaX = 0,
deltaY = 0;
if (curSnap0 && curSnap1) {
if (curSnap0.point.distance < curSnap1.point.distance) {
deltaX = curSnap0.point.x - newVertex0X;
deltaY = curSnap0.point.y - newVertex0Y;
} else {
deltaX = curSnap1.point.x - newVertex1X;
deltaY = curSnap1.point.y - newVertex1Y;
}
} else {
if (curSnap0) {
deltaX = curSnap0.point.x - newVertex0X;
deltaY = curSnap0.point.y - newVertex0Y;
}
if (curSnap1) {
deltaX = curSnap1.point.x - newVertex1X;
deltaY = curSnap1.point.y - newVertex1Y;
}
}
newVertex0X += deltaX;
newVertex0Y += deltaY;
newVertex1X += deltaX;
newVertex1Y += deltaY;
}
(0, _layerOperations.mergeEqualsVertices)(layer, line.vertices.get(0));
(0, _layerOperations.mergeEqualsVertices)(layer, line.vertices.get(1));
(0, _layerOperations.removeLine)(layer, lineID);
if (!(0, _geometry.samePoints)({ newVertex0X: newVertex0X, newVertex0Y: newVertex0Y }, { newVertex1X: newVertex1X, newVertex1Y: newVertex1Y })) {
(0, _layerOperations.addLineAvoidingIntersections)(layer, line.type, newVertex0X, newVertex0Y, newVertex1X, newVertex1Y, catalog, line.properties, holesWithOffsetPosition);
}
(0, _layerOperations.detectAndUpdateAreas)(layer, catalog);
});
});
state.merge({
mode: _constants.MODE_IDLE,
scene: scene,
draggingSupport: null,
activeSnapElement: null,
snapElements: new _immutable.List(),
sceneHistory: state.sceneHistory.push(scene)
});
});
}
function selectLine(state, layerID, lineID) {
var scene = state.scene;
scene = scene.merge({
layers: scene.layers.map(_layerOperations.unselectAll),
selectedLayer: layerID
});
scene = scene.updateIn(['layers', layerID], function (layer) {
return layer.withMutations(function (layer) {
var line = layer.getIn(['lines', lineID]);
(0, _layerOperations.select)(layer, 'lines', lineID);
(0, _layerOperations.select)(layer, 'vertices', line.vertices.get(0));
(0, _layerOperations.select)(layer, 'vertices', line.vertices.get(1));
});
});
return state.merge({
scene: scene,
sceneHistory: state.sceneHistory.push(scene)
});
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9yZWR1Y2Vycy9saW5lcy1yZWR1Y2VyLmpzIl0sIm5hbWVzIjpbInN0YXRlIiwiYWN0aW9uIiwidHlwZSIsInNlbGVjdFRvb2xEcmF3aW5nTGluZSIsInNjZW5lQ29tcG9uZW50VHlwZSIsImJlZ2luRHJhd2luZ0xpbmUiLCJsYXllcklEIiwieCIsInkiLCJ1cGRhdGVEcmF3aW5nTGluZSIsImVuZERyYXdpbmdMaW5lIiwiYmVnaW5EcmFnZ2luZ0xpbmUiLCJsaW5lSUQiLCJ1cGRhdGVEcmFnZ2luZ0xpbmUiLCJlbmREcmFnZ2luZ0xpbmUiLCJzZWxlY3RMaW5lIiwiR2VvbWV0cnkiLCJtZXJnZSIsIm1vZGUiLCJkcmF3aW5nU3VwcG9ydCIsImNhdGFsb2ciLCJzbmFwRWxlbWVudHMiLCJzY2VuZSIsInNuYXBNYXNrIiwic25hcCIsImlzRW1wdHkiLCJwb2ludCIsIndpdGhNdXRhdGlvbnMiLCJhIiwiYiIsImMiLCJob3Jpem9udGFsTGluZSIsInZlcnRpY2FsTGluZSIsImdldCIsInNldCIsInVwZGF0ZUluIiwibGF5ZXIiLCJsaW5lIiwiaWQiLCJ2ZXJ0aWNlcyIsImFjdGl2ZVNuYXBFbGVtZW50IiwiZ2V0SW4iLCJmaXJzdCIsInZlcnRleCIsInYwIiwic2NlbmVIaXN0b3J5IiwicHVzaCIsImxheWVycyIsImxpbmVzIiwidmVydGV4MCIsInZlcnRleDEiLCJkcmFnZ2luZ1N1cHBvcnQiLCJzdGFydFBvaW50WCIsInN0YXJ0UG9pbnRZIiwic3RhcnRWZXJ0ZXgwWCIsInN0YXJ0VmVydGV4MFkiLCJzdGFydFZlcnRleDFYIiwic3RhcnRWZXJ0ZXgxWSIsImRpZmZYIiwiZGlmZlkiLCJuZXdWZXJ0ZXgwWCIsIm5ld1ZlcnRleDBZIiwibmV3VmVydGV4MVgiLCJuZXdWZXJ0ZXgxWSIsImN1clNuYXAwIiwiY3VyU25hcDEiLCJkZWx0YVgiLCJkZWx0YVkiLCJkaXN0YW5jZSIsImxpbmVWZXJ0aWNlcyIsIm1heFYiLCJtYXhWZXJ0ZXgiLCJtaW5WIiwibWluVmVydGV4IiwibGluZUxlbmd0aCIsInZlcnRpY2VzRGlzdGFuY2UiLCJhbHBoYSIsIk1hdGgiLCJhdGFuMiIsImhvbGVzV2l0aE9mZnNldFBvc2l0aW9uIiwiaG9sZXMiLCJmb3JFYWNoIiwiaG9sZSIsImhvbGVJRCIsInBvaW50T25MaW5lIiwib2Zmc2V0Iiwib2Zmc2V0UG9zaXRpb24iLCJjb3MiLCJzaW4iLCJwcm9wZXJ0aWVzIiwibWFwIiwic2VsZWN0ZWRMYXllciJdLCJtYXBwaW5ncyI6Ijs7Ozs7O2tCQWdDZSxVQUFVQSxLQUFWLEVBQWlCQyxNQUFqQixFQUF5QjtBQUN0QyxVQUFRQSxPQUFPQyxJQUFmO0FBQ0U7QUFDRSxhQUFPQyxzQkFBc0JILEtBQXRCLEVBQTZCQyxPQUFPRyxrQkFBcEMsQ0FBUDs7QUFFRjtBQUNFLGFBQU9DLGlCQUFpQkwsS0FBakIsRUFBd0JDLE9BQU9LLE9BQS9CLEVBQXdDTCxPQUFPTSxDQUEvQyxFQUFrRE4sT0FBT08sQ0FBekQsQ0FBUDs7QUFFRjtBQUNFLGFBQU9DLGtCQUFrQlQsS0FBbEIsRUFBeUJDLE9BQU9NLENBQWhDLEVBQW1DTixPQUFPTyxDQUExQyxDQUFQOztBQUVGO0FBQ0UsYUFBT0UsZUFBZVYsS0FBZixFQUFzQkMsT0FBT00sQ0FBN0IsRUFBZ0NOLE9BQU9PLENBQXZDLENBQVA7O0FBRUY7QUFDRSxhQUFPRyxrQkFBa0JYLEtBQWxCLEVBQXlCQyxPQUFPSyxPQUFoQyxFQUF5Q0wsT0FBT1csTUFBaEQsRUFBd0RYLE9BQU9NLENBQS9ELEVBQWtFTixPQUFPTyxDQUF6RSxDQUFQOztBQUVGO0FBQ0UsYUFBT0ssbUJBQW1CYixLQUFuQixFQUEwQkMsT0FBT00sQ0FBakMsRUFBb0NOLE9BQU9PLENBQTNDLENBQVA7O0FBRUY7QUFDRSxhQUFPTSxnQkFBZ0JkLEtBQWhCLEVBQXVCQyxPQUFPTSxDQUE5QixFQUFpQ04sT0FBT08sQ0FBeEMsQ0FBUDs7QUFFRjtBQUNFLGFBQU9PLFdBQVdmLEtBQVgsRUFBa0JDLE9BQU9LLE9BQXpCLEVBQWtDTCxPQUFPVyxNQUF6QyxDQUFQOztBQUVGO0FBQ0UsYUFBT1osS0FBUDtBQTFCSjtBQTRCRCxDOztBQTdERDs7QUFFQTs7QUFlQTs7SUFBWWdCLFE7O0FBQ1o7O0FBVUE7O0FBQ0E7Ozs7QUFrQ0EsU0FBU2IscUJBQVQsQ0FBK0JILEtBQS9CLEVBQXNDSSxrQkFBdEMsRUFBMEQ7QUFDeEQsU0FBT0osTUFBTWlCLEtBQU4sQ0FBWTtBQUNqQkMsOENBRGlCO0FBRWpCQyxvQkFBZ0Isb0JBQUk7QUFDbEJqQixZQUFNRTtBQURZLEtBQUo7QUFGQyxHQUFaLENBQVA7QUFNRDs7QUFFRDtBQUNBLFNBQVNDLGdCQUFULENBQTBCTCxLQUExQixFQUFpQ00sT0FBakMsRUFBMENDLENBQTFDLEVBQTZDQyxDQUE3QyxFQUFnRDtBQUM5QyxNQUFJWSxVQUFVcEIsTUFBTW9CLE9BQXBCOztBQUVBLE1BQUlDLGVBQWUsa0NBQWtCckIsTUFBTXNCLEtBQXhCLEVBQStCLHFCQUEvQixFQUEyQ3RCLE1BQU11QixRQUFqRCxDQUFuQjtBQUNBLE1BQUlDLE9BQU8sSUFBWDs7QUFFQSxNQUFJeEIsTUFBTXVCLFFBQU4sSUFBa0IsQ0FBQ3ZCLE1BQU11QixRQUFOLENBQWVFLE9BQWYsRUFBdkIsRUFBaUQ7QUFDL0NELFdBQU8sdUJBQVlILFlBQVosRUFBMEJkLENBQTFCLEVBQTZCQyxDQUE3QixFQUFnQ1IsTUFBTXVCLFFBQXRDLENBQVA7QUFDQSxRQUFJQyxJQUFKO0FBQVU7O0FBQVYsd0JBQW9CQSxLQUFLRSxLQUF6QjtBQUFZbkIsT0FBWixlQUFZQSxDQUFaO0FBQWVDLE9BQWYsZUFBZUEsQ0FBZjtBQUFBLEtBRUFhLGVBQWVBLGFBQWFNLGFBQWIsQ0FBMkIsd0JBQWdCO0FBQ3hELFVBQUlDLFVBQUo7QUFBQSxVQUFPQyxVQUFQO0FBQUEsVUFBVUMsVUFBVjs7QUFEd0Qsa0NBRTNDZCxTQUFTZSxjQUFULENBQXdCdkIsQ0FBeEIsQ0FGMkM7O0FBRXREb0IsT0FGc0QseUJBRXREQSxDQUZzRDtBQUVuREMsT0FGbUQseUJBRW5EQSxDQUZtRDtBQUVoREMsT0FGZ0QseUJBRWhEQSxDQUZnRDs7QUFHeEQsNkJBQVlULFlBQVosRUFBMEJPLENBQTFCLEVBQTZCQyxDQUE3QixFQUFnQ0MsQ0FBaEMsRUFBbUMsRUFBbkMsRUFBdUMsQ0FBdkMsRUFBMEMsSUFBMUM7O0FBSHdELGtDQUkzQ2QsU0FBU2dCLFlBQVQsQ0FBc0J6QixDQUF0QixDQUoyQzs7QUFJdERxQixPQUpzRCx5QkFJdERBLENBSnNEO0FBSW5EQyxPQUptRCx5QkFJbkRBLENBSm1EO0FBSWhEQyxPQUpnRCx5QkFJaERBLENBSmdEOztBQUt4RCw2QkFBWVQsWUFBWixFQUEwQk8sQ0FBMUIsRUFBNkJDLENBQTdCLEVBQWdDQyxDQUFoQyxFQUFtQyxFQUFuQyxFQUF1QyxDQUF2QyxFQUEwQyxJQUExQztBQUNELEtBTmMsQ0FBZjtBQU9EOztBQUVELE1BQUlYLGlCQUFpQm5CLE1BQU1pQyxHQUFOLENBQVUsZ0JBQVYsRUFBNEJDLEdBQTVCLENBQWdDLFNBQWhDLEVBQTJDNUIsT0FBM0MsQ0FBckI7QUFDQSxNQUFJZ0IsUUFBUXRCLE1BQU1zQixLQUFOLENBQVlhLFFBQVosQ0FBcUIsQ0FBQyxRQUFELEVBQVc3QixPQUFYLENBQXJCLEVBQTBDO0FBQUEsV0FBUzhCLE1BQU1ULGFBQU4sQ0FBb0IsaUJBQVM7QUFDMUYsd0NBQVlTLEtBQVo7O0FBRDBGLHFCQUU3RSw4QkFBUUEsS0FBUixFQUFlakIsZUFBZWMsR0FBZixDQUFtQixNQUFuQixDQUFmLEVBQTJDMUIsQ0FBM0MsRUFBOENDLENBQTlDLEVBQWlERCxDQUFqRCxFQUFvREMsQ0FBcEQsRUFBdURZLE9BQXZELENBRjZFO0FBQUEsVUFFckZpQixJQUZxRixZQUVyRkEsSUFGcUY7O0FBRzFGLG1DQUFPRCxLQUFQLEVBQWMsT0FBZCxFQUF1QkMsS0FBS0MsRUFBNUI7QUFDQSxtQ0FBT0YsS0FBUCxFQUFjLFVBQWQsRUFBMEJDLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUExQjtBQUNBLG1DQUFPRyxLQUFQLEVBQWMsVUFBZCxFQUEwQkMsS0FBS0UsUUFBTCxDQUFjTixHQUFkLENBQWtCLENBQWxCLENBQTFCO0FBQ0QsS0FOOEQsQ0FBVDtBQUFBLEdBQTFDLENBQVo7O0FBUUEsU0FBT2pDLE1BQU1pQixLQUFOLENBQVk7QUFDakJDLHNDQURpQjtBQUVqQkksZ0JBRmlCO0FBR2pCRCw4QkFIaUI7QUFJakJtQix1QkFBbUJoQixPQUFPQSxLQUFLQSxJQUFaLEdBQW1CLElBSnJCO0FBS2pCTDtBQUxpQixHQUFaLENBQVA7QUFPRDs7QUFFRCxTQUFTVixpQkFBVCxDQUEyQlQsS0FBM0IsRUFBa0NPLENBQWxDLEVBQXFDQyxDQUFyQyxFQUF3Qzs7QUFFdEMsTUFBSWdCLE9BQU8sSUFBWDtBQUNBLE1BQUl4QixNQUFNdUIsUUFBTixJQUFrQixDQUFDdkIsTUFBTXVCLFFBQU4sQ0FBZUUsT0FBZixFQUF2QixFQUFpRDtBQUMvQ0QsV0FBTyx1QkFBWXhCLE1BQU1xQixZQUFsQixFQUFnQ2QsQ0FBaEMsRUFBbUNDLENBQW5DLEVBQXNDUixNQUFNdUIsUUFBNUMsQ0FBUDtBQUNBLFFBQUlDLElBQUo7QUFBVTtBQUFWLHlCQUFvQkEsS0FBS0UsS0FBekI7QUFBWW5CLE9BQVosZ0JBQVlBLENBQVo7QUFBZUMsT0FBZixnQkFBZUEsQ0FBZjtBQUFBO0FBQ0Q7O0FBRUQsTUFBSUYsVUFBVU4sTUFBTXlDLEtBQU4sQ0FBWSxDQUFDLGdCQUFELEVBQW1CLFNBQW5CLENBQVosQ0FBZDtBQUNBLE1BQUluQixRQUFRdEIsTUFBTXNCLEtBQU4sQ0FBWWEsUUFBWixDQUFxQixDQUFDLFFBQUQsRUFBVzdCLE9BQVgsQ0FBckIsRUFBMEM7QUFBQSxXQUFTOEIsTUFBTVQsYUFBTixDQUFvQixpQkFBUztBQUMxRixVQUFJZixTQUFTd0IsTUFBTUssS0FBTixDQUFZLENBQUMsVUFBRCxFQUFhLE9BQWIsQ0FBWixFQUFtQ0MsS0FBbkMsRUFBYjtBQUNBLFVBQUlDLGVBQUo7O0FBRjBGLCtCQUd2RSx3Q0FBa0JQLEtBQWxCLEVBQXlCeEIsTUFBekIsRUFBaUMsQ0FBakMsRUFBb0NMLENBQXBDLEVBQXVDQyxDQUF2QyxDQUh1RTs7QUFHeEY0QixXQUh3RixzQkFHeEZBLEtBSHdGO0FBR2pGTyxZQUhpRixzQkFHakZBLE1BSGlGOztBQUkxRixtQ0FBT1AsS0FBUCxFQUFjLFVBQWQsRUFBMEJPLE9BQU9MLEVBQWpDO0FBQ0EsYUFBT0YsS0FBUDtBQUNELEtBTjhELENBQVQ7QUFBQSxHQUExQyxDQUFaOztBQVFBLFNBQU9wQyxNQUFNaUIsS0FBTixDQUFZO0FBQ2pCSyxnQkFEaUI7QUFFakJrQix1QkFBbUJoQixPQUFPQSxLQUFLQSxJQUFaLEdBQW1CO0FBRnJCLEdBQVosQ0FBUDtBQUlEOztBQUVELFNBQVNkLGNBQVQsQ0FBd0JWLEtBQXhCLEVBQStCTyxDQUEvQixFQUFrQ0MsQ0FBbEMsRUFBcUM7O0FBRW5DLE1BQUlZLFVBQVVwQixNQUFNb0IsT0FBcEI7O0FBRUEsTUFBSXBCLE1BQU11QixRQUFOLElBQWtCLENBQUN2QixNQUFNdUIsUUFBTixDQUFlRSxPQUFmLEVBQXZCLEVBQWlEO0FBQy9DLFFBQUlELE9BQU8sdUJBQVl4QixNQUFNcUIsWUFBbEIsRUFBZ0NkLENBQWhDLEVBQW1DQyxDQUFuQyxFQUFzQ1IsTUFBTXVCLFFBQTVDLENBQVg7QUFDQSxRQUFJQyxJQUFKO0FBQVU7QUFBVix5QkFBb0JBLEtBQUtFLEtBQXpCO0FBQVluQixPQUFaLGdCQUFZQSxDQUFaO0FBQWVDLE9BQWYsZ0JBQWVBLENBQWY7QUFBQTtBQUNEOztBQUVELE1BQUlGLFVBQVVOLE1BQU15QyxLQUFOLENBQVksQ0FBQyxnQkFBRCxFQUFtQixTQUFuQixDQUFaLENBQWQ7QUFDQSxNQUFJbkIsUUFBUXRCLE1BQU1zQixLQUFOLENBQVlhLFFBQVosQ0FBcUIsQ0FBQyxRQUFELEVBQVc3QixPQUFYLENBQXJCLEVBQTBDO0FBQUEsV0FBUzhCLE1BQU1ULGFBQU4sQ0FBb0IsaUJBQVM7QUFDMUYsVUFBSWYsU0FBU3dCLE1BQU1LLEtBQU4sQ0FBWSxDQUFDLFVBQUQsRUFBYSxPQUFiLENBQVosRUFBbUNDLEtBQW5DLEVBQWI7QUFDQSxVQUFJTCxPQUFPRCxNQUFNSyxLQUFOLENBQVksQ0FBQyxPQUFELEVBQVU3QixNQUFWLENBQVosQ0FBWDtBQUNBLFVBQUlnQyxLQUFLUixNQUFNRyxRQUFOLENBQWVOLEdBQWYsQ0FBbUJJLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUFuQixDQUFUOztBQUVBLHFDQUFTRyxLQUFULEVBQWdCLE9BQWhCLEVBQXlCeEIsTUFBekI7QUFDQSxxQ0FBU3dCLEtBQVQsRUFBZ0IsVUFBaEIsRUFBNEJDLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUE1QjtBQUNBLHFDQUFTRyxLQUFULEVBQWdCLFVBQWhCLEVBQTRCQyxLQUFLRSxRQUFMLENBQWNOLEdBQWQsQ0FBa0IsQ0FBbEIsQ0FBNUI7QUFDQSx1Q0FBV0csS0FBWCxFQUFrQnhCLE1BQWxCO0FBQ0EseURBQTZCd0IsS0FBN0IsRUFBb0NDLEtBQUtuQyxJQUF6QyxFQUErQzBDLEdBQUdyQyxDQUFsRCxFQUFxRHFDLEdBQUdwQyxDQUF4RCxFQUEyREQsQ0FBM0QsRUFBOERDLENBQTlELEVBQWlFWSxPQUFqRTtBQUNBLGlEQUFxQmdCLEtBQXJCLEVBQTRCaEIsT0FBNUI7QUFDRCxLQVg4RCxDQUFUO0FBQUEsR0FBMUMsQ0FBWjs7QUFhQSxTQUFPcEIsTUFBTWlCLEtBQU4sQ0FBWTtBQUNqQkMsOENBRGlCO0FBRWpCSSxnQkFGaUI7QUFHakJELGtCQUFjLHFCQUhHO0FBSWpCbUIsdUJBQW1CLElBSkY7QUFLakJLLGtCQUFjN0MsTUFBTTZDLFlBQU4sQ0FBbUJDLElBQW5CLENBQXdCeEIsS0FBeEI7QUFMRyxHQUFaLENBQVA7QUFPRDs7QUFFRCxTQUFTWCxpQkFBVCxDQUEyQlgsS0FBM0IsRUFBa0NNLE9BQWxDLEVBQTJDTSxNQUEzQyxFQUFtREwsQ0FBbkQsRUFBc0RDLENBQXRELEVBQXlEOztBQUV2RCxNQUFJYSxlQUFlLGtDQUFrQnJCLE1BQU1zQixLQUF4QixFQUErQixxQkFBL0IsRUFBMkN0QixNQUFNdUIsUUFBakQsQ0FBbkI7O0FBRUEsTUFBSWEsUUFBUXBDLE1BQU1zQixLQUFOLENBQVl5QixNQUFaLENBQW1CZCxHQUFuQixDQUF1QjNCLE9BQXZCLENBQVo7QUFDQSxNQUFJK0IsT0FBT0QsTUFBTVksS0FBTixDQUFZZixHQUFaLENBQWdCckIsTUFBaEIsQ0FBWDs7QUFFQSxNQUFJcUMsVUFBVWIsTUFBTUcsUUFBTixDQUFlTixHQUFmLENBQW1CSSxLQUFLRSxRQUFMLENBQWNOLEdBQWQsQ0FBa0IsQ0FBbEIsQ0FBbkIsQ0FBZDtBQUNBLE1BQUlpQixVQUFVZCxNQUFNRyxRQUFOLENBQWVOLEdBQWYsQ0FBbUJJLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUFuQixDQUFkOztBQUVBLFNBQU9qQyxNQUFNaUIsS0FBTixDQUFZO0FBQ2pCQyx1Q0FEaUI7QUFFakJHLDhCQUZpQjtBQUdqQjhCLHFCQUFpQixvQkFBSTtBQUNuQjdDLHNCQURtQixFQUNWTSxjQURVO0FBRW5Cd0MsbUJBQWE3QyxDQUZNO0FBR25COEMsbUJBQWE3QyxDQUhNO0FBSW5COEMscUJBQWVMLFFBQVExQyxDQUpKO0FBS25CZ0QscUJBQWVOLFFBQVF6QyxDQUxKO0FBTW5CZ0QscUJBQWVOLFFBQVEzQyxDQU5KO0FBT25Ca0QscUJBQWVQLFFBQVExQztBQVBKLEtBQUo7QUFIQSxHQUFaLENBQVA7QUFhRDs7QUFFRCxTQUFTSyxrQkFBVCxDQUE0QmIsS0FBNUIsRUFBbUNPLENBQW5DLEVBQXNDQyxDQUF0QyxFQUF5Qzs7QUFFdkMsTUFBSTJDLGtCQUFrQm5ELE1BQU1tRCxlQUE1QjtBQUNBLE1BQUk5QixlQUFlckIsTUFBTXFCLFlBQXpCOztBQUVBLE1BQUlmLFVBQVU2QyxnQkFBZ0JsQixHQUFoQixDQUFvQixTQUFwQixDQUFkO0FBQ0EsTUFBSXJCLFNBQVN1QyxnQkFBZ0JsQixHQUFoQixDQUFvQixRQUFwQixDQUFiO0FBQ0EsTUFBSXlCLFFBQVFuRCxJQUFJNEMsZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsYUFBcEIsQ0FBaEI7QUFDQSxNQUFJMEIsUUFBUW5ELElBQUkyQyxnQkFBZ0JsQixHQUFoQixDQUFvQixhQUFwQixDQUFoQjtBQUNBLE1BQUkyQixjQUFjVCxnQkFBZ0JsQixHQUFoQixDQUFvQixlQUFwQixJQUF1Q3lCLEtBQXpEO0FBQ0EsTUFBSUcsY0FBY1YsZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsZUFBcEIsSUFBdUMwQixLQUF6RDtBQUNBLE1BQUlHLGNBQWNYLGdCQUFnQmxCLEdBQWhCLENBQW9CLGVBQXBCLElBQXVDeUIsS0FBekQ7QUFDQSxNQUFJSyxjQUFjWixnQkFBZ0JsQixHQUFoQixDQUFvQixlQUFwQixJQUF1QzBCLEtBQXpEOztBQUdBLE1BQUluQixvQkFBb0IsSUFBeEI7QUFDQSxNQUFJd0IsV0FBVyxJQUFmO0FBQUEsTUFBcUJDLFdBQVcsSUFBaEM7QUFDQSxNQUFJakUsTUFBTXVCLFFBQU4sSUFBa0IsQ0FBQ3ZCLE1BQU11QixRQUFOLENBQWVFLE9BQWYsRUFBdkIsRUFBaUQ7QUFDL0N1QyxlQUFXLHVCQUFZM0MsWUFBWixFQUEwQnVDLFdBQTFCLEVBQXVDQyxXQUF2QyxFQUFvRDdELE1BQU11QixRQUExRCxDQUFYO0FBQ0EwQyxlQUFXLHVCQUFZNUMsWUFBWixFQUEwQnlDLFdBQTFCLEVBQXVDQyxXQUF2QyxFQUFvRC9ELE1BQU11QixRQUExRCxDQUFYO0FBQ0Q7O0FBRUQsTUFBSTJDLFNBQVMsQ0FBYjtBQUFBLE1BQWdCQyxTQUFTLENBQXpCO0FBQ0EsTUFBSUgsWUFBWUMsUUFBaEIsRUFBMEI7QUFDeEIsUUFBSUQsU0FBU3RDLEtBQVQsQ0FBZTBDLFFBQWYsR0FBMEJILFNBQVN2QyxLQUFULENBQWUwQyxRQUE3QyxFQUF1RDtBQUNyREYsZUFBU0YsU0FBU3RDLEtBQVQsQ0FBZW5CLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNBTyxlQUFTSCxTQUFTdEMsS0FBVCxDQUFlbEIsQ0FBZixHQUFtQnFELFdBQTVCO0FBQ0FyQiwwQkFBb0J3QixTQUFTeEMsSUFBN0I7QUFDRCxLQUpELE1BSU87QUFDTDBDLGVBQVNELFNBQVN2QyxLQUFULENBQWVuQixDQUFmLEdBQW1CdUQsV0FBNUI7QUFDQUssZUFBU0YsU0FBU3ZDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNBdkIsMEJBQW9CeUIsU0FBU3pDLElBQTdCO0FBQ0Q7QUFDRixHQVZELE1BVU87QUFDTCxRQUFJd0MsUUFBSixFQUFjO0FBQ1pFLGVBQVNGLFNBQVN0QyxLQUFULENBQWVuQixDQUFmLEdBQW1CcUQsV0FBNUI7QUFDQU8sZUFBU0gsU0FBU3RDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNBckIsMEJBQW9Cd0IsU0FBU3hDLElBQTdCO0FBQ0Q7QUFDRCxRQUFJeUMsUUFBSixFQUFjO0FBQ1pDLGVBQVNELFNBQVN2QyxLQUFULENBQWVuQixDQUFmLEdBQW1CdUQsV0FBNUI7QUFDQUssZUFBU0YsU0FBU3ZDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNBdkIsMEJBQW9CeUIsU0FBU3pDLElBQTdCO0FBQ0Q7QUFDRjs7QUFFRG9DLGlCQUFlTSxNQUFmO0FBQ0FMLGlCQUFlTSxNQUFmO0FBQ0FMLGlCQUFlSSxNQUFmO0FBQ0FILGlCQUFlSSxNQUFmOztBQUVBLFNBQU9uRSxNQUFNaUIsS0FBTixDQUFZO0FBQ2pCdUIsd0NBRGlCO0FBRWpCbEIsV0FBT3RCLE1BQU1zQixLQUFOLENBQVlhLFFBQVosQ0FBcUIsQ0FBQyxRQUFELEVBQVc3QixPQUFYLENBQXJCLEVBQTBDO0FBQUEsYUFBUzhCLE1BQU1ULGFBQU4sQ0FBb0IsaUJBQVM7QUFDckYsWUFBSTBDLGVBQWVqQyxNQUFNSyxLQUFOLENBQVksQ0FBQyxPQUFELEVBQVU3QixNQUFWLEVBQWtCLFVBQWxCLENBQVosQ0FBbkI7QUFDQXdCLGNBQU1ELFFBQU4sQ0FBZSxDQUFDLFVBQUQsRUFBYWtDLGFBQWFwQyxHQUFiLENBQWlCLENBQWpCLENBQWIsQ0FBZixFQUFrRDtBQUFBLGlCQUFVVSxPQUFPMUIsS0FBUCxDQUFhLEVBQUNWLEdBQUdxRCxXQUFKLEVBQWlCcEQsR0FBR3FELFdBQXBCLEVBQWIsQ0FBVjtBQUFBLFNBQWxEO0FBQ0F6QixjQUFNRCxRQUFOLENBQWUsQ0FBQyxVQUFELEVBQWFrQyxhQUFhcEMsR0FBYixDQUFpQixDQUFqQixDQUFiLENBQWYsRUFBa0Q7QUFBQSxpQkFBVVUsT0FBTzFCLEtBQVAsQ0FBYSxFQUFDVixHQUFHdUQsV0FBSixFQUFpQnRELEdBQUd1RCxXQUFwQixFQUFiLENBQVY7QUFBQSxTQUFsRDtBQUNBLGVBQU8zQixLQUFQO0FBQ0QsT0FMeUQsQ0FBVDtBQUFBLEtBQTFDO0FBRlUsR0FBWixDQUFQO0FBU0Q7O0FBRUQsU0FBU3RCLGVBQVQsQ0FBeUJkLEtBQXpCLEVBQWdDTyxDQUFoQyxFQUFtQ0MsQ0FBbkMsRUFBc0M7QUFDcEMsTUFBSVksVUFBVXBCLE1BQU1vQixPQUFwQjtBQURvQyxNQUUvQitCLGVBRitCLEdBRVpuRCxLQUZZLENBRS9CbUQsZUFGK0I7O0FBR3BDLE1BQUk3QyxVQUFVNkMsZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsU0FBcEIsQ0FBZDtBQUNBLE1BQUlHLFFBQVFwQyxNQUFNc0IsS0FBTixDQUFZeUIsTUFBWixDQUFtQmQsR0FBbkIsQ0FBdUIzQixPQUF2QixDQUFaO0FBQ0EsTUFBSU0sU0FBU3VDLGdCQUFnQmxCLEdBQWhCLENBQW9CLFFBQXBCLENBQWI7QUFDQSxNQUFJSSxPQUFPRCxNQUFNWSxLQUFOLENBQVlmLEdBQVosQ0FBZ0JyQixNQUFoQixDQUFYOztBQUVBLE1BQUlxQyxVQUFVYixNQUFNRyxRQUFOLENBQWVOLEdBQWYsQ0FBbUJJLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUFuQixDQUFkO0FBQ0EsTUFBSWlCLFVBQVVkLE1BQU1HLFFBQU4sQ0FBZU4sR0FBZixDQUFtQkksS0FBS0UsUUFBTCxDQUFjTixHQUFkLENBQWtCLENBQWxCLENBQW5CLENBQWQ7O0FBRUEsTUFBSXFDLE9BQU90RCxTQUFTdUQsU0FBVCxDQUFtQnRCLE9BQW5CLEVBQTRCQyxPQUE1QixDQUFYO0FBQ0EsTUFBSXNCLE9BQU94RCxTQUFTeUQsU0FBVCxDQUFtQnhCLE9BQW5CLEVBQTRCQyxPQUE1QixDQUFYOztBQUVBLE1BQUl3QixhQUFhMUQsU0FBUzJELGdCQUFULENBQTBCSCxJQUExQixFQUErQkYsSUFBL0IsQ0FBakI7QUFDQSxNQUFJTSxRQUFRQyxLQUFLQyxLQUFMLENBQVdSLEtBQUs5RCxDQUFMLEdBQVNnRSxLQUFLaEUsQ0FBekIsRUFBNEI4RCxLQUFLL0QsQ0FBTCxHQUFTaUUsS0FBS2pFLENBQTFDLENBQVo7O0FBRUEsTUFBSXdFLDBCQUEwQixFQUE5QjtBQUNBM0MsUUFBTVksS0FBTixDQUFZZixHQUFaLENBQWdCckIsTUFBaEIsRUFBd0JvRSxLQUF4QixDQUE4QkMsT0FBOUIsQ0FBc0Msa0JBQVU7QUFDOUMsUUFBSUMsT0FBTzlDLE1BQU00QyxLQUFOLENBQVkvQyxHQUFaLENBQWdCa0QsTUFBaEIsQ0FBWDtBQUNBLFFBQUlDLGNBQWNWLGFBQWFRLEtBQUtHLE1BQXBDOztBQUVBLFFBQUlDLGlCQUFpQjtBQUNuQi9FLFNBQUc2RSxjQUFjUCxLQUFLVSxHQUFMLENBQVNYLEtBQVQsQ0FBZCxHQUFnQ0osS0FBS2pFLENBRHJCO0FBRW5CQyxTQUFHNEUsY0FBY1AsS0FBS1csR0FBTCxDQUFTWixLQUFULENBQWQsR0FBZ0NKLEtBQUtoRTtBQUZyQixLQUFyQjs7QUFLQXVFLDRCQUF3QmpDLElBQXhCLENBQTZCLEVBQUNvQyxVQUFELEVBQU9JLDhCQUFQLEVBQTdCO0FBQ0QsR0FWRDs7QUFZQSxTQUFPdEYsTUFBTTJCLGFBQU4sQ0FBb0IsaUJBQVM7QUFDbEMsUUFBSUwsUUFBUXRCLE1BQU1zQixLQUFOLENBQVlhLFFBQVosQ0FBcUIsQ0FBQyxRQUFELEVBQVc3QixPQUFYLENBQXJCLEVBQTBDO0FBQUEsYUFBUzhCLE1BQU1ULGFBQU4sQ0FBb0IsaUJBQVM7O0FBRTFGLFlBQUkrQixRQUFRbkQsSUFBSTRDLGdCQUFnQmxCLEdBQWhCLENBQW9CLGFBQXBCLENBQWhCO0FBQ0EsWUFBSTBCLFFBQVFuRCxJQUFJMkMsZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsYUFBcEIsQ0FBaEI7QUFDQSxZQUFJMkIsY0FBY1QsZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsZUFBcEIsSUFBdUN5QixLQUF6RDtBQUNBLFlBQUlHLGNBQWNWLGdCQUFnQmxCLEdBQWhCLENBQW9CLGVBQXBCLElBQXVDMEIsS0FBekQ7QUFDQSxZQUFJRyxjQUFjWCxnQkFBZ0JsQixHQUFoQixDQUFvQixlQUFwQixJQUF1Q3lCLEtBQXpEO0FBQ0EsWUFBSUssY0FBY1osZ0JBQWdCbEIsR0FBaEIsQ0FBb0IsZUFBcEIsSUFBdUMwQixLQUF6RDs7QUFFQSxZQUFJM0QsTUFBTXVCLFFBQU4sSUFBa0IsQ0FBQ3ZCLE1BQU11QixRQUFOLENBQWVFLE9BQWYsRUFBdkIsRUFBaUQ7O0FBRS9DLGNBQUl1QyxXQUFXLHVCQUFZaEUsTUFBTXFCLFlBQWxCLEVBQWdDdUMsV0FBaEMsRUFBNkNDLFdBQTdDLEVBQTBEN0QsTUFBTXVCLFFBQWhFLENBQWY7QUFDQSxjQUFJMEMsV0FBVyx1QkFBWWpFLE1BQU1xQixZQUFsQixFQUFnQ3lDLFdBQWhDLEVBQTZDQyxXQUE3QyxFQUEwRC9ELE1BQU11QixRQUFoRSxDQUFmOztBQUVBLGNBQUkyQyxTQUFTLENBQWI7QUFBQSxjQUFnQkMsU0FBUyxDQUF6QjtBQUNBLGNBQUlILFlBQVlDLFFBQWhCLEVBQTBCO0FBQ3hCLGdCQUFJRCxTQUFTdEMsS0FBVCxDQUFlMEMsUUFBZixHQUEwQkgsU0FBU3ZDLEtBQVQsQ0FBZTBDLFFBQTdDLEVBQXVEO0FBQ3JERix1QkFBU0YsU0FBU3RDLEtBQVQsQ0FBZW5CLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNBTyx1QkFBU0gsU0FBU3RDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNELGFBSEQsTUFHTztBQUNMSyx1QkFBU0QsU0FBU3ZDLEtBQVQsQ0FBZW5CLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNBSyx1QkFBU0YsU0FBU3ZDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNEO0FBQ0YsV0FSRCxNQVFPO0FBQ0wsZ0JBQUlDLFFBQUosRUFBYztBQUNaRSx1QkFBU0YsU0FBU3RDLEtBQVQsQ0FBZW5CLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNBTyx1QkFBU0gsU0FBU3RDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJxRCxXQUE1QjtBQUNEO0FBQ0QsZ0JBQUlJLFFBQUosRUFBYztBQUNaQyx1QkFBU0QsU0FBU3ZDLEtBQVQsQ0FBZW5CLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNBSyx1QkFBU0YsU0FBU3ZDLEtBQVQsQ0FBZWxCLENBQWYsR0FBbUJ1RCxXQUE1QjtBQUNEO0FBQ0Y7O0FBRURILHlCQUFlTSxNQUFmO0FBQ0FMLHlCQUFlTSxNQUFmO0FBQ0FMLHlCQUFlSSxNQUFmO0FBQ0FILHlCQUFlSSxNQUFmO0FBQ0Q7O0FBRUQsa0RBQW9CL0IsS0FBcEIsRUFBMkJDLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUEzQjtBQUNBLGtEQUFvQkcsS0FBcEIsRUFBMkJDLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUEzQjs7QUFFQSx5Q0FBV0csS0FBWCxFQUFrQnhCLE1BQWxCOztBQUVBLFlBQUcsQ0FBQywwQkFBVyxFQUFDZ0Qsd0JBQUQsRUFBY0Msd0JBQWQsRUFBWCxFQUF1QyxFQUFDQyx3QkFBRCxFQUFjQyx3QkFBZCxFQUF2QyxDQUFKLEVBQXdFO0FBQ3RFLDZEQUE2QjNCLEtBQTdCLEVBQW9DQyxLQUFLbkMsSUFBekMsRUFDRTBELFdBREYsRUFDZUMsV0FEZixFQUM0QkMsV0FENUIsRUFDeUNDLFdBRHpDLEVBRUUzQyxPQUZGLEVBRVdpQixLQUFLb0QsVUFGaEIsRUFFNEJWLHVCQUY1QjtBQUdEOztBQUVELG1EQUFxQjNDLEtBQXJCLEVBQTRCaEIsT0FBNUI7QUFDRCxPQXBEOEQsQ0FBVDtBQUFBLEtBQTFDLENBQVo7O0FBc0RBcEIsVUFBTWlCLEtBQU4sQ0FBWTtBQUNWQyxnQ0FEVTtBQUVWSSxrQkFGVTtBQUdWNkIsdUJBQWlCLElBSFA7QUFJVlgseUJBQW1CLElBSlQ7QUFLVm5CLG9CQUFjLHFCQUxKO0FBTVZ3QixvQkFBYzdDLE1BQU02QyxZQUFOLENBQW1CQyxJQUFuQixDQUF3QnhCLEtBQXhCO0FBTkosS0FBWjtBQVFELEdBL0RNLENBQVA7QUFnRUQ7O0FBRUQsU0FBU1AsVUFBVCxDQUFvQmYsS0FBcEIsRUFBMkJNLE9BQTNCLEVBQW9DTSxNQUFwQyxFQUE0QztBQUMxQyxNQUFJVSxRQUFRdEIsTUFBTXNCLEtBQWxCOztBQUVBQSxVQUFRQSxNQUFNTCxLQUFOLENBQVk7QUFDbEI4QixZQUFRekIsTUFBTXlCLE1BQU4sQ0FBYTJDLEdBQWIsOEJBRFU7QUFFbEJDLG1CQUFlckY7QUFGRyxHQUFaLENBQVI7O0FBS0FnQixVQUFRQSxNQUFNYSxRQUFOLENBQWUsQ0FBQyxRQUFELEVBQVc3QixPQUFYLENBQWYsRUFBb0M7QUFBQSxXQUFTOEIsTUFBTVQsYUFBTixDQUFvQixpQkFBUztBQUM5RSxVQUFJVSxPQUFPRCxNQUFNSyxLQUFOLENBQVksQ0FBQyxPQUFELEVBQVU3QixNQUFWLENBQVosQ0FBWDtBQUNBLG1DQUFPd0IsS0FBUCxFQUFjLE9BQWQsRUFBdUJ4QixNQUF2QjtBQUNBLG1DQUFPd0IsS0FBUCxFQUFjLFVBQWQsRUFBMEJDLEtBQUtFLFFBQUwsQ0FBY04sR0FBZCxDQUFrQixDQUFsQixDQUExQjtBQUNBLG1DQUFPRyxLQUFQLEVBQWMsVUFBZCxFQUEwQkMsS0FBS0UsUUFBTCxDQUFjTixHQUFkLENBQWtCLENBQWxCLENBQTFCO0FBQ0QsS0FMa0QsQ0FBVDtBQUFBLEdBQXBDLENBQVI7O0FBUUEsU0FBT2pDLE1BQU1pQixLQUFOLENBQVk7QUFDakJLLGdCQURpQjtBQUVqQnVCLGtCQUFjN0MsTUFBTTZDLFlBQU4sQ0FBbUJDLElBQW5CLENBQXdCeEIsS0FBeEI7QUFGRyxHQUFaLENBQVA7QUFJRCIsImZpbGUiOiJsaW5lcy1yZWR1Y2VyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtMaXN0LCBNYXB9IGZyb20gJ2ltbXV0YWJsZSc7XG5cbmltcG9ydCB7XG4gIFNFTEVDVF9UT09MX0RSQVdJTkdfTElORSxcbiAgQkVHSU5fRFJBV0lOR19MSU5FLFxuICBVUERBVEVfRFJBV0lOR19MSU5FLFxuICBFTkRfRFJBV0lOR19MSU5FLFxuICBCRUdJTl9EUkFHR0lOR19MSU5FLFxuICBVUERBVEVfRFJBR0dJTkdfTElORSxcbiAgRU5EX0RSQUdHSU5HX0xJTkUsXG4gIFNFTEVDVF9MSU5FLFxuICBNT0RFX0lETEUsXG4gIE1PREVfV0FJVElOR19EUkFXSU5HX0xJTkUsXG4gIE1PREVfRFJBV0lOR19MSU5FLFxuICBNT0RFX0RSQUdHSU5HX0xJTkVcbn0gZnJvbSAnLi4vY29uc3RhbnRzJztcblxuaW1wb3J0ICogYXMgR2VvbWV0cnkgZnJvbSAnLi4vdXRpbHMvZ2VvbWV0cnknO1xuaW1wb3J0IHtcbiAgYWRkTGluZSxcbiAgcmVwbGFjZUxpbmVWZXJ0ZXgsXG4gIHJlbW92ZUxpbmUsXG4gIHNlbGVjdCxcbiAgdW5zZWxlY3QsXG4gIGFkZExpbmVBdm9pZGluZ0ludGVyc2VjdGlvbnMsXG4gIHVuc2VsZWN0QWxsLFxuICBkZXRlY3RBbmRVcGRhdGVBcmVhcywgbWVyZ2VFcXVhbHNWZXJ0aWNlcyxcbn0gZnJvbSAnLi4vdXRpbHMvbGF5ZXItb3BlcmF0aW9ucyc7XG5pbXBvcnQge25lYXJlc3RTbmFwLCBhZGRQb2ludFNuYXAsIGFkZExpbmVTbmFwLCBhZGRMaW5lU2VnbWVudFNuYXB9IGZyb20gJy4uL3V0aWxzL3NuYXAnO1xuaW1wb3J0IHtzY2VuZVNuYXBFbGVtZW50c30gZnJvbSAnLi4vdXRpbHMvc25hcC1zY2VuZSc7XG5pbXBvcnQge3NhbWVQb2ludHN9IGZyb20gXCIuLi91dGlscy9nZW9tZXRyeVwiO1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiAoc3RhdGUsIGFjdGlvbikge1xuICBzd2l0Y2ggKGFjdGlvbi50eXBlKSB7XG4gICAgY2FzZSBTRUxFQ1RfVE9PTF9EUkFXSU5HX0xJTkU6XG4gICAgICByZXR1cm4gc2VsZWN0VG9vbERyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24uc2NlbmVDb21wb25lbnRUeXBlKTtcblxuICAgIGNhc2UgQkVHSU5fRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGJlZ2luRHJhd2luZ0xpbmUoc3RhdGUsIGFjdGlvbi5sYXllcklELCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBVUERBVEVfRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIHVwZGF0ZURyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBFTkRfRFJBV0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGVuZERyYXdpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBCRUdJTl9EUkFHR0lOR19MSU5FOlxuICAgICAgcmV0dXJuIGJlZ2luRHJhZ2dpbmdMaW5lKHN0YXRlLCBhY3Rpb24ubGF5ZXJJRCwgYWN0aW9uLmxpbmVJRCwgYWN0aW9uLngsIGFjdGlvbi55KTtcblxuICAgIGNhc2UgVVBEQVRFX0RSQUdHSU5HX0xJTkU6XG4gICAgICByZXR1cm4gdXBkYXRlRHJhZ2dpbmdMaW5lKHN0YXRlLCBhY3Rpb24ueCwgYWN0aW9uLnkpO1xuXG4gICAgY2FzZSBFTkRfRFJBR0dJTkdfTElORTpcbiAgICAgIHJldHVybiBlbmREcmFnZ2luZ0xpbmUoc3RhdGUsIGFjdGlvbi54LCBhY3Rpb24ueSk7XG5cbiAgICBjYXNlIFNFTEVDVF9MSU5FOlxuICAgICAgcmV0dXJuIHNlbGVjdExpbmUoc3RhdGUsIGFjdGlvbi5sYXllcklELCBhY3Rpb24ubGluZUlEKTtcblxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gc3RhdGU7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2VsZWN0VG9vbERyYXdpbmdMaW5lKHN0YXRlLCBzY2VuZUNvbXBvbmVudFR5cGUpIHtcbiAgcmV0dXJuIHN0YXRlLm1lcmdlKHtcbiAgICBtb2RlOiBNT0RFX1dBSVRJTkdfRFJBV0lOR19MSU5FLFxuICAgIGRyYXdpbmdTdXBwb3J0OiBNYXAoe1xuICAgICAgdHlwZTogc2NlbmVDb21wb25lbnRUeXBlXG4gICAgfSlcbiAgfSk7XG59XG5cbi8qKiBsaW5lcyBvcGVyYXRpb25zICoqL1xuZnVuY3Rpb24gYmVnaW5EcmF3aW5nTGluZShzdGF0ZSwgbGF5ZXJJRCwgeCwgeSkge1xuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG5cbiAgbGV0IHNuYXBFbGVtZW50cyA9IHNjZW5lU25hcEVsZW1lbnRzKHN0YXRlLnNjZW5lLCBuZXcgTGlzdCgpLCBzdGF0ZS5zbmFwTWFzayk7XG4gIGxldCBzbmFwID0gbnVsbDtcblxuICBpZiAoc3RhdGUuc25hcE1hc2sgJiYgIXN0YXRlLnNuYXBNYXNrLmlzRW1wdHkoKSkge1xuICAgIHNuYXAgPSBuZWFyZXN0U25hcChzbmFwRWxlbWVudHMsIHgsIHksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICBpZiAoc25hcCkgKHt4LCB5fSA9IHNuYXAucG9pbnQpO1xuXG4gICAgc25hcEVsZW1lbnRzID0gc25hcEVsZW1lbnRzLndpdGhNdXRhdGlvbnMoc25hcEVsZW1lbnRzID0+IHtcbiAgICAgIGxldCBhLCBiLCBjO1xuICAgICAgKHthLCBiLCBjfSA9IEdlb21ldHJ5Lmhvcml6b250YWxMaW5lKHkpKTtcbiAgICAgIGFkZExpbmVTbmFwKHNuYXBFbGVtZW50cywgYSwgYiwgYywgMTAsIDMsIG51bGwpO1xuICAgICAgKHthLCBiLCBjfSA9IEdlb21ldHJ5LnZlcnRpY2FsTGluZSh4KSk7XG4gICAgICBhZGRMaW5lU25hcChzbmFwRWxlbWVudHMsIGEsIGIsIGMsIDEwLCAzLCBudWxsKTtcbiAgICB9KTtcbiAgfVxuXG4gIGxldCBkcmF3aW5nU3VwcG9ydCA9IHN0YXRlLmdldCgnZHJhd2luZ1N1cHBvcnQnKS5zZXQoJ2xheWVySUQnLCBsYXllcklEKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgdW5zZWxlY3RBbGwobGF5ZXIpO1xuICAgIGxldCB7bGluZX0gPSBhZGRMaW5lKGxheWVyLCBkcmF3aW5nU3VwcG9ydC5nZXQoJ3R5cGUnKSwgeCwgeSwgeCwgeSwgY2F0YWxvZyk7XG4gICAgc2VsZWN0KGxheWVyLCAnbGluZXMnLCBsaW5lLmlkKTtcbiAgICBzZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgICBzZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDEpKTtcbiAgfSkpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgbW9kZTogTU9ERV9EUkFXSU5HX0xJTkUsXG4gICAgc2NlbmUsXG4gICAgc25hcEVsZW1lbnRzLFxuICAgIGFjdGl2ZVNuYXBFbGVtZW50OiBzbmFwID8gc25hcC5zbmFwIDogbnVsbCxcbiAgICBkcmF3aW5nU3VwcG9ydFxuICB9KTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlRHJhd2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgc25hcCA9IG51bGw7XG4gIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG4gICAgc25hcCA9IG5lYXJlc3RTbmFwKHN0YXRlLnNuYXBFbGVtZW50cywgeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGlmIChzbmFwKSAoe3gsIHl9ID0gc25hcC5wb2ludCk7XG4gIH1cblxuICBsZXQgbGF5ZXJJRCA9IHN0YXRlLmdldEluKFsnZHJhd2luZ1N1cHBvcnQnLCAnbGF5ZXJJRCddKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgbGV0IGxpbmVJRCA9IGxheWVyLmdldEluKFsnc2VsZWN0ZWQnLCAnbGluZXMnXSkuZmlyc3QoKTtcbiAgICBsZXQgdmVydGV4O1xuICAgICh7bGF5ZXIsIHZlcnRleH0gPSByZXBsYWNlTGluZVZlcnRleChsYXllciwgbGluZUlELCAxLCB4LCB5KSk7XG4gICAgc2VsZWN0KGxheWVyLCAndmVydGljZXMnLCB2ZXJ0ZXguaWQpO1xuICAgIHJldHVybiBsYXllcjtcbiAgfSkpO1xuXG4gIHJldHVybiBzdGF0ZS5tZXJnZSh7XG4gICAgc2NlbmUsXG4gICAgYWN0aXZlU25hcEVsZW1lbnQ6IHNuYXAgPyBzbmFwLnNuYXAgOiBudWxsLFxuICB9KTtcbn1cblxuZnVuY3Rpb24gZW5kRHJhd2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG5cbiAgaWYgKHN0YXRlLnNuYXBNYXNrICYmICFzdGF0ZS5zbmFwTWFzay5pc0VtcHR5KCkpIHtcbiAgICBsZXQgc25hcCA9IG5lYXJlc3RTbmFwKHN0YXRlLnNuYXBFbGVtZW50cywgeCwgeSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGlmIChzbmFwKSAoe3gsIHl9ID0gc25hcC5wb2ludCk7XG4gIH1cblxuICBsZXQgbGF5ZXJJRCA9IHN0YXRlLmdldEluKFsnZHJhd2luZ1N1cHBvcnQnLCAnbGF5ZXJJRCddKTtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgbGV0IGxpbmVJRCA9IGxheWVyLmdldEluKFsnc2VsZWN0ZWQnLCAnbGluZXMnXSkuZmlyc3QoKTtcbiAgICBsZXQgbGluZSA9IGxheWVyLmdldEluKFsnbGluZXMnLCBsaW5lSURdKTtcbiAgICBsZXQgdjAgPSBsYXllci52ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMCkpO1xuXG4gICAgdW5zZWxlY3QobGF5ZXIsICdsaW5lcycsIGxpbmVJRCk7XG4gICAgdW5zZWxlY3QobGF5ZXIsICd2ZXJ0aWNlcycsIGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgICB1bnNlbGVjdChsYXllciwgJ3ZlcnRpY2VzJywgbGluZS52ZXJ0aWNlcy5nZXQoMSkpO1xuICAgIHJlbW92ZUxpbmUobGF5ZXIsIGxpbmVJRCk7XG4gICAgYWRkTGluZUF2b2lkaW5nSW50ZXJzZWN0aW9ucyhsYXllciwgbGluZS50eXBlLCB2MC54LCB2MC55LCB4LCB5LCBjYXRhbG9nKTtcbiAgICBkZXRlY3RBbmRVcGRhdGVBcmVhcyhsYXllciwgY2F0YWxvZyk7XG4gIH0pKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIG1vZGU6IE1PREVfV0FJVElOR19EUkFXSU5HX0xJTkUsXG4gICAgc2NlbmUsXG4gICAgc25hcEVsZW1lbnRzOiBuZXcgTGlzdCgpLFxuICAgIGFjdGl2ZVNuYXBFbGVtZW50OiBudWxsLFxuICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBiZWdpbkRyYWdnaW5nTGluZShzdGF0ZSwgbGF5ZXJJRCwgbGluZUlELCB4LCB5KSB7XG5cbiAgbGV0IHNuYXBFbGVtZW50cyA9IHNjZW5lU25hcEVsZW1lbnRzKHN0YXRlLnNjZW5lLCBuZXcgTGlzdCgpLCBzdGF0ZS5zbmFwTWFzayk7XG5cbiAgbGV0IGxheWVyID0gc3RhdGUuc2NlbmUubGF5ZXJzLmdldChsYXllcklEKTtcbiAgbGV0IGxpbmUgPSBsYXllci5saW5lcy5nZXQobGluZUlEKTtcblxuICBsZXQgdmVydGV4MCA9IGxheWVyLnZlcnRpY2VzLmdldChsaW5lLnZlcnRpY2VzLmdldCgwKSk7XG4gIGxldCB2ZXJ0ZXgxID0gbGF5ZXIudmVydGljZXMuZ2V0KGxpbmUudmVydGljZXMuZ2V0KDEpKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIG1vZGU6IE1PREVfRFJBR0dJTkdfTElORSxcbiAgICBzbmFwRWxlbWVudHMsXG4gICAgZHJhZ2dpbmdTdXBwb3J0OiBNYXAoe1xuICAgICAgbGF5ZXJJRCwgbGluZUlELFxuICAgICAgc3RhcnRQb2ludFg6IHgsXG4gICAgICBzdGFydFBvaW50WTogeSxcbiAgICAgIHN0YXJ0VmVydGV4MFg6IHZlcnRleDAueCxcbiAgICAgIHN0YXJ0VmVydGV4MFk6IHZlcnRleDAueSxcbiAgICAgIHN0YXJ0VmVydGV4MVg6IHZlcnRleDEueCxcbiAgICAgIHN0YXJ0VmVydGV4MVk6IHZlcnRleDEueSxcbiAgICB9KVxuICB9KVxufVxuXG5mdW5jdGlvbiB1cGRhdGVEcmFnZ2luZ0xpbmUoc3RhdGUsIHgsIHkpIHtcblxuICBsZXQgZHJhZ2dpbmdTdXBwb3J0ID0gc3RhdGUuZHJhZ2dpbmdTdXBwb3J0O1xuICBsZXQgc25hcEVsZW1lbnRzID0gc3RhdGUuc25hcEVsZW1lbnRzO1xuXG4gIGxldCBsYXllcklEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnbGF5ZXJJRCcpO1xuICBsZXQgbGluZUlEID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnbGluZUlEJyk7XG4gIGxldCBkaWZmWCA9IHggLSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFBvaW50WCcpO1xuICBsZXQgZGlmZlkgPSB5IC0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRQb2ludFknKTtcbiAgbGV0IG5ld1ZlcnRleDBYID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgwWCcpICsgZGlmZlg7XG4gIGxldCBuZXdWZXJ0ZXgwWSA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0VmVydGV4MFknKSArIGRpZmZZO1xuICBsZXQgbmV3VmVydGV4MVggPSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFZlcnRleDFYJykgKyBkaWZmWDtcbiAgbGV0IG5ld1ZlcnRleDFZID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgxWScpICsgZGlmZlk7XG5cblxuICBsZXQgYWN0aXZlU25hcEVsZW1lbnQgPSBudWxsO1xuICBsZXQgY3VyU25hcDAgPSBudWxsLCBjdXJTbmFwMSA9IG51bGw7XG4gIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG4gICAgY3VyU25hcDAgPSBuZWFyZXN0U25hcChzbmFwRWxlbWVudHMsIG5ld1ZlcnRleDBYLCBuZXdWZXJ0ZXgwWSwgc3RhdGUuc25hcE1hc2spO1xuICAgIGN1clNuYXAxID0gbmVhcmVzdFNuYXAoc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgxWCwgbmV3VmVydGV4MVksIHN0YXRlLnNuYXBNYXNrKTtcbiAgfVxuXG4gIGxldCBkZWx0YVggPSAwLCBkZWx0YVkgPSAwO1xuICBpZiAoY3VyU25hcDAgJiYgY3VyU25hcDEpIHtcbiAgICBpZiAoY3VyU25hcDAucG9pbnQuZGlzdGFuY2UgPCBjdXJTbmFwMS5wb2ludC5kaXN0YW5jZSkge1xuICAgICAgZGVsdGFYID0gY3VyU25hcDAucG9pbnQueCAtIG5ld1ZlcnRleDBYO1xuICAgICAgZGVsdGFZID0gY3VyU25hcDAucG9pbnQueSAtIG5ld1ZlcnRleDBZO1xuICAgICAgYWN0aXZlU25hcEVsZW1lbnQgPSBjdXJTbmFwMC5zbmFwO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWx0YVggPSBjdXJTbmFwMS5wb2ludC54IC0gbmV3VmVydGV4MVg7XG4gICAgICBkZWx0YVkgPSBjdXJTbmFwMS5wb2ludC55IC0gbmV3VmVydGV4MVk7XG4gICAgICBhY3RpdmVTbmFwRWxlbWVudCA9IGN1clNuYXAxLnNuYXA7XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGlmIChjdXJTbmFwMCkge1xuICAgICAgZGVsdGFYID0gY3VyU25hcDAucG9pbnQueCAtIG5ld1ZlcnRleDBYO1xuICAgICAgZGVsdGFZID0gY3VyU25hcDAucG9pbnQueSAtIG5ld1ZlcnRleDBZO1xuICAgICAgYWN0aXZlU25hcEVsZW1lbnQgPSBjdXJTbmFwMC5zbmFwO1xuICAgIH1cbiAgICBpZiAoY3VyU25hcDEpIHtcbiAgICAgIGRlbHRhWCA9IGN1clNuYXAxLnBvaW50LnggLSBuZXdWZXJ0ZXgxWDtcbiAgICAgIGRlbHRhWSA9IGN1clNuYXAxLnBvaW50LnkgLSBuZXdWZXJ0ZXgxWTtcbiAgICAgIGFjdGl2ZVNuYXBFbGVtZW50ID0gY3VyU25hcDEuc25hcDtcbiAgICB9XG4gIH1cblxuICBuZXdWZXJ0ZXgwWCArPSBkZWx0YVg7XG4gIG5ld1ZlcnRleDBZICs9IGRlbHRhWTtcbiAgbmV3VmVydGV4MVggKz0gZGVsdGFYO1xuICBuZXdWZXJ0ZXgxWSArPSBkZWx0YVk7XG5cbiAgcmV0dXJuIHN0YXRlLm1lcmdlKHtcbiAgICBhY3RpdmVTbmFwRWxlbWVudCxcbiAgICBzY2VuZTogc3RhdGUuc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgICBsZXQgbGluZVZlcnRpY2VzID0gbGF5ZXIuZ2V0SW4oWydsaW5lcycsIGxpbmVJRCwgJ3ZlcnRpY2VzJ10pO1xuICAgICAgbGF5ZXIudXBkYXRlSW4oWyd2ZXJ0aWNlcycsIGxpbmVWZXJ0aWNlcy5nZXQoMCldLCB2ZXJ0ZXggPT4gdmVydGV4Lm1lcmdlKHt4OiBuZXdWZXJ0ZXgwWCwgeTogbmV3VmVydGV4MFl9KSk7XG4gICAgICBsYXllci51cGRhdGVJbihbJ3ZlcnRpY2VzJywgbGluZVZlcnRpY2VzLmdldCgxKV0sIHZlcnRleCA9PiB2ZXJ0ZXgubWVyZ2Uoe3g6IG5ld1ZlcnRleDFYLCB5OiBuZXdWZXJ0ZXgxWX0pKTtcbiAgICAgIHJldHVybiBsYXllcjtcbiAgICB9KSlcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIGVuZERyYWdnaW5nTGluZShzdGF0ZSwgeCwgeSkge1xuICBsZXQgY2F0YWxvZyA9IHN0YXRlLmNhdGFsb2c7XG4gIGxldCB7ZHJhZ2dpbmdTdXBwb3J0fSA9IHN0YXRlO1xuICBsZXQgbGF5ZXJJRCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ2xheWVySUQnKTtcbiAgbGV0IGxheWVyID0gc3RhdGUuc2NlbmUubGF5ZXJzLmdldChsYXllcklEKTtcbiAgbGV0IGxpbmVJRCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ2xpbmVJRCcpO1xuICBsZXQgbGluZSA9IGxheWVyLmxpbmVzLmdldChsaW5lSUQpO1xuXG4gIGxldCB2ZXJ0ZXgwID0gbGF5ZXIudmVydGljZXMuZ2V0KGxpbmUudmVydGljZXMuZ2V0KDApKTtcbiAgbGV0IHZlcnRleDEgPSBsYXllci52ZXJ0aWNlcy5nZXQobGluZS52ZXJ0aWNlcy5nZXQoMSkpO1xuXG4gIGxldCBtYXhWID0gR2VvbWV0cnkubWF4VmVydGV4KHZlcnRleDAsIHZlcnRleDEpO1xuICBsZXQgbWluViA9IEdlb21ldHJ5Lm1pblZlcnRleCh2ZXJ0ZXgwLCB2ZXJ0ZXgxKTtcblxuICBsZXQgbGluZUxlbmd0aCA9IEdlb21ldHJ5LnZlcnRpY2VzRGlzdGFuY2UobWluVixtYXhWKTtcbiAgbGV0IGFscGhhID0gTWF0aC5hdGFuMihtYXhWLnkgLSBtaW5WLnksIG1heFYueCAtIG1pblYueCk7XG5cbiAgbGV0IGhvbGVzV2l0aE9mZnNldFBvc2l0aW9uID0gW107XG4gIGxheWVyLmxpbmVzLmdldChsaW5lSUQpLmhvbGVzLmZvckVhY2goaG9sZUlEID0+IHtcbiAgICBsZXQgaG9sZSA9IGxheWVyLmhvbGVzLmdldChob2xlSUQpO1xuICAgIGxldCBwb2ludE9uTGluZSA9IGxpbmVMZW5ndGggKiBob2xlLm9mZnNldDtcblxuICAgIGxldCBvZmZzZXRQb3NpdGlvbiA9IHtcbiAgICAgIHg6IHBvaW50T25MaW5lICogTWF0aC5jb3MoYWxwaGEpICsgbWluVi54LFxuICAgICAgeTogcG9pbnRPbkxpbmUgKiBNYXRoLnNpbihhbHBoYSkgKyBtaW5WLnlcbiAgICB9O1xuXG4gICAgaG9sZXNXaXRoT2Zmc2V0UG9zaXRpb24ucHVzaCh7aG9sZSwgb2Zmc2V0UG9zaXRpb259KTtcbiAgfSk7XG5cbiAgcmV0dXJuIHN0YXRlLndpdGhNdXRhdGlvbnMoc3RhdGUgPT4ge1xuICAgIGxldCBzY2VuZSA9IHN0YXRlLnNjZW5lLnVwZGF0ZUluKFsnbGF5ZXJzJywgbGF5ZXJJRF0sIGxheWVyID0+IGxheWVyLndpdGhNdXRhdGlvbnMobGF5ZXIgPT4ge1xuXG4gICAgICBsZXQgZGlmZlggPSB4IC0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRQb2ludFgnKTtcbiAgICAgIGxldCBkaWZmWSA9IHkgLSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFBvaW50WScpO1xuICAgICAgbGV0IG5ld1ZlcnRleDBYID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgwWCcpICsgZGlmZlg7XG4gICAgICBsZXQgbmV3VmVydGV4MFkgPSBkcmFnZ2luZ1N1cHBvcnQuZ2V0KCdzdGFydFZlcnRleDBZJykgKyBkaWZmWTtcbiAgICAgIGxldCBuZXdWZXJ0ZXgxWCA9IGRyYWdnaW5nU3VwcG9ydC5nZXQoJ3N0YXJ0VmVydGV4MVgnKSArIGRpZmZYO1xuICAgICAgbGV0IG5ld1ZlcnRleDFZID0gZHJhZ2dpbmdTdXBwb3J0LmdldCgnc3RhcnRWZXJ0ZXgxWScpICsgZGlmZlk7XG5cbiAgICAgIGlmIChzdGF0ZS5zbmFwTWFzayAmJiAhc3RhdGUuc25hcE1hc2suaXNFbXB0eSgpKSB7XG5cbiAgICAgICAgbGV0IGN1clNuYXAwID0gbmVhcmVzdFNuYXAoc3RhdGUuc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgwWCwgbmV3VmVydGV4MFksIHN0YXRlLnNuYXBNYXNrKTtcbiAgICAgICAgbGV0IGN1clNuYXAxID0gbmVhcmVzdFNuYXAoc3RhdGUuc25hcEVsZW1lbnRzLCBuZXdWZXJ0ZXgxWCwgbmV3VmVydGV4MVksIHN0YXRlLnNuYXBNYXNrKTtcblxuICAgICAgICBsZXQgZGVsdGFYID0gMCwgZGVsdGFZID0gMDtcbiAgICAgICAgaWYgKGN1clNuYXAwICYmIGN1clNuYXAxKSB7XG4gICAgICAgICAgaWYgKGN1clNuYXAwLnBvaW50LmRpc3RhbmNlIDwgY3VyU25hcDEucG9pbnQuZGlzdGFuY2UpIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGN1clNuYXAwLnBvaW50LnggLSBuZXdWZXJ0ZXgwWDtcbiAgICAgICAgICAgIGRlbHRhWSA9IGN1clNuYXAwLnBvaW50LnkgLSBuZXdWZXJ0ZXgwWTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGVsdGFYID0gY3VyU25hcDEucG9pbnQueCAtIG5ld1ZlcnRleDFYO1xuICAgICAgICAgICAgZGVsdGFZID0gY3VyU25hcDEucG9pbnQueSAtIG5ld1ZlcnRleDFZO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoY3VyU25hcDApIHtcbiAgICAgICAgICAgIGRlbHRhWCA9IGN1clNuYXAwLnBvaW50LnggLSBuZXdWZXJ0ZXgwWDtcbiAgICAgICAgICAgIGRlbHRhWSA9IGN1clNuYXAwLnBvaW50LnkgLSBuZXdWZXJ0ZXgwWTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGN1clNuYXAxKSB7XG4gICAgICAgICAgICBkZWx0YVggPSBjdXJTbmFwMS5wb2ludC54IC0gbmV3VmVydGV4MVg7XG4gICAgICAgICAgICBkZWx0YVkgPSBjdXJTbmFwMS5wb2ludC55IC0gbmV3VmVydGV4MVk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbmV3VmVydGV4MFggKz0gZGVsdGFYO1xuICAgICAgICBuZXdWZXJ0ZXgwWSArPSBkZWx0YVk7XG4gICAgICAgIG5ld1ZlcnRleDFYICs9IGRlbHRhWDtcbiAgICAgICAgbmV3VmVydGV4MVkgKz0gZGVsdGFZO1xuICAgICAgfVxuXG4gICAgICBtZXJnZUVxdWFsc1ZlcnRpY2VzKGxheWVyLCBsaW5lLnZlcnRpY2VzLmdldCgwKSk7XG4gICAgICBtZXJnZUVxdWFsc1ZlcnRpY2VzKGxheWVyLCBsaW5lLnZlcnRpY2VzLmdldCgxKSk7XG5cbiAgICAgIHJlbW92ZUxpbmUobGF5ZXIsIGxpbmVJRCk7XG5cbiAgICAgIGlmKCFzYW1lUG9pbnRzKHtuZXdWZXJ0ZXgwWCwgbmV3VmVydGV4MFl9LCB7bmV3VmVydGV4MVgsIG5ld1ZlcnRleDFZfSkpIHtcbiAgICAgICAgYWRkTGluZUF2b2lkaW5nSW50ZXJzZWN0aW9ucyhsYXllciwgbGluZS50eXBlLFxuICAgICAgICAgIG5ld1ZlcnRleDBYLCBuZXdWZXJ0ZXgwWSwgbmV3VmVydGV4MVgsIG5ld1ZlcnRleDFZLFxuICAgICAgICAgIGNhdGFsb2csIGxpbmUucHJvcGVydGllcywgaG9sZXNXaXRoT2Zmc2V0UG9zaXRpb24pO1xuICAgICAgfVxuXG4gICAgICBkZXRlY3RBbmRVcGRhdGVBcmVhcyhsYXllciwgY2F0YWxvZyk7XG4gICAgfSkpO1xuXG4gICAgc3RhdGUubWVyZ2Uoe1xuICAgICAgbW9kZTogTU9ERV9JRExFLFxuICAgICAgc2NlbmUsXG4gICAgICBkcmFnZ2luZ1N1cHBvcnQ6IG51bGwsXG4gICAgICBhY3RpdmVTbmFwRWxlbWVudDogbnVsbCxcbiAgICAgIHNuYXBFbGVtZW50czogbmV3IExpc3QoKSxcbiAgICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RMaW5lKHN0YXRlLCBsYXllcklELCBsaW5lSUQpIHtcbiAgbGV0IHNjZW5lID0gc3RhdGUuc2NlbmU7XG5cbiAgc2NlbmUgPSBzY2VuZS5tZXJnZSh7XG4gICAgbGF5ZXJzOiBzY2VuZS5sYXllcnMubWFwKHVuc2VsZWN0QWxsKSxcbiAgICBzZWxlY3RlZExheWVyOiBsYXllcklEXG4gIH0pO1xuXG4gIHNjZW5lID0gc2NlbmUudXBkYXRlSW4oWydsYXllcnMnLCBsYXllcklEXSwgbGF5ZXIgPT4gbGF5ZXIud2l0aE11dGF0aW9ucyhsYXllciA9PiB7XG4gICAgICBsZXQgbGluZSA9IGxheWVyLmdldEluKFsnbGluZXMnLCBsaW5lSURdKTtcbiAgICAgIHNlbGVjdChsYXllciwgJ2xpbmVzJywgbGluZUlEKTtcbiAgICAgIHNlbGVjdChsYXllciwgJ3ZlcnRpY2VzJywgbGluZS52ZXJ0aWNlcy5nZXQoMCkpO1xuICAgICAgc2VsZWN0KGxheWVyLCAndmVydGljZXMnLCBsaW5lLnZlcnRpY2VzLmdldCgxKSk7XG4gICAgfSlcbiAgKTtcblxuICByZXR1cm4gc3RhdGUubWVyZ2Uoe1xuICAgIHNjZW5lLFxuICAgIHNjZW5lSGlzdG9yeTogc3RhdGUuc2NlbmVIaXN0b3J5LnB1c2goc2NlbmUpXG4gIH0pXG59XG4iXX0=