1 | ;
|
2 |
|
3 | var _slicedToArray2 = require('babel-runtime/helpers/slicedToArray');
|
4 |
|
5 | var _slicedToArray3 = _interopRequireDefault(_slicedToArray2);
|
6 |
|
7 | var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
|
8 |
|
9 | var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
|
10 |
|
11 | var _createClass2 = require('babel-runtime/helpers/createClass');
|
12 |
|
13 | var _createClass3 = _interopRequireDefault(_createClass2);
|
14 |
|
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
16 |
|
17 | var ChatServiceError = require('./ChatServiceError');
|
18 | var Promise = require('bluebird');
|
19 | var _ = require('lodash');
|
20 |
|
21 | var _require = require('./utils');
|
22 |
|
23 | var checkNameSymbols = _require.checkNameSymbols;
|
24 | var possiblyCallback = _require.possiblyCallback;
|
25 |
|
26 | /**
|
27 | * Server side operations.
|
28 | *
|
29 | * @mixin
|
30 | * @memberof chat-service
|
31 | * @see chat-service.ChatService
|
32 | */
|
33 |
|
34 | var ServiceAPI = function () {
|
35 | function ServiceAPI(state, makeUser, clusterBus) {
|
36 | (0, _classCallCheck3.default)(this, ServiceAPI);
|
37 |
|
38 | this.state = state;
|
39 | this.makeUser = makeUser;
|
40 | this.clusterBus = clusterBus;
|
41 | }
|
42 |
|
43 | /**
|
44 | * Executes {@link rpc.clientRequests} handlers.
|
45 | *
|
46 | * @param {string|boolean|Object} context Is a `userName` if
|
47 | * `string`, or a `bypassPermissions` if `boolean`, or an options
|
48 | * object if `Object`.
|
49 | * @param {string} command Command name.
|
50 | * @param {...*} args Command arguments.
|
51 | * @param {callback} [cb] Optional callback.
|
52 | *
|
53 | * @property {string} [context.userName] User name.
|
54 | * @property {string} [context.id] Socket id, it is required for
|
55 | * {@link rpc.clientRequests.roomJoin} and {@link
|
56 | * rpc.clientRequests.roomLeave} commands.
|
57 | * @property {boolean} [context.bypassHooks=false] If `false`
|
58 | * executes command without before and after hooks.
|
59 | * @property {boolean} [context.bypassPermissions=false] If `true`
|
60 | * executes command (except {@link rpc.clientRequests.roomJoin})
|
61 | * bypassing built-in permissions checking.
|
62 | *
|
63 | * @return {Promise<Array>} Array of command results.
|
64 | *
|
65 | * @see rpc.clientRequests
|
66 | */
|
67 |
|
68 |
|
69 | (0, _createClass3.default)(ServiceAPI, [{
|
70 | key: 'execUserCommand',
|
71 | value: function execUserCommand(context, command) {
|
72 | var _this = this;
|
73 |
|
74 | if (_.isObject(context)) {
|
75 | var _context = context;
|
76 | var userName = _context.userName;
|
77 |
|
78 | context = _.clone(context);
|
79 | } else if (_.isBoolean(context)) {
|
80 | context = { bypassPermissions: context };
|
81 | } else {
|
82 | userName = context;
|
83 | context = {};
|
84 | }
|
85 | context.isLocalCall = true;
|
86 |
|
87 | for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
|
88 | args[_key - 2] = arguments[_key];
|
89 | }
|
90 |
|
91 | var _possiblyCallback = possiblyCallback(args);
|
92 |
|
93 | var _possiblyCallback2 = (0, _slicedToArray3.default)(_possiblyCallback, 2);
|
94 |
|
95 | var nargs = _possiblyCallback2[0];
|
96 | var cb = _possiblyCallback2[1];
|
97 |
|
98 | return Promise.try(function () {
|
99 | if (userName) {
|
100 | return _this.state.getUser(userName);
|
101 | } else {
|
102 | return _this.makeUser();
|
103 | }
|
104 | }).then(function (user) {
|
105 | return user.exec(command, context, nargs);
|
106 | }).asCallback(cb, { spread: true });
|
107 | }
|
108 |
|
109 | /**
|
110 | * Adds an user with a state.
|
111 | *
|
112 | * @param {string} userName User name.
|
113 | * @param {Object} [state] User state.
|
114 | * @param {callback} [cb] Optional callback.
|
115 | *
|
116 | * @property {Array<string>} [state.whitelist=[]] User direct messages
|
117 | * whitelist.
|
118 | * @property {Array<string>} [state.blacklist=[]] User direct messages
|
119 | * blacklist.
|
120 | * @property {boolean} [state.whitelistOnly=false] User direct
|
121 | * messages whitelistOnly mode.
|
122 | *
|
123 | * @return {Promise<undefined>} Promise that resolves without any data.
|
124 | */
|
125 |
|
126 | }, {
|
127 | key: 'addUser',
|
128 | value: function addUser(userName, state, cb) {
|
129 | var _this2 = this;
|
130 |
|
131 | return checkNameSymbols(userName).then(function () {
|
132 | return _this2.state.addUser(userName, state);
|
133 | }).return().asCallback(cb);
|
134 | }
|
135 |
|
136 | /**
|
137 | * Deletes an offline user. Will raise an error if a user has online
|
138 | * sockets.
|
139 | *
|
140 | * @param {string} userName User name.
|
141 | * @param {callback} [cb] Optional callback.
|
142 | *
|
143 | * @return {Promise<undefined>} Promise that resolves without any data.
|
144 | */
|
145 |
|
146 | }, {
|
147 | key: 'deleteUser',
|
148 | value: function deleteUser(userName, cb) {
|
149 | var _this3 = this;
|
150 |
|
151 | return this.state.getUser(userName).then(function (user) {
|
152 | return user.listOwnSockets().then(function (sockets) {
|
153 | if (sockets && _.size(sockets) > 0) {
|
154 | return Promise.reject(new ChatServiceError('userOnline', userName));
|
155 | } else {
|
156 | return Promise.all([user.removeState(), _this3.state.removeUser(userName)]);
|
157 | }
|
158 | });
|
159 | }).return().asCallback(cb);
|
160 | }
|
161 |
|
162 | /**
|
163 | * Checks for an user existence.
|
164 | *
|
165 | * @param {string} userName User name.
|
166 | * @param {callback} [cb] Optional callback.
|
167 | *
|
168 | * @return {Promise<boolean>} Predicate result.
|
169 | */
|
170 |
|
171 | }, {
|
172 | key: 'hasUser',
|
173 | value: function hasUser(userName, cb) {
|
174 | return this.state.getUser(userName, true).then(function (user) {
|
175 | return Boolean(user);
|
176 | }).asCallback(cb);
|
177 | }
|
178 |
|
179 | /**
|
180 | * Checks for a name existence in a direct messaging list.
|
181 | *
|
182 | * @param {string} userName User name.
|
183 | * @param {string} listName List name.
|
184 | * @param {string} item List element.
|
185 | * @param {callback} [cb] Optional callback.
|
186 | *
|
187 | * @return {Promise<boolean>} Predicate result.
|
188 | */
|
189 |
|
190 | }, {
|
191 | key: 'userHasInList',
|
192 | value: function userHasInList(userName, listName, item, cb) {
|
193 | return this.state.getUser(userName).then(function (user) {
|
194 | return user.directMessaging.hasInList(listName, item);
|
195 | }).asCallback(cb);
|
196 | }
|
197 |
|
198 | /**
|
199 | * Checks for a direct messaging permission.
|
200 | *
|
201 | * @param {string} recipient Recipient name.
|
202 | * @param {string} sender Sender name.
|
203 | * @param {callback} [cb] Optional callback.
|
204 | *
|
205 | * @return {Promise<boolean>} Predicate result.
|
206 | */
|
207 |
|
208 | }, {
|
209 | key: 'hasDirectAccess',
|
210 | value: function hasDirectAccess(recipient, sender, cb) {
|
211 | return this.state.getUser(recipient).then(function (user) {
|
212 | return user.directMessaging.checkAcess(sender);
|
213 | }).return(true).catchReturn(ChatServiceError, false).asCallback(cb);
|
214 | }
|
215 |
|
216 | /**
|
217 | * Disconnects user's sockets for all service instances. Method is
|
218 | * asynchronous, returns without waiting for the completion.
|
219 | *
|
220 | * @param {string} userName User name.
|
221 | *
|
222 | * @return {undefined} Returns no data.
|
223 | */
|
224 |
|
225 | }, {
|
226 | key: 'disconnectUserSockets',
|
227 | value: function disconnectUserSockets(userName) {
|
228 | this.clusterBus.emit('disconnectUserSockets', userName);
|
229 | }
|
230 |
|
231 | /**
|
232 | * Adds a room with a state.
|
233 | *
|
234 | * @param {string} roomName Room name.
|
235 | * @param {Object} [state] Room state.
|
236 | * @param {callback} [cb] Optional callback.
|
237 | *
|
238 | * @property {Array<string>} [state.whitelist=[]] Room whitelist.
|
239 | * @property {Array<string>} [state.blacklist=[]] Room blacklist
|
240 | * @property {Array<string>} [state.adminlist=[]] Room adminlist.
|
241 | * @property {boolean} [state.whitelistOnly=false] Room
|
242 | * whitelistOnly mode.
|
243 | * @property {string} [state.owner] Room owner.
|
244 | * @property {number} [state.historyMaxSize] Room history maximum
|
245 | * size. Defalut value is {@link chat-service.config.options}
|
246 | * `historyMaxSize`.
|
247 | * @property {boolean} [state.enableAccessListsUpdates] Room enable
|
248 | * access lists updates. Defalut value is {@link
|
249 | * chat-service.config.options} `enableAccessListsUpdates`.
|
250 | * @property {boolean} [state.enableUserlistUpdates] Room enable
|
251 | * userlist updates. Defalut value is {@link
|
252 | * chat-service.config.options} `enableUserlistUpdates`.
|
253 | *
|
254 | * @return {Promise<undefined>} Promise that resolves without any data.
|
255 | */
|
256 |
|
257 | }, {
|
258 | key: 'addRoom',
|
259 | value: function addRoom(roomName, state, cb) {
|
260 | var _this4 = this;
|
261 |
|
262 | return checkNameSymbols(roomName).then(function () {
|
263 | return _this4.state.addRoom(roomName, state);
|
264 | }).return().asCallback(cb);
|
265 | }
|
266 |
|
267 | /**
|
268 | * Removes all joined users from the room and removes all room data.
|
269 | *
|
270 | * @param {string} roomName Room name.
|
271 | * @param {callback} [cb] Optional callback.
|
272 | *
|
273 | * @return {Promise<undefined>} Promise that resolves without any data.
|
274 | */
|
275 |
|
276 | }, {
|
277 | key: 'deleteRoom',
|
278 | value: function deleteRoom(roomName, cb) {
|
279 | return this.execUserCommand(true, 'roomDelete', roomName).return().asCallback(cb);
|
280 | }
|
281 |
|
282 | /**
|
283 | * Checks for a room existence.
|
284 | *
|
285 | * @param {string} roomName Room name.
|
286 | * @param {callback} [cb] Optional callback.
|
287 | *
|
288 | * @return {Promise<boolean>} Predicate result.
|
289 | */
|
290 |
|
291 | }, {
|
292 | key: 'hasRoom',
|
293 | value: function hasRoom(roomName, cb) {
|
294 | return this.state.getRoom(roomName, true).then(function (room) {
|
295 | return Boolean(room);
|
296 | }).asCallback(cb);
|
297 | }
|
298 |
|
299 | /**
|
300 | * Checks for a name existence in a room list.
|
301 | *
|
302 | * @param {string} roomName Room name.
|
303 | * @param {string} listName List name.
|
304 | * @param {string} item List element.
|
305 | * @param {callback} [cb] Optional callback.
|
306 | *
|
307 | * @return {Promise<boolean>} Predicate result.
|
308 | */
|
309 |
|
310 | }, {
|
311 | key: 'roomHasInList',
|
312 | value: function roomHasInList(roomName, listName, item, cb) {
|
313 | return this.state.getRoom(roomName).then(function (room) {
|
314 | return room.roomState.hasInList(listName, item);
|
315 | }).asCallback(cb);
|
316 | }
|
317 |
|
318 | /**
|
319 | * Checks for a room access permission.
|
320 | *
|
321 | * @param {string} roomName Room name.
|
322 | * @param {string} userName User name.
|
323 | * @param {callback} [cb] Optional callback.
|
324 | *
|
325 | * @return {Promise<boolean>} Predicate result.
|
326 | */
|
327 |
|
328 | }, {
|
329 | key: 'hasRoomAccess',
|
330 | value: function hasRoomAccess(roomName, userName, cb) {
|
331 | return this.state.getRoom(roomName).then(function (room) {
|
332 | return room.checkAcess(userName);
|
333 | }).return(true).catchReturn(ChatServiceError, false).asCallback(cb);
|
334 | }
|
335 |
|
336 | /**
|
337 | * Changes the room owner.
|
338 | *
|
339 | * @param {string} roomName Room name.
|
340 | * @param {string} owner Owner user name.
|
341 | * @param {callback} [cb] Optional callback.
|
342 | *
|
343 | * @return {Promise<undefined>} Promise that resolves without any data.
|
344 | */
|
345 |
|
346 | }, {
|
347 | key: 'changeRoomOwner',
|
348 | value: function changeRoomOwner(roomName, owner, cb) {
|
349 | return this.state.getRoom(roomName).then(function (room) {
|
350 | return room.roomState.ownerSet(owner);
|
351 | }).return().asCallback(cb);
|
352 | }
|
353 |
|
354 | /**
|
355 | * Changes the room history size.
|
356 | *
|
357 | * @param {string} roomName Room name.
|
358 | * @param {number} size Room history size.
|
359 | * @param {callback} [cb] Optional callback.
|
360 | *
|
361 | * @return {Promise<undefined>} Promise that resolves without any data.
|
362 | */
|
363 |
|
364 | }, {
|
365 | key: 'changeRoomHistoryMaxSize',
|
366 | value: function changeRoomHistoryMaxSize(roomName, size, cb) {
|
367 | return this.state.getRoom(roomName).then(function (room) {
|
368 | return room.roomState.historyMaxSizeSet(size);
|
369 | }).return().asCallback(cb);
|
370 | }
|
371 |
|
372 | /**
|
373 | * Enables or disables access lists updates for the room.
|
374 | *
|
375 | * @param {string} roomName Room name.
|
376 | * @param {boolean} mode Enable or disable.
|
377 | * @param {callback} [cb] Optional callback.
|
378 | *
|
379 | * @return {Promise<undefined>} Promise that resolves without any data.
|
380 | *
|
381 | * @see rpc.serverNotifications.roomAccessListAdded
|
382 | * @see rpc.serverNotifications.roomAccessListRemoved
|
383 | * @see rpc.serverNotifications.roomModeChanged
|
384 | */
|
385 |
|
386 | }, {
|
387 | key: 'changeAccessListsUpdates',
|
388 | value: function changeAccessListsUpdates(roomName, mode, cb) {
|
389 | return this.state.getRoom(roomName).then(function (room) {
|
390 | return room.roomState.accessListsUpdatesSet(mode);
|
391 | }).return().asCallback(cb);
|
392 | }
|
393 |
|
394 | /**
|
395 | * Enables or disables user list updates for the room.
|
396 | *
|
397 | * @param {string} roomName Room name.
|
398 | * @param {boolean} mode Enable or disable.
|
399 | * @param {callback} [cb] Optional callback.
|
400 | *
|
401 | * @return {Promise<undefined>} Promise that resolves without any data.
|
402 | *
|
403 | * @see rpc.serverNotifications.roomUserJoined
|
404 | * @see rpc.serverNotifications.roomUserLeft
|
405 | */
|
406 |
|
407 | }, {
|
408 | key: 'changeUserlistUpdates',
|
409 | value: function changeUserlistUpdates(roomName, mode, cb) {
|
410 | return this.state.getRoom(roomName).then(function (room) {
|
411 | return room.roomState.userlistUpdatesSet(mode);
|
412 | }).return().asCallback(cb);
|
413 | }
|
414 | }]);
|
415 | return ServiceAPI;
|
416 | }();
|
417 |
|
418 | module.exports = ServiceAPI;
|
419 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9TZXJ2aWNlQVBJLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7O0FBRUEsSUFBTSxtQkFBbUIsUUFBUSxvQkFBUixDQUF6QjtBQUNBLElBQU0sVUFBVSxRQUFRLFVBQVIsQ0FBaEI7QUFDQSxJQUFNLElBQUksUUFBUSxRQUFSLENBQVY7O2VBQytDLFFBQVEsU0FBUixDOztJQUF2QyxnQixZQUFBLGdCO0lBQWtCLGdCLFlBQUEsZ0I7O0FBRTFCOzs7Ozs7OztJQU9NLFU7QUFFSixzQkFBYSxLQUFiLEVBQW9CLFFBQXBCLEVBQThCLFVBQTlCLEVBQTBDO0FBQUE7O0FBQ3hDLFNBQUssS0FBTCxHQUFhLEtBQWI7QUFDQSxTQUFLLFFBQUwsR0FBZ0IsUUFBaEI7QUFDQSxTQUFLLFVBQUwsR0FBa0IsVUFBbEI7QUFDRDs7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztvQ0F3QmlCLE8sRUFBUyxPLEVBQWtCO0FBQUE7O0FBQzFDLFVBQUksRUFBRSxRQUFGLENBQVcsT0FBWCxDQUFKLEVBQXlCO0FBQUEsdUJBQ0osT0FESTtBQUFBLFlBQ2pCLFFBRGlCLFlBQ2pCLFFBRGlCOztBQUV2QixrQkFBVSxFQUFFLEtBQUYsQ0FBUSxPQUFSLENBQVY7QUFDRCxPQUhELE1BR08sSUFBSSxFQUFFLFNBQUYsQ0FBWSxPQUFaLENBQUosRUFBMEI7QUFDL0Isa0JBQVUsRUFBQyxtQkFBbUIsT0FBcEIsRUFBVjtBQUNELE9BRk0sTUFFQTtBQUNMLG1CQUFXLE9BQVg7QUFDQSxrQkFBVSxFQUFWO0FBQ0Q7QUFDRCxjQUFRLFdBQVIsR0FBc0IsSUFBdEI7O0FBVjBDLHdDQUFOLElBQU07QUFBTixZQUFNO0FBQUE7O0FBQUEsOEJBV3hCLGlCQUFpQixJQUFqQixDQVh3Qjs7QUFBQTs7QUFBQSxVQVdyQyxLQVhxQztBQUFBLFVBVzlCLEVBWDhCOztBQVkxQyxhQUFPLFFBQVEsR0FBUixDQUFZLFlBQU07QUFDdkIsWUFBSSxR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LENBQ0M7QUFBQSxlQUFRLEtBQUssU0FBTCxDQUFlLFFBQWYsQ0FBd0IsS0FBeEIsQ0FBUjtBQUFBLE9BREQsRUFFSixNQUZJLEdBR0osVUFISSxDQUdPLEVBSFAsQ0FBUDtBQUlEOztBQUVEOzs7Ozs7Ozs7Ozs7NkNBUzBCLFEsRUFBVSxJLEVBQU0sRSxFQUFJO0FBQzVDLGFBQU8sS0FBSyxLQUFMLENBQVcsT0FBWCxDQUFtQixRQUFuQixFQUNKLElBREksQ0FDQztBQUFBLGVBQVEsS0FBSyxTQUFMLENBQWUsaUJBQWYsQ0FBaUMsSUFBakMsQ0FBUjtBQUFBLE9BREQsRUFFSixNQUZJLEdBR0osVUFISSxDQUdPLEVBSFAsQ0FBUDtBQUlEOztBQUVEOzs7Ozs7Ozs7Ozs7Ozs7OzZDQWEwQixRLEVBQVUsSSxFQUFNLEUsRUFBSTtBQUM1QyxhQUFPLEtBQUssS0FBTCxDQUFXLE9BQVgsQ0FBbUIsUUFBbkIsRUFDSixJQURJLENBQ0M7QUFBQSxlQUFRLEtBQUssU0FBTCxDQUFlLHFCQUFmLENBQXFDLElBQXJDLENBQVI7QUFBQSxPQURELEVBRUosTUFGSSxHQUdKLFVBSEksQ0FHTyxFQUhQLENBQVA7QUFJRDs7QUFFRDs7Ozs7Ozs7Ozs7Ozs7OzBDQVl1QixRLEVBQVUsSSxFQUFNLEUsRUFBSTtBQUN6QyxhQUFPLEtBQUssS0FBTCxDQUFXLE9BQVgsQ0FBbUIsUUFBbkIsRUFDSixJQURJLENBQ0M7QUFBQSxlQUFRLEtBQUssU0FBTCxDQUFlLGtCQUFmLENBQWtDLElBQWxDLENBQVI7QUFBQSxPQURELEVBRUosTUFGSSxHQUdKLFVBSEksQ0FHTyxFQUhQLENBQVA7QUFJRDs7Ozs7QUFJSCxPQUFPLE9BQVAsR0FBaUIsVUFBakIiLCJmaWxlIjoiU2VydmljZUFQSS5qcyIsInNvdXJjZXNDb250ZW50IjpbIid1c2Ugc3RyaWN0J1xuXG5jb25zdCBDaGF0U2VydmljZUVycm9yID0gcmVxdWlyZSgnLi9DaGF0U2VydmljZUVycm9yJylcbmNvbnN0IFByb21pc2UgPSByZXF1aXJlKCdibHVlYmlyZCcpXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJylcbmNvbnN0IHsgY2hlY2tOYW1lU3ltYm9scywgcG9zc2libHlDYWxsYmFjayB9ID0gcmVxdWlyZSgnLi91dGlscycpXG5cbi8qKlxuICogU2VydmVyIHNpZGUgb3BlcmF0aW9ucy5cbiAqXG4gKiBAbWl4aW5cbiAqIEBtZW1iZXJvZiBjaGF0LXNlcnZpY2VcbiAqIEBzZWUgY2hhdC1zZXJ2aWNlLkNoYXRTZXJ2aWNlXG4gKi9cbmNsYXNzIFNlcnZpY2VBUEkge1xuXG4gIGNvbnN0cnVjdG9yIChzdGF0ZSwgbWFrZVVzZXIsIGNsdXN0ZXJCdXMpIHtcbiAgICB0aGlzLnN0YXRlID0gc3RhdGVcbiAgICB0aGlzLm1ha2VVc2VyID0gbWFrZVVzZXJcbiAgICB0aGlzLmNsdXN0ZXJCdXMgPSBjbHVzdGVyQnVzXG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMge0BsaW5rIHJwYy5jbGllbnRSZXF1ZXN0c30gaGFuZGxlcnMuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfGJvb2xlYW58T2JqZWN0fSBjb250ZXh0IElzIGEgYHVzZXJOYW1lYCBpZlxuICAgKiBgc3RyaW5nYCwgb3IgYSBgYnlwYXNzUGVybWlzc2lvbnNgIGlmIGBib29sZWFuYCwgb3IgYW4gb3B0aW9uc1xuICAgKiBvYmplY3QgaWYgYE9iamVjdGAuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBjb21tYW5kIENvbW1hbmQgbmFtZS5cbiAgICogQHBhcmFtIHsuLi4qfSBhcmdzIENvbW1hbmQgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbY2JdIE9wdGlvbmFsIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcHJvcGVydHkge3N0cmluZ30gW2NvbnRleHQudXNlck5hbWVdIFVzZXIgbmFtZS5cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IFtjb250ZXh0LmlkXSBTb2NrZXQgaWQsIGl0IGlzIHJlcXVpcmVkIGZvclxuICAgKiB7QGxpbmsgcnBjLmNsaWVudFJlcXVlc3RzLnJvb21Kb2lufSBhbmQge0BsaW5rXG4gICAqIHJwYy5jbGllbnRSZXF1ZXN0cy5yb29tTGVhdmV9IGNvbW1hbmRzLlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb250ZXh0LmJ5cGFzc0hvb2tzPWZhbHNlXSBJZiBgZmFsc2VgXG4gICAqIGV4ZWN1dGVzIGNvbW1hbmQgd2l0aG91dCBiZWZvcmUgYW5kIGFmdGVyIGhvb2tzLlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtjb250ZXh0LmJ5cGFzc1Blcm1pc3Npb25zPWZhbHNlXSBJZiBgdHJ1ZWBcbiAgICogZXhlY3V0ZXMgY29tbWFuZCAoZXhjZXB0IHtAbGluayBycGMuY2xpZW50UmVxdWVzdHMucm9vbUpvaW59KVxuICAgKiBieXBhc3NpbmcgYnVpbHQtaW4gcGVybWlzc2lvbnMgY2hlY2tpbmcuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8QXJyYXk+fSBBcnJheSBvZiBjb21tYW5kIHJlc3VsdHMuXG4gICAqXG4gICAqIEBzZWUgcnBjLmNsaWVudFJlcXVlc3RzXG4gICAqL1xuICBleGVjVXNlckNvbW1hbmQgKGNvbnRleHQsIGNvbW1hbmQsIC4uLmFyZ3MpIHtcbiAgICBpZiAoXy5pc09iamVjdChjb250ZXh0KSkge1xuICAgICAgdmFyIHsgdXNlck5hbWUgfSA9IGNvbnRleHRcbiAgICAgIGNvbnRleHQgPSBfLmNsb25lKGNvbnRleHQpXG4gICAgfSBlbHNlIGlmIChfLmlzQm9vbGVhbihjb250ZXh0KSkge1xuICAgICAgY29udGV4dCA9IHtieXBhc3NQZXJtaXNzaW9uczogY29udGV4dH1cbiAgICB9IGVsc2Uge1xuICAgICAgdXNlck5hbWUgPSBjb250ZXh0XG4gICAgICBjb250ZXh0ID0ge31cbiAgICB9XG4gICAgY29udGV4dC5pc0xvY2FsQ2FsbCA9IHRydWVcbiAgICBsZXQgW25hcmdzLCBjYl0gPSBwb3NzaWJseUNhbGxiYWNrKGFyZ3MpXG4gICAgcmV0dXJuIFByb21pc2UudHJ5KCgpID0+IHtcbiAgICAgIGlmICh1c2VyTmFtZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRVc2VyKHVzZXJOYW1lKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFrZVVzZXIoKVxuICAgICAgfVxuICAgIH0pLnRoZW4odXNlciA9PiB1c2VyLmV4ZWMoY29tbWFuZCwgY29udGV4dCwgbmFyZ3MpKVxuICAgICAgLmFzQ2FsbGJhY2soY2IsIHsgc3ByZWFkOiB0cnVlIH0pXG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhbiB1c2VyIHdpdGggYSBzdGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIFVzZXIgbmFtZS5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtzdGF0ZV0gVXNlciBzdGF0ZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbc3RhdGUud2hpdGVsaXN0PVtdXSBVc2VyIGRpcmVjdCBtZXNzYWdlc1xuICAgKiB3aGl0ZWxpc3QuXG4gICAqIEBwcm9wZXJ0eSB7QXJyYXk8c3RyaW5nPn0gW3N0YXRlLmJsYWNrbGlzdD1bXV0gVXNlciBkaXJlY3QgbWVzc2FnZXNcbiAgICogYmxhY2tsaXN0LlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzdGF0ZS53aGl0ZWxpc3RPbmx5PWZhbHNlXSBVc2VyIGRpcmVjdFxuICAgKiBtZXNzYWdlcyB3aGl0ZWxpc3RPbmx5IG1vZGUuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dW5kZWZpbmVkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGhvdXQgYW55IGRhdGEuXG4gICAqL1xuICBhZGRVc2VyICh1c2VyTmFtZSwgc3RhdGUsIGNiKSB7XG4gICAgcmV0dXJuIGNoZWNrTmFtZVN5bWJvbHModXNlck5hbWUpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnN0YXRlLmFkZFVzZXIodXNlck5hbWUsIHN0YXRlKSlcbiAgICAgIC5yZXR1cm4oKVxuICAgICAgLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxuICAvKipcbiAgICogRGVsZXRlcyBhbiBvZmZsaW5lIHVzZXIuIFdpbGwgcmFpc2UgYW4gZXJyb3IgaWYgYSB1c2VyIGhhcyBvbmxpbmVcbiAgICogc29ja2V0cy5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIFVzZXIgbmFtZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx1bmRlZmluZWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aG91dCBhbnkgZGF0YS5cbiAgICovXG4gIGRlbGV0ZVVzZXIgKHVzZXJOYW1lLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFVzZXIodXNlck5hbWUpLnRoZW4odXNlciA9PiB7XG4gICAgICByZXR1cm4gdXNlci5saXN0T3duU29ja2V0cygpLnRoZW4oc29ja2V0cyA9PiB7XG4gICAgICAgIGlmIChzb2NrZXRzICYmIF8uc2l6ZShzb2NrZXRzKSA+IDApIHtcbiAgICAgICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QobmV3IENoYXRTZXJ2aWNlRXJyb3IoJ3VzZXJPbmxpbmUnLCB1c2VyTmFtZSkpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIFByb21pc2UuYWxsKFtcbiAgICAgICAgICAgIHVzZXIucmVtb3ZlU3RhdGUoKSxcbiAgICAgICAgICAgIHRoaXMuc3RhdGUucmVtb3ZlVXNlcih1c2VyTmFtZSlcbiAgICAgICAgICBdKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH0pLnJldHVybigpLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBhbiB1c2VyIGV4aXN0ZW5jZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIFVzZXIgbmFtZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gUHJlZGljYXRlIHJlc3VsdC5cbiAgICovXG4gIGhhc1VzZXIgKHVzZXJOYW1lLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFVzZXIodXNlck5hbWUsIHRydWUpXG4gICAgICAudGhlbih1c2VyID0+IEJvb2xlYW4odXNlcikpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgZm9yIGEgbmFtZSBleGlzdGVuY2UgaW4gYSBkaXJlY3QgbWVzc2FnaW5nIGxpc3QuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB1c2VyTmFtZSBVc2VyIG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBsaXN0TmFtZSBMaXN0IG5hbWUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpdGVtIExpc3QgZWxlbWVudC5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gUHJlZGljYXRlIHJlc3VsdC5cbiAgICovXG4gIHVzZXJIYXNJbkxpc3QgKHVzZXJOYW1lLCBsaXN0TmFtZSwgaXRlbSwgY2IpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRVc2VyKHVzZXJOYW1lKVxuICAgICAgLnRoZW4odXNlciA9PiB1c2VyLmRpcmVjdE1lc3NhZ2luZy5oYXNJbkxpc3QobGlzdE5hbWUsIGl0ZW0pKVxuICAgICAgLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBhIGRpcmVjdCBtZXNzYWdpbmcgcGVybWlzc2lvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlY2lwaWVudCBSZWNpcGllbnQgbmFtZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHNlbmRlciBTZW5kZXIgbmFtZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTxib29sZWFuPn0gUHJlZGljYXRlIHJlc3VsdC5cbiAgICovXG4gIGhhc0RpcmVjdEFjY2VzcyAocmVjaXBpZW50LCBzZW5kZXIsIGNiKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0VXNlcihyZWNpcGllbnQpXG4gICAgICAudGhlbih1c2VyID0+IHVzZXIuZGlyZWN0TWVzc2FnaW5nLmNoZWNrQWNlc3Moc2VuZGVyKSlcbiAgICAgIC5yZXR1cm4odHJ1ZSlcbiAgICAgIC5jYXRjaFJldHVybihDaGF0U2VydmljZUVycm9yLCBmYWxzZSlcbiAgICAgIC5hc0NhbGxiYWNrKGNiKVxuICB9XG5cbiAgLyoqXG4gICAqIERpc2Nvbm5lY3RzIHVzZXIncyBzb2NrZXRzIGZvciBhbGwgc2VydmljZSBpbnN0YW5jZXMuIE1ldGhvZCBpc1xuICAgKiBhc3luY2hyb25vdXMsIHJldHVybnMgd2l0aG91dCB3YWl0aW5nIGZvciB0aGUgY29tcGxldGlvbi5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHVzZXJOYW1lIFVzZXIgbmFtZS5cbiAgICpcbiAgICogQHJldHVybiB7dW5kZWZpbmVkfSBSZXR1cm5zIG5vIGRhdGEuXG4gICAqL1xuICBkaXNjb25uZWN0VXNlclNvY2tldHMgKHVzZXJOYW1lKSB7XG4gICAgdGhpcy5jbHVzdGVyQnVzLmVtaXQoJ2Rpc2Nvbm5lY3RVc2VyU29ja2V0cycsIHVzZXJOYW1lKVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSByb29tIHdpdGggYSBzdGF0ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb21OYW1lIFJvb20gbmFtZS5cbiAgICogQHBhcmFtIHtPYmplY3R9IFtzdGF0ZV0gUm9vbSBzdGF0ZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbc3RhdGUud2hpdGVsaXN0PVtdXSBSb29tIHdoaXRlbGlzdC5cbiAgICogQHByb3BlcnR5IHtBcnJheTxzdHJpbmc+fSBbc3RhdGUuYmxhY2tsaXN0PVtdXSBSb29tIGJsYWNrbGlzdFxuICAgKiBAcHJvcGVydHkge0FycmF5PHN0cmluZz59IFtzdGF0ZS5hZG1pbmxpc3Q9W11dIFJvb20gYWRtaW5saXN0LlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzdGF0ZS53aGl0ZWxpc3RPbmx5PWZhbHNlXSBSb29tXG4gICAqIHdoaXRlbGlzdE9ubHkgbW9kZS5cbiAgICogQHByb3BlcnR5IHtzdHJpbmd9IFtzdGF0ZS5vd25lcl0gUm9vbSBvd25lci5cbiAgICogQHByb3BlcnR5IHtudW1iZXJ9IFtzdGF0ZS5oaXN0b3J5TWF4U2l6ZV0gUm9vbSBoaXN0b3J5IG1heGltdW1cbiAgICogc2l6ZS4gRGVmYWx1dCB2YWx1ZSBpcyB7QGxpbmsgY2hhdC1zZXJ2aWNlLmNvbmZpZy5vcHRpb25zfVxuICAgKiBgaGlzdG9yeU1heFNpemVgLlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzdGF0ZS5lbmFibGVBY2Nlc3NMaXN0c1VwZGF0ZXNdIFJvb20gZW5hYmxlXG4gICAqIGFjY2VzcyBsaXN0cyB1cGRhdGVzLiBEZWZhbHV0IHZhbHVlIGlzIHtAbGlua1xuICAgKiBjaGF0LXNlcnZpY2UuY29uZmlnLm9wdGlvbnN9IGBlbmFibGVBY2Nlc3NMaXN0c1VwZGF0ZXNgLlxuICAgKiBAcHJvcGVydHkge2Jvb2xlYW59IFtzdGF0ZS5lbmFibGVVc2VybGlzdFVwZGF0ZXNdIFJvb20gZW5hYmxlXG4gICAqIHVzZXJsaXN0IHVwZGF0ZXMuIERlZmFsdXQgdmFsdWUgaXMge0BsaW5rXG4gICAqIGNoYXQtc2VydmljZS5jb25maWcub3B0aW9uc30gYGVuYWJsZVVzZXJsaXN0VXBkYXRlc2AuXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dW5kZWZpbmVkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGhvdXQgYW55IGRhdGEuXG4gICAqL1xuICBhZGRSb29tIChyb29tTmFtZSwgc3RhdGUsIGNiKSB7XG4gICAgcmV0dXJuIGNoZWNrTmFtZVN5bWJvbHMocm9vbU5hbWUpXG4gICAgICAudGhlbigoKSA9PiB0aGlzLnN0YXRlLmFkZFJvb20ocm9vbU5hbWUsIHN0YXRlKSlcbiAgICAgIC5yZXR1cm4oKVxuICAgICAgLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhbGwgam9pbmVkIHVzZXJzIGZyb20gdGhlIHJvb20gYW5kIHJlbW92ZXMgYWxsIHJvb20gZGF0YS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb21OYW1lIFJvb20gbmFtZS5cbiAgICogQHBhcmFtIHtjYWxsYmFja30gW2NiXSBPcHRpb25hbCBjYWxsYmFjay5cbiAgICpcbiAgICogQHJldHVybiB7UHJvbWlzZTx1bmRlZmluZWQ+fSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2l0aG91dCBhbnkgZGF0YS5cbiAgICovXG4gIGRlbGV0ZVJvb20gKHJvb21OYW1lLCBjYikge1xuICAgIHJldHVybiB0aGlzLmV4ZWNVc2VyQ29tbWFuZCh0cnVlLCAncm9vbURlbGV0ZScsIHJvb21OYW1lKVxuICAgICAgLnJldHVybigpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgZm9yIGEgcm9vbSBleGlzdGVuY2UuXG4gICAqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByb29tTmFtZSBSb29tIG5hbWUuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gT3B0aW9uYWwgY2FsbGJhY2suXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFByZWRpY2F0ZSByZXN1bHQuXG4gICAqL1xuICBoYXNSb29tIChyb29tTmFtZSwgY2IpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0ZS5nZXRSb29tKHJvb21OYW1lLCB0cnVlKVxuICAgICAgLnRoZW4ocm9vbSA9PiBCb29sZWFuKHJvb20pKVxuICAgICAgLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIGZvciBhIG5hbWUgZXhpc3RlbmNlIGluIGEgcm9vbSBsaXN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9vbU5hbWUgUm9vbSBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGlzdE5hbWUgTGlzdCBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaXRlbSBMaXN0IGVsZW1lbnQuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gT3B0aW9uYWwgY2FsbGJhY2suXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8Ym9vbGVhbj59IFByZWRpY2F0ZSByZXN1bHQuXG4gICAqL1xuICByb29tSGFzSW5MaXN0IChyb29tTmFtZSwgbGlzdE5hbWUsIGl0ZW0sIGNiKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5yb29tU3RhdGUuaGFzSW5MaXN0KGxpc3ROYW1lLCBpdGVtKSlcbiAgICAgIC5hc0NhbGxiYWNrKGNiKVxuICB9XG5cbiAgLyoqXG4gICAqIENoZWNrcyBmb3IgYSByb29tIGFjY2VzcyBwZXJtaXNzaW9uLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9vbU5hbWUgUm9vbSBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdXNlck5hbWUgVXNlciBuYW1lLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbY2JdIE9wdGlvbmFsIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPGJvb2xlYW4+fSBQcmVkaWNhdGUgcmVzdWx0LlxuICAgKi9cbiAgaGFzUm9vbUFjY2VzcyAocm9vbU5hbWUsIHVzZXJOYW1lLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHJvb20uY2hlY2tBY2Vzcyh1c2VyTmFtZSkpXG4gICAgICAucmV0dXJuKHRydWUpXG4gICAgICAuY2F0Y2hSZXR1cm4oQ2hhdFNlcnZpY2VFcnJvciwgZmFsc2UpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGFuZ2VzIHRoZSByb29tIG93bmVyLlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcm9vbU5hbWUgUm9vbSBuYW1lLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3duZXIgT3duZXIgdXNlciBuYW1lLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbY2JdIE9wdGlvbmFsIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHVuZGVmaW5lZD59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRob3V0IGFueSBkYXRhLlxuICAgKi9cbiAgY2hhbmdlUm9vbU93bmVyIChyb29tTmFtZSwgb3duZXIsIGNiKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5yb29tU3RhdGUub3duZXJTZXQob3duZXIpKVxuICAgICAgLnJldHVybigpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGFuZ2VzIHRoZSByb29tIGhpc3Rvcnkgc2l6ZS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb21OYW1lIFJvb20gbmFtZS5cbiAgICogQHBhcmFtIHtudW1iZXJ9IHNpemUgUm9vbSBoaXN0b3J5IHNpemUuXG4gICAqIEBwYXJhbSB7Y2FsbGJhY2t9IFtjYl0gT3B0aW9uYWwgY2FsbGJhY2suXG4gICAqXG4gICAqIEByZXR1cm4ge1Byb21pc2U8dW5kZWZpbmVkPn0gUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdpdGhvdXQgYW55IGRhdGEuXG4gICAqL1xuICBjaGFuZ2VSb29tSGlzdG9yeU1heFNpemUgKHJvb21OYW1lLCBzaXplLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHJvb20ucm9vbVN0YXRlLmhpc3RvcnlNYXhTaXplU2V0KHNpemUpKVxuICAgICAgLnJldHVybigpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIGFjY2VzcyBsaXN0cyB1cGRhdGVzIGZvciB0aGUgcm9vbS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb21OYW1lIFJvb20gbmFtZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBtb2RlIEVuYWJsZSBvciBkaXNhYmxlLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbY2JdIE9wdGlvbmFsIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHVuZGVmaW5lZD59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRob3V0IGFueSBkYXRhLlxuICAgKlxuICAgKiBAc2VlIHJwYy5zZXJ2ZXJOb3RpZmljYXRpb25zLnJvb21BY2Nlc3NMaXN0QWRkZWRcbiAgICogQHNlZSBycGMuc2VydmVyTm90aWZpY2F0aW9ucy5yb29tQWNjZXNzTGlzdFJlbW92ZWRcbiAgICogQHNlZSBycGMuc2VydmVyTm90aWZpY2F0aW9ucy5yb29tTW9kZUNoYW5nZWRcbiAgICovXG4gIGNoYW5nZUFjY2Vzc0xpc3RzVXBkYXRlcyAocm9vbU5hbWUsIG1vZGUsIGNiKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdGUuZ2V0Um9vbShyb29tTmFtZSlcbiAgICAgIC50aGVuKHJvb20gPT4gcm9vbS5yb29tU3RhdGUuYWNjZXNzTGlzdHNVcGRhdGVzU2V0KG1vZGUpKVxuICAgICAgLnJldHVybigpXG4gICAgICAuYXNDYWxsYmFjayhjYilcbiAgfVxuXG4gIC8qKlxuICAgKiBFbmFibGVzIG9yIGRpc2FibGVzIHVzZXIgbGlzdCB1cGRhdGVzIGZvciB0aGUgcm9vbS5cbiAgICpcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJvb21OYW1lIFJvb20gbmFtZS5cbiAgICogQHBhcmFtIHtib29sZWFufSBtb2RlIEVuYWJsZSBvciBkaXNhYmxlLlxuICAgKiBAcGFyYW0ge2NhbGxiYWNrfSBbY2JdIE9wdGlvbmFsIGNhbGxiYWNrLlxuICAgKlxuICAgKiBAcmV0dXJuIHtQcm9taXNlPHVuZGVmaW5lZD59IFByb21pc2UgdGhhdCByZXNvbHZlcyB3aXRob3V0IGFueSBkYXRhLlxuICAgKlxuICAgKiBAc2VlIHJwYy5zZXJ2ZXJOb3RpZmljYXRpb25zLnJvb21Vc2VySm9pbmVkXG4gICAqIEBzZWUgcnBjLnNlcnZlck5vdGlmaWNhdGlvbnMucm9vbVVzZXJMZWZ0XG4gICAqL1xuICBjaGFuZ2VVc2VybGlzdFVwZGF0ZXMgKHJvb21OYW1lLCBtb2RlLCBjYikge1xuICAgIHJldHVybiB0aGlzLnN0YXRlLmdldFJvb20ocm9vbU5hbWUpXG4gICAgICAudGhlbihyb29tID0+IHJvb20ucm9vbVN0YXRlLnVzZXJsaXN0VXBkYXRlc1NldChtb2RlKSlcbiAgICAgIC5yZXR1cm4oKVxuICAgICAgLmFzQ2FsbGJhY2soY2IpXG4gIH1cblxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IFNlcnZpY2VBUElcbiJdfQ== |
\ | No newline at end of file |