UNPKG

react-planner-viewer

Version:

react-planner-viewer is a React Component for view plans builded with react-planner in 2D mode

268 lines (228 loc) 26.1 kB
"use strict"; /** * 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,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9ncmFwaC1jeWNsZXMuanMiXSwibmFtZXMiOlsic3ViIiwidjEiLCJ2MiIsIm1vZCIsIm4iLCJtIiwiY29tcHV0ZV9ldl9tYXBwaW5nIiwiRVYiLCJldl9tYXBwaW5nIiwibWFwIiwiZXYiLCJjb2xvciIsImRpcmVjdGlvbiIsImNvbXB1dGVfYW5nbGUiLCJQIiwiViIsInBvaW50IiwiYW5nbGUiLCJNYXRoIiwiYXRhbjIiLCJjb21wdXRlX2luY2lkZW5jZXMiLCJpbmNpZGVuY2VzIiwidmVydGV4IiwiaSIsImluY2lkZW5jZSIsImZvckVhY2giLCJlZGdlIiwiaiIsImVuZHBvaW50IiwicG9zaXRpb24iLCJ1bmRlZmluZWQiLCJwdXNoIiwiaW5kZXgiLCJzb3J0IiwiaTEiLCJpMiIsImdldF9zdGFydGluZ19lZGdlIiwiZSIsImxlbmd0aCIsImdldF9uZXh0X2VkZ2UiLCJpdGVtcyIsIm5faXRlbXMiLCJpdGVtIiwib3V0IiwiZmluZF9jeWNsZXMiLCJWX2N5Y2xlcyIsIkVfY3ljbGVzIiwiZGlyX0VfY3ljbGVzIiwiVl9jeWNsZSIsIkVfY3ljbGUiLCJkaXJfRV9jeWNsZSIsIm5leHQiLCJjb3VudGVyIiwic3RhcnQiLCJ2X2N5Y2xlcyIsImVfY3ljbGVzIiwiZGlyX2VfY3ljbGVzIiwiZmluZF9zaG9ydF9jeWNsZXNfaW5kZXhlcyIsImluZGV4ZXMiLCJlX2N5Y2xlIiwidl9jeWNsZSIsImZpbmRfaW5uZXJfY3ljbGVzIiwiY3ljbGVzIiwic2hvcnRfY3ljbGVzX2luZGV4ZXMiLCJzcGxpY2UiLCJpbmR4Iiwicm9vbXNfdmFsdWVzIiwiY3ljbGUiLCJkaXIiLCJyb29tc19zdW1zIiwicm9vbSIsInJlZHVjZSIsImEiLCJiIiwicG9zaXRpdmVfY291bnQiLCJmaWx0ZXIiLCJzdW0iLCJuZWdhdGl2ZV9jb3VudCIsInJtX25lZyIsInYiLCJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOztBQUFBOzs7O0FBSUEsU0FB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QUFpQkwsV0FBV00sTUFBWCxDQUFrQjtBQUFBLFdBQU9DLE1BQU0sQ0FBYjtBQUFBLEdBQWxCLEVBQWtDdEMsTUFBdkQ7QUFDQSxNQUFJdUMsaUJBQWlCUixXQUFXL0IsTUFBWCxHQUFvQm9DLGNBQXpDOztBQUVBLE1BQUlJLFNBQVVKLGtCQUFrQkcsY0FBbEIsR0FBbUMsQ0FBbkMsR0FBdUMsQ0FBQyxDQUF0RDs7QUFFQSxTQUFPO0FBQ0x2QixjQUFVUSxPQUFPUixRQUFQLENBQWdCcUIsTUFBaEIsQ0FBdUIsVUFBQ0ksQ0FBRCxFQUFJeEQsQ0FBSjtBQUFBLGFBQVd1RCxTQUFTVCxXQUFXOUMsQ0FBWCxDQUFWLEdBQTJCLENBQXJDO0FBQUEsS0FBdkIsQ0FETDtBQUVMZ0MsY0FBVU8sT0FBT1AsUUFBUCxDQUFnQm9CLE1BQWhCLENBQXVCLFVBQUNJLENBQUQsRUFBSXhELENBQUo7QUFBQSxhQUFXdUQsU0FBU1QsV0FBVzlDLENBQVgsQ0FBVixHQUEyQixDQUFyQztBQUFBLEtBQXZCLENBRkw7QUFHTGYsZ0JBQVlzRCxPQUFPdEQ7QUFIZCxHQUFQO0FBS0Q7O0FBRUQ7QUFDQXdFLE9BQU9DLE9BQVAsR0FBaUJwQixpQkFBakI7O0FBRUE7Ozs7QUFJQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTs7OztBQUlBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJncmFwaC1jeWNsZXMuanMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFVUSUxTXG4gKi9cblxuZnVuY3Rpb24gc3ViICh2MSwgdjIpIHtcbiAgcmV0dXJuIFt2MVswXSAtIHYyWzBdLCB2MVsxXSAtIHYyWzFdXVxufVxuXG5mdW5jdGlvbiBtb2QgKG4sIG0pIHtcbiAgcmV0dXJuICgobiAlIG0pICsgbSkgJSBtXG59XG5cbi8qKlxuICogQ1lDTEVTXG4gKi9cblxuZnVuY3Rpb24gY29tcHV0ZV9ldl9tYXBwaW5nIChFVikge1xuICB2YXIgZXZfbWFwcGluZyA9IEVWLm1hcChmdW5jdGlvbiAoZXYpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZXY6IGV2LFxuICAgICAgY29sb3I6IDAsXG4gICAgICBkaXJlY3Rpb246IC0xXG4gICAgfVxuICB9KVxuXG4gIHJldHVybiBldl9tYXBwaW5nXG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVfYW5nbGUgKFAsIFYpIHtcbiAgdmFyIHBvaW50ID0gc3ViKFYsIFApXG4gIHZhciBhbmdsZSA9IE1hdGguYXRhbjIocG9pbnRbMV0sIHBvaW50WzBdKVxuICByZXR1cm4gYW5nbGVcbn1cblxuZnVuY3Rpb24gY29tcHV0ZV9pbmNpZGVuY2VzIChWLCBFVikge1xuICB2YXIgaW5jaWRlbmNlcyA9IFYubWFwKGZ1bmN0aW9uICh2ZXJ0ZXgsIGkpIHtcbiAgICB2YXIgaW5jaWRlbmNlID0gW11cbiAgICBFVi5mb3JFYWNoKGZ1bmN0aW9uIChlZGdlLCBqKSB7XG4gICAgICB2YXIgZW5kcG9pbnRcbiAgICAgIHZhciBwb3NpdGlvblxuXG4gICAgICBpZiAoZWRnZVswXSA9PT0gaSkge1xuICAgICAgICBlbmRwb2ludCA9IGVkZ2VbMV1cbiAgICAgICAgcG9zaXRpb24gPSAxXG4gICAgICB9XG5cbiAgICAgIGlmIChlZGdlWzFdID09PSBpKSB7XG4gICAgICAgIGVuZHBvaW50ID0gZWRnZVswXVxuICAgICAgICBwb3NpdGlvbiA9IDBcbiAgICAgIH1cblxuICAgICAgZW5kcG9pbnQgIT09IHVuZGVmaW5lZCAmJiBpbmNpZGVuY2UucHVzaCh7XG4gICAgICAgIGluZGV4OiBqLFxuICAgICAgICBlbmRwb2ludDogZW5kcG9pbnQsXG4gICAgICAgIGFuZ2xlOiBjb21wdXRlX2FuZ2xlKHZlcnRleCwgVltlbmRwb2ludF0pLFxuICAgICAgICBlZGdlOiBlZGdlLFxuICAgICAgICBwb3NpdGlvbjogcG9zaXRpb25cbiAgICAgIH0pXG4gICAgfSlcblxuICAgIGluY2lkZW5jZS5zb3J0KGZ1bmN0aW9uIChpMSwgaTIpIHtcbiAgICAgIHJldHVybiBpMi5hbmdsZSAtIGkxLmFuZ2xlXG4gICAgfSlcblxuICAgIHJldHVybiBpbmNpZGVuY2VcbiAgfSlcblxuICByZXR1cm4gaW5jaWRlbmNlc1xufVxuXG5mdW5jdGlvbiBnZXRfc3RhcnRpbmdfZWRnZSAoaW5jaWRlbmNlcywgZXZfbWFwcGluZykge1xuICB2YXIgZVxuICB2YXIgcG9zaXRpb25cbiAgdmFyIGRpcmVjdGlvblxuICBmb3IgKGUgPSAwOyBlIDwgZXZfbWFwcGluZy5sZW5ndGg7IGUgKz0gMSkge1xuICAgIGlmIChldl9tYXBwaW5nW2VdLmNvbG9yIDwgMikge1xuICAgICAgZGlyZWN0aW9uID0gLTEgKiBldl9tYXBwaW5nW2VdLmRpcmVjdGlvblxuICAgICAgY29sb3IoZXZfbWFwcGluZywgZSwgZGlyZWN0aW9uKVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWRnZTogZSxcbiAgICAgICAgZGlyZWN0aW9uOiBkaXJlY3Rpb24sXG4gICAgICAgIHBvc2l0aW9uOiBkaXJlY3Rpb24gPT09IC0xID8gMCA6IDFcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0X25leHRfZWRnZSAoaW5jaWRlbmNlcywgZWRnZSwgcG9zaXRpb24sIEVWKSB7XG4gIHZhciBpdGVtcyA9IGluY2lkZW5jZXNbRVZbZWRnZV1bcG9zaXRpb25dXVxuICAvL2NvbnNvbGUubG9nKGl0ZW1zLCBpbmNpZGVuY2VzLCBFViwgZWRnZSwgcG9zaXRpb24pO1xuICB2YXIgbl9pdGVtcyA9IGl0ZW1zLmxlbmd0aFxuICB2YXIgaXRlbVxuICB2YXIgb3V0XG4gIHZhciBqXG4gIGZvciAoaiA9IDA7IGogPCBuX2l0ZW1zOyBqICs9IDEpIHtcbiAgICBpdGVtID0gaXRlbXNbal1cbiAgICBpZiAoaXRlbS5pbmRleCA9PT0gZWRnZSkge1xuICAgICAgb3V0ID0gaXRlbXNbbW9kKGogKyAxLCBpdGVtcy5sZW5ndGgpXVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZWRnZTogb3V0LmluZGV4LFxuICAgICAgICB2ZXJ0ZXg6IG91dC5lbmRwb2ludCxcbiAgICAgICAgcG9zaXRpb246IG91dC5wb3NpdGlvbixcbiAgICAgICAgZGlyZWN0aW9uOiBvdXQucG9zaXRpb24gPyAxIDogLTFcbiAgICAgIH1cbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY29sb3IgKGV2X21hcHBpbmcsIGluZGV4LCBkaXJlY3Rpb24pIHtcbiAgZXZfbWFwcGluZ1tpbmRleF0uY29sb3IgKz0gMVxuICBldl9tYXBwaW5nW2luZGV4XS5kaXJlY3Rpb24gPSBkaXJlY3Rpb25cbn1cblxuZnVuY3Rpb24gZmluZF9jeWNsZXMgKFYsIEVWKSB7XG4gIHZhciBldl9tYXBwaW5nID0gY29tcHV0ZV9ldl9tYXBwaW5nKEVWKVxuICB2YXIgaW5jaWRlbmNlcyA9IGNvbXB1dGVfaW5jaWRlbmNlcyhWLCBFVilcbiAgdmFyIFZfY3ljbGVzID0gW11cbiAgdmFyIEVfY3ljbGVzID0gW11cbiAgdmFyIGRpcl9FX2N5Y2xlcyA9IFtdXG4gIHZhciBWX2N5Y2xlXG4gIHZhciBFX2N5Y2xlXG4gIHZhciBkaXJfRV9jeWNsZVxuICB2YXIgbmV4dFxuICB2YXIgY291bnRlciA9IDBcbiAgdmFyIHN0YXJ0ID0gZ2V0X3N0YXJ0aW5nX2VkZ2UoaW5jaWRlbmNlcywgZXZfbWFwcGluZylcblxuICB3aGlsZSAoc3RhcnQgIT09IHVuZGVmaW5lZCkge1xuICAgIFZfY3ljbGUgPSBbRVZbc3RhcnQuZWRnZV1bbW9kKHN0YXJ0LnBvc2l0aW9uICsgMSwgMildLCBFVltzdGFydC5lZGdlXVtzdGFydC5wb3NpdGlvbl1dXG4gICAgRV9jeWNsZSA9IFtzdGFydC5lZGdlXVxuICAgIGRpcl9FX2N5Y2xlID0gW3N0YXJ0LmRpcmVjdGlvbl1cbiAgICBuZXh0ID0gZ2V0X25leHRfZWRnZShpbmNpZGVuY2VzLCBzdGFydC5lZGdlLCBzdGFydC5wb3NpdGlvbiwgRVYpXG4gICAgd2hpbGUgKG5leHQuZWRnZSAhPT0gc3RhcnQuZWRnZSkge1xuICAgICAgVl9jeWNsZS5wdXNoKG5leHQudmVydGV4KVxuICAgICAgRV9jeWNsZS5wdXNoKG5leHQuZWRnZSlcbiAgICAgIGRpcl9FX2N5Y2xlLnB1c2gobmV4dC5kaXJlY3Rpb24pXG4gICAgICBjb2xvcihldl9tYXBwaW5nLCBuZXh0LmVkZ2UsIG5leHQuZGlyZWN0aW9uKVxuICAgICAgbmV4dCA9IGdldF9uZXh0X2VkZ2UoaW5jaWRlbmNlcywgbmV4dC5lZGdlLCBuZXh0LnBvc2l0aW9uLCBFVilcbiAgICB9XG4gICAgRV9jeWNsZXMucHVzaChFX2N5Y2xlKVxuICAgIFZfY3ljbGVzLnB1c2goVl9jeWNsZSlcbiAgICBkaXJfRV9jeWNsZXMucHVzaChkaXJfRV9jeWNsZSlcblxuICAgIC8vY29uc29sZS5sb2coJyMjIyMjIyMjIyMjIyMjIENZQ0xFICcsICsrY291bnRlcilcbiAgICAvL2NvbnNvbGUubG9nKCdFREdFUzonLCBFX2N5Y2xlKVxuICAgIC8vY29uc29sZS5sb2coJ1ZFUlRJQ0VTOicsIFZfY3ljbGUpXG4gICAgLy9jb25zb2xlLmxvZygnU1RBUlQnLCAnZWRnZTonLCBzdGFydC5lZGdlLCAncG9zaXRpb246Jywgc3RhcnQucG9zaXRpb24pXG4gICAgLy9jb25zb2xlLmxvZygnQ09VTlRFUjonLCBldl9tYXBwaW5nLm1hcChlID0+IGUuY29sb3IpLCBldl9tYXBwaW5nLm1hcChlID0+IGUuY29sb3IpLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpKTtcbiAgICAvL2NvbnNvbGUubG9nKCdcXG4nKVxuXG4gICAgc3RhcnQgPSBnZXRfc3RhcnRpbmdfZWRnZShpbmNpZGVuY2VzLCBldl9tYXBwaW5nKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB2X2N5Y2xlczogVl9jeWNsZXMsXG4gICAgZV9jeWNsZXM6IEVfY3ljbGVzLFxuICAgIGRpcl9lX2N5Y2xlczogZGlyX0VfY3ljbGVzLFxuICAgIGV2X21hcHBpbmc6IGV2X21hcHBpbmdcbiAgfVxufVxuXG5mdW5jdGlvbiBmaW5kX3Nob3J0X2N5Y2xlc19pbmRleGVzICh2X2N5Y2xlcywgZV9jeWNsZXMpIHtcbiAgdmFyIGluZGV4ZXMgPSBbXTtcbiAgdmFyIGVfY3ljbGU7XG4gIHZhciB2X2N5Y2xlO1xuICB2YXIgaTtcblxuICBmb3IgKGkgPSAwOyBpIDwgZV9jeWNsZXMubGVuZ3RoOyBpICs9IDEpIHtcbiAgICBlX2N5Y2xlID0gZV9jeWNsZXNbaV07XG4gICAgdl9jeWNsZSA9IHZfY3ljbGVzW2ldO1xuICAgIGlmICgoZV9jeWNsZS5sZW5ndGggPCAzKSB8fCAodl9jeWNsZVswXSAhPT0gdl9jeWNsZVt2X2N5Y2xlLmxlbmd0aCAtIDFdKSkge1xuICAgICAgaW5kZXhlcy5wdXNoKGkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpbmRleGVzO1xufVxuXG5mdW5jdGlvbiBmaW5kX2lubmVyX2N5Y2xlcyAoViwgRVYpIHtcbiAgdmFyIGN5Y2xlcyA9IGZpbmRfY3ljbGVzKFYsIEVWKTtcbiAgdmFyIHZfY3ljbGVzID0gY3ljbGVzLnZfY3ljbGVzO1xuICB2YXIgZV9jeWNsZXMgPSBjeWNsZXMuZV9jeWNsZXM7XG4gIHZhciBzaG9ydF9jeWNsZXNfaW5kZXhlcyA9IGZpbmRfc2hvcnRfY3ljbGVzX2luZGV4ZXModl9jeWNsZXMsIGVfY3ljbGVzKTtcbiAgc2hvcnRfY3ljbGVzX2luZGV4ZXMuZm9yRWFjaChpbmR4ID0+IHtcbiAgICB2X2N5Y2xlcy5zcGxpY2UoaW5keCwgMSk7XG4gICAgZV9jeWNsZXMuc3BsaWNlKGluZHgsIDEpO1xuICB9KVxuICB2YXIgZGlyX2VfY3ljbGVzID0gY3ljbGVzLmRpcl9lX2N5Y2xlcztcbiAgdmFyIHJvb21zX3ZhbHVlcyA9IGN5Y2xlcy5lX2N5Y2xlcy5tYXAoKGN5Y2xlLCBpKSA9PiBjeWNsZS5tYXAoZnVuY3Rpb24gKGVkZ2UsIGopIHtcbiAgICB2YXIgdjE7XG4gICAgdmFyIHYyO1xuXG4gICAgdmFyIGRpciA9IGRpcl9lX2N5Y2xlc1tpXVtqXSA+IDBcblxuICAgIGlmIChkaXIgPiAwKSB7XG4gICAgICB2MSA9IEVWW2VkZ2VdWzBdO1xuICAgICAgdjIgPSBFVltlZGdlXVsxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdjEgPSBFVltlZGdlXVsxXTtcbiAgICAgIHYyID0gRVZbZWRnZV1bMF07XG4gICAgfVxuXG4gICAgcmV0dXJuIChWW3YyXVswXSAgLSBWW3YxXVswXSkgKiAoVlt2Ml1bMV0gKyBWW3YxXVsxXSk7XG4gIH0pKTtcblxuICB2YXIgcm9vbXNfc3VtcyA9IHJvb21zX3ZhbHVlcy5tYXAocm9vbSA9PiByb29tLnJlZHVjZSgoYSwgYikgPT4gYSArIGIpKVxuXG4gIHZhciBwb3NpdGl2ZV9jb3VudCA9IHJvb21zX3N1bXMuZmlsdGVyKHN1bSA9PiBzdW0gPiAwKS5sZW5ndGg7XG4gIHZhciBuZWdhdGl2ZV9jb3VudCA9IHJvb21zX3N1bXMubGVuZ3RoIC0gcG9zaXRpdmVfY291bnQ7XG5cbiAgdmFyIHJtX25lZyA9ICBwb3NpdGl2ZV9jb3VudCA+PSBuZWdhdGl2ZV9jb3VudCA/IDEgOiAtMTtcblxuICByZXR1cm4ge1xuICAgIHZfY3ljbGVzOiBjeWNsZXMudl9jeWNsZXMuZmlsdGVyKCh2LCBpKSA9PiAocm1fbmVnICogcm9vbXNfc3Vtc1tpXSkgPiAwICksXG4gICAgZV9jeWNsZXM6IGN5Y2xlcy5lX2N5Y2xlcy5maWx0ZXIoKHYsIGkpID0+IChybV9uZWcgKiByb29tc19zdW1zW2ldKSA+IDAgKSxcbiAgICBldl9tYXBwaW5nOiBjeWNsZXMuZXZfbWFwcGluZ1xuICB9XG59XG5cbi8vIGV4cG9ydCBkZWZhdWx0IGZpbmRfaW5uZXJfY3ljbGVzO1xubW9kdWxlLmV4cG9ydHMgPSBmaW5kX2lubmVyX2N5Y2xlc1xuXG4vKipcbiogREFUQVxuKi9cblxuLy8gdmFyIFYgPSBbWzAuNTc3NCwgMS4wXSwgWzEuMCwgMS4wXSwgWzEuMTU0NywgMC4wXSwgWzEuMCwgMC4wXSwgWzAuMCwgMC4wXSwgWzAuMCwgMC43MzJdLCBbMS4wLCAwLjE1NDddLCBbMC43MzIsIDAuMF0sIFsxLjA0OTEsIDAuMTgzXSwgWy0wLjMxNywgMC41NDldLCBbMS4wLCAwLjI2OF0sIFswLjE4MywgLTAuMzE2OV0sIFswLjU0OTEsIDEuMDQ5XSwgWzAuNDY0MiwgMS4wXSwgWzAuMCwgLTAuNDIyNl0sIFswLjAsIDEuMF1dXG4vLyB2YXIgRVYgPSBbWzAsIDFdLCBbMiwgM10sIFs1LCA0XSwgWzcsIDZdLCBbMiwgOF0sIFszLCA2XSwgWzQsIDldLCBbMCwgMTBdLCBbOSwgNV0sIFs4LCAxMF0sIFs3LCAxMV0sIFsxMiwgMTNdLCBbNiwgOF0sIFs2LCAxMF0sIFs0LCA3XSwgWzQsIDExXSwgWzQsIDE0XSwgWzUsIDE1XSwgWzExLCAxNF0sIFswLCAxMl0sIFsxMywgMTVdLCBbMCwgMTNdLCBbMSwgMTBdLCBbMywgN10sIFs1LCAxM11dXG5cbi8vIHZhciBWID0gW1swLDBdLFsxMCwwXSxbMTAsMTBdLFswLDEwXSwgWzEwMCwxMDBdLFsxMTAsMTAwXSxbMTEwLDExMF0sWzEwMCwxMTBdLCBbNSwwXSwgWzUsMTBdXVxuLy8gdmFyIFYgPSBbWzAsMC41XSxbMTIsLTAuN10sWzE0LDE0XSxbLTIsMTBdLCBbMTAzLDEwNl0sWzExNyw5OF0sWzk2LDExMl0sWzEwNCwxMDldLCBbNS41LDAuOF0sIFs0LjgsMTAuNV1dXG4vLyB2YXIgRVYgPSBbWzMsOV0sWzksMl0sWzIsMV0sWzEsOF0sWzgsMF0sWzAsM10sWzgsOV1dIC8vIElUIFdPUktTXG4vLyB2YXIgRVYgPSBbWzMsOV0sWzksMl0sWzIsMV0sWzEsOF0sWzgsMF0sWzAsM10sWzgsOV0sIFs1LDZdLCBbNiw3XSwgWzIsNV1dIC8vIElUIERPRVNOJ1QgV09SS1xuLy8gdmFyIEVWID0gW1szLDJdLFsyLDFdLFsxLDBdLFswLDNdXSAvLyBJVCBXT1JLU1xuLy8gdmFyIEVWID0gW1syLDNdLFsxLDJdLFswLDFdLFszLDBdXSAvLyBJVCBXT1JLU1xuLy8gdmFyIEVWID0gW1syLDNdLFsxLDJdLFswLDFdLFszLDBdLFs2LDddLFs1LDZdLFs0LDVdLFs3LDRdXSAvLyBJVCBXT1JLU1xuLy8gdmFyIEVWID0gW1szLDJdLFsyLDFdLFsxLDBdLFswLDNdLFs3LDZdLFs2LDVdLFs1LDRdLFs0LDddXSAvLyBJVCBXT1JLU1xuXG4vLyB2YXIgViA9IFtbMiw1XSxbNSw2XSxbMTAsNi44XSxbMjMsOF0sWzkuNiwxMS4zXSxbMjAsMTVdLFsyNSwxNl0sWzI5LDE4XSxbMzAsMjJdLFs0LDExXSxbNiwxMF0sWzI0LDI1XSxbMTgsMjBdLFsyNyw3XV1cbi8vIHZhciBFViA9IFtbMCwxXSxbMTAsMF0sWzksMTBdLFs5LDFdLFsxLDJdLFs0LDJdLFszLDEzXSxbMiwzXSxbNCw1XSxbNSw2XSxbNiw3XSxbMTIsNV0sWzEyLDExXSxbMTEsNl0sWzExLDhdLFs3LDhdLFs5LDRdXVxuXG4vKipcbiogTUFJTlxuKi9cblxuLy8gdmFyIGN5Y2xlc19kYXRhID0gZmluZF9pbm5lcl9jeWNsZXMoViwgRVYpXG4vLyBjb25zb2xlLmxvZygnIyMjIyMjIyMjIyMjIyMgT1VUUFVUJylcbi8vIGNvbnNvbGUubG9nKCdFREdFUzonKVxuLy8gY29uc29sZS5sb2coY3ljbGVzX2RhdGEuZV9jeWNsZXMpXG4vLyBjb25zb2xlLmxvZygnXFxuJylcbi8vIGNvbnNvbGUubG9nKCdWRVJUSUNFUzonKVxuLy8gY29uc29sZS5sb2coY3ljbGVzX2RhdGEudl9jeWNsZXMpXG4vLyBjb25zb2xlLmxvZygnXFxuJylcbi8vIGNvbnNvbGUubG9nKGN5Y2xlc19kYXRhLmV2X21hcHBpbmcuZXZlcnkobSA9PiBtLmNvbG9yID09PSAyKSlcblxuIl19