1 | ;
|
2 |
|
3 | var _toConsumableArray2 = require('babel-runtime/helpers/toConsumableArray');
|
4 |
|
5 | var _toConsumableArray3 = _interopRequireDefault(_toConsumableArray2);
|
6 |
|
7 | var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
8 |
|
9 | var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
|
10 |
|
11 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
12 |
|
13 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
14 |
|
15 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
16 |
|
17 | var _createClass3 = _interopRequireDefault(_createClass2);
|
18 |
|
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
20 |
|
21 | var Promise = require('bluebird');
|
22 | var _ = require('lodash');
|
23 |
|
24 | /**
|
25 | * Service infrastructure failures recovery.
|
26 | *
|
27 | * @mixin
|
28 | * @memberof chat-service
|
29 | * @see chat-service.ChatService.event:storeConsistencyFailure
|
30 | */
|
31 |
|
32 | var RecoveryAPI = function () {
|
33 | function RecoveryAPI(state, transport, execUserCommand, instanceUID) {
|
34 | (0, _classCallCheck3.default)(this, RecoveryAPI);
|
35 |
|
36 | this.state = state;
|
37 | this.transport = transport;
|
38 | this.instanceUID = instanceUID;
|
39 | this.execUserCommand = execUserCommand;
|
40 | }
|
41 |
|
42 | (0, _createClass3.default)(RecoveryAPI, [{
|
43 | key: 'checkUserSockets',
|
44 | value: function checkUserSockets(user) {
|
45 | var _this = this;
|
46 |
|
47 | var userName = user.userName;
|
48 |
|
49 | return user.userState.getSocketsToInstance().then(function (sockets) {
|
50 | return Promise.each(_.toPairs(sockets), function (_ref) {
|
51 | var _ref2 = (0, _slicedToArray3.default)(_ref, 2);
|
52 |
|
53 | var socket = _ref2[0];
|
54 | var instance = _ref2[1];
|
55 |
|
56 | if (instance === _this.instanceUID) {
|
57 | if (!_this.transport.getSocket(socket)) {
|
58 | return user.userState.removeSocket(socket);
|
59 | }
|
60 | }
|
61 | return Promise.resolve();
|
62 | });
|
63 | }).then(function () {
|
64 | return user.userState.getSocketsToRooms();
|
65 | }).then(function (data) {
|
66 | var args = _.values(data);
|
67 | return _.intersection.apply(_, (0, _toConsumableArray3.default)(args));
|
68 | }).then(function (rooms) {
|
69 | return Promise.each(rooms, function (roomName) {
|
70 | return _this.state.getRoom(roomName).then(function (room) {
|
71 | return room.roomState.hasInList('userlist', userName);
|
72 | }).then(function (isPresent) {
|
73 | return isPresent ? Promise.resolve() : user.removeFromRoom(roomName);
|
74 | }).catchReturn();
|
75 | });
|
76 | });
|
77 | }
|
78 | }, {
|
79 | key: 'checkRoomJoined',
|
80 | value: function checkRoomJoined(room) {
|
81 | var _this2 = this;
|
82 |
|
83 | var roomName = room.roomName;
|
84 |
|
85 | return room.getList(null, 'userlist', true).then(function (userlist) {
|
86 | return Promise.each(userlist, function (userName) {
|
87 | return _this2.state.getUser(userName).then(function (user) {
|
88 | return user.userState.getRoomToSockets(roomName).then(function (sockets) {
|
89 | if (!sockets || !sockets.length) {
|
90 | return user.removeFromRoom(roomName);
|
91 | } else {
|
92 | return Promise.resolve();
|
93 | }
|
94 | }).catchReturn().then(function () {
|
95 | return room.checkAcess(userName);
|
96 | }).catch(function () {
|
97 | return user.removeFromRoom(roomName);
|
98 | });
|
99 | }).catchReturn();
|
100 | });
|
101 | });
|
102 | }
|
103 |
|
104 | /**
|
105 | * Sync user to sockets associations.
|
106 | *
|
107 | * @param {string} userName User name.
|
108 | * @param {callback} [cb] Optional callback.
|
109 | *
|
110 | * @return {Promise<undefined>} Promise that resolves without any data.
|
111 | */
|
112 |
|
113 | }, {
|
114 | key: 'userStateSync',
|
115 | value: function userStateSync(userName, cb) {
|
116 | var _this3 = this;
|
117 |
|
118 | return this.state.getUser(userName).then(function (user) {
|
119 | return _this3.checkUserSockets(user);
|
120 | }).asCallback(cb);
|
121 | }
|
122 |
|
123 | /**
|
124 | * Sync room to users associations.
|
125 | *
|
126 | * @param {string} roomName Room name.
|
127 | * @param {callback} [cb] Optional callback.
|
128 | *
|
129 | * @return {Promise<undefined>} Promise that resolves without any data.
|
130 | */
|
131 |
|
132 | }, {
|
133 | key: 'roomStateSync',
|
134 | value: function roomStateSync(roomName, cb) {
|
135 | var _this4 = this;
|
136 |
|
137 | return this.state.getRoom(roomName).then(function (room) {
|
138 | return _this4.checkRoomJoined(room);
|
139 | }).asCallback(cb);
|
140 | }
|
141 |
|
142 | /**
|
143 | * Fixes an instance data after an incorrect service shutdown.
|
144 | *
|
145 | * @param {string} id Instance id.
|
146 | * @param {callback} [cb] Optional callback.
|
147 | *
|
148 | * @return {Promise<undefined>} Promise that resolves without any data.
|
149 | */
|
150 |
|
151 | }, {
|
152 | key: 'instanceRecovery',
|
153 | value: function instanceRecovery(id, cb) {
|
154 | var _this5 = this;
|
155 |
|
156 | return this.state.getInstanceSockets(id).then(function (sockets) {
|
157 | return Promise.each(_.toPairs(sockets), function (_ref3) {
|
158 | var _ref4 = (0, _slicedToArray3.default)(_ref3, 2);
|
159 |
|
160 | var id = _ref4[0];
|
161 | var userName = _ref4[1];
|
162 |
|
163 | return _this5.state.getUser(userName).then(function (user) {
|
164 | return user.removeSocket(id);
|
165 | }).catchReturn();
|
166 | });
|
167 | }).asCallback(cb);
|
168 | }
|
169 |
|
170 | /**
|
171 | * Gets an instance heartbeat.
|
172 | *
|
173 | * @param {string} id Instance id.
|
174 | * @param {callback} [cb] Optional callback.
|
175 | *
|
176 | * @return {Promise<number>} Heartbeat timestamp.
|
177 | */
|
178 |
|
179 | }, {
|
180 | key: 'getInstanceHeartbeat',
|
181 | value: function getInstanceHeartbeat(id, cb) {
|
182 | return this.state.getInstanceHeartbeat(id).asCallback(cb);
|
183 | }
|
184 | }]);
|
185 | return RecoveryAPI;
|
186 | }();
|
187 |
|
188 | module.exports = RecoveryAPI;
|
189 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9SZWNvdmVyeUFQSS5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFFQSxJQUFNLFVBQVUsUUFBUSxVQUFSLENBQWhCO0FBQ0EsSUFBTSxJQUFJLFFBQVEsUUFBUixDQUFWOztBQUVBOzs7Ozs7OztJQU9NLFc7QUFFSix1QkFBYSxLQUFiLEVBQW9CLFNBQXBCLEVBQStCLGVBQS9CLEVBQWdELFdBQWhELEVBQTZEO0FBQUE7O0FBQzNELFNBQUssS0FBTCxHQUFhLEtBQWI7QUFDQSxTQUFLLFNBQUwsR0FBaUIsU0FBakI7QUFDQSxTQUFLLFdBQUwsR0FBbUIsV0FBbkI7QUFDQSxTQUFLLGVBQUwsR0FBdUIsZUFBdkI7QUFDRDs7OztxQ0FFaUIsSSxFQUFNO0FBQUE7O0FBQUEsVUFDaEIsUUFEZ0IsR0FDSCxJQURHLENBQ2hCLFFBRGdCOztBQUV0QixhQUFPLEtBQUssU0FBTCxDQUFlLG9CQUFmLEdBQXNDLElBQXRDLENBQTJDLG1CQUFXO0FBQzNELGVBQU8sUUFBUSxJQUFSLENBQWEsRUFBRSxPQUFGLENBQVUsT0FBVixDQUFiLEVBQWlDLGdCQUF3QjtBQUFBOztBQUFBLGNBQXRCLE1BQXNCO0FBQUEsY0FBZCxRQUFjOztBQUM5RCxjQUFJLGFBQWEsTUFBSyxXQUF0QixFQUFtQztBQUNqQyxnQkFBSSxDQUFDLE1BQUssU0FBTCxDQUFlLFNBQWYsQ0FBeUIsTUFBekIsQ0FBTCxFQUF1QztBQUNyQyxxQkFBTyxLQUFLLFNBQUwsQ0FBZSxZQUFmLENBQTRCLE1BQTVCLENBQVA7QUFDRDtBQUNGO0FBQ0QsaUJBQU8sUUFBUSxPQUFSLEVBQVA7QUFDRCxTQVBNLENBQVA7QUFRRCxPQVRNLEVBU0osSUFUSSxDQVNDLFlBQU07QUFDWixlQUFPLEtBQUssU0FBTCxDQUFlLGlCQUFmLEVBQVA7QUFDRCxPQVhNLEVBV0osSUFYSSxDQVdDLGdCQUFRO0FBQ2QsWUFBSSxPQUFPLEVBQUUsTUFBRixDQUFTLElBQVQsQ0FBWDtBQUNBLGVBQU8sRUFBRSxZQUFGLDJDQUFrQixJQUFsQixFQUFQO0FBQ0QsT0FkTSxFQWNKLElBZEksQ0FjQyxpQkFBUztBQUNmLGVBQU8sUUFBUSxJQUFSLENBQWEsS0FBYixFQUFvQixvQkFBWTtBQUNyQyxpQkFBTyxNQUFLLEtBQUwsQ0FBVyxPQUFYLENBQW1CLFFBQW5CLEVBQ0osSUFESSxDQUNDO0FBQUEsbUJBQVEsS0FBSyxTQUFMLENBQWUsU0FBZixDQUF5QixVQUF6QixFQUFxQyxRQUFyQyxDQUFSO0FBQUEsV0FERCxFQUVKLElBRkksQ0FFQztBQUFBLG1CQUNBLFlBQVksUUFBUSxPQUFSLEVBQVosR0FBZ0MsS0FBSyxjQUFMLENBQW9CLFFBQXBCLENBRGhDO0FBQUEsV0FGRCxFQUlKLFdBSkksRUFBUDtBQUtELFNBTk0sQ0FBUDtBQU9ELE9BdEJNLENBQVA7QUF1QkQ7OztvQ0FFZ0IsSSxFQUFNO0FBQUE7O0FBQUEsVUFDZixRQURlLEdBQ0YsSUFERSxDQUNmLFFBRGU7O0FBRXJCLGFBQU8sS0FBSyxPQUFMLENBQWEsSUFBYixFQUFtQixVQUFuQixFQUErQixJQUEvQixFQUFxQyxJQUFyQyxDQUEwQyxvQkFBWTtBQUMzRCxlQUFPLFFBQVEsSUFBUixDQUFhLFFBQWIsRUFBdUIsb0JBQVk7QUFDeEMsaUJBQU8sT0FBSyxLQUFMLENBQVcsT0FBWCxDQUFtQixRQUFuQixFQUE2QixJQUE3QixDQUFrQyxnQkFBUTtBQUMvQyxtQkFBTyxLQUFLLFNBQUwsQ0FBZSxnQkFBZixDQUFnQyxRQUFoQyxFQUEwQyxJQUExQyxDQUErQyxtQkFBVztBQUMvRCxrQkFBSSxDQUFDLE9BQUQsSUFBWSxDQUFDLFFBQVEsTUFBekIsRUFBaUM7QUFDL0IsdUJBQU8sS0FBSyxjQUFMLENBQW9CLFFBQXBCLENBQVA7QUFDRCxlQUZELE1BRU87QUFDTCx1QkFBTyxRQUFRLE9BQVIsRUFBUDtBQUNEO0FBQ0YsYUFOTSxFQU1KLFdBTkksR0FPSixJQVBJLENBT0M7QUFBQSxxQkFBTSxLQUFLLFVBQUwsQ0FBZ0IsUUFBaEIsQ0FBTjtBQUFBLGFBUEQsRUFRSixLQVJJLENBUUU7QUFBQSxxQkFBTSxLQUFLLGNBQUwsQ0FBb0IsUUFBcEIsQ0FBTjtBQUFBLGFBUkYsQ0FBUDtBQVNELFdBVk0sRUFVSixXQVZJLEVBQVA7QUFXRCxTQVpNLENBQVA7QUFhRCxPQWRNLENBQVA7QUFlRDs7QUFFRDs7Ozs7Ozs7Ozs7a0NBUWUsUSxFQUFVLEUsRUFBSTtBQUFBOztBQUMzQixhQUFPLEtBQUssS0FBTCxDQUFXLE9BQVgsQ0FBbUIsUUFBbkIsRUFDSixJQURJLENBQ0M7QUFBQSxlQUFRLE9BQUssZ0JBQUwsQ0FBc0IsSUFBdEIsQ0FBUjtBQUFBLE9BREQsRUFFSixVQUZJLENBRU8sRUFGUCxDQUFQO0FBR0Q7O0FBRUQ7Ozs7Ozs7Ozs7O2tDQVFlLFEsRUFBVSxFLEVBQUk7QUFBQTs7QUFDM0IsYUFBTyxLQUFLLEtBQUwsQ0FBVyxPQUFYLENBQW1CLFFBQW5CLEVBQ0osSUFESSxDQUNDO0FBQUEsZUFBUSxPQUFLLGVBQUwsQ0FBcUIsSUFBckIsQ0FBUjtBQUFBLE9BREQsRUFFSixVQUZJLENBRU8sRUFGUCxDQUFQO0FBR0Q7O0FBRUQ7Ozs7Ozs7Ozs7O3FDQVFrQixFLEVBQUksRSxFQUFJO0FBQUE7O0FBQ3hCLGFBQU8sS0FBSyxLQUFMLENBQVcsa0JBQVgsQ0FBOEIsRUFBOUIsRUFBa0MsSUFBbEMsQ0FBdUMsbUJBQVc7QUFDdkQsZUFBTyxRQUFRLElBQVIsQ0FBYSxFQUFFLE9BQUYsQ0FBVSxPQUFWLENBQWIsRUFBaUMsaUJBQW9CO0FBQUE7O0FBQUEsY0FBbEIsRUFBa0I7QUFBQSxjQUFkLFFBQWM7O0FBQzFELGlCQUFPLE9BQUssS0FBTCxDQUFXLE9BQVgsQ0FBbUIsUUFBbkIsRUFDSixJQURJLENBQ0M7QUFBQSxtQkFBUSxLQUFLLFlBQUwsQ0FBa0IsRUFBbEIsQ0FBUjtBQUFBLFdBREQsRUFFSixXQUZJLEVBQVA7QUFHRCxTQUpNLENBQVA7QUFLRCxPQU5NLEVBTUosVUFOSSxDQU1PLEVBTlAsQ0FBUDtBQU9EOztBQUVEOzs7Ozs7Ozs7Ozt5Q0FRc0IsRSxFQUFJLEUsRUFBSTtBQUM1QixhQUFPLEtBQUssS0FBTCxDQUFXLG9CQUFYLENBQWdDLEVBQWhDLEVBQW9DLFVBQXBDLENBQStDLEVBQS9DLENBQVA7QUFDRDs7Ozs7QUFJSCxPQUFPLE9BQVAsR0FBaUIsV0FBakIiLCJmaWxlIjoiUmVjb3ZlcnlBUEkuanMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCdcblxuY29uc3QgUHJvbWlzZSA9IHJlcXVpcmUoJ2JsdWViaXJkJylcbmNvbnN0IF8gPSByZXF1aXJlKCdsb2Rhc2gnKVxuXG4vKipcbiAqIFNlcnZpY2UgaW5mcmFzdHJ1Y3R1cmUgZmFpbHVyZXMgcmVjb3ZlcnkuXG4gKlxuICogQG1peGluXG4gKiBAbWVtYmVyb2YgY2hhdC1zZXJ2aWNlXG4gKiBAc2VlIGNoYXQtc2VydmljZS5DaGF0U2VydmljZS5ldmVudDpzdG9yZUNvbnNpc3RlbmN5RmFpbHVyZVxuICovXG5jbGFzcyBSZWNvdmVyeUFQSSB7XG5cbiAgY29uc3RydWN0b3IgKHN0YXRlLCB0cmFuc3BvcnQsIGV4ZWNVc2VyQ29tbWFuZCwgaW5zdGFuY2VVSUQpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGVcbiAgICB0aGlzLnRyYW5zcG9ydCA9IHRyYW5zcG9ydFxuICAgIHRoaXMuaW5zdGFuY2VVSUQgPSBpbnN0YW5jZVVJRFxuICAgIHRoaXMuZXhlY1VzZXJDb21tYW5kID0gZXhlY1VzZXJDb21tYW5kXG4gIH1cblxuICBjaGVja1VzZXJTb2NrZXRzICh1c2VyKSB7XG4gICAgbGV0IHsgdXNlck5hbWUgfSA9IHVzZXJcbiAgICByZXR1cm4gdXNlci51c2VyU3RhdGUuZ2V0U29ja2V0c1RvSW5zdGFuY2UoKS50aGVuKHNvY2tldHMgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UuZWFjaChfLnRvUGFpcnMoc29ja2V0cyksIChbc29ja2V0LCBpbnN0YW5jZV0pID0+IHtcbiAgICAgICAgaWYgKGluc3RhbmNlID09PSB0aGlzLmluc3RhbmNlVUlEKSB7XG4gICAgICAgICAgaWYgKCF0aGlzLnRyYW5zcG9ydC5nZXRTb2NrZXQoc29ja2V0KSkge1xuICAgICAgICAgICAgcmV0dXJuIHVzZXIudXNlclN0YXRlLnJlbW92ZVNvY2tldChzb2NrZXQpXG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoKVxuICAgICAgfSlcbiAgICB9KS50aGVuKCgpID0+IHtcbiAgICAgIHJldHVybiB1c2VyLnVzZXJTdGF0ZS5nZXRTb2NrZXRzVG9Sb29tcygpXG4gICAgfSkudGhlbihkYXRhID0+IHtcbiAgICAgIGxldCBhcmdzID0gXy52YWx1ZXMoZGF0YSlcbiAgICAgIHJldHVybiBfLmludGVyc2VjdGlvbiguLi5hcmdzKVxuICAgIH0pLnRoZW4ocm9vbXMgPT4ge1xuICAgICAgcmV0dXJuIFByb21pc2UuZWFjaChyb29tcywgcm9vbU5hbWUgPT4ge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lKVxuICAgICAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5yb29tU3RhdGUuaGFzSW5MaXN0KCd1c2VybGlzdCcsIHVzZXJOYW1lKSlcbiAgICAgICAgICAudGhlbihpc1ByZXNlbnQgPT5cbiAgICAgICAgICAgICAgICBpc1ByZXNlbnQgPyBQcm9taXNlLnJlc29sdmUoKSA6IHVzZXIucmVtb3ZlRnJvbVJvb20ocm9vbU5hbWUpKVxuICAgICAgICAgIC5jYXRjaFJldHVybigpXG4gICAgICB9KVxuICAgIH0pXG4gIH1cblxuICBjaGVja1Jvb21Kb2luZWQgKHJvb20pIHtcbiAgICBsZXQgeyByb29tTmFtZSB9ID0gcm9vbVxuICAgIHJldHVybiByb29tLmdldExpc3QobnVsbCwgJ3VzZXJsaXN0JywgdHJ1ZSkudGhlbih1c2VybGlzdCA9PiB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5lYWNoKHVzZXJsaXN0LCB1c2VyTmFtZSA9PiB7XG4gICAgICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFVzZXIodXNlck5hbWUpLnRoZW4odXNlciA9PiB7XG4gICAgICAgICAgcmV0dXJuIHVzZXIudXNlclN0YXRlLmdldFJvb21Ub1NvY2tldHMocm9vbU5hbWUpLnRoZW4oc29ja2V0cyA9PiB7XG4gICAgICAgICAgICBpZiAoIXNvY2tldHMgfHwgIXNvY2tldHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJldHVybiB1c2VyLnJlbW92ZUZyb21Sb29tKHJvb21OYW1lKVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSkuY2F0Y2hSZXR1cm4oKVxuICAgICAgICAgICAgLnRoZW4oKCkgPT4gcm9vbS5jaGVja0FjZXNzKHVzZXJOYW1lKSlcbiAgICAgICAgICAgIC5jYXRjaCgoKSA9PiB1c2VyLnJlbW92ZUZyb21Sb29tKHJvb21OYW1lKSlcbiAgICAgICAgfSkuY2F0Y2hSZXR1cm4oKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFN5bmMgdXNlciB0byBzb2NrZXRzIGFzc29jaWF0aW9ucy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIFVzZXIgbmFtZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx1bmRlZmluZWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aG91dCBhbnkgZGF0YS5cbiAgICovXG4gIHVzZXJTdGF0ZVN5bmMgKHVzZXJOYW1lLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFVzZXIodXNlck5hbWUpXG4gICAgICAudGhlbih1c2VyID0+IHRoaXMuY2hlY2tVc2VyU29ja2V0cyh1c2VyKSlcbiAgICAgIC5hc0NhbGxiYWNrKGNiKVxuICB9XG5cbiAgLyoqXG4gICAqIFN5bmMgcm9vbSB0byB1c2VycyBhc3NvY2lhdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb29tTmFtZSBSb29tIG5hbWUuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gT3B0aW9uYWwgY2FsbGJhY2suXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dW5kZWZpbmVkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGhvdXQgYW55IGRhdGEuXG4gICAqL1xuICByb29tU3RhdGVTeW5jIChyb29tTmFtZSwgY2IpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lKVxuICAgICAgLnRoZW4ocm9vbSA9PiB0aGlzLmNoZWNrUm9vbUpvaW5lZChyb29tKSlcbiAgICAgIC5hc0NhbGxiYWNrKGNiKVxuICB9XG5cbiAgLyoqXG4gICAqIEZpeGVzIGFuIGluc3RhbmNlIGRhdGEgYWZ0ZXIgYW4gaW5jb3JyZWN0IHNlcnZpY2Ugc2h1dGRvd24uXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpZCBJbnN0YW5jZSBpZC5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx1bmRlZmluZWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aG91dCBhbnkgZGF0YS5cbiAgICovXG4gIGluc3RhbmNlUmVjb3ZlcnkgKGlkLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldEluc3RhbmNlU29ja2V0cyhpZCkudGhlbihzb2NrZXRzID0+IHtcbiAgICAgIHJldHVybiBQcm9taXNlLmVhY2goXy50b1BhaXJzKHNvY2tldHMpLCAoW2lkLCB1c2VyTmFtZV0pID0+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0VXNlcih1c2VyTmFtZSlcbiAgICAgICAgICAudGhlbih1c2VyID0+IHVzZXIucmVtb3ZlU29ja2V0KGlkKSlcbiAgICAgICAgICAuY2F0Y2hSZXR1cm4oKVxuICAgICAgfSlcbiAgICB9KS5hc0NhbGxiYWNrKGNiKVxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgYW4gaW5zdGFuY2UgaGVhcnRiZWF0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaWQgSW5zdGFuY2UgaWQuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gT3B0aW9uYWwgY2FsbGJhY2suXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8bnVtYmVyPn0gSGVhcnRiZWF0IHRpbWVzdGFtcC5cbiAgICovXG4gIGdldEluc3RhbmNlSGVhcnRiZWF0IChpZCwgY2IpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRJbnN0YW5jZUhlYXJ0YmVhdChpZCkuYXNDYWxsYmFjayhjYilcbiAgfVxuXG59XG5cbm1vZHVsZS5leHBvcnRzID0gUmVjb3ZlcnlBUElcbiJdfQ== |
\ | No newline at end of file |