react-planner-viewer
Version:
react-planner-viewer is a React Component for view plans builded with react-planner in 2D mode
266 lines (227 loc) • 26.1 kB
JavaScript
/**
* UTILS
*/
function sub(v1, v2) {
return [v1[0] - v2[0], v1[1] - v2[1]];
}
function mod(n, m) {
return (n % m + m) % m;
}
/**
* CYCLES
*/
function compute_ev_mapping(EV) {
var ev_mapping = EV.map(function (ev) {
return {
ev: ev,
color: 0,
direction: -1
};
});
return ev_mapping;
}
function compute_angle(P, V) {
var point = sub(V, P);
var angle = Math.atan2(point[1], point[0]);
return angle;
}
function compute_incidences(V, EV) {
var incidences = V.map(function (vertex, i) {
var incidence = [];
EV.forEach(function (edge, j) {
var endpoint;
var position;
if (edge[0] === i) {
endpoint = edge[1];
position = 1;
}
if (edge[1] === i) {
endpoint = edge[0];
position = 0;
}
endpoint !== undefined && incidence.push({
index: j,
endpoint: endpoint,
angle: compute_angle(vertex, V[endpoint]),
edge: edge,
position: position
});
});
incidence.sort(function (i1, i2) {
return i2.angle - i1.angle;
});
return incidence;
});
return incidences;
}
function get_starting_edge(incidences, ev_mapping) {
var e;
var position;
var direction;
for (e = 0; e < ev_mapping.length; e += 1) {
if (ev_mapping[e].color < 2) {
direction = -1 * ev_mapping[e].direction;
color(ev_mapping, e, direction);
return {
edge: e,
direction: direction,
position: direction === -1 ? 0 : 1
};
}
}
}
function get_next_edge(incidences, edge, position, EV) {
var items = incidences[EV[edge][position]];
//console.log(items, incidences, EV, edge, position);
var n_items = items.length;
var item;
var out;
var j;
for (j = 0; j < n_items; j += 1) {
item = items[j];
if (item.index === edge) {
out = items[mod(j + 1, items.length)];
return {
edge: out.index,
vertex: out.endpoint,
position: out.position,
direction: out.position ? 1 : -1
};
}
}
}
function color(ev_mapping, index, direction) {
ev_mapping[index].color += 1;
ev_mapping[index].direction = direction;
}
function find_cycles(V, EV) {
var ev_mapping = compute_ev_mapping(EV);
var incidences = compute_incidences(V, EV);
var V_cycles = [];
var E_cycles = [];
var dir_E_cycles = [];
var V_cycle;
var E_cycle;
var dir_E_cycle;
var next;
var counter = 0;
var start = get_starting_edge(incidences, ev_mapping);
while (start !== undefined) {
V_cycle = [EV[start.edge][mod(start.position + 1, 2)], EV[start.edge][start.position]];
E_cycle = [start.edge];
dir_E_cycle = [start.direction];
next = get_next_edge(incidences, start.edge, start.position, EV);
while (next.edge !== start.edge) {
V_cycle.push(next.vertex);
E_cycle.push(next.edge);
dir_E_cycle.push(next.direction);
color(ev_mapping, next.edge, next.direction);
next = get_next_edge(incidences, next.edge, next.position, EV);
}
E_cycles.push(E_cycle);
V_cycles.push(V_cycle);
dir_E_cycles.push(dir_E_cycle);
//console.log('############## CYCLE ', ++counter)
//console.log('EDGES:', E_cycle)
//console.log('VERTICES:', V_cycle)
//console.log('START', 'edge:', start.edge, 'position:', start.position)
//console.log('COUNTER:', ev_mapping.map(e => e.color), ev_mapping.map(e => e.color).reduce((a, b) => a + b));
//console.log('\n')
start = get_starting_edge(incidences, ev_mapping);
}
return {
v_cycles: V_cycles,
e_cycles: E_cycles,
dir_e_cycles: dir_E_cycles,
ev_mapping: ev_mapping
};
}
function find_short_cycles_indexes(v_cycles, e_cycles) {
var indexes = [];
var e_cycle;
var v_cycle;
var i;
for (i = 0; i < e_cycles.length; i += 1) {
e_cycle = e_cycles[i];
v_cycle = v_cycles[i];
if (e_cycle.length < 3 || v_cycle[0] !== v_cycle[v_cycle.length - 1]) {
indexes.push(i);
}
}
return indexes;
}
function find_inner_cycles(V, EV) {
var cycles = find_cycles(V, EV);
var v_cycles = cycles.v_cycles;
var e_cycles = cycles.e_cycles;
var short_cycles_indexes = find_short_cycles_indexes(v_cycles, e_cycles);
short_cycles_indexes.forEach(function (indx) {
v_cycles.splice(indx, 1);
e_cycles.splice(indx, 1);
});
var dir_e_cycles = cycles.dir_e_cycles;
var rooms_values = cycles.e_cycles.map(function (cycle, i) {
return cycle.map(function (edge, j) {
var v1;
var v2;
var dir = dir_e_cycles[i][j] > 0;
if (dir > 0) {
v1 = EV[edge][0];
v2 = EV[edge][1];
} else {
v1 = EV[edge][1];
v2 = EV[edge][0];
}
return (V[v2][0] - V[v1][0]) * (V[v2][1] + V[v1][1]);
});
});
var rooms_sums = rooms_values.map(function (room) {
return room.reduce(function (a, b) {
return a + b;
});
});
var positive_count = rooms_sums.filter(function (sum) {
return sum > 0;
}).length;
var negative_count = rooms_sums.length - positive_count;
var rm_neg = positive_count >= negative_count ? 1 : -1;
return {
v_cycles: cycles.v_cycles.filter(function (v, i) {
return rm_neg * rooms_sums[i] > 0;
}),
e_cycles: cycles.e_cycles.filter(function (v, i) {
return rm_neg * rooms_sums[i] > 0;
}),
ev_mapping: cycles.ev_mapping
};
}
// export default find_inner_cycles;
module.exports = find_inner_cycles;
/**
* DATA
*/
// var V = [[0.5774, 1.0], [1.0, 1.0], [1.1547, 0.0], [1.0, 0.0], [0.0, 0.0], [0.0, 0.732], [1.0, 0.1547], [0.732, 0.0], [1.0491, 0.183], [-0.317, 0.549], [1.0, 0.268], [0.183, -0.3169], [0.5491, 1.049], [0.4642, 1.0], [0.0, -0.4226], [0.0, 1.0]]
// var EV = [[0, 1], [2, 3], [5, 4], [7, 6], [2, 8], [3, 6], [4, 9], [0, 10], [9, 5], [8, 10], [7, 11], [12, 13], [6, 8], [6, 10], [4, 7], [4, 11], [4, 14], [5, 15], [11, 14], [0, 12], [13, 15], [0, 13], [1, 10], [3, 7], [5, 13]]
// var V = [[0,0],[10,0],[10,10],[0,10], [100,100],[110,100],[110,110],[100,110], [5,0], [5,10]]
// var V = [[0,0.5],[12,-0.7],[14,14],[-2,10], [103,106],[117,98],[96,112],[104,109], [5.5,0.8], [4.8,10.5]]
// var EV = [[3,9],[9,2],[2,1],[1,8],[8,0],[0,3],[8,9]] // IT WORKS
// var EV = [[3,9],[9,2],[2,1],[1,8],[8,0],[0,3],[8,9], [5,6], [6,7], [2,5]] // IT DOESN'T WORK
// var EV = [[3,2],[2,1],[1,0],[0,3]] // IT WORKS
// var EV = [[2,3],[1,2],[0,1],[3,0]] // IT WORKS
// var EV = [[2,3],[1,2],[0,1],[3,0],[6,7],[5,6],[4,5],[7,4]] // IT WORKS
// var EV = [[3,2],[2,1],[1,0],[0,3],[7,6],[6,5],[5,4],[4,7]] // IT WORKS
// var V = [[2,5],[5,6],[10,6.8],[23,8],[9.6,11.3],[20,15],[25,16],[29,18],[30,22],[4,11],[6,10],[24,25],[18,20],[27,7]]
// var EV = [[0,1],[10,0],[9,10],[9,1],[1,2],[4,2],[3,13],[2,3],[4,5],[5,6],[6,7],[12,5],[12,11],[11,6],[11,8],[7,8],[9,4]]
/**
* MAIN
*/
// var cycles_data = find_inner_cycles(V, EV)
// console.log('############## OUTPUT')
// console.log('EDGES:')
// console.log(cycles_data.e_cycles)
// console.log('\n')
// console.log('VERTICES:')
// console.log(cycles_data.v_cycles)
// console.log('\n')
// console.log(cycles_data.ev_mapping.every(m => m.color === 2))
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ncmFwaC1jeWNsZXMuanMiXSwibmFtZXMiOlsic3ViIiwidjEiLCJ2MiIsIm1vZCIsIm4iLCJtIiwiY29tcHV0ZV9ldl9tYXBwaW5nIiwiRVYiLCJldl9tYXBwaW5nIiwibWFwIiwiZXYiLCJjb2xvciIsImRpcmVjdGlvbiIsImNvbXB1dGVfYW5nbGUiLCJQIiwiViIsInBvaW50IiwiYW5nbGUiLCJNYXRoIiwiYXRhbjIiLCJjb21wdXRlX2luY2lkZW5jZXMiLCJpbmNpZGVuY2VzIiwidmVydGV4IiwiaSIsImluY2lkZW5jZSIsImZvckVhY2giLCJlZGdlIiwiaiIsImVuZHBvaW50IiwicG9zaXRpb24iLCJ1bmRlZmluZWQiLCJwdXNoIiwiaW5kZXgiLCJzb3J0IiwiaTEiLCJpMiIsImdldF9zdGFydGluZ19lZGdlIiwiZSIsImxlbmd0aCIsImdldF9uZXh0X2VkZ2UiLCJpdGVtcyIsIm5faXRlbXMiLCJpdGVtIiwib3V0IiwiZmluZF9jeWNsZXMiLCJWX2N5Y2xlcyIsIkVfY3ljbGVzIiwiZGlyX0VfY3ljbGVzIiwiVl9jeWNsZSIsIkVfY3ljbGUiLCJkaXJfRV9jeWNsZSIsIm5leHQiLCJjb3VudGVyIiwic3RhcnQiLCJ2X2N5Y2xlcyIsImVfY3ljbGVzIiwiZGlyX2VfY3ljbGVzIiwiZmluZF9zaG9ydF9jeWNsZXNfaW5kZXhlcyIsImluZGV4ZXMiLCJlX2N5Y2xlIiwidl9jeWNsZSIsImZpbmRfaW5uZXJfY3ljbGVzIiwiY3ljbGVzIiwic2hvcnRfY3ljbGVzX2luZGV4ZXMiLCJzcGxpY2UiLCJpbmR4Iiwicm9vbXNfdmFsdWVzIiwiY3ljbGUiLCJkaXIiLCJyb29tc19zdW1zIiwicm9vbSIsInJlZHVjZSIsImEiLCJiIiwicG9zaXRpdmVfY291bnQiLCJmaWx0ZXIiLCJzdW0iLCJuZWdhdGl2ZV9jb3VudCIsInJtX25lZyIsInYiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiQUFBQTs7OztBQUlBLFNBQVNB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aUJMLFdBQVdNLE1BQVgsQ0FBa0I7QUFBQSxXQUFPQyxNQUFNLENBQWI7QUFBQSxHQUFsQixFQUFrQ3RDLE1BQXZEO0FBQ0EsTUFBSXVDLGlCQUFpQlIsV0FBVy9CLE1BQVgsR0FBb0JvQyxjQUF6Qzs7QUFFQSxNQUFJSSxTQUFVSixrQkFBa0JHLGNBQWxCLEdBQW1DLENBQW5DLEdBQXVDLENBQUMsQ0FBdEQ7O0FBRUEsU0FBTztBQUNMdkIsY0FBVVEsT0FBT1IsUUFBUCxDQUFnQnFCLE1BQWhCLENBQXVCLFVBQUNJLENBQUQsRUFBSXhELENBQUo7QUFBQSxhQUFXdUQsU0FBU1QsV0FBVzlDLENBQVgsQ0FBVixHQUEyQixDQUFyQztBQUFBLEtBQXZCLENBREw7QUFFTGdDLGNBQVVPLE9BQU9QLFFBQVAsQ0FBZ0JvQixNQUFoQixDQUF1QixVQUFDSSxDQUFELEVBQUl4RCxDQUFKO0FBQUEsYUFBV3VELFNBQVNULFdBQVc5QyxDQUFYLENBQVYsR0FBMkIsQ0FBckM7QUFBQSxLQUF2QixDQUZMO0FBR0xmLGdCQUFZc0QsT0FBT3REO0FBSGQsR0FBUDtBQUtEOztBQUVEO0FBQ0F3RSxPQUFPQyxPQUFQLEdBQWlCcEIsaUJBQWpCOztBQUVBOzs7O0FBSUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7Ozs7QUFJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ3JhcGgtY3ljbGVzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVVElMU1xuICovXG5cbmZ1bmN0aW9uIHN1YiAodjEsIHYyKSB7XG4gIHJldHVybiBbdjFbMF0gLSB2MlswXSwgdjFbMV0gLSB2MlsxXV1cbn1cblxuZnVuY3Rpb24gbW9kIChuLCBtKSB7XG4gIHJldHVybiAoKG4gJSBtKSArIG0pICUgbVxufVxuXG4vKipcbiAqIENZQ0xFU1xuICovXG5cbmZ1bmN0aW9uIGNvbXB1dGVfZXZfbWFwcGluZyAoRVYpIHtcbiAgdmFyIGV2X21hcHBpbmcgPSBFVi5tYXAoZnVuY3Rpb24gKGV2KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGV2OiBldixcbiAgICAgIGNvbG9yOiAwLFxuICAgICAgZGlyZWN0aW9uOiAtMVxuICAgIH1cbiAgfSlcblxuICByZXR1cm4gZXZfbWFwcGluZ1xufVxuXG5mdW5jdGlvbiBjb21wdXRlX2FuZ2xlIChQLCBWKSB7XG4gIHZhciBwb2ludCA9IHN1YihWLCBQKVxuICB2YXIgYW5nbGUgPSBNYXRoLmF0YW4yKHBvaW50WzFdLCBwb2ludFswXSlcbiAgcmV0dXJuIGFuZ2xlXG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVfaW5jaWRlbmNlcyAoViwgRVYpIHtcbiAgdmFyIGluY2lkZW5jZXMgPSBWLm1hcChmdW5jdGlvbiAodmVydGV4LCBpKSB7XG4gICAgdmFyIGluY2lkZW5jZSA9IFtdXG4gICAgRVYuZm9yRWFjaChmdW5jdGlvbiAoZWRnZSwgaikge1xuICAgICAgdmFyIGVuZHBvaW50XG4gICAgICB2YXIgcG9zaXRpb25cblxuICAgICAgaWYgKGVkZ2VbMF0gPT09IGkpIHtcbiAgICAgICAgZW5kcG9pbnQgPSBlZGdlWzFdXG4gICAgICAgIHBvc2l0aW9uID0gMVxuICAgICAgfVxuXG4gICAgICBpZiAoZWRnZVsxXSA9PT0gaSkge1xuICAgICAgICBlbmRwb2ludCA9IGVkZ2VbMF1cbiAgICAgICAgcG9zaXRpb24gPSAwXG4gICAgICB9XG5cbiAgICAgIGVuZHBvaW50ICE9PSB1bmRlZmluZWQgJiYgaW5jaWRlbmNlLnB1c2goe1xuICAgICAgICBpbmRleDogaixcbiAgICAgICAgZW5kcG9pbnQ6IGVuZHBvaW50LFxuICAgICAgICBhbmdsZTogY29tcHV0ZV9hbmdsZSh2ZXJ0ZXgsIFZbZW5kcG9pbnRdKSxcbiAgICAgICAgZWRnZTogZWRnZSxcbiAgICAgICAgcG9zaXRpb246IHBvc2l0aW9uXG4gICAgICB9KVxuICAgIH0pXG5cbiAgICBpbmNpZGVuY2Uuc29ydChmdW5jdGlvbiAoaTEsIGkyKSB7XG4gICAgICByZXR1cm4gaTIuYW5nbGUgLSBpMS5hbmdsZVxuICAgIH0pXG5cbiAgICByZXR1cm4gaW5jaWRlbmNlXG4gIH0pXG5cbiAgcmV0dXJuIGluY2lkZW5jZXNcbn1cblxuZnVuY3Rpb24gZ2V0X3N0YXJ0aW5nX2VkZ2UgKGluY2lkZW5jZXMsIGV2X21hcHBpbmcpIHtcbiAgdmFyIGVcbiAgdmFyIHBvc2l0aW9uXG4gIHZhciBkaXJlY3Rpb25cbiAgZm9yIChlID0gMDsgZSA8IGV2X21hcHBpbmcubGVuZ3RoOyBlICs9IDEpIHtcbiAgICBpZiAoZXZfbWFwcGluZ1tlXS5jb2xvciA8IDIpIHtcbiAgICAgIGRpcmVjdGlvbiA9IC0xICogZXZfbWFwcGluZ1tlXS5kaXJlY3Rpb25cbiAgICAgIGNvbG9yKGV2X21hcHBpbmcsIGUsIGRpcmVjdGlvbilcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVkZ2U6IGUsXG4gICAgICAgIGRpcmVjdGlvbjogZGlyZWN0aW9uLFxuICAgICAgICBwb3NpdGlvbjogZGlyZWN0aW9uID09PSAtMSA/IDAgOiAxXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGdldF9uZXh0X2VkZ2UgKGluY2lkZW5jZXMsIGVkZ2UsIHBvc2l0aW9uLCBFVikge1xuICB2YXIgaXRlbXMgPSBpbmNpZGVuY2VzW0VWW2VkZ2VdW3Bvc2l0aW9uXV1cbiAgLy9jb25zb2xlLmxvZyhpdGVtcywgaW5jaWRlbmNlcywgRVYsIGVkZ2UsIHBvc2l0aW9uKTtcbiAgdmFyIG5faXRlbXMgPSBpdGVtcy5sZW5ndGhcbiAgdmFyIGl0ZW1cbiAgdmFyIG91dFxuICB2YXIgalxuICBmb3IgKGogPSAwOyBqIDwgbl9pdGVtczsgaiArPSAxKSB7XG4gICAgaXRlbSA9IGl0ZW1zW2pdXG4gICAgaWYgKGl0ZW0uaW5kZXggPT09IGVkZ2UpIHtcbiAgICAgIG91dCA9IGl0ZW1zW21vZChqICsgMSwgaXRlbXMubGVuZ3RoKV1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIGVkZ2U6IG91dC5pbmRleCxcbiAgICAgICAgdmVydGV4OiBvdXQuZW5kcG9pbnQsXG4gICAgICAgIHBvc2l0aW9uOiBvdXQucG9zaXRpb24sXG4gICAgICAgIGRpcmVjdGlvbjogb3V0LnBvc2l0aW9uID8gMSA6IC0xXG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNvbG9yIChldl9tYXBwaW5nLCBpbmRleCwgZGlyZWN0aW9uKSB7XG4gIGV2X21hcHBpbmdbaW5kZXhdLmNvbG9yICs9IDFcbiAgZXZfbWFwcGluZ1tpbmRleF0uZGlyZWN0aW9uID0gZGlyZWN0aW9uXG59XG5cbmZ1bmN0aW9uIGZpbmRfY3ljbGVzIChWLCBFVikge1xuICB2YXIgZXZfbWFwcGluZyA9IGNvbXB1dGVfZXZfbWFwcGluZyhFVilcbiAgdmFyIGluY2lkZW5jZXMgPSBjb21wdXRlX2luY2lkZW5jZXMoViwgRVYpXG4gIHZhciBWX2N5Y2xlcyA9IFtdXG4gIHZhciBFX2N5Y2xlcyA9IFtdXG4gIHZhciBkaXJfRV9jeWNsZXMgPSBbXVxuICB2YXIgVl9jeWNsZVxuICB2YXIgRV9jeWNsZVxuICB2YXIgZGlyX0VfY3ljbGVcbiAgdmFyIG5leHRcbiAgdmFyIGNvdW50ZXIgPSAwXG4gIHZhciBzdGFydCA9IGdldF9zdGFydGluZ19lZGdlKGluY2lkZW5jZXMsIGV2X21hcHBpbmcpXG5cbiAgd2hpbGUgKHN0YXJ0ICE9PSB1bmRlZmluZWQpIHtcbiAgICBWX2N5Y2xlID0gW0VWW3N0YXJ0LmVkZ2VdW21vZChzdGFydC5wb3NpdGlvbiArIDEsIDIpXSwgRVZbc3RhcnQuZWRnZV1bc3RhcnQucG9zaXRpb25dXVxuICAgIEVfY3ljbGUgPSBbc3RhcnQuZWRnZV1cbiAgICBkaXJfRV9jeWNsZSA9IFtzdGFydC5kaXJlY3Rpb25dXG4gICAgbmV4dCA9IGdldF9uZXh0X2VkZ2UoaW5jaWRlbmNlcywgc3RhcnQuZWRnZSwgc3RhcnQucG9zaXRpb24sIEVWKVxuICAgIHdoaWxlIChuZXh0LmVkZ2UgIT09IHN0YXJ0LmVkZ2UpIHtcbiAgICAgIFZfY3ljbGUucHVzaChuZXh0LnZlcnRleClcbiAgICAgIEVfY3ljbGUucHVzaChuZXh0LmVkZ2UpXG4gICAgICBkaXJfRV9jeWNsZS5wdXNoKG5leHQuZGlyZWN0aW9uKVxuICAgICAgY29sb3IoZXZfbWFwcGluZywgbmV4dC5lZGdlLCBuZXh0LmRpcmVjdGlvbilcbiAgICAgIG5leHQgPSBnZXRfbmV4dF9lZGdlKGluY2lkZW5jZXMsIG5leHQuZWRnZSwgbmV4dC5wb3NpdGlvbiwgRVYpXG4gICAgfVxuICAgIEVfY3ljbGVzLnB1c2goRV9jeWNsZSlcbiAgICBWX2N5Y2xlcy5wdXNoKFZfY3ljbGUpXG4gICAgZGlyX0VfY3ljbGVzLnB1c2goZGlyX0VfY3ljbGUpXG5cbiAgICAvL2NvbnNvbGUubG9nKCcjIyMjIyMjIyMjIyMjIyBDWUNMRSAnLCArK2NvdW50ZXIpXG4gICAgLy9jb25zb2xlLmxvZygnRURHRVM6JywgRV9jeWNsZSlcbiAgICAvL2NvbnNvbGUubG9nKCdWRVJUSUNFUzonLCBWX2N5Y2xlKVxuICAgIC8vY29uc29sZS5sb2coJ1NUQVJUJywgJ2VkZ2U6Jywgc3RhcnQuZWRnZSwgJ3Bvc2l0aW9uOicsIHN0YXJ0LnBvc2l0aW9uKVxuICAgIC8vY29uc29sZS5sb2coJ0NPVU5URVI6JywgZXZfbWFwcGluZy5tYXAoZSA9PiBlLmNvbG9yKSwgZXZfbWFwcGluZy5tYXAoZSA9PiBlLmNvbG9yKS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiKSk7XG4gICAgLy9jb25zb2xlLmxvZygnXFxuJylcblxuICAgIHN0YXJ0ID0gZ2V0X3N0YXJ0aW5nX2VkZ2UoaW5jaWRlbmNlcywgZXZfbWFwcGluZylcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdl9jeWNsZXM6IFZfY3ljbGVzLFxuICAgIGVfY3ljbGVzOiBFX2N5Y2xlcyxcbiAgICBkaXJfZV9jeWNsZXM6IGRpcl9FX2N5Y2xlcyxcbiAgICBldl9tYXBwaW5nOiBldl9tYXBwaW5nXG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZF9zaG9ydF9jeWNsZXNfaW5kZXhlcyAodl9jeWNsZXMsIGVfY3ljbGVzKSB7XG4gIHZhciBpbmRleGVzID0gW107XG4gIHZhciBlX2N5Y2xlO1xuICB2YXIgdl9jeWNsZTtcbiAgdmFyIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IGVfY3ljbGVzLmxlbmd0aDsgaSArPSAxKSB7XG4gICAgZV9jeWNsZSA9IGVfY3ljbGVzW2ldO1xuICAgIHZfY3ljbGUgPSB2X2N5Y2xlc1tpXTtcbiAgICBpZiAoKGVfY3ljbGUubGVuZ3RoIDwgMykgfHwgKHZfY3ljbGVbMF0gIT09IHZfY3ljbGVbdl9jeWNsZS5sZW5ndGggLSAxXSkpIHtcbiAgICAgIGluZGV4ZXMucHVzaChpKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaW5kZXhlcztcbn1cblxuZnVuY3Rpb24gZmluZF9pbm5lcl9jeWNsZXMgKFYsIEVWKSB7XG4gIHZhciBjeWNsZXMgPSBmaW5kX2N5Y2xlcyhWLCBFVik7XG4gIHZhciB2X2N5Y2xlcyA9IGN5Y2xlcy52X2N5Y2xlcztcbiAgdmFyIGVfY3ljbGVzID0gY3ljbGVzLmVfY3ljbGVzO1xuICB2YXIgc2hvcnRfY3ljbGVzX2luZGV4ZXMgPSBmaW5kX3Nob3J0X2N5Y2xlc19pbmRleGVzKHZfY3ljbGVzLCBlX2N5Y2xlcyk7XG4gIHNob3J0X2N5Y2xlc19pbmRleGVzLmZvckVhY2goaW5keCA9PiB7XG4gICAgdl9jeWNsZXMuc3BsaWNlKGluZHgsIDEpO1xuICAgIGVfY3ljbGVzLnNwbGljZShpbmR4LCAxKTtcbiAgfSlcbiAgdmFyIGRpcl9lX2N5Y2xlcyA9IGN5Y2xlcy5kaXJfZV9jeWNsZXM7XG4gIHZhciByb29tc192YWx1ZXMgPSBjeWNsZXMuZV9jeWNsZXMubWFwKChjeWNsZSwgaSkgPT4gY3ljbGUubWFwKGZ1bmN0aW9uIChlZGdlLCBqKSB7XG4gICAgdmFyIHYxO1xuICAgIHZhciB2MjtcblxuICAgIHZhciBkaXIgPSBkaXJfZV9jeWNsZXNbaV1bal0gPiAwXG5cbiAgICBpZiAoZGlyID4gMCkge1xuICAgICAgdjEgPSBFVltlZGdlXVswXTtcbiAgICAgIHYyID0gRVZbZWRnZV1bMV07XG4gICAgfSBlbHNlIHtcbiAgICAgIHYxID0gRVZbZWRnZV1bMV07XG4gICAgICB2MiA9IEVWW2VkZ2VdWzBdO1xuICAgIH1cblxuICAgIHJldHVybiAoVlt2Ml1bMF0gIC0gVlt2MV1bMF0pICogKFZbdjJdWzFdICsgVlt2MV1bMV0pO1xuICB9KSk7XG5cbiAgdmFyIHJvb21zX3N1bXMgPSByb29tc192YWx1ZXMubWFwKHJvb20gPT4gcm9vbS5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiKSlcblxuICB2YXIgcG9zaXRpdmVfY291bnQgPSByb29tc19zdW1zLmZpbHRlcihzdW0gPT4gc3VtID4gMCkubGVuZ3RoO1xuICB2YXIgbmVnYXRpdmVfY291bnQgPSByb29tc19zdW1zLmxlbmd0aCAtIHBvc2l0aXZlX2NvdW50O1xuXG4gIHZhciBybV9uZWcgPSAgcG9zaXRpdmVfY291bnQgPj0gbmVnYXRpdmVfY291bnQgPyAxIDogLTE7XG5cbiAgcmV0dXJuIHtcbiAgICB2X2N5Y2xlczogY3ljbGVzLnZfY3ljbGVzLmZpbHRlcigodiwgaSkgPT4gKHJtX25lZyAqIHJvb21zX3N1bXNbaV0pID4gMCApLFxuICAgIGVfY3ljbGVzOiBjeWNsZXMuZV9jeWNsZXMuZmlsdGVyKCh2LCBpKSA9PiAocm1fbmVnICogcm9vbXNfc3Vtc1tpXSkgPiAwICksXG4gICAgZXZfbWFwcGluZzogY3ljbGVzLmV2X21hcHBpbmdcbiAgfVxufVxuXG4vLyBleHBvcnQgZGVmYXVsdCBmaW5kX2lubmVyX2N5Y2xlcztcbm1vZHVsZS5leHBvcnRzID0gZmluZF9pbm5lcl9jeWNsZXNcblxuLyoqXG4qIERBVEFcbiovXG5cbi8vIHZhciBWID0gW1swLjU3NzQsIDEuMF0sIFsxLjAsIDEuMF0sIFsxLjE1NDcsIDAuMF0sIFsxLjAsIDAuMF0sIFswLjAsIDAuMF0sIFswLjAsIDAuNzMyXSwgWzEuMCwgMC4xNTQ3XSwgWzAuNzMyLCAwLjBdLCBbMS4wNDkxLCAwLjE4M10sIFstMC4zMTcsIDAuNTQ5XSwgWzEuMCwgMC4yNjhdLCBbMC4xODMsIC0wLjMxNjldLCBbMC41NDkxLCAxLjA0OV0sIFswLjQ2NDIsIDEuMF0sIFswLjAsIC0wLjQyMjZdLCBbMC4wLCAxLjBdXVxuLy8gdmFyIEVWID0gW1swLCAxXSwgWzIsIDNdLCBbNSwgNF0sIFs3LCA2XSwgWzIsIDhdLCBbMywgNl0sIFs0LCA5XSwgWzAsIDEwXSwgWzksIDVdLCBbOCwgMTBdLCBbNywgMTFdLCBbMTIsIDEzXSwgWzYsIDhdLCBbNiwgMTBdLCBbNCwgN10sIFs0LCAxMV0sIFs0LCAxNF0sIFs1LCAxNV0sIFsxMSwgMTRdLCBbMCwgMTJdLCBbMTMsIDE1XSwgWzAsIDEzXSwgWzEsIDEwXSwgWzMsIDddLCBbNSwgMTNdXVxuXG4vLyB2YXIgViA9IFtbMCwwXSxbMTAsMF0sWzEwLDEwXSxbMCwxMF0sIFsxMDAsMTAwXSxbMTEwLDEwMF0sWzExMCwxMTBdLFsxMDAsMTEwXSwgWzUsMF0sIFs1LDEwXV1cbi8vIHZhciBWID0gW1swLDAuNV0sWzEyLC0wLjddLFsxNCwxNF0sWy0yLDEwXSwgWzEwMywxMDZdLFsxMTcsOThdLFs5NiwxMTJdLFsxMDQsMTA5XSwgWzUuNSwwLjhdLCBbNC44LDEwLjVdXVxuLy8gdmFyIEVWID0gW1szLDldLFs5LDJdLFsyLDFdLFsxLDhdLFs4LDBdLFswLDNdLFs4LDldXSAvLyBJVCBXT1JLU1xuLy8gdmFyIEVWID0gW1szLDldLFs5LDJdLFsyLDFdLFsxLDhdLFs4LDBdLFswLDNdLFs4LDldLCBbNSw2XSwgWzYsN10sIFsyLDVdXSAvLyBJVCBET0VTTidUIFdPUktcbi8vIHZhciBFViA9IFtbMywyXSxbMiwxXSxbMSwwXSxbMCwzXV0gLy8gSVQgV09SS1Ncbi8vIHZhciBFViA9IFtbMiwzXSxbMSwyXSxbMCwxXSxbMywwXV0gLy8gSVQgV09SS1Ncbi8vIHZhciBFViA9IFtbMiwzXSxbMSwyXSxbMCwxXSxbMywwXSxbNiw3XSxbNSw2XSxbNCw1XSxbNyw0XV0gLy8gSVQgV09SS1Ncbi8vIHZhciBFViA9IFtbMywyXSxbMiwxXSxbMSwwXSxbMCwzXSxbNyw2XSxbNiw1XSxbNSw0XSxbNCw3XV0gLy8gSVQgV09SS1NcblxuLy8gdmFyIFYgPSBbWzIsNV0sWzUsNl0sWzEwLDYuOF0sWzIzLDhdLFs5LjYsMTEuM10sWzIwLDE1XSxbMjUsMTZdLFsyOSwxOF0sWzMwLDIyXSxbNCwxMV0sWzYsMTBdLFsyNCwyNV0sWzE4LDIwXSxbMjcsN11dXG4vLyB2YXIgRVYgPSBbWzAsMV0sWzEwLDBdLFs5LDEwXSxbOSwxXSxbMSwyXSxbNCwyXSxbMywxM10sWzIsM10sWzQsNV0sWzUsNl0sWzYsN10sWzEyLDVdLFsxMiwxMV0sWzExLDZdLFsxMSw4XSxbNyw4XSxbOSw0XV1cblxuLyoqXG4qIE1BSU5cbiovXG5cbi8vIHZhciBjeWNsZXNfZGF0YSA9IGZpbmRfaW5uZXJfY3ljbGVzKFYsIEVWKVxuLy8gY29uc29sZS5sb2coJyMjIyMjIyMjIyMjIyMjIE9VVFBVVCcpXG4vLyBjb25zb2xlLmxvZygnRURHRVM6Jylcbi8vIGNvbnNvbGUubG9nKGN5Y2xlc19kYXRhLmVfY3ljbGVzKVxuLy8gY29uc29sZS5sb2coJ1xcbicpXG4vLyBjb25zb2xlLmxvZygnVkVSVElDRVM6Jylcbi8vIGNvbnNvbGUubG9nKGN5Y2xlc19kYXRhLnZfY3ljbGVzKVxuLy8gY29uc29sZS5sb2coJ1xcbicpXG4vLyBjb25zb2xlLmxvZyhjeWNsZXNfZGF0YS5ldl9tYXBwaW5nLmV2ZXJ5KG0gPT4gbS5jb2xvciA9PT0gMikpXG5cbiJdfQ==