function Chat() {
const loggingUsers = new Set();
const loginCount = new Map();
const login = (id) => {
if (loggingUsers.has(id)) {
console.log(`User ${id} is already logged in.`);
} else {
console.log(`User ${id} has logged in.`);
loggingUsers.add(id);
if (!loginCount.has(id)) loginCount.set(id, 0);
}
};
const logout = (id) => {
if (!loggingUsers.has(id)) {
console.log(`User ${id} is not logged in.`);
} else {
console.log(`User ${id} has logged out.`);
loggingUsers.delete(id);
loginCount.set(id, loginCount.get(id) + 1);
}
};
const isOnline = (id) => loggingUsers.has(id);
const countOnline = () => loggingUsers.size;
const countLogins = (id) => loginCount.get(id);
return {
login,
logout,
isOnline,
countOnline,
countLogins,
};
}
const myChat = Chat();
myChat.login(3);
myChat.logout(3);
myChat.login(2);
myChat.login(1);
myChat.login(2); // already logged in
myChat.logout(3); // not logged in
console.log(myChat.countOnline()); // 2
console.log(myChat.countLogins(3)); // 1
ZnVuY3Rpb24gQ2hhdCgpIHsKICBjb25zdCBsb2dnaW5nVXNlcnMgPSBuZXcgU2V0KCk7CiAgY29uc3QgbG9naW5Db3VudCA9IG5ldyBNYXAoKTsKCiAgY29uc3QgbG9naW4gPSAoaWQpID0+IHsKICAgIGlmIChsb2dnaW5nVXNlcnMuaGFzKGlkKSkgewogICAgICBjb25zb2xlLmxvZyhgVXNlciAke2lkfSBpcyBhbHJlYWR5IGxvZ2dlZCBpbi5gKTsKICAgIH0gZWxzZSB7CiAgICAgIGNvbnNvbGUubG9nKGBVc2VyICR7aWR9IGhhcyBsb2dnZWQgaW4uYCk7CiAgICAgIGxvZ2dpbmdVc2Vycy5hZGQoaWQpOwogICAgICBpZiAoIWxvZ2luQ291bnQuaGFzKGlkKSkgbG9naW5Db3VudC5zZXQoaWQsIDApOwogICAgfQogIH07CgogIGNvbnN0IGxvZ291dCA9IChpZCkgPT4gewogICAgaWYgKCFsb2dnaW5nVXNlcnMuaGFzKGlkKSkgewogICAgICBjb25zb2xlLmxvZyhgVXNlciAke2lkfSBpcyBub3QgbG9nZ2VkIGluLmApOwogICAgfSBlbHNlIHsKICAgICAgY29uc29sZS5sb2coYFVzZXIgJHtpZH0gaGFzIGxvZ2dlZCBvdXQuYCk7CiAgICAgIGxvZ2dpbmdVc2Vycy5kZWxldGUoaWQpOwogICAgICBsb2dpbkNvdW50LnNldChpZCwgbG9naW5Db3VudC5nZXQoaWQpICsgMSk7CiAgICB9CiAgfTsKCiAgY29uc3QgaXNPbmxpbmUgPSAoaWQpID0+IGxvZ2dpbmdVc2Vycy5oYXMoaWQpOwogIGNvbnN0IGNvdW50T25saW5lID0gKCkgPT4gbG9nZ2luZ1VzZXJzLnNpemU7CiAgY29uc3QgY291bnRMb2dpbnMgPSAoaWQpID0+IGxvZ2luQ291bnQuZ2V0KGlkKTsKCiAgcmV0dXJuIHsKICAgIGxvZ2luLAogICAgbG9nb3V0LAogICAgaXNPbmxpbmUsCiAgICBjb3VudE9ubGluZSwKICAgIGNvdW50TG9naW5zLAogIH07Cn0KCmNvbnN0IG15Q2hhdCA9IENoYXQoKTsKbXlDaGF0LmxvZ2luKDMpOwpteUNoYXQubG9nb3V0KDMpOwpteUNoYXQubG9naW4oMik7Cm15Q2hhdC5sb2dpbigxKTsKbXlDaGF0LmxvZ2luKDIpOyAvLyBhbHJlYWR5IGxvZ2dlZCBpbgpteUNoYXQubG9nb3V0KDMpOyAvLyBub3QgbG9nZ2VkIGluCmNvbnNvbGUubG9nKG15Q2hhdC5jb3VudE9ubGluZSgpKTsgLy8gMgpjb25zb2xlLmxvZyhteUNoYXQuY291bnRMb2dpbnMoMykpOyAvLyAxCg==