diff --git a/Utilities/LibMatrix.HomeserverEmulator/.gitignore b/Utilities/LibMatrix.HomeserverEmulator/.gitignore
new file mode 100644
 index 0000000..8fce603
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/.gitignore
@@ -0,0 +1 @@
+data/
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/AuthController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/AuthController.cs
new file mode 100644
 index 0000000..5550c26
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/AuthController.cs
@@ -0,0 +1,143 @@
+using System.Security.Cryptography;
+using System.Text.Json.Nodes;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class AuthController(ILogger<AuthController> logger, UserStore userStore, TokenService tokenService, HSEConfiguration config) : ControllerBase {
+    [HttpPost("login")]
+    public async Task<LoginResponse> Login(LoginRequest request) {
+        if (!request.Identifier.User.StartsWith('@'))
+            request.Identifier.User = $"@{request.Identifier.User}:{tokenService.GenerateServerName(HttpContext)}";
+        if (request.Identifier.User.EndsWith("localhost"))
+            request.Identifier.User = request.Identifier.User.Replace("localhost", tokenService.GenerateServerName(HttpContext));
+
+        var user = await userStore.GetUserById(request.Identifier.User);
+        if (user is null) {
+            user = await userStore.CreateUser(request.Identifier.User);
+        }
+
+        return user.Login();
+    }
+
+    [HttpGet("login")]
+    public async Task<LoginFlowsResponse> GetLoginFlows() {
+        return new LoginFlowsResponse {
+            Flows = ((string[]) [
+                "m.login.password",
+                "m.login.recaptcha",
+                "m.login.sso",
+                "m.login.email.identity",
+                "m.login.msisdn",
+                "m.login.dummy",
+                "m.login.registration_token",
+            ]).Select(x => new LoginFlowsResponse.LoginFlow { Type = x }).ToList()
+        };
+    }
+
+    [HttpPost("logout")]
+    public async Task<object> Logout() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        if (!user.AccessTokens.ContainsKey(token))
+            throw new MatrixException() {
+                ErrorCode = MatrixException.ErrorCodes.M_NOT_FOUND,
+                Error = "Token not found"
+            };
+
+        user.AccessTokens.Remove(token);
+        return new { };
+    }
+
+    [HttpPost("register")]
+    public async Task<object> Register(JsonObject request, [FromQuery] string kind = "user") {
+        if (kind == "guest") {
+            var user = await userStore.CreateUser(Random.Shared.NextInt64(long.MaxValue).ToString(), kind: "guest");
+            return user.Login();
+        }
+
+        if (request.Count == 0) {
+            return new {
+                session = Guid.NewGuid().ToString(),
+                flows = new {
+                    stages = new[] {
+                        "m.login.dummy",
+                    }
+                }
+            };
+        }
+
+        if (request.ContainsKey("password")) {
+            var parts = request["username"].ToString().Split(':');
+            var localpart = parts[0].TrimStart('@');
+            var user = await userStore.CreateUser($"@{localpart}:{config.ServerName}");
+            var login = user.Login();
+
+            if (request.ContainsKey("initial_device_display_name"))
+                user.AccessTokens[login.AccessToken].DeviceName = request["initial_device_display_name"]!.ToString();
+
+            return login;
+        }
+
+        return new { };
+    }
+
+    [HttpGet("register/available")]
+    public async Task<object> IsUsernameAvailable([FromQuery] string username) {
+        return new {
+            available = await userStore.GetUserById($"@{username}:{config.ServerName}") is null
+        };
+    }
+    
+    // [HttpPost("account/deactivate")]
+    // public async Task<object> DeactivateAccount() {
+    //     var token = tokenService.GetAccessToken(HttpContext);
+    //     var user = await userStore.GetUserByToken(token);
+    //     if (user == null)
+    //         throw new MatrixException() {
+    //             ErrorCode = "M_UNKNOWN_TOKEN",
+    //             Error = "No such user"
+    //         };
+    //
+    //     
+    //     return new { };
+    // }
+    
+    #region 3PID
+    
+    [HttpGet("account/3pid")]
+    public async Task<object> Get3pid() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        return new {
+            threepids = (object[])[]
+        };
+    }
+    
+    #endregion
+}
+
+public class LoginFlowsResponse {
+    public required List<LoginFlow> Flows { get; set; }
+
+    public class LoginFlow {
+        public required string Type { get; set; }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/DirectoryController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/DirectoryController.cs
new file mode 100644
 index 0000000..b29edf5
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/DirectoryController.cs
@@ -0,0 +1,67 @@
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Homeservers;
+using LibMatrix.Responses;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/")]
+public class DirectoryController(ILogger<DirectoryController> logger, RoomStore roomStore) : ControllerBase {
+#region Room directory
+
+    [HttpGet("client/v3/directory/room/{alias}")]
+    public async Task<AliasResult> GetRoomAliasV3(string alias) {
+        var match = roomStore._rooms.FirstOrDefault(x =>
+            x.State.Any(y => y.Type == RoomCanonicalAliasEventContent.EventId && y.StateKey == "" && y.RawContent?["alias"]?.ToString() == alias));
+
+        if (match == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        var servers = match.State.Where(x => x.Type == RoomMemberEventContent.EventId && x.RawContent?["membership"]?.ToString() == "join")
+            .Select(x => x.StateKey!.Split(':', 2)[1]).ToList();
+
+        return new() {
+            RoomId = match.RoomId,
+            Servers = servers
+        };
+    }
+
+#endregion
+
+#region User directory
+
+    [HttpPost("client/v3/user_directory/search")]
+    public async Task<UserDirectoryResponse> SearchUserDirectory([FromBody] UserDirectoryRequest request) {
+        var users = roomStore._rooms
+            .SelectMany(x => x.State.Where(y =>
+                    y.Type == RoomMemberEventContent.EventId
+                    && y.RawContent?["membership"]?.ToString() == "join"
+                    && (y.StateKey!.ContainsAnyCase(request.SearchTerm) || y.RawContent?["displayname"]?.ToString()?.ContainsAnyCase(request.SearchTerm) == true)
+                )
+            )
+            .DistinctBy(x => x.StateKey)
+            .ToList();
+
+        request.Limit ??= 10;
+
+        return new() {
+            Results = users.Select(x => new UserDirectoryResponse.UserDirectoryResult {
+                UserId = x.StateKey!,
+                DisplayName = x.RawContent?["displayname"]?.ToString(),
+                AvatarUrl = x.RawContent?["avatar_url"]?.ToString()
+            }).ToList(),
+            Limited = users.Count > request.Limit
+        };
+    }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/HEDebug/HEDebugController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/HEDebug/HEDebugController.cs
new file mode 100644
 index 0000000..9e0c17c
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/HEDebug/HEDebugController.cs
@@ -0,0 +1,18 @@
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_hsEmulator")]
+public class HEDebugController(ILogger<HEDebugController> logger, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("users")]
+    public async Task<List<UserStore.User>> GetUsers() {
+        return userStore._users.ToList();
+    }
+    
+    [HttpGet("rooms")]
+    public async Task<List<RoomStore.Room>> GetRooms() {
+        return roomStore._rooms.ToList();
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/KeysController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/KeysController.cs
new file mode 100644
 index 0000000..18cccf6
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/KeysController.cs
@@ -0,0 +1,122 @@
+// using System.Security.Cryptography;
+// using System.Text.Json.Nodes;
+// using System.Text.Json.Serialization;
+// using LibMatrix.HomeserverEmulator.Services;
+// using LibMatrix.Responses;
+// using LibMatrix.Services;
+// using Microsoft.AspNetCore.Mvc;
+//
+// namespace LibMatrix.HomeserverEmulator.Controllers;
+//
+// [ApiController]
+// [Route("/_matrix/client/{version}/")]
+// public class KeysController(ILogger<KeysController> logger, TokenService tokenService, UserStore userStore) : ControllerBase {
+//     [HttpPost("keys/upload")]
+//     public async Task<object> UploadKeys(DeviceKeysUploadRequest request) {
+//         var token = tokenService.GetAccessToken(HttpContext);
+//         if (token == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_MISSING_TOKEN",
+//                 Error = "Missing token"
+//             };
+//
+//         var user = await userStore.GetUserByToken(token);
+//         if (user == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_UNKNOWN_TOKEN",
+//                 Error = "No such user"
+//             };
+//
+//         return new { };
+//     }
+//     
+//     [HttpGet("room_keys/version")]
+//     public async Task<RoomKeysResponse> GetRoomKeys() {
+//         var token = tokenService.GetAccessToken(HttpContext);
+//         if (token == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_MISSING_TOKEN",
+//                 Error = "Missing token"
+//             };
+//
+//         var user = await userStore.GetUserByToken(token);
+//         if (user == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_UNKNOWN_TOKEN",
+//                 Error = "No such user"
+//             };
+//
+//         if (user.RoomKeys is not { Count: > 0 })
+//             throw new MatrixException() {
+//                 ErrorCode = "M_NOT_FOUND",
+//                 Error = "No keys found"
+//             };
+//
+//         return user.RoomKeys.Values.Last();
+//     }
+//
+//     [HttpPost("room_keys/version")]
+//     public async Task<RoomKeysResponse> UploadRoomKeys(RoomKeysRequest request) {
+//         var token = tokenService.GetAccessToken(HttpContext);
+//         if (token == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_MISSING_TOKEN",
+//                 Error = "Missing token"
+//             };
+//
+//         var user = await userStore.GetUserByToken(token);
+//         if (user == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_UNKNOWN_TOKEN",
+//                 Error = "No such user"
+//             };
+//
+//         var roomKeys = new RoomKeysResponse {
+//             Version = Guid.NewGuid().ToString(),
+//             Etag = Guid.NewGuid().ToString(),
+//             Algorithm = request.Algorithm,
+//             AuthData = request.AuthData
+//         };
+//         user.RoomKeys.Add(roomKeys.Version, roomKeys);
+//         return roomKeys;
+//     }
+//     
+//     [HttpPost("keys/device_signing/upload")]
+//     public async Task<object> UploadDeviceSigning(JsonObject request) {
+//         var token = tokenService.GetAccessToken(HttpContext);
+//         if (token == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_MISSING_TOKEN",
+//                 Error = "Missing token"
+//             };
+//
+//         var user = await userStore.GetUserByToken(token);
+//         if (user == null)
+//             throw new MatrixException() {
+//                 ErrorCode = "M_UNKNOWN_TOKEN",
+//                 Error = "No such user"
+//             };
+//
+//         return new { };
+//     }
+// }
+//
+// public class DeviceSigningRequest {
+//     public CrossSigningKey? MasterKey { get; set; }
+//     public CrossSigningKey? SelfSigningKey { get; set; }
+//     public CrossSigningKey? UserSigningKey { get; set; }
+//     
+//     public class CrossSigningKey {
+//         [JsonPropertyName("keys")]
+//         public Dictionary<string, string> Keys { get; set; }
+//         
+//         [JsonPropertyName("signatures")]
+//         public Dictionary<string, Dictionary<string, string>> Signatures { get; set; }
+//         
+//         [JsonPropertyName("usage")]
+//         public List<string> Usage { get; set; }
+//         
+//         [JsonPropertyName("user_id")]
+//         public string UserId { get; set; }
+//     }
+// }
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/LegacyController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/LegacyController.cs
new file mode 100644
 index 0000000..1fb427e
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/LegacyController.cs
@@ -0,0 +1,56 @@
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using System.Security.Cryptography;
+using System.Text.Json.Nodes;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class LegacyController(ILogger<LegacyController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("rooms/{roomId}/initialSync")]
+    [SuppressMessage("ReSharper.DPA", "DPA0011: High execution time of MVC action", Justification = "Endpoint is expected to wait until data is available or timeout.")]
+    public async Task<object> Sync([FromRoute] string roomId, [FromQuery] int limit = 20) {
+        var sw = Stopwatch.StartNew();
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+        var room = roomStore.GetRoomById(roomId);
+        if (room is null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found."
+            };
+        var accountData = room.AccountData.GetOrCreate(user.UserId, _ => []);
+        var membership = room.State.FirstOrDefault(x => x.Type == "m.room.member" && x.StateKey == user.UserId);
+        var timelineChunk = room.Timeline.TakeLast(limit).ToList();
+        return new {
+            account_data = accountData,
+            membership = (membership?.TypedContent as RoomMemberEventContent)?.Membership ?? "leave",
+            room_id = room.RoomId,
+            state = room.State.ToList(),
+            visibility = "public",
+            messages = new PaginatedChunkedStateEventResponse() {
+                Chunk = timelineChunk,
+                End = timelineChunk.Last().EventId,
+                Start = timelineChunk.Count >= limit ? timelineChunk.First().EventId : null
+            }
+        };
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Media/MediaController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Media/MediaController.cs
new file mode 100644
 index 0000000..59d37ff
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Media/MediaController.cs
@@ -0,0 +1,104 @@
+using System.Text.Json.Nodes;
+using System.Text.RegularExpressions;
+using ArcaneLibs.Collections;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Media;
+
+[ApiController]
+[Route("/_matrix/media/{version}/")]
+public class MediaController(
+    ILogger<MediaController> logger,
+    TokenService tokenService,
+    UserStore userStore,
+    HSEConfiguration cfg,
+    HomeserverResolverService hsResolver,
+    MediaStore mediaStore)
+    : ControllerBase {
+    [HttpPost("upload")]
+    public async Task<object> UploadMedia([FromHeader(Name = "Content-Type")] string ContentType, [FromQuery] string filename, [FromBody] Stream file) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var mediaId = Guid.NewGuid().ToString();
+        var media = new {
+            content_uri = $"mxc://{tokenService.GenerateServerName(HttpContext)}/{mediaId}"
+        };
+        return media;
+    }
+
+    [HttpGet("download/{serverName}/{mediaId}")]
+    public async Task DownloadMedia(string serverName, string mediaId) {
+        Response.Headers["Access-Control-Allow-Origin"] = "*";
+        Response.Headers["Access-Control-Allow-Methods"] = "GET";
+        
+        var stream = await DownloadRemoteMedia(serverName, mediaId);
+        await stream.CopyToAsync(Response.Body);
+    }
+
+    [HttpGet("thumbnail/{serverName}/{mediaId}")]
+    public async Task DownloadThumbnail(string serverName, string mediaId) {
+        await DownloadMedia(serverName, mediaId);
+    }
+
+    [HttpGet("preview_url")]
+    public async Task<JsonObject> GetPreviewUrl([FromQuery] string url) {
+        JsonObject data = new();
+
+        using var hc = new HttpClient();
+        logger.LogInformation("Getting URL preview for {}", url);
+        using var response = await hc.GetAsync(url);
+        var doc = await response.Content.ReadAsStringAsync();
+        var match = Regex.Match(doc, "<meta property=\"(.*?)\" content=\"(.*?)\"");
+
+        while (match.Success) {
+            data[match.Groups[1].Value] = match.Groups[2].Value;
+            match = match.NextMatch();
+        }
+
+        return data;
+    }
+
+    private async Task<Stream> DownloadRemoteMedia(string serverName, string mediaId) {
+        if (cfg.StoreData) {
+            var path = Path.Combine(cfg.DataStoragePath, "media", serverName, mediaId);
+            if (!System.IO.File.Exists(path)) {
+                var mediaUrl = await hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+                if (mediaUrl is null)
+                    throw new MatrixException() {
+                        ErrorCode = "M_NOT_FOUND",
+                        Error = "Media not found"
+                    };
+                using var client = new HttpClient();
+                var stream = await client.GetStreamAsync(mediaUrl);
+                Directory.CreateDirectory(Path.GetDirectoryName(path)!);
+                await using var fs = System.IO.File.Create(path);
+                await stream.CopyToAsync(fs);
+            }
+            return new FileStream(path, FileMode.Open);
+        }
+        else {
+            var mediaUrl = await hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+            if (mediaUrl is null)
+                throw new MatrixException() {
+                    ErrorCode = "M_NOT_FOUND",
+                    Error = "Media not found"
+                };
+            using var client = new HttpClient();
+            return await client.GetStreamAsync(mediaUrl);
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomAccountDataController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomAccountDataController.cs
new file mode 100644
 index 0000000..bac803f
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomAccountDataController.cs
@@ -0,0 +1,78 @@
+using System.Text.Json.Serialization;
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/rooms/{roomId}")]
+public class RoomAccountDataController(ILogger<RoomAccountDataController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpPost("read_markers")]
+    public async Task<object> SetReadMarkers(string roomId, [FromBody] ReadMarkersData data) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        if (!room.ReadMarkers.ContainsKey(user.UserId))
+            room.ReadMarkers[user.UserId] = new();
+
+        if (data.FullyRead != null)
+            room.ReadMarkers[user.UserId].FullyRead = data.FullyRead;
+        if (data.Read != null)
+            room.ReadMarkers[user.UserId].Read = data.Read;
+        if (data.ReadPrivate != null)
+            room.ReadMarkers[user.UserId].ReadPrivate = data.ReadPrivate;
+
+        if (!room.AccountData.ContainsKey(user.UserId))
+            room.AccountData[user.UserId] = new();
+
+        room.AccountData[user.UserId].Add(new StateEventResponse() {
+            Type = "m.fully_read",
+            StateKey = user.UserId,
+            RawContent = new() {
+                ["event_id"] = data.FullyRead
+            }
+        });
+
+        room.AccountData[user.UserId].Add(new StateEventResponse() {
+            Type = "m.read",
+            StateKey = user.UserId,
+            RawContent = new() {
+                ["event_id"] = data.Read
+            }
+        });
+
+        room.AccountData[user.UserId].Add(new StateEventResponse() {
+            Type = "m.read.private",
+            StateKey = user.UserId,
+            RawContent = new() {
+                ["event_id"] = data.ReadPrivate
+            }
+        });
+
+        return data;
+    }
+}
+
+public class ReadMarkersData {
+    [JsonPropertyName("m.fully_read")]
+    public string? FullyRead { get; set; }
+
+    [JsonPropertyName("m.read")]
+    public string? Read { get; set; }
+
+    [JsonPropertyName("m.read.private")]
+    public string? ReadPrivate { get; set; }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomMembersController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomMembersController.cs
new file mode 100644
 index 0000000..7d735f7
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomMembersController.cs
@@ -0,0 +1,79 @@
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/rooms/{roomId}/")]
+public class RoomMembersController(
+    ILogger<RoomMembersController> logger,
+    TokenService tokenService,
+    UserStore userStore,
+    RoomStore roomStore,
+    PaginationTokenResolverService paginationTokenResolver) : ControllerBase {
+    [HttpGet("members")]
+    public async Task<List<StateEventResponse>> GetMembers(string roomId, string? at = null, string? membership = null, string? not_membership = null) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        var members = room.Timeline.Where(x => x.Type == "m.room.member" && x.StateKey != null).ToList();
+
+        if (membership != null)
+            members = members.Where(x => (x.TypedContent as RoomMemberEventContent)?.Membership == membership).ToList();
+
+        if (not_membership != null)
+            members = members.Where(x => (x.TypedContent as RoomMemberEventContent)?.Membership != not_membership).ToList();
+
+        if (at != null) {
+            StateEventResponse? evt = null;
+            if (at.StartsWith('$'))
+                evt = await paginationTokenResolver.ResolveTokenToEvent(at, room);
+
+            if (evt is null) {
+                var time = await paginationTokenResolver.ResolveTokenToTimestamp(at);
+                evt = room.Timeline.LastOrDefault(x => x.OriginServerTs <= time);
+                if (evt is null) {
+                    logger.LogWarning("Sent empty list of members for room {roomId} at {at}, because there were no events at this time!", roomId, at);
+                    return [];
+                }
+            }
+            else if (!room.Timeline.Contains(evt)) {
+                evt = room.Timeline.LastOrDefault(x => x.OriginServerTs <= evt.OriginServerTs);
+                if (evt is null) {
+                    logger.LogWarning("Sent empty list of members for room {roomId} at {at}, because there were no events at this time!", roomId, at);
+                    return [];
+                }
+            }
+
+            // evt = room.Timeline.FirstOrDefault(x => x.EventId == at);
+            if (evt == null)
+                throw new MatrixException() {
+                    ErrorCode = "M_NOT_FOUND",
+                    Error = "Event not found"
+                };
+
+            members = members.Where(x => x.OriginServerTs <= evt.OriginServerTs).ToList();
+        }
+
+        return members;
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
new file mode 100644
 index 0000000..74c70a3
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomStateController.cs
@@ -0,0 +1,113 @@
+using System.Collections.Frozen;
+using System.Text.Json.Nodes;
+using LibMatrix.HomeserverEmulator.Extensions;
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/rooms/{roomId}/state")]
+public class RoomStateController(ILogger<RoomStateController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("")]
+    public async Task<FrozenSet<StateEventResponse>> GetState(string roomId) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        return room.State;
+    }
+
+    [HttpGet("{eventType}")]
+    public async Task<object?> GetState(string roomId, string eventType, [FromQuery] string format = "client") {
+        return await GetState(roomId, eventType, "", format);
+    }
+
+    [HttpGet("{eventType}/{stateKey}")]
+    public async Task<object?> GetState(string roomId, string eventType, string stateKey, [FromQuery] string format = "client") {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        var stateEvent = room.State.FirstOrDefault(x => x.Type == eventType && x.StateKey == stateKey);
+        if (stateEvent == null) {
+            Console.WriteLine($"Event not found in room {roomId} matching {eventType}/{stateKey}");
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+        }
+
+        // return stateEvent;
+        return format == "event" ? stateEvent : stateEvent.RawContent;
+    }
+
+    [HttpPut("{eventType}")]
+    public async Task<EventIdResponse> SetState(string roomId, string eventType, [FromBody] JsonObject? request) {
+        return await SetState(roomId, eventType, "", request);
+    }
+
+    [HttpPut("{eventType}/{stateKey}")]
+    public async Task<EventIdResponse> SetState(string roomId, string eventType, string stateKey, [FromBody] JsonObject? request) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+        var evt = room.SetStateInternal(new StateEvent() { Type = eventType, StateKey = stateKey, RawContent = request }.ToStateEvent(user, room));
+        evt.Type = eventType;
+        evt.StateKey = stateKey;
+        return new EventIdResponse() {
+            EventId = evt.EventId ?? throw new InvalidOperationException("EventId is null")
+        };
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs
new file mode 100644
 index 0000000..7a16ace
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomTimelineController.cs
@@ -0,0 +1,456 @@
+using System.Collections.Immutable;
+using System.Diagnostics;
+using System.Text.Json.Nodes;
+using ArcaneLibs;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Helpers;
+using LibMatrix.HomeserverEmulator.Extensions;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/rooms/{roomId}")]
+public class RoomTimelineController(
+    ILogger<RoomTimelineController> logger,
+    TokenService tokenService,
+    UserStore userStore,
+    RoomStore roomStore,
+    HomeserverProviderService hsProvider) : ControllerBase {
+    [HttpPut("send/{eventType}/{txnId}")]
+    public async Task<EventIdResponse> SendMessage(string roomId, string eventType, string txnId, [FromBody] JsonObject content) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        var evt = new StateEvent() {
+            RawContent = content,
+            Type = eventType
+        }.ToStateEvent(user, room);
+
+        room.Timeline.Add(evt);
+        if (evt.Type == RoomMessageEventContent.EventId && (evt.TypedContent as RoomMessageEventContent).Body.StartsWith("!hse"))
+            _ = Task.Run(() => HandleHseCommand(evt, room, user));
+        // else
+
+        return new() {
+            EventId = evt.EventId
+        };
+    }
+
+    [HttpGet("messages")]
+    public async Task<MessagesResponse> GetMessages(string roomId, [FromQuery] string? from = null, [FromQuery] string? to = null, [FromQuery] int limit = 100,
+        [FromQuery] string? dir = "b") {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        if (dir == "b") {
+            var timeline = room.Timeline.TakeLast(limit).ToList();
+            return new() {
+                Start = timeline.First().EventId,
+                End = timeline.Last().EventId,
+                Chunk = timeline.AsEnumerable().Reverse().ToList(),
+                State = timeline.GetCalculatedState()
+            };
+        }
+        else if (dir == "f") {
+            var timeline = room.Timeline.Take(limit).ToList();
+            return new() {
+                Start = timeline.First().EventId,
+                End = room.Timeline.Last() == timeline.Last() ? null : timeline.Last().EventId,
+                Chunk = timeline
+            };
+        }
+        else
+            throw new MatrixException() {
+                ErrorCode = "M_BAD_REQUEST",
+                Error = $"Invalid direction '{dir}'"
+            };
+    }
+
+    [HttpGet("event/{eventId}")]
+    public async Task<StateEventResponse> GetEvent(string roomId, string eventId) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        var evt = room.Timeline.SingleOrDefault(x => x.EventId == eventId);
+        if (evt == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+
+        return evt;
+    }
+
+    [HttpGet("relations/{eventId}")]
+    public async Task<RecursedBatchedChunkedStateEventResponse> GetRelations(string roomId, string eventId, [FromQuery] string? dir = "b", [FromQuery] string? from = null,
+        [FromQuery] int? limit = 100, [FromQuery] bool? recurse = false, [FromQuery] string? to = null) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        var evt = room.Timeline.SingleOrDefault(x => x.EventId == eventId);
+        if (evt == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+
+        var matchingEvents = await GetRelationsInternal(roomId, eventId, dir, from, limit, recurse, to);
+
+        return new() {
+            Chunk = matchingEvents.ToList()
+        };
+    }
+
+    [HttpGet("relations/{eventId}/{relationType}")]
+    public async Task<RecursedBatchedChunkedStateEventResponse> GetRelations(string roomId, string eventId, string relationType, [FromQuery] string? dir = "b",
+        [FromQuery] string? from = null, [FromQuery] int? limit = 100, [FromQuery] bool? recurse = false, [FromQuery] string? to = null) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        var evt = room.Timeline.SingleOrDefault(x => x.EventId == eventId);
+        if (evt == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+
+        var matchingEvents = await GetRelationsInternal(roomId, eventId, dir, from, limit, recurse, to);
+
+        return new() {
+            Chunk = matchingEvents.ToList()
+        };
+    }
+
+    [HttpGet("relations/{eventId}/{relationType}/{eventType}")]
+    public async Task<RecursedBatchedChunkedStateEventResponse> GetRelations(string roomId, string eventId, string relationType, string eventType, [FromQuery] string? dir = "b",
+        [FromQuery] string? from = null, [FromQuery] int? limit = 100, [FromQuery] bool? recurse = false, [FromQuery] string? to = null) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token);
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        if (!room.JoinedMembers.Any(x => x.StateKey == user.UserId))
+            throw new MatrixException() {
+                ErrorCode = "M_FORBIDDEN",
+                Error = "User is not in the room"
+            };
+
+        var evt = room.Timeline.SingleOrDefault(x => x.EventId == eventId);
+        if (evt == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+
+        var matchingEvents = await GetRelationsInternal(roomId, eventId, dir, from, limit, recurse, to);
+
+        return new() {
+            Chunk = matchingEvents.ToList()
+        };
+    }
+
+    private async Task<IEnumerable<StateEventResponse>> GetRelationsInternal(string roomId, string eventId, string dir, string? from, int? limit, bool? recurse, string? to) {
+        var room = roomStore.GetRoomById(roomId);
+        var evt = room.Timeline.SingleOrDefault(x => x.EventId == eventId);
+        if (evt == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Event not found"
+            };
+
+        var relatedEvents = room.Timeline.Where(x => x.RawContent?["m.relates_to"]?["event_id"]?.GetValue<string>() == eventId);
+        if (dir == "b") {
+            relatedEvents = relatedEvents.TakeLast(limit ?? 100);
+        }
+        else if (dir == "f") {
+            relatedEvents = relatedEvents.Take(limit ?? 100);
+        }
+
+        return relatedEvents;
+    }
+
+#region Commands
+
+    private void InternalSendMessage(RoomStore.Room room, string content) {
+        InternalSendMessage(room, new MessageBuilder().WithBody(content).Build());
+    }
+
+    private void InternalSendMessage(RoomStore.Room room, RoomMessageEventContent content) {
+        logger.LogInformation("Sending internal message: {content}", content.Body);
+        room.Timeline.Add(new StateEventResponse() {
+            Type = RoomMessageEventContent.EventId,
+            TypedContent = content,
+            Sender = $"@hse:{tokenService.GenerateServerName(HttpContext)}",
+            RoomId = room.RoomId,
+            EventId = "$" + string.Join("", Random.Shared.GetItems("abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789".ToCharArray(), 100)),
+            OriginServerTs = DateTimeOffset.Now.ToUnixTimeMilliseconds()
+        });
+    }
+
+    private async Task HandleHseCommand(StateEventResponse evt, RoomStore.Room room, UserStore.User user) {
+        logger.LogWarning("Handling HSE command for {0}: {1}", user.UserId, evt.RawContent.ToJson(false, true));
+        try {
+            var msgContent = evt.TypedContent as RoomMessageEventContent;
+            var parts = msgContent.Body.Split('\n')[0].Split(" ");
+            if (parts.Length < 2) return;
+
+            var command = parts[1];
+            Console.WriteLine($"Handling command {command}");
+            switch (command) {
+                case "import":
+                    await HandleImportCommand(parts[2..], evt, room, user);
+                    break;
+                case "import-nheko-profiles":
+                    await HandleImportNhekoProfilesCommand(parts[2..], evt, room, user);
+                    break;
+                case "clear-sync-states":
+                    foreach (var (token, session) in user.AccessTokens) {
+                        session.SyncStates.Clear();
+                        InternalSendMessage(room, $"Cleared sync states for {token}.");
+                    }
+
+                    break;
+                case "rsp": {
+                    await Task.Delay(1000);
+                    var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789";
+                    for (int i = 0; i < 10000; i++) {
+                        // await Task.Delay(100);
+                        // InternalSendMessage(room, $"https://music.youtube.com/watch?v=90oZtyvavSk&i={i}");
+                        var url = $"https://music.youtube.com/watch?v=";
+                        for (int j = 0; j < 11; j++) {
+                            url += chars[Random.Shared.Next(chars.Length)];
+                        }
+
+                        InternalSendMessage(room, url + "&i=" + i);
+                        if (i % 5000 == 0 || i == 9999) {
+                            Thread.Sleep(5000);
+
+                            do {
+                                InternalSendMessage(room,
+                                    $"Current GC memory: {Util.BytesToString(GC.GetTotalMemory(false))}, total process memory: {Util.BytesToString(Process.GetCurrentProcess().WorkingSet64)}");
+                                GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true);
+                                GC.WaitForPendingFinalizers();
+                                InternalSendMessage(room,
+                                    $"GC memory: {Util.BytesToString(GC.GetTotalMemory(false))}, total process memory: {Util.BytesToString(Process.GetCurrentProcess().WorkingSet64)}");
+                                await Task.Delay(5000);
+                            } while (Process.GetCurrentProcess().WorkingSet64 >= 1_024_000_000);
+                        }
+                    }
+
+                    break;
+                }
+                case "genrooms": {
+                    var sw = Stopwatch.StartNew();
+                    var count = 1000;
+                    for (int i = 0; i < count; i++) {
+                        var crq = new CreateRoomRequest() {
+                            Name = "Test room",
+                            CreationContent = new() {
+                                ["version"] = "11"
+                            },
+                            InitialState = []
+                        };
+
+                        if (Random.Shared.Next(100) > 75) {
+                            crq.CreationContent["type"] = "m.space";
+                            foreach (var item in Random.Shared.GetItems(roomStore._rooms.ToArray(), 50)) {
+                                crq.InitialState!.Add(new StateEvent() {
+                                    Type = "m.space.child",
+                                    StateKey = item.RoomId,
+                                    TypedContent = new SpaceChildEventContent() {
+                                        Suggested = true,
+                                        AutoJoin = true,
+                                        Via = new List<string>()
+                                    }
+                                }.ToStateEvent(user, room));
+                            }
+                        }
+
+                        var newRoom = roomStore.CreateRoom(crq);
+                        newRoom.AddUser(user.UserId);
+                    }
+
+                    InternalSendMessage(room, $"Generated {count} new rooms in {sw.Elapsed}!");
+                    break;
+                }
+                case "gc":
+                    InternalSendMessage(room,
+                        $"Current GC memory: {Util.BytesToString(GC.GetTotalMemory(false))}, total process memory: {Util.BytesToString(Process.GetCurrentProcess().WorkingSet64)}");
+                    GC.Collect(GC.MaxGeneration, GCCollectionMode.Aggressive, true, true);
+                    GC.WaitForPendingFinalizers();
+                    InternalSendMessage(room,
+                        $"GC memory: {Util.BytesToString(GC.GetTotalMemory(false))}, total process memory: {Util.BytesToString(Process.GetCurrentProcess().WorkingSet64)}");
+                    break;
+                case "leave-all-rooms": {
+                    var rooms = roomStore.GetRoomsByMember(user.UserId);
+                    foreach (var memberEvt in rooms) {
+                        var roomObj = roomStore.GetRoomById(memberEvt.RoomId);
+                        roomObj.SetStateInternal(new() {
+                            Type = RoomMemberEventContent.EventId,
+                            StateKey = user.UserId,
+                            TypedContent = new RoomMemberEventContent() {
+                                Membership = "leave"
+                            },
+                        }, senderId: user.UserId);
+                    }
+
+                    break;
+                }
+                default:
+                    InternalSendMessage(room, $"Command {command} not found!");
+                    break;
+            }
+        }
+        catch (Exception ex) {
+            InternalSendMessage(room, $"An error occurred: {ex.Message}");
+        }
+    }
+
+    private async Task HandleImportNhekoProfilesCommand(string[] args, StateEventResponse evt, RoomStore.Room room, UserStore.User user) {
+        var msgContent = evt.TypedContent as RoomMessageEventContent;
+        var parts = msgContent.Body.Split('\n');
+
+        var data = parts.Where(x => x.Contains(@"\auth\access_token") || x.Contains(@"\auth\home_server")).ToList();
+        if (data.Count < 2) {
+            InternalSendMessage(room, "Invalid data.");
+            return;
+        }
+
+        foreach (var line in data) {
+            var processedLine = line.Replace("\\\\", "\\").Replace("\\_", "_");
+
+            if (!processedLine.Contains(@"\auth\")) continue;
+            var profile = processedLine.Split(@"\auth\")[0];
+            if (!user.AuthorizedSessions.ContainsKey(profile))
+                user.AuthorizedSessions.Add(profile, new());
+            if (processedLine.Contains(@"home_server")) {
+                var server = processedLine.Split('=')[1];
+                user.AuthorizedSessions[profile].Homeserver = server;
+            }
+            else if (processedLine.Contains(@"access_token")) {
+                var token = processedLine.Split('=')[1];
+                user.AuthorizedSessions[profile].AccessToken = token;
+            }
+        }
+
+        foreach (var (key, session) in user.AuthorizedSessions.ToList()) {
+            if (string.IsNullOrWhiteSpace(session.Homeserver) || string.IsNullOrWhiteSpace(session.AccessToken)) {
+                InternalSendMessage(room, $"Invalid profile {key}");
+                user.AuthorizedSessions.Remove(key);
+                continue;
+            }
+
+            InternalSendMessage(room, $"Got profile {key} with server {session.AccessToken}");
+        }
+    }
+
+    private async Task HandleImportCommand(string[] args, StateEventResponse evt, RoomStore.Room room, UserStore.User user) {
+        var roomId = args[0];
+        var profile = args[1];
+
+        InternalSendMessage(room, $"Importing room {roomId} through profile {profile}...");
+        if (!user.AuthorizedSessions.ContainsKey(profile)) {
+            InternalSendMessage(room, $"Profile {profile} not found.");
+            return;
+        }
+
+        var userProfile = user.AuthorizedSessions[profile];
+
+        InternalSendMessage(room, $"Authenticating with {userProfile.Homeserver}...");
+        var hs = await hsProvider.GetAuthenticatedWithToken(userProfile.Homeserver, userProfile.AccessToken);
+        InternalSendMessage(room, $"Authenticated with {userProfile.Homeserver}.");
+        var hsRoom = hs.GetRoom(roomId);
+
+        InternalSendMessage(room, $"Starting import...");
+        var internalRoom = new RoomStore.Room(roomId);
+
+        var timeline = hsRoom.GetManyMessagesAsync(limit: int.MaxValue, dir: "b", chunkSize: 100000);
+        await foreach (var resp in timeline) {
+            internalRoom.Timeline = new(resp.Chunk.AsEnumerable().Reverse().Concat(internalRoom.Timeline));
+            InternalSendMessage(room, $"Imported {resp.Chunk.Count} events. Now up to a total of {internalRoom.Timeline.Count} events.");
+        }
+
+        InternalSendMessage(room, $"Import complete. Saving and inserting user");
+        roomStore.AddRoom(internalRoom);
+        internalRoom.AddUser(user.UserId);
+        InternalSendMessage(room, $"Import complete. Room is now available.");
+    }
+
+#endregion
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs
new file mode 100644
 index 0000000..c24e6e9
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Rooms/RoomsController.cs
@@ -0,0 +1,139 @@
+using System.Text.Json.Serialization;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.EventTypes.Spec.State.RoomInfo;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using LibMatrix.RoomTypes;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.Rooms;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class RoomsController(ILogger<RoomsController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    //createRoom
+    [HttpPost("createRoom")]
+    public async Task<RoomIdResponse> CreateRoom([FromBody] CreateRoomRequest request) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        // var room = new RoomStore.Room($"!{Guid.NewGuid()}:{tokenService.GenerateServerName(HttpContext)}");
+        var room = roomStore.CreateRoom(request, user);
+
+        return new() {
+            RoomId = room.RoomId
+        };
+    }
+
+    [HttpPost("rooms/{roomId}/upgrade")]
+    public async Task<object> UpgradeRoom(string roomId, [FromBody] UpgradeRoomRequest request) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var oldRoom = roomStore.GetRoomById(roomId);
+        if (oldRoom == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+
+        var room = new RoomStore.Room($"!{Guid.NewGuid()}:{tokenService.GenerateServerName(HttpContext)}");
+
+        var eventTypesToTransfer = new[] {
+            RoomServerACLEventContent.EventId,
+            RoomEncryptionEventContent.EventId,
+            RoomNameEventContent.EventId,
+            RoomAvatarEventContent.EventId,
+            RoomTopicEventContent.EventId,
+            RoomGuestAccessEventContent.EventId,
+            RoomHistoryVisibilityEventContent.EventId,
+            RoomJoinRulesEventContent.EventId,
+            RoomPowerLevelEventContent.EventId,
+        };
+
+        var createEvent = room.SetStateInternal(new() {
+            Type = RoomCreateEventContent.EventId,
+            RawContent = new() {
+                ["creator"] = user.UserId
+            }
+        });
+
+        oldRoom.State.Where(x => eventTypesToTransfer.Contains(x.Type)).ToList().ForEach(x => room.SetStateInternal(x));
+
+        room.AddUser(user.UserId);
+
+        // user.Rooms.Add(room.RoomId, room);
+        return new {
+            replacement_room = room.RoomId
+        };
+    }
+
+    public class ReasonBody {
+        [JsonPropertyName("reason")]
+        public string? Reason { get; set; }
+    }
+    [HttpPost("rooms/{roomId}/leave")] // TODO: implement
+    public async Task<object> LeaveRoom(string roomId, [FromBody] ReasonBody body) {
+        var token = tokenService.GetAccessTokenOrNull(HttpContext);
+        if (token == null)
+            throw new MatrixException() {
+                ErrorCode = "M_MISSING_TOKEN",
+                Error = "Missing token"
+            };
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+
+        var room = roomStore.GetRoomById(roomId);
+        if (room == null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Room not found"
+            };
+        
+        room.SetStateInternal(new() {
+            Type = RoomMemberEventContent.EventId,
+            TypedContent = new RoomMemberEventContent() {
+                Membership = "leave",
+                Reason = body.Reason
+            },
+            StateKey = user.UserId
+        });
+
+        logger.LogTrace($"User {user.UserId} left room {room.RoomId}");
+        return new {
+            room_id = room.RoomId
+        };
+    }
+}
+
+public class UpgradeRoomRequest {
+    [JsonPropertyName("new_version")]
+    public required string NewVersion { get; set; }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs
new file mode 100644
 index 0000000..f585eed
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/SyncController.cs
@@ -0,0 +1,286 @@
+using System.Diagnostics;
+using System.Diagnostics.CodeAnalysis;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.HomeserverEmulator.Extensions;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class SyncController(ILogger<SyncController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore, HSEConfiguration cfg) : ControllerBase {
+    [HttpGet("sync")]
+    [SuppressMessage("ReSharper.DPA", "DPA0011: High execution time of MVC action", Justification = "Endpoint is expected to wait until data is available or timeout.")]
+    public async Task<SyncResponse> Sync([FromQuery] string? since = null, [FromQuery] int? timeout = 5000) {
+        var sw = Stopwatch.StartNew();
+        var token = tokenService.GetAccessToken(HttpContext);
+
+        var user = await userStore.GetUserByToken(token);
+        if (user == null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "No such user"
+            };
+        var session = user.AccessTokens[token];
+        UserStore.User.SessionInfo.UserSyncState newSyncState = new();
+
+        SyncResponse syncResp;
+        if (string.IsNullOrWhiteSpace(since) || !session.SyncStates.TryGetValue(since, out var syncState))
+            syncResp = InitialSync(user, session);
+        else {
+            newSyncState = syncState.Clone();
+
+            var newSyncToken = Guid.NewGuid().ToString();
+            do {
+                syncResp = IncrementalSync(user, session, syncState);
+                syncResp.NextBatch = newSyncToken;
+            } while (!await HasDataOrStall(syncResp) && sw.ElapsedMilliseconds < timeout);
+
+            if (sw.ElapsedMilliseconds > timeout) {
+                logger.LogTrace("Sync timed out after {Elapsed}", sw.Elapsed);
+                return new() {
+                    NextBatch = since
+                };
+            }
+        }
+
+        session.SyncStates[syncResp.NextBatch] = RecalculateSyncStates(newSyncState, syncResp);
+        logger.LogTrace("Responding to sync after {totalElapsed}", sw.Elapsed);
+        return syncResp;
+    }
+
+    private UserStore.User.SessionInfo.UserSyncState RecalculateSyncStates(UserStore.User.SessionInfo.UserSyncState newSyncState, SyncResponse sync) {
+        logger.LogTrace("Updating sync state");
+        var syncStateRecalcSw = Stopwatch.StartNew();
+        foreach (var (roomId, roomData) in sync.Rooms?.Join ?? []) {
+            if (!newSyncState.RoomPositions.ContainsKey(roomId))
+                newSyncState.RoomPositions[roomId] = new();
+            var state = newSyncState.RoomPositions[roomId];
+
+            state.TimelinePosition += roomData.Timeline?.Events?.Count ?? 0;
+            state.LastTimelineEventId = roomData.Timeline?.Events?.LastOrDefault()?.EventId ?? state.LastTimelineEventId;
+            state.AccountDataPosition += roomData.AccountData?.Events?.Count ?? 0;
+            state.Joined = true;
+        }
+
+        foreach (var (roomId, _) in sync.Rooms?.Invite ?? []) {
+            if (!newSyncState.RoomPositions.ContainsKey(roomId))
+                newSyncState.RoomPositions[roomId] = new() {
+                    Joined = false
+                };
+        }
+
+        foreach (var (roomId, _) in sync.Rooms?.Leave ?? []) {
+            if (newSyncState.RoomPositions.ContainsKey(roomId))
+                newSyncState.RoomPositions.Remove(roomId);
+        }
+
+        logger.LogTrace("Updated sync state in {Elapsed}", syncStateRecalcSw.Elapsed);
+
+        return newSyncState;
+    }
+
+#region Initial Sync parts
+
+    private SyncResponse InitialSync(UserStore.User user, UserStore.User.SessionInfo session) {
+        var response = new SyncResponse() {
+            NextBatch = Guid.NewGuid().ToString(),
+            DeviceOneTimeKeysCount = new(),
+            AccountData = new(events: user.AccountData.ToList())
+        };
+
+        session.SyncStates.Add(response.NextBatch, new());
+
+        var rooms = roomStore._rooms.Where(x => x.State.Any(y => y.Type == "m.room.member" && y.StateKey == user.UserId)).ToList();
+        foreach (var room in rooms) {
+            response.Rooms ??= new();
+            response.Rooms.Join ??= new();
+
+            response.Rooms.Join[room.RoomId] = new() {
+                State = new(room.State.ToList()),
+                Timeline = new(events: room.Timeline.ToList(), limited: false),
+                AccountData = new(room.AccountData.GetOrCreate(user.UserId, _ => []).ToList())
+            };
+        }
+
+        return response;
+    }
+
+    private SyncResponse.RoomsDataStructure.JoinedRoomDataStructure GetInitialSyncRoomData(RoomStore.Room room, UserStore.User user) {
+        return new() {
+            State = new(room.State.ToList()),
+            Timeline = new(room.Timeline.ToList(), false),
+            AccountData = new(room.AccountData.GetOrCreate(user.UserId, _ => []).ToList())
+        };
+    }
+
+#endregion
+
+    private SyncResponse IncrementalSync(UserStore.User user, UserStore.User.SessionInfo session, UserStore.User.SessionInfo.UserSyncState syncState) {
+        return new SyncResponse {
+            Rooms = GetIncrementalSyncRooms(user, session, syncState)
+        };
+    }
+
+#region Incremental Sync parts
+
+    private SyncResponse.RoomsDataStructure GetIncrementalSyncRooms(UserStore.User user, UserStore.User.SessionInfo session, UserStore.User.SessionInfo.UserSyncState syncState) {
+        SyncResponse.RoomsDataStructure data = new() {
+            Join = [],
+            Invite = [],
+            Leave = []
+        };
+
+        // step 1: check previously synced rooms
+        foreach (var (roomId, roomPosition) in syncState.RoomPositions) {
+            var room = roomStore.GetRoomById(roomId);
+            if (room == null) {
+                // room no longer exists
+                data.Leave[roomId] = new();
+                continue;
+            }
+
+            if (roomPosition.Joined) {
+                var newTimelineEvents = room.Timeline.Skip(roomPosition.TimelinePosition).ToList();
+                var newAccountDataEvents = room.AccountData[user.UserId].Skip(roomPosition.AccountDataPosition).ToList();
+                if (newTimelineEvents.Count == 0 && newAccountDataEvents.Count == 0) continue;
+                data.Join[room.RoomId] = new() {
+                    State = new(newTimelineEvents.GetCalculatedState()),
+                    Timeline = new(newTimelineEvents, false)
+                };
+            }
+        }
+
+        if (data.Join.Count > 0) {
+            logger.LogTrace("Found {count} updated rooms", data.Join.Count);
+            return data;
+        }
+
+        // step 2: check newly joined rooms
+        var untrackedRooms = roomStore._rooms.Where(r => !syncState.RoomPositions.ContainsKey(r.RoomId)).ToList();
+
+        var allJoinedRooms = roomStore.GetRoomsByMember(user.UserId).ToArray();
+        if (allJoinedRooms.Length == 0) return data;
+        var rooms = Random.Shared.GetItems(allJoinedRooms, Math.Min(allJoinedRooms.Length, 50));
+        foreach (var membership in rooms) {
+            var membershipContent = membership.TypedContent as RoomMemberEventContent ??
+                                    throw new InvalidOperationException("Membership event content is not RoomMemberEventContent");
+            var room = roomStore.GetRoomById(membership.RoomId!);
+            //handle leave
+            if (syncState.RoomPositions.TryGetValue(membership.RoomId!, out var syncPosition)) {
+                // logger.LogTrace("Found sync position {roomId} {value}", room.RoomId, syncPosition.ToJson(indent: false, ignoreNull: false));
+
+                if (membershipContent.Membership == "join") {
+                    var newTimelineEvents = room.Timeline.Skip(syncPosition.TimelinePosition).ToList();
+                    var newAccountDataEvents = room.AccountData[user.UserId].Skip(syncPosition.AccountDataPosition).ToList();
+                    if (newTimelineEvents.Count == 0 && newAccountDataEvents.Count == 0) continue;
+                    data.Join[room.RoomId] = new() {
+                        State = new(newTimelineEvents.GetCalculatedState()),
+                        Timeline = new(newTimelineEvents, false)
+                    };
+                }
+            }
+            else {
+                //syncPosisition = null
+                if (membershipContent.Membership == "join") {
+                    var joinData = data.Join[membership.RoomId!] = new() {
+                        State = new(room.State.ToList()),
+                        Timeline = new(events: room.Timeline.ToList(), limited: false),
+                        AccountData = new(room.AccountData.GetOrCreate(user.UserId, _ => []).ToList())
+                    };
+                }
+            }
+        }
+
+        //handle nonexistant rooms
+        foreach (var roomId in syncState.RoomPositions.Keys) {
+            if (!roomStore._rooms.Any(x => x.RoomId == roomId)) {
+                data.Leave[roomId] = new();
+                session.SyncStates[session.SyncStates.Last().Key].RoomPositions.Remove(roomId);
+            }
+        }
+
+        return data;
+    }
+
+#endregion
+
+    private bool HasData(SyncResponse resp) {
+        return resp.Rooms?.Invite?.Count > 0 || resp.Rooms?.Join?.Count > 0 || resp.Rooms?.Leave?.Count > 0;
+    }
+    
+    private async Task<bool> HasDataOrStall(SyncResponse resp) {
+        // logger.LogTrace("Checking if sync response has data: {resp}", resp.ToJson(indent: false, ignoreNull: true));
+        // if (resp.AccountData?.Events?.Count > 0) return true;
+        // if (resp.Rooms?.Invite?.Count > 0) return true;
+        // if (resp.Rooms?.Join?.Count > 0) return true;
+        // if (resp.Rooms?.Leave?.Count > 0) return true;
+        // if (resp.Presence?.Events?.Count > 0) return true;
+        // if (resp.DeviceLists?.Changed?.Count > 0) return true;
+        // if (resp.DeviceLists?.Left?.Count > 0) return true;
+        // if (resp.ToDevice?.Events?.Count > 0) return true;
+        //
+        // var hasData =
+        //     resp is not {
+        //         AccountData: null or {
+        //             Events: null or { Count: 0 }
+        //         },
+        //         Rooms: null or {
+        //             Invite: null or { Count: 0 },
+        //             Join: null or { Count: 0 },
+        //             Leave: null or { Count: 0 }
+        //         },
+        //         Presence: null or {
+        //             Events: null or { Count: 0 }
+        //         },
+        //         DeviceLists: null or {
+        //             Changed: null or { Count: 0 },
+        //             Left: null or { Count: 0 }
+        //         },
+        //         ToDevice: null or {
+        //             Events: null or { Count: 0 }
+        //         }
+        //     };
+
+        var hasData = resp is {
+            AccountData: {
+                Events: { Count: > 0 }
+            }
+        } or {
+            Presence: {
+                Events: { Count: > 0 }
+            }
+        } or {
+            DeviceLists: {
+                Changed: { Count: > 0 },
+                Left: { Count: > 0 }
+            }
+        } or {
+            ToDevice: {
+                Events: { Count: > 0 }
+            }
+        } or {
+            Rooms: {
+                Invite: { Count: > 0 }
+            } or {
+                Join: { Count: > 0 }
+            } or {
+                Leave: { Count: > 0 }
+            }
+        };
+
+        if (!hasData) {
+            // hasData = 
+        }
+
+        if (!hasData) {
+            // logger.LogDebug($"Sync response has no data, stalling for 1000ms: {resp.ToJson(indent: false, ignoreNull: true)}");
+            await Task.Delay(10);
+        }
+
+        return hasData;
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/ThirdParty/ThirdPartyController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/ThirdParty/ThirdPartyController.cs
new file mode 100644
 index 0000000..ff006df
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/ThirdParty/ThirdPartyController.cs
@@ -0,0 +1,25 @@
+using LibMatrix.HomeserverEmulator.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers.ThirdParty;
+
+[ApiController]
+[Route("/_matrix/client/{version}/thirdparty/")]
+public class ThirdPartyController(ILogger<ThirdPartyController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("protocols")]
+    public async Task<object> GetProtocols() {
+        return new { };
+    }
+
+    [HttpGet("location")]
+    public async Task<List<object>> GetLocations([FromQuery] string alias) {
+        // TODO: implement
+        return [];
+    }
+
+    [HttpGet("location/{protocol}")]
+    public async Task<List<object>> GetLocation([FromRoute] string protocol) {
+        // TODO: implement
+        return [];
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/AccountDataController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/AccountDataController.cs
new file mode 100644
 index 0000000..a32d283
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/AccountDataController.cs
@@ -0,0 +1,68 @@
+using System.Text.Json.Nodes;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Filters;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class AccountDataController(ILogger<AccountDataController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("user/{mxid}/account_data/{type}")]
+    public async Task<object> GetAccountData(string type) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+
+        var value = user.AccountData.FirstOrDefault(x => x.Type == type);
+        if (value is null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Key not found."
+            };
+        return value;
+    }
+
+    [HttpPut("user/{mxid}/account_data/{type}")]
+    public async Task<object> SetAccountData(string type, [FromBody] JsonObject data) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+
+        user.AccountData.Add(new() {
+            Type = type,
+            RawContent = data
+        });
+        return data;
+    }
+
+    // specialised account data...
+    [HttpGet("pushrules")]
+    public async Task<object> GetPushRules() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        if (token is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "No token passed."
+            };
+
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+        return new { };
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/FilterController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/FilterController.cs
new file mode 100644
 index 0000000..bdee7bc
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/FilterController.cs
@@ -0,0 +1,46 @@
+using System.Text.Json.Nodes;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Filters;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class FilterController(ILogger<FilterController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpPost("user/{mxid}/filter")]
+    public async Task<object> CreateFilter(string mxid, [FromBody] SyncFilter filter) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+        var filterId = Guid.NewGuid().ToString();
+        user.Filters[filterId] = filter;
+        return new {
+            filter_id = filterId
+        };
+    }
+    
+    [HttpGet("user/{mxid}/filter/{filterId}")]
+    public async Task<SyncFilter> GetFilter(string mxid, string filterId) {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+        if (!user.Filters.ContainsKey(filterId))
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Filter not found."
+            };
+        return user.Filters[filterId];
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/ProfileController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/ProfileController.cs
new file mode 100644
 index 0000000..98c41da
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/ProfileController.cs
@@ -0,0 +1,52 @@
+using System.Text.Json.Nodes;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Filters;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class ProfileController(ILogger<ProfileController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("profile/{userId}")]
+    public async Task<IDictionary<string, object>> GetProfile(string userId) {
+        var user = await userStore.GetUserById(userId, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "User not found."
+            };
+        return user.Profile;
+    }
+
+    [HttpGet("profile/{userId}/{key}")]
+    public async Task<object> GetProfile(string userId, string key) {
+        var user = await userStore.GetUserById(userId, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "User not found."
+            };
+        if (!user.Profile.TryGetValue(key, out var value))
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "Key not found."
+            };
+        return value;
+    }
+
+    [HttpPut("profile/{userId}/{key}")]
+    public async Task<object> SetProfile(string userId, string key, [FromBody] JsonNode value) {
+        var user = await userStore.GetUserById(userId, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_NOT_FOUND",
+                Error = "User not found."
+            };
+        user.Profile[key] = value[key]?.AsObject();
+        return value;
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs
new file mode 100644
 index 0000000..2be3896
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/Users/UserController.cs
@@ -0,0 +1,80 @@
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Filters;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Responses;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/client/{version}/")]
+public class UserController(ILogger<UserController> logger, TokenService tokenService, UserStore userStore, RoomStore roomStore) : ControllerBase {
+    [HttpGet("account/whoami")]
+    public async Task<WhoAmIResponse> Login() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, Random.Shared.Next(101) <= 10, tokenService.GenerateServerName(HttpContext));
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNKNOWN_TOKEN",
+                Error = "Invalid token."
+            };
+        var whoAmIResponse = new WhoAmIResponse {
+            UserId = user.UserId
+        };
+        return whoAmIResponse;
+    }
+
+    [HttpGet("joined_rooms")]
+    public async Task<object> GetJoinedRooms() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+        // return user.JoinedRooms;
+
+        return new {
+            joined_rooms = roomStore._rooms.Where(r =>
+                r.State.Any(s => s.StateKey == user.UserId && s.Type == RoomMemberEventContent.EventId && (s.TypedContent as RoomMemberEventContent).Membership == "join")
+            ).Select(r => r.RoomId).ToList()
+        };
+    }
+    
+    [HttpGet("devices")]
+    public async Task<DevicesResponse> GetDevices() {
+        var token = tokenService.GetAccessToken(HttpContext);
+        var user = await userStore.GetUserByToken(token, false);
+        if (user is null)
+            throw new MatrixException() {
+                ErrorCode = "M_UNAUTHORIZED",
+                Error = "Invalid token."
+            };
+        return new() {
+            Devices = user.AccessTokens.Select(x=>new DevicesResponse.Device() {
+                DeviceId = x.Value.DeviceId,
+                DisplayName = x.Value.DeviceId
+            }).ToList()
+        };
+    }
+
+    public class DevicesResponse {
+        [JsonPropertyName("devices")]
+        public List<Device> Devices { get; set; }
+        
+        public class Device {
+            [JsonPropertyName("device_id")]
+            public string DeviceId { get; set; }
+            [JsonPropertyName("display_name")]
+            public string DisplayName { get; set; }
+            [JsonPropertyName("last_seen_ip")]
+            public string LastSeenIp { get; set; }
+            [JsonPropertyName("last_seen_ts")]
+            public long LastSeenTs { get; set; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/VersionsController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/VersionsController.cs
new file mode 100644
 index 0000000..0c3bde6
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/VersionsController.cs
@@ -0,0 +1,96 @@
+using System.Text.Json.Nodes;
+using System.Text.Json.Serialization;
+using LibMatrix.Homeservers;
+using LibMatrix.Responses;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/_matrix/")]
+public class VersionsController(ILogger<WellKnownController> logger) : ControllerBase {
+    [HttpGet("client/versions")]
+    public async Task<ClientVersionsResponse> GetClientVersions() {
+        var clientVersions = new ClientVersionsResponse {
+            Versions = new() {
+                "r0.0.1",
+                "r0.1.0",
+                "r0.2.0",
+                "r0.3.0",
+                "r0.4.0",
+                "r0.5.0",
+                "r0.6.0",
+                "r0.6.1",
+                "v1.1",
+                "v1.2",
+                "v1.3",
+                "v1.4",
+                "v1.5",
+                "v1.6",
+                "v1.7",
+                "v1.8",
+            },
+            UnstableFeatures = new()
+        };
+        return clientVersions;
+    }
+
+    [HttpGet("federation/v1/version")]
+    public async Task<ServerVersionResponse> GetServerVersions() {
+        var clientVersions = new ServerVersionResponse() {
+            Server = new() {
+                Name = "LibMatrix.HomeserverEmulator",
+                Version = "0.0.0"
+            }
+        };
+        return clientVersions;
+    }
+
+    [HttpGet("client/{version}/capabilities")]
+    public async Task<CapabilitiesResponse> GetCapabilities() {
+        var caps = new CapabilitiesResponse() {
+            Capabilities = new() {
+                ChangePassword = new() {
+                    Enabled = false
+                },
+                RoomVersions = new() {
+                    Default = "11",
+                    Available = []
+                }
+            }
+        };
+
+        for (int i = 0; i < 15; i++) {
+            caps.Capabilities.RoomVersions.Available.Add(i.ToString(), "stable");
+        }
+
+        return caps;
+    }
+}
+
+public class CapabilitiesResponse {
+    [JsonPropertyName("capabilities")]
+    public CapabilitiesContent Capabilities { get; set; }
+
+    public class CapabilitiesContent {
+        [JsonPropertyName("m.room_versions")]
+        public RoomVersionsContent RoomVersions { get; set; }
+
+        [JsonPropertyName("m.change_password")]
+        public ChangePasswordContent ChangePassword { get; set; }
+
+        public class ChangePasswordContent {
+            [JsonPropertyName("enabled")]
+            public bool Enabled { get; set; }
+        }
+
+        public class RoomVersionsContent {
+            [JsonPropertyName("default")]
+            public string Default { get; set; }
+
+            [JsonPropertyName("available")]
+            public Dictionary<string, string> Available { get; set; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Controllers/WellKnownController.cs b/Utilities/LibMatrix.HomeserverEmulator/Controllers/WellKnownController.cs
new file mode 100644
 index 0000000..97e460d
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Controllers/WellKnownController.cs
@@ -0,0 +1,32 @@
+using System.Text.Json.Nodes;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Mvc;
+
+namespace LibMatrix.HomeserverEmulator.Controllers;
+
+[ApiController]
+[Route("/.well-known/matrix/")]
+public class WellKnownController(ILogger<WellKnownController> logger) : ControllerBase {
+    [HttpGet("client")]
+    public JsonObject GetClientWellKnown() {
+        var obj = new JsonObject() {
+            ["m.homeserver"] = new JsonObject() {
+                ["base_url"] = $"{Request.Scheme}://{Request.Host}"
+            }
+        };
+
+        logger.LogInformation("Serving client well-known: {}", obj);
+
+        return obj;
+    }
+    [HttpGet("server")]
+    public JsonObject GetServerWellKnown() {
+        var obj = new JsonObject() {
+            ["m.server"] = $"{Request.Scheme}://{Request.Host}"
+        };
+
+        logger.LogInformation("Serving server well-known: {}", obj);
+
+        return obj;
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Extensions/EventExtensions.cs b/Utilities/LibMatrix.HomeserverEmulator/Extensions/EventExtensions.cs
new file mode 100644
 index 0000000..d938b1b
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Extensions/EventExtensions.cs
@@ -0,0 +1,24 @@
+using LibMatrix.HomeserverEmulator.Services;
+
+namespace LibMatrix.HomeserverEmulator.Extensions;
+
+public static class EventExtensions {
+    public static StateEventResponse ToStateEvent(this StateEvent stateEvent, UserStore.User user, RoomStore.Room room) {
+        return new StateEventResponse {
+            RawContent = stateEvent.RawContent,
+            EventId = "$" + string.Join("", Random.Shared.GetItems("abcdefghijklmnopqrstuvwxyzABCDEFGHIJLKMNOPQRSTUVWXYZ0123456789".ToCharArray(), 100)),
+            RoomId = room.RoomId,
+            Sender = user.UserId,
+            StateKey = stateEvent.StateKey,
+            Type = stateEvent.Type,
+            OriginServerTs = DateTimeOffset.Now.ToUnixTimeMilliseconds()
+        };
+    }
+
+    public static List<StateEventResponse> GetCalculatedState(this IEnumerable<StateEventResponse> events) {
+        return events.Where(s => s.StateKey != null)
+            .OrderByDescending(s => s.OriginServerTs)
+            .DistinctBy(x => (x.Type, x.StateKey))
+            .ToList();
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.csproj b/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.csproj
new file mode 100644
 index 0000000..f5ff2d1
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.csproj
@@ -0,0 +1,1032 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+    <PropertyGroup>
+        <TargetFramework>net9.0</TargetFramework>
+        <Nullable>enable</Nullable>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <InvariantGlobalization>true</InvariantGlobalization>
+        <LangVersion>preview</LangVersion>
+        <GenerateDocumentationFile>true</GenerateDocumentationFile>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <PackageReference Include="EasyCompressor.LZMA" Version="2.0.2" />
+        <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
+        <PackageReference Include="Swashbuckle.AspNetCore" Version="7.0.0" />
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\..\LibMatrix\LibMatrix.csproj"/>
+<!--        <ProjectReference Include="..\..\Utilities\LibMatrix.Utilities.Bot\LibMatrix.Utilities.Bot.csproj"/>-->
+    </ItemGroup>
+
+    <ItemGroup>
+      <Folder Include="data\users\" />
+    </ItemGroup>
+
+    <ItemGroup>
+      <_ContentIncludedByDefault Remove="data\rooms\!009948f3-9034-4a24-a748-a6391dd886bd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!00e1caa3-d6bf-4a0a-9793-0cebe26d4a96.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!011ed14b-f495-4c52-9f0f-b0fd0bd72f26.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0151df7a-3b06-4048-8b1c-11ea88987ceb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!017179e2-c121-49c2-ad06-197f4cf39155.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!01830986-341e-4622-a51e-6368a6064c2b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!018a12f5-8ed7-4dbc-9285-2165ae1ca39a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!01951dc5-d87a-4b27-b444-809f4907755b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!01d8efb7-52b3-461d-a95e-f16ca6ca5888.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!01f2c6dd-1bab-40e6-ac62-fcb5abf15e73.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!025c937f-13fd-445f-af46-69bda3d08d02.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!02d2dd0c-e57b-4454-a197-046d81f8d7bb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!02f00a13-d09a-4b42-888f-f6651d7882b8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!031b3eb4-d25d-47ef-b3ce-e06f6f4f154a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!032dd423-f2d3-4f3f-9b8d-10febd9de20b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!03ba6761-0bb4-4bfa-b895-6e4428795410.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!03ce824c-450b-4d13-a8a5-43a6ba4f1da6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!03cfb867-3155-4ef4-8e2a-0939e6837ec2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!03e4b54c-c41e-46e0-b47d-a6486fe524bc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!044df1bc-13a1-4496-9ba3-bcf60d45fbb4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0482a9e8-a7a1-4e66-a98d-1735758f8013.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!04ae0100-c074-4a0b-bb29-5c88b3199fb4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0511d862-353b-4cb9-9392-04eb3d6b756a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!054b1613-1757-438b-bfe9-73b501390617.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!05877fed-59a3-430b-9b04-10d70ca9aef1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!05d2ac50-d014-4e72-93b1-d8e18ee4cf8c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!05e4883f-4784-4a25-9748-d9d8ce4d314e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!06475f48-8175-45e9-8cf0-15741f27ad8f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!06b3a783-949c-42d3-a4d4-813273e3bab0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!07b2ed26-caba-440e-8cb7-172e311c1d78.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!07e9491b-f799-4552-90e7-242413ea69cf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!08602758-2108-45e5-8f08-baf57f8e90df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!086b0484-a1ed-4c04-93f7-2f73009570fa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!08fc4a55-9107-442b-961e-5353203623e0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!091cf52d-7932-4510-974b-c41ef0d05787.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!093a2862-3c0f-487a-bf43-6ae4d7ab9278.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!09925e93-ec19-49bd-ba19-e7b0fd0bd029.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!09f14b3a-21d0-41ed-bb86-1a602b07370e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0a34a93d-db6a-47cf-a5cc-8f9354435ea2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0a71f415-ec9a-40df-b300-c3fb79d4dd13.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0ab184df-be0f-4877-80f8-0aa34d5ad00b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0ad9691a-d4e9-4f4a-8f48-86a8adad7f43.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0afbbfb2-caf0-4829-a7f0-06472c16cb4b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0b6f3cb8-37ed-4a7a-b95c-5d299ac73755.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0ba81dce-f4d6-40fb-84fd-0df52347eb99.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0bd9becb-401f-465a-8b55-f2f20b4cdb78.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0c1f5b9c-4b80-4c83-989d-3dbcffa6f74a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0d7ece98-e347-4082-a9a4-d5e4cd594bf0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0d877be3-7545-49ca-9941-191e3299b7fe.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0dd1c03a-0455-4ffd-9ecb-5777039d4165.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0e3ca29e-0270-4ab9-8b07-c76f4662dcd0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0ea8696f-f527-4e11-916a-69dd9e086d9e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0f08c6a1-47aa-436f-9a44-3fdbd5aff348.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0f6a7cc3-2f2e-49fd-a953-401c9a16c38d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0f9fcf53-412d-452c-bcea-43d6dbb3d705.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0fb1c6b5-8bb9-47e8-8d9b-a126cb5eff7d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0fb79121-1e83-4fe9-8bf9-f8a5ed364efa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!0fc9886d-ecbf-4525-8f5c-a43fc4dc1b58.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1000acc2-a562-41f0-9f40-6eaf73b99f66.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!100204b5-f690-42b9-a49b-3fc3df91bdb2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!101265f1-eacb-4185-9470-269bf51b1829.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!108535e1-632b-489a-a9e8-e2fcf60d8c83.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!109f5a13-3a9f-4ced-a4a4-b0191a84b7d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!10c5ff39-6ac2-42a8-8fae-292f01a5cb32.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!111e8be3-72e1-4200-83aa-241c6e98764d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!11381a2e-0b1e-4a56-b53f-0dd2cf65a187.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!114243be-a9f3-4909-bb03-8171eacdf1ee.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!116a3988-1763-45ec-b24c-ebb9e57faf4e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!11a149c7-ee5c-4ada-9145-052976d3ab18.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1214a2eb-57ea-4662-8b32-742678cf130f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!13207273-2393-45a6-8cc9-7c4fbbbc9736.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!133f8b66-d9d5-44e4-95e9-dde76cceee0d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!13ed7c78-7160-4ebd-a84f-7124479d0b3b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!14586508-6e3a-4bc3-a8ac-dbcb177310de.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1459a8ab-3aa5-4619-bb94-7d636f9a4576.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!14cb8826-1b94-4106-b530-0f9609d93679.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1524fc2d-6985-44d4-9d77-08f02e2df93a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1528dc79-229f-4a0a-9433-ca0d8fe81fdc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!15d52bea-102a-4352-92a5-f2817e879083.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!15f05e3c-4694-403a-a95e-10def22cb013.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!161bbd52-f6e8-4ade-a139-27209aab5ca7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!164a1783-6218-4335-aa82-b9db00aa4cf9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1680277b-9540-43b3-813c-83bce9c2581d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!169d4aca-5385-4df3-afc4-5cc3f94708d3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!16a88afc-09dd-45f8-8202-98bb7a88cef2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!16c80534-e338-45d3-beaf-0e4e93695abb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!16d4b0c1-9bd3-408c-bfb9-48bb8ef7b679.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1709e1bd-5539-40fd-9124-0bfb5c62341f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!17308b64-da60-4966-bf85-409df16d5ec4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1749eb5f-f7ea-4eb0-8a77-7243123bbbf8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1761367d-a128-4ad9-9c7a-acb5a4e5a1b6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!176f30db-9b87-4a06-b3f3-895bd8f41448.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!178abf28-9ac4-432e-bac8-9c75f800fbfa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!17e1e888-b9e2-4aca-85a2-48e5d1d0b35c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!186cbe4b-c6b2-4e2d-ad85-931c8d078185.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!189c6c4a-fa84-4fb4-bdfc-ab25e959e243.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!18c0440c-5c3e-4c80-8397-95658769c20c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1909d1c2-18e6-4f41-b6d4-01a0350ecb4c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!191141f8-0556-43e3-b982-142854e40385.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1940357b-f2b8-45b9-a830-d35e7f4f46f1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!19ad183e-18f5-41a2-837f-5c440047a0c7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!19b0fc7b-0359-4aa3-9597-29a97145e7cd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!19cb0696-af13-4036-b000-7aa03bef9541.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!19e9f51d-278c-412f-9ecf-cb96a83282c7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1a0767ef-4897-4a87-8d95-9c1446b07780.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1a1e71ce-5f6a-4a9f-a3cf-8f95189eae24.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1a995531-85bc-4f90-b36e-29a1e8620e7e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1b2eb324-6682-4ea3-8377-2e17da2fd996.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1b3c2d02-b76a-449d-a458-15baf8254298.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1b60b136-19a4-4551-b682-b02a6cea94d4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1bc97814-3491-455b-8fc2-ca2916f77813.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1bdf6ed0-cac5-48d2-84ed-83b7f5ef3a42.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1c0450bd-8cb2-487f-9160-3ca95543410f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1c18b32b-c3b2-48ee-8562-bdbc1697adab.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1c273675-9267-46e1-901e-50460328d95a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1ce174af-bd5e-4ae5-ac1e-b71eb4b44594.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1cff0104-9ffa-460c-ae4a-4a4c17e2784f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1d3e4977-6df2-4f69-b8b8-e13ccffdec71.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1d4821a3-f202-46f4-aabf-7fa88387283c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1d6dc82d-978f-4f7f-8514-12f099d4e699.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1e3463cd-408a-4f85-b79f-5f1f9a2f4160.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1e96e1e2-e2d9-4547-90c2-c9311fdc1ffc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1ed2a1ee-ed46-4444-967a-3ad686fee01f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1ee34f83-373b-4508-94a9-3ab61873ecd6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1f1e1492-eef4-4dc3-a5bc-ff2aac6fd10c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1fd36873-80cc-4d2d-95e3-11e3df524dac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1ff577ed-8eed-41be-a839-2e9985d4ee5b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!1ffe979c-e5c4-4db4-b0d1-c0e615cb76cc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!202568b3-39a9-41a2-a040-bc8845e50449.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!20da7437-06fd-43b3-b5ed-e2f87198daad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!20f5dbc1-e343-428a-8a76-781193037198.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!210b0c40-0cb3-49bd-8ef5-028cf01499de.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!216fa2ed-abd6-4d1c-b87a-4dba953da630.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2170b28b-1c11-411c-ad8e-1b4d884b509b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!221ecfe5-5d11-44e5-a7f3-ab71ce8c9774.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!231333d5-f5c4-4df4-9d09-814338ff0b36.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!235e6b94-0c1b-409b-881f-f293d356bcd8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2363d819-977b-465a-81a5-d16ab55a2e22.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!23766876-4d3e-421f-a26c-abb822473a1f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!23a77580-70a5-4f71-bf88-383caa4edaba.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!23c45ba3-cd4f-4fa2-b129-948a350d28a9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!23faa183-1aed-4a7e-937a-6b46768c9e16.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2449949d-7cfe-4680-99d7-97167eea6b52.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!24b54660-10aa-44be-a54b-c7b571d0427c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!24e064e4-b388-4bc9-b379-88e485deab8a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!253ea427-a360-46fa-a1bd-e319055a9bf5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!25f695b3-ee00-4161-ad85-209101aa600c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!25f6ff1e-e9bb-47b9-a9ca-f72f7c5ac797.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!26089b3d-c318-4d35-af3e-255eef32bc7e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!267a5f9e-1dac-4b5f-89cf-d0f1741aedf1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!26879a0f-d760-440b-be38-c70ba711e016.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!26a15ed6-2da6-4796-8526-d63385e62189.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!270af0c6-1496-46af-91f6-9977aeefeef1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!27897886-242b-4f28-a79c-9c71b787a956.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!27adc88d-bda5-4888-b6bd-9691f55f3a3b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2830fdb4-947f-4f7a-aac1-c793f84c2d7b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!285a2bfa-8e59-4613-bc4f-f0300ed990a7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!293d9933-de29-455f-9a89-aa1b131afc2b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!296bf7a9-68fc-47b7-9c6c-eab873a25565.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2987c88d-23fe-43bc-99bf-a57fd0f13675.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2987f9ed-ae51-42f2-b0c6-6ae736646360.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!29ecae78-49d0-4b07-98ab-ab75527f68be.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2a763c96-c63b-4332-9ed6-dc7e842a0440.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2af2278f-aa89-43d8-88bb-f20480ff9c58.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2b1e1b17-babd-4e87-a119-16ceefa61be3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2bbf11fc-ff3d-476a-beb6-4f0b515c93ea.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2bd0be39-ea9f-4c56-9faf-cdf5b1f3c079.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2bec4090-07ec-440a-908a-a722168fb4e7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2c2e3e2e-50d8-4440-86a9-9047ff752cdf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ca6f22d-34b9-4ca5-ad14-c96abc6c17e8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ce029f3-f023-44af-94dd-06390e68198d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ce31ed9-b818-4b70-86bc-2e41a7d71b3d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ce9adde-2a0b-4a87-bfee-74f262cc73fc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2cfe6d51-ddea-4915-8e5f-21a74df2bfac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2d00f9bc-0fd3-4da9-a254-a90e61c15067.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2d87b8b1-0ca6-416c-acba-3349b6a2a514.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2dac26f3-01e8-4aa6-817e-2a89cc59290d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2dc32058-e0b1-4e46-8c5f-a46a60fe85ad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2e0a9a01-5bc5-432e-81c7-378a9b35ead4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2e1facae-b5c7-4a96-ad59-a15a28da15a4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2e5640d9-8e1a-42e9-b630-a869ea6c44c1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2eaf153a-d5a2-40b3-9d59-a0424133003a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ee4350b-006e-4d2b-9b71-87b8ac202e6e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ee9c481-dbbf-4230-8d4c-d8dc11bec46c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2f61cf24-2da9-4050-8d71-ff96cfd478c8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2f709dd0-2acf-4553-9d3f-1b3e7d7e9a3b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2fe91768-c1ff-4360-9dc0-ea052da98d4a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!2ffad0b7-fa7f-4b88-97c9-54830b4f460c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3047fc05-26c5-4649-8fc5-6d83afd9d42c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!31197c74-10be-46d2-b36a-e2b96d22d57b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3142892e-219c-470d-80f3-0d7e5c34150f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!31a3f8cf-614b-4b08-a61e-52290f3a197b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!31cf85c8-3c6d-492e-b43f-4d0a8c2a055a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!31d505c2-817f-4e4a-88bb-710ca54869ed.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!31f9f8d9-e3d5-4c77-805c-3cdcd4d1a140.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!321a0118-d05e-4d95-901f-b7929e65628c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!324aac37-6820-45e3-8b14-21a21334a718.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3288ee08-56ae-4371-8fcc-fae09bb29053.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!33d6862e-cf55-499d-963f-93a9e393cc5d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!33ed93c1-91f9-4a3c-b55d-35c927a034d1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!344ceb77-d29b-49b0-a328-0104c35f233f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!34a06da6-fecf-401e-9dbc-1a072b0da618.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!34b6371c-977d-410d-b3c8-920b1fda6b84.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!34c9fb4b-912e-4d0c-a593-cc072b07376d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!34f7fd18-78f4-47fe-b0e9-28f0181aef28.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!35334b1b-0748-4ae6-b290-2b9d952a0cc6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!353ec49e-5261-49d9-b701-0073818dd29a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!35d3f72b-29c9-42ca-adb0-89302521cc58.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!35dc7a95-211f-4383-a123-466555ca192d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!35ebd4e9-69a9-44d2-a152-426330bac118.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!36132c8e-a7eb-4a04-866c-b97d95fd51d6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!362d1839-0159-465d-9a81-faf0f4b9a223.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!365e92dc-d8ea-4e86-8d42-0aacb460e98f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3780fe5d-358d-4b32-8f29-fba7cdada78c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!379a776d-54c8-4eee-bef4-0492e1b05e3a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3866c302-ce01-4ffb-8b7b-4d83bab72ca4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!38cfc692-cd7b-43b0-b242-4d4445b750d8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!391d087a-62d9-4a38-ab28-d58aa9c6e970.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!39392d41-09c3-4a2f-90c2-52a8805ea39c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!394c788f-640f-4ac9-9d54-10607998b486.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3964e3d1-7f92-45e8-b24b-7ab15013891d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!39bccce2-b78c-4cf9-8428-308793b32e71.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3a446fce-8d08-4ce7-819a-f2f316dc0153.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3a5b7b5e-a7d1-4515-977c-59f968f7c132.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3a6a92be-939f-4820-9366-dc485d46dc4c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3b08bd24-dd41-4fe6-8a73-5e696201f5ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3baa7569-6cd3-4a38-a9d9-be6bda89f5ef.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3be0678a-feb2-47ab-8b1c-bbc4d78dc171.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3c0a0580-8152-4bdf-a511-26ba9f32857b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3c19888e-ab9d-408d-90ad-4bb92b2bdbf2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3c353341-5051-40b5-b97c-ad7284dfda13.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3c6b7be3-d937-4f2b-a251-14b0814af9ee.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3c95c9ef-6ca0-4f22-a4c2-82581f5ce566.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3cf1cd63-6e1d-41f8-b38b-99919923445a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3d69d242-b996-4912-b637-b2ff675b019d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3d69d419-4f1f-420f-a86d-8be471e522e5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3dd5ace5-70f3-443f-a77b-f2b3efc8b6a4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3ddd3d20-ae93-4448-8b65-38ce0cdf64b3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3ead0dc7-f117-4478-a8e1-28bd33969d65.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3fd47b87-b7f0-4aac-87f5-7370282cadca.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!3fe3728d-6531-4b01-ab58-bbd17cc8edca.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!401b32b9-cd18-4da1-ab56-02470a6ca453.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!40cf93b8-ac5e-47a1-ae71-998ad27ca189.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!40e14dc3-d16b-400d-8c13-dbf2d5ca90ee.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!40ef037d-369d-4e0b-9dfe-582bc9f73525.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!40f5792b-73a0-48fa-82cf-c13e0b8469d2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!41a0a70a-a5e1-41cd-bad4-dc1b371172fb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!41a7775c-cf14-4060-b897-ebba44d643ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!41bf7a42-68a4-4df3-8006-cf8524d3dae6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!41fb0617-119f-4fa3-b813-ff80a5c6b817.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!42a66b22-60c7-45db-a17d-f78822e758b0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!42dbf858-050f-49c6-82f9-5bfecbe77cfb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!43510534-019c-43e9-a9fe-ae868411967c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4383cd84-9f31-4779-a798-a1a237d3efc9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!43d322d3-42a7-4f27-ade1-7886fe5c955e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!442e840f-fc88-4fd3-8932-4943c8753360.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!44684574-21b6-4ca1-a8cc-2fe11e459ca5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!44b00d92-c007-493a-85c8-ee0dd43fbfe0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!44d3ca18-311a-44a8-9fff-8912c7ecac60.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!451aff08-e181-45b6-a78a-c594f0fa056c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!452cbd9e-1d72-4e84-83dd-b42449f05baf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!45600fdd-f784-42f6-a514-7f1e34e5c745.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!45afbb30-3ab4-43ab-90ac-f5b902c70557.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!45daabc6-cd56-4052-b6eb-8663f8b8dbe2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!45ff7d79-4e27-40d2-93ee-8b24f78e89ec.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!461b5b97-1d25-4171-bb20-aa925d72bce6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!462b0be0-065f-44e3-96a6-3e67179d6674.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!46430d1f-b496-48d0-b5bc-5de79cadf175.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!46962d6e-92b2-4245-8a03-b10d38546911.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!46efb743-ab87-4ac7-9682-c3fcd15ed92c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!47199b5c-57c0-4aa4-bbfb-20d5c70212af.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4719ae4d-008f-4191-89e8-6c15f31c1fb7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4723262f-5574-4a31-bb74-57ec1e0651ab.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4776dea5-e0fd-4421-be38-c671999842e3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!478f85ae-4468-49ef-8d22-4d4d05570fae.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!47ef9d8c-24ad-44a4-ba40-526716184725.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!48f5f5eb-6fd5-480c-9658-c23e2952b81c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4909420b-44e9-4a00-9c97-3b8d61a0a1ef.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4917c167-f8bc-4416-bafc-37d2fa05537d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!491dcbbb-5398-4520-a6a8-71ff45dfbb49.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!49636e8f-be76-4105-ab9e-90e9bc6855d3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!496f12b0-20f6-4388-a078-74e31c9c8db8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!49a0ed75-a6ab-4005-ace4-a9cf6351cbcd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!49a133d9-a891-4d85-b46d-da7b7160c1f6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4a43c56b-93f7-4ce2-9cc9-eadb58f38487.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4a65073e-7651-45d6-b501-e9437434fcac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4a850743-1c6a-4f08-a580-a2ec5d91845c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b1244f7-ca4e-4833-b500-c9a377dbb7ca.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b15fb46-8496-49c5-8f6d-bf9c7daa6793.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b33efd9-b324-40c9-bfdc-3c1970b86195.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b358236-7bd5-4fe1-be79-5b6d0985e112.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b466e87-444d-437b-a830-14c0cb6fe2f4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b6f50dd-a934-44a5-9925-004e6a89a779.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4b82a600-3b76-4865-a422-517b6155034c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4bf9b456-2028-42d5-bec8-53f046eae7a7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4c0351ae-e696-40a6-857d-45b82fc4f9a6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4c262d60-7c86-47ad-b6b7-17e3ee5d2b65.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4c2c29be-4591-4ff7-acd0-bb5f13225315.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4c65cfdc-3c2c-469f-b204-a71f50ee3a11.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4c6d07db-ed39-41a5-b489-89f77ae4c67f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4cd1a8da-c3fa-4feb-ba5e-b93131f33729.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4d180222-335e-4c40-8e61-abd709ddbfa0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4d528a08-13d1-4d0a-8f69-d870f1245a9a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4da181a0-9cee-44ce-a2db-9acdb2154fac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4dbdaa18-bf2a-46a7-9fa5-272a503fcd57.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4e0cc5d6-eca3-4cd2-af5a-0a5e472a9a40.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4e42d7d0-b511-42ec-8888-858bd10b4413.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4e478383-798e-4f22-b4a9-919b0609267f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4eec4377-98a0-40fa-ba06-be2777d6a463.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4f68be5d-749f-4ae2-bf17-ff248c6c47b0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4f863192-0991-4618-975e-55772df49772.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!4ff69980-0724-49c8-b885-ee5c86aee9f1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!500d38f4-f55e-4091-8bbe-806c9bbec2df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!50340cb9-b71e-4748-9dbd-80d5e2ab4533.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!508ade04-1815-49b3-bd31-81a9da598277.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!50a458ad-1ab0-4da8-8175-b90e1f987b09.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5107d457-b1a4-464a-93ce-452a5aaab204.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!514dbafe-7499-410b-aa6b-9a3cfc39ed94.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!527b3e69-4a28-4cac-a358-c204444f499d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!528ca094-7692-4a01-b1a3-0790926d5544.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!528ce4fb-8249-4d3f-9743-a1dc9bba8829.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5296546d-7aab-4e5d-9d4a-027966246645.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!529c7af7-691e-4480-b88d-f4c424c30610.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!52a3ae7e-0653-46b1-8052-8cf1cf17da95.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!52a3e47b-0213-4872-9bfa-94ac62c92698.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!52c624d8-2ed5-40eb-b3ca-cfc19cdc8e71.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!52d1bfcd-3d9a-4469-8fa1-413491ca75ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!52d49ea6-a9b2-4332-b712-46a9fe47e7cf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!530618be-416e-4281-bdf4-432cca2ba154.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!53205a54-7175-4adf-9362-9e83d27a1414.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!53219c8d-ab96-486c-8d72-32c08d8d1e14.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!536e266b-8b25-4a1b-a5f5-6778399c90b4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!53869421-9475-4607-9ef9-efd4af0d3b98.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!53ed8360-33f8-4539-9f27-ebee01d3cfdc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!541ac3af-938d-4d2d-87ec-d40a7d51f949.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!54385af9-0e23-44dd-bc4d-2bf6362da26c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5457ed85-c48c-4ccf-8905-44751b42225f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!545e67e1-1744-4937-9bf1-a9666a903a0f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!54cf9e45-e833-4e90-9fef-7b49da74dd8a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5540a57e-b315-407a-ba5a-e41be9436b3b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!555a5486-947b-414e-a500-5248395bcd97.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!55cc236a-7120-4b8d-b990-afb7f6386e2d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!56624f0c-b9d6-4107-8c1b-e238ab6d1182.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!56805a47-39e7-4b6f-9f1c-d6762a70e655.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5691c070-0e79-44c6-8c01-2fb0031df8af.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!56a13e14-6a26-443e-ad58-84c7f8703ca5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!56eea411-09d9-4339-b21e-dcbceca22a8b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!570f1dfe-8829-4593-bef0-f42230b519ef.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!580a90be-62cd-4679-bdd7-1b28f9934b0d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!580f5147-ea97-432d-ad40-42cfcb3cf2e6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5890f4c0-88ad-4800-8232-d67b3da9b9d8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!58e03112-fd39-4e87-9b8b-fe8e9a92cc94.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!590ae097-0b16-4a6c-8a3d-fbfe6d56224a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!593c6e1e-de58-4cbc-a933-9eeedad35cc4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5994b78b-a10e-4a43-87b4-9c2c313f3c9d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!59e04135-5a7e-4c38-91e8-6e3213c384df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5a165c73-27a7-449a-9a8a-94c377e78d92.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5a176a47-1bae-411f-86c4-5ce9a434878c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5a6465c4-ca0a-4ff5-a3c9-60be0e2485ee.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5a8bf716-15e5-40a6-8d4e-d4c6cdef49cd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5a9e4fd6-0206-4fcd-85e2-aeb0414c223a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5ab45d5f-316c-4519-8552-30222f670430.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5b777c93-d41b-448c-b14c-4f8e6bdf0956.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5be6fb36-dffc-4ffe-a553-f164714f6370.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5c0c8af0-e2e6-436f-867c-ea652a0c8a4d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5c191dd2-a708-4bec-be43-12a392460ffc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5c6d36dd-07fc-4421-bcf5-48008c49b592.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5cb2c113-40fe-45c2-97db-786ac0003a69.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5cd92388-abf1-40ff-82c8-f8b448680114.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5cf9dec3-bc79-4d2b-b12d-49132108abc2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5d022dfa-9ac2-4396-9683-f6f32c8afffd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5d65c2b7-a08d-40d2-ac79-2675933e0594.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5d743f7c-884e-4ab5-ab60-caa95ab2a935.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5db3bc2b-39d2-4ecf-8c70-e009243c0e1e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5ddf0dd3-5782-444e-9610-093b736ddfc8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5dfb804d-d608-4b1f-9cd5-d3bd8a4d767c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5e439239-b615-4827-822c-d2c16adf909f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5e61773b-5593-4752-867e-7c0555d89b35.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5e79c9b9-c28a-4cd4-a1e5-29c32987a56e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5e97d736-2d04-4c28-9692-bc22b6a2fcfc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5e9eb177-ead9-4476-8418-567c01b4ab87.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5ea34f5c-48ba-4100-b56b-0592cb44a691.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5f3f177c-9e7a-4471-8c2b-b9c82196ac29.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5f64dd66-fec7-4e6a-a356-ed786534481c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5f975c45-c190-4aa1-9f04-20301c3ce827.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5fed32d8-3433-4fef-a31a-d07dd279f505.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!5ff2de80-5117-4132-be8e-fb640c017658.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!608b89e8-29cc-408c-94a0-332f4d5fa220.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!60b22989-525c-43d6-a2e5-d4763c7c35cd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!60b51119-3f74-4ee7-8382-022b876627dc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!60c64de3-a206-4ec7-a471-6231e2a87ad8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6103ef62-4d3f-4c45-b8c5-917479681fe4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6114533a-571b-4678-bd70-282e33652305.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!61334577-4c4b-4f15-a044-4e5b37ca99fb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6161938b-41a6-490b-9fc8-80549584b3c3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6162d9db-7522-44e7-aa6b-5cf919d931c7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6163f333-883f-47e6-b9cd-2ab8f58253ec.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!616f742e-7a02-4b87-9ca8-ad1ab6424ada.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!61a27993-72d2-4f6b-9f33-fc05b83b9a92.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!61b1bd3c-6cb4-43ba-850c-4f008020cf75.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!61b2b409-7935-4a49-a77b-b8385651afb1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!623b5349-f07d-4124-a018-ea4203f0f584.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!623c857d-300e-4b82-a7c9-841ad3ff5720.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!625b9cb6-df51-4d54-953c-f0d903286af9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!627ac2fa-8384-4c2d-b14a-57cadffa9307.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!629fa0a6-d0de-46cb-8670-c3b78b5b026c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!62ecec36-777b-4e75-a8e2-ecc1b5acc989.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!636119e3-4107-441a-bb92-ac39aa04e28a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!63821479-398e-4f03-bef1-e050ee0cc7e5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!63d0ca04-40c0-465e-b31f-52c008241771.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!63d4aa81-eadf-4d81-913b-64e26851d093.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!63f904f6-a1cc-474a-a43b-06ec3d07191e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6443867d-f5b3-4a85-8df1-57aaac003dd8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!648fe408-e54a-40e1-b148-b97162fd6c61.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!64954fab-f87f-4cb7-9bf0-88829f91b25f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!649e9af2-3160-4a44-9bd7-ecc909f51f69.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!64a42e40-2bd3-4b35-915c-2034abd3fb37.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!64fd2ab6-fdad-4299-8278-61769de3c386.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!655e242b-68d7-4c73-b053-5a398ef9daa0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!66097526-6373-42e8-8d7f-9930899d42ad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6613b5ce-70b0-4286-824e-6cdd5504e5d2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!663e92df-0e24-483d-aad0-7f8745b7eedc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!66d37076-cdc3-4a7d-82fb-2d53dd9a083d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!66ea76e7-2fec-4397-bada-48783193a2f0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!67345f81-971a-481d-92a5-c93a89168247.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!674e4ac2-fa73-4707-b8ae-5c179c076c51.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6794ef03-6d4d-4c47-8285-a37cdba4d64e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!67cd0076-0a88-470a-be4f-796239108eef.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!67d57362-ce3e-496b-929b-a8da87cd3862.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!68422c19-788b-4dea-acfb-5e49f4800990.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!68467b77-4a4b-408a-ada2-41ac4613dffc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!68b476dd-95a5-4e4e-b202-35b81e5a3731.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!694b53f0-000e-4c58-8f80-0ef9076cbeb8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!69906978-ce3e-4f70-b89a-380c69b13982.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!69bb2ff8-6db7-40d8-b45a-ef101cd969fa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!69e5c80f-58f2-4615-8044-86af98bf3086.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!69eef5e8-ab54-4eb0-8e69-5198a4dd45d1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6a3216f7-5afd-42a4-b021-02dfb397321e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6a54ee0a-5567-4e89-ac6d-c2902bc4fdf8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6a5ecdeb-e183-45b3-8a30-7bbc3545aa27.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6a9002da-8c11-4e6f-8ad3-15d79111ddcd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6b81c752-01e9-458f-b261-bf8d4688166b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6b8a143f-ccc9-472e-b077-bcc0e044fe36.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6b9cc525-e7ea-4fe0-aa3a-5ffd31d5faad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6bcb38c1-4958-4e3a-bdd5-32f52b58a3f7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6bf138cc-5bfa-4fd0-9c04-c2d5f072ccd5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6d840bfb-0045-463a-b226-727c278f155f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6d93ea42-f79c-4385-bd9b-5e0fba1a5909.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6de3378e-baae-45a3-8a84-03ec11148bc3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6e49ac34-422c-42d2-9c77-305b68a0ac54.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6e7c7434-fd9f-42ae-8cc4-aba1e2ff18aa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6e9d7e45-865c-4867-9f4d-0e96f3921c35.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6ee08cd7-3540-489f-9c6b-674b298737d6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6f7a879e-b2cf-4a20-bec5-5c09de93c4ad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!6f829ba4-b4e3-433c-a860-8e186e30ac85.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!70c4999f-08e3-4aea-8973-ebc3389c5e35.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!70ddde73-376f-4562-a097-b1424f2cd70e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!70edd37a-7220-437c-9619-26748a492a3a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!714e6e75-7832-45ef-af06-bf66039166f8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!719db094-4cb1-4cb7-be57-3bbbf6e34ec7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!72315498-eb3b-44a3-a008-c2d46463daeb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!724a70f3-b99a-457c-a074-b5899daaa4d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7285b815-f6cf-4cb8-904a-1fcee299d77e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7295f5f1-1342-408f-99d8-d2c10bc86f23.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!736868b2-3f5a-4688-b391-790b7d5fc5e3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!73ad57ab-b839-4fec-9af8-814115c27e68.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!73fbafd6-ca4d-4f7d-bf00-b2c878f36891.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!73ff3e24-d56f-4bd4-91d1-e95725bb5139.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!74eb5bd8-4757-4263-9a6c-e77c9c2ae6f7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!756e9840-5e66-4d10-b93b-7a7b6cf38832.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7571dd3c-e54a-4c39-87c0-33cbaeaf9648.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!75d61410-1198-40d6-9a2b-3c5da0c3ac92.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!75e6c3a8-5e47-491b-82f3-0c7000df0f2c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!760b828c-374b-466c-b27d-39b04a2af257.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!761ee42c-bb77-43bd-ac52-46a1a00a833e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!76fa27b9-c343-4c79-b500-7821f787592b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!76fb2de5-6c22-45ad-a984-e15fd2f4b93c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7767a63d-7556-4b2d-a91b-485df33a6889.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7784e064-fdab-429a-8505-042653461c7a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!77dc5e61-c8e0-4be7-b604-4e1e2ed5fafc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!77ebb6f7-97d9-4846-91b4-208396eb89e5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!781a5078-228d-4a04-8371-0071970a913f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!783efa63-029a-48bc-9d7f-789811a1c43e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!786de287-e4ac-4269-90ee-0f8d1c99e2c3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!787d6c56-a077-447d-958a-1183108265af.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!794406d4-3ad0-4436-af85-3320115799fb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!79519d6d-83b9-4bd8-bbe9-f85296401068.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!79da8d0b-947a-44f4-8b63-213d4a276eba.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a2d5031-ff86-41f2-bb18-204ddfd631aa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a452301-05b9-4114-b5dd-ed8de24c97ad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a48212d-d1a2-4680-9bff-f6dc2e322c03.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a4d1809-bf26-4ee3-8c9b-8de0470fb883.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a67a249-01d7-4cd2-b885-c18781d1b2a0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7a9dfabc-f519-4adb-ba00-2dd6c2827e08.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7ab35026-dfda-471f-baee-3c0c8ea03eeb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7ae7061a-0931-438a-b905-c1e54f48c474.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7afb9033-4f15-421a-981e-f4161d006e85.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7b59eec6-53fc-4b9d-8c5b-6f3ecc5a4ebe.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7b7d15a8-aa1c-4044-a759-2947b9131324.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7bc0b3a0-f830-43b7-81a7-a31c52fafe16.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7bd17e98-bf49-45ab-b1a7-bd6d85035a07.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7bd5547f-aac6-469d-892a-53f3f9f71d0b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7c4f45e1-02d4-4e48-ba3e-4a637f3790db.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7ccaf774-35b4-4116-ba95-69316b85dd35.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d27f50f-1d49-4293-834f-3663e16a98cb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d42d75a-7c2b-4fa7-9031-c7cb005f1967.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d488e6f-f188-46aa-a140-22fd49e22f0b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d7f7373-0ad2-460d-9b46-c2d57eca8e04.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d823240-f3bc-40b8-9e7f-c6f1b77918e7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7d980a7a-6d46-4034-8f1a-d119b4350f05.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7df9eacf-941a-4828-a262-6d132c095dcd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7e4d28ed-c284-4354-a018-78072c374052.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7e79d4b3-fbee-487a-93bb-786d259d8c10.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7e8eda49-46ee-435e-9a90-717192068160.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7f3ec66a-08ea-4461-ad43-d5309502ad88.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7f515865-7563-459f-9f89-ec4649ccf6da.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7f9e76ad-7803-44fc-ad43-24c1fd7f2914.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7fe13852-666c-49eb-a91f-da36122a1794.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7feecbb9-b6db-40a7-9e06-05a025a39d7c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!7ff3ec0a-f857-467f-bf42-242056982142.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!80213af7-e194-429b-9a88-043c0c556e4d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!80336cab-19d9-4cc6-a81c-b34063b8b87d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!809abe8b-7091-4df1-9229-1749ceda56c1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!80e7ff58-53e1-473a-9a29-ff5e4f033f1d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!80f697d5-8f52-467b-9526-f4709689c5a2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!810287ef-4020-42c4-9a00-2c22552b409f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8179f1be-f633-4867-b554-055946a9c9fe.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!819c4318-5c18-41ad-8bf7-7148cbdc94ca.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!81bf0e44-2afc-4adb-8906-b912d7324dea.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!81c501b2-21cc-43d6-bc92-a4619ebc3d02.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8240981d-9292-4c82-b263-3d478bff5064.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!826ff981-e71a-42c8-97b2-95e36dcf2b5b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!828c8579-9c75-43b7-aef3-3436516361df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!82aca1f3-e6a0-4eb0-9850-0b4225383cdf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!82e303df-50e3-4d96-a685-ff4f8b4b2ebd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!82e9aa2e-4cec-4325-8901-5db37fdfd0c7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!82f61d00-9565-412d-8dbd-71677ce2b9bd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!82fd4e98-e5f6-4b4e-a63e-778f37d95e70.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8309da6c-6419-4d42-9700-c510705f6611.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!830e080b-c885-44af-ad2f-06ca60fcbf8d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!83531791-e6c8-46cb-81b5-474e0a2aa330.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!83ec3f44-cd1f-4300-8af7-d2b5c6aa1379.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!846d6318-3637-49f6-ad26-3ad5f7a72e6b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!848aede3-f8aa-4f24-a4d7-6ee8f5862ea3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!84baf477-3e1d-4af9-afcd-a1c6480dd897.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!84cba453-dc0a-4db0-8663-bebe9b729d42.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!84d82be2-4f5a-4a4b-9709-e81253736f47.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!851fef2f-538f-4b64-ad62-46d399c0b9fe.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!85529642-880e-43e6-b628-5d83ee0a3499.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8569d782-7a72-4a08-ac99-48364a0664ee.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!85724c05-e2bf-45b8-859e-c27ba22d6c06.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8610348f-6220-48be-af80-c2e3e3bcaadb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8614e7a3-8af0-45f8-bab1-f3c5b3c988aa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8666776a-5c94-4480-aba5-fa03c9610b60.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!86aab75b-c414-4ee9-a248-69481d8970d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!86c30f5a-174a-4ead-900a-01b8f6549833.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!86c3b3e4-dd53-4362-97b0-f813406b7e93.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8708eb0d-45fa-44a1-a933-daa7f037d6fb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8769b30e-93fd-4878-8630-6cd79bf37e3f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!87b12842-e6cf-4edb-adeb-d04d9052ffbc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!87bf5cff-f62e-4f7f-9bcb-f095bd027ad5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!880f5cac-8b76-4be0-b6a4-9a5b1a76d7cb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8863ecac-3c8f-4c49-9651-9daf581c3661.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!887df1bd-70a8-4ee7-acaa-14944486a0f9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!888fadf9-58d1-4147-bac8-e192d87728db.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!88c986fd-f3dc-4fb1-a36b-2c31aac6e82e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!893de46f-fd7c-45b4-b161-64875029bed7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!897dfd06-82e4-46a4-9534-05f09078c8f0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!89824cb3-e607-486b-aed9-a56ae41b6a28.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!89a36790-14d5-47a8-954e-cd8df0cc735f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8a4ce707-c4d8-4416-8111-03670b92da13.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8a5b653f-2bc6-416e-ba2d-881b9f891e32.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8a5e4f44-5a35-464c-b465-5310afbb21be.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8ae39bc3-8ce8-4e10-9baf-34771e6af458.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8af94adb-44cd-44f4-8d94-c6d9a495c826.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8b371195-6702-439f-950f-f71e2ee233bd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8b7bd3b0-5063-4881-88bc-5dbdd029202e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8bc1e90e-c2ea-4a08-ac4a-c1bbf7421f30.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8c74a87c-03ad-4f75-b928-b7c9e01c0cea.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8d00edda-9300-4834-acb9-b4fccb581886.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8d3461c2-0ba7-41d6-bdcc-3b1f37109334.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8d8a7616-affe-4ed2-9d41-d5b9a3a5ad4b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8dc2a80b-7e5f-4eaf-9b7a-4b59b5979078.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8e345f62-0a2b-4399-9815-4420681fdcd6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8e583211-dd76-438e-b980-c64e99a3db2d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8e6157b9-51dc-467e-be1a-ed2ccc50cb7d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8e8a5d26-9841-491d-80dc-9a1ed1a03ca4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8edc03ed-f541-4147-b780-dc5d771bb2db.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8f913ee0-31a1-439c-9f91-b476b6cc8595.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8f9a93d3-3222-469a-8c25-1ca5bc7e98e1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!8fb8ac48-f2b6-45b8-98bd-daa519d242dc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!918fb788-49a9-45ff-afed-7e5a274a00dd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!91a34035-db1e-471a-b69c-ad3c1e7f86ab.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!91c7d204-3bae-4d5b-ac03-015206ff86df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!91da77d8-35ec-4894-b17c-dd9b787abcfd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!91fcd66a-a3d5-4452-a7c4-5bc8c7634727.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!933fc143-21d1-41a1-b2e4-1259485693e2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!93407142-ad96-4e20-a7b0-23781ea069b5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!93579f05-47b3-428e-954f-637ca1a635cf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!93c6717d-79a9-4f5a-b447-a4d148ce55e3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!940c863f-ca7a-418d-86ad-0f561a7a5cc7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!958ce060-b2f6-49dc-96cc-7203cb6e4048.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!95c24965-59d9-4197-b203-9d28fef41c32.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!95c24d4a-510b-40f9-8703-e82ce2aacf17.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!95ce6440-c5a3-4c78-a40f-0a6bdbe8f11c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9640253d-cbe6-4e63-832f-c8c5862646d3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!96b66bf2-632e-499b-b51a-dffe3d74b7cc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!976989b0-3036-499e-ae81-1614a027db98.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!976fd366-5337-46ce-b252-cf7afa0c3368.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!978060e7-a3b5-48c8-b2cd-d186fcd1c9b6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9799cb4e-dcba-465f-9c75-49f3ef5f1acd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!97abdb0a-a490-4528-8b7c-0f3dcf7b4325.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!984d09f3-a2f6-46b6-9fa8-61860a74f85a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!98c77d4e-fccb-45c2-8a02-6ee2a5415fa2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!98f30fc1-da53-403e-9e2d-6034b50c2f9c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9903fc3e-0984-4dce-aa04-3f4dac0f541f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9918eae5-18bb-4aca-8963-a0fe59d9e781.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!991f85e0-6f1e-4d5c-8019-d856349e14b2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!99770653-f825-43f4-b0f5-edf87aa4023d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!999bd22f-b7b0-494d-b5e9-4b7c824d3382.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9a0f8e15-86e1-4e7a-8b9e-961cafc45629.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9a66a615-7ae6-4952-ae92-efaafb819cbc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9b54e996-fda5-4e27-af77-d876eb7f9f7e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9b56b840-1819-409e-b6fa-66919471c651.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9b70d17b-8976-4368-afb3-51df6e632860.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9bd82993-74a9-453f-9764-1b3ad5ac7f9c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9c385667-6e21-4ee9-b010-f5dfbce33062.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9c38ece0-a2f3-4ad8-a171-5e8ffc161350.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9c5a1e44-8cdc-426a-bc9b-aa6f6c74e3da.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9c719a62-7841-4e25-8b93-ee59f7c20233.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9c7fac0d-445e-4a84-b7d5-45ff59c027e8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9cacdd4f-d708-4357-9ac3-175f64b7b163.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9d64cdc2-c11a-4185-af80-377fd2ffde6f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9d72af86-5de2-457e-b03c-8e8c9acf1d72.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9d991242-911f-4b3d-9d3e-657c09dabd11.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9ddb6a8c-45a9-41e6-99da-eff96797c186.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9de8324c-ce97-4a13-9962-0057c558bd19.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9df30072-b3c9-404d-b773-bf9ef89858ef.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9df59639-d274-42c3-bac2-93809e5baa22.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9e2765f1-9e81-4164-926a-776c17efcee8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9e5359b0-024f-4ebe-969f-672a199c5b73.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9e62b6f9-23ca-47dc-adef-22c908593a21.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9e806174-f27a-4fd0-b419-73a20fb1bc17.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9f04c67d-e38f-4ab3-8cf6-4dcc2d4dcd7f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9f52feb2-65ae-4652-9fb9-d7efdd78a259.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!9f95db47-94b6-43b9-9094-f523295f14a4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a0574842-95ef-4402-b003-514936196fc6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a07c9e8a-27ad-4a53-9aa1-b4cc17a031f3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a0d73922-5fe4-4631-b0f3-0b6724d66e17.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a0d9e00f-87e7-4168-ae85-472f7e162dda.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a1025da4-a811-4068-8416-16202f7e899c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a1dc84cb-462f-4183-95f8-5203c4080be5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a2116151-c4ee-4f0e-8d25-cd582c2a2751.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a2248fa0-e9a8-4742-94ee-00b919cd5368.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a25a6e7a-e7fa-467b-b26e-0b80d16e9617.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a2e8690c-17ac-492e-a0e0-b56fa854f91c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a31148c2-7b4c-467f-91fc-0362b8a340f2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a339bd4d-dec7-44b9-873f-a28fc6b451bc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a3555a97-c6cc-45ed-bb72-b20061cd7e58.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a36b9b6c-f204-42fb-9cdb-e71c6207e82e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a38286fb-fbc1-45a7-ac24-1b30f49c2f9e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a3d2b5e3-2de6-42e3-bcfb-67dfe8e5ae1b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a3d2d4f0-d27a-4dff-a16e-cf8f6ab078c6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a440aa7e-13c3-47b5-a707-7c825260ab2a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a45a3767-fa8f-4450-9d3f-4b620878039d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a4a49991-8cff-4045-8cd2-c9fa5ccc6ed7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a4e3366d-7408-4a05-825b-4510bce62b4a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a5194fad-bbaa-4f01-b5b4-78f3347398b1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a5274826-976e-42ba-9cb5-439c4f780b99.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a5abe2dd-6ba4-4c54-9401-9b88fa83cf39.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a5c46de7-eeef-431a-8b35-b71fcf81d12e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a5fa0d25-4d76-444f-81e8-00028f2c07f4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a6a4b783-b5c5-40b0-8237-052c81bb7c38.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a6bdf3c4-5b6a-4eeb-8eca-bdc14058a8ae.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a6c5b19f-560b-4e98-acbf-e6646194fe2a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a6dfa64d-5f6d-4d3e-b92a-bb78fc41db89.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a6f4c62c-1ae7-4bb9-902d-8ee9b282c72d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a70a38d9-cf3e-4e5b-8501-c964ab7cf20d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a76461bb-23c8-4344-a932-34f602d873bf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a764ac61-393f-4d3d-a45d-314768f99380.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a7710298-8c29-421e-a758-2de643aec29f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a77ec1c5-4d57-439c-921d-8e116de97214.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a7b1cfec-7d6a-4a88-9c21-db876816ab34.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a7cb2ce6-4777-4e26-b420-deff47f05fdc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a7d07d48-5235-45ef-b673-a38f2289db4b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a7d3ed16-2c24-4b3e-8cdc-d36826460fae.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!a8fd042e-ce3c-446e-beca-00aef4418597.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!aa2d7528-a27a-47ca-ba4b-72fd12946f17.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!aa45208c-ebc2-428d-8af7-e893f7378169.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!aaffe828-6a01-4a5f-a081-04f7606df81a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ab61fbf0-ccfe-4ada-8772-dff5c3a02247.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ab90ed9b-50e3-4031-9393-24fe8e992fd7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!acad28d3-9f1b-442e-bc4e-dd7622f91fae.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!acca7ef4-f7d3-4b7f-8c9d-ab00dd4b6645.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ad0c5018-db28-4851-a03f-d94497e059f1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ad258585-b8b1-4a5d-a67c-c2e6d7d95be2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ad38071e-4ff5-4fbc-bb94-3f22963b44c1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ae865b74-d384-47cf-bda0-e30c42c99d2e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ae8d8426-24c3-4465-822f-8abe89e9712d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!aee0f24c-933d-459c-9a3a-a6e2bb506e05.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!af3abfac-532e-4a28-8214-3468dfa95e5d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!af40349f-0b62-474e-90e8-d5f6142245fc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!aff2e91e-3b3c-4cac-bba9-6f2876dbf441.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b078e4f2-a8f1-4792-9fa3-03f2ffbb1fc2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b0c2ebf1-94c8-449c-9c0c-ebb237de45e2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b111a966-160c-480f-b0d9-a17e14777e4a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b12bbc43-f6c0-4115-89c1-69635bc76306.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b1e32c37-a825-4f3a-9c2b-766cc0ce82d3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b241102d-a7c9-40ab-adbb-ed4b3d80e489.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b25b1552-cf53-4079-9710-20163fb0a69a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b2767de4-2c85-4923-aa2d-57997602c958.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b27f17da-3788-477e-a9d9-666316736922.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b2a5072b-65f8-4e01-acdf-4575d9707dd3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b2e0de4b-42c8-4e71-a4f3-141e77a9700c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b2eb4fdb-5e67-49ed-b181-ebc9cad9418c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b34de8cd-f3c8-4478-ace1-c10f9bff4e96.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b3acf88b-80d0-44c0-abee-6dec4fbdedbe.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b3c3ed1c-8b2a-4884-96c9-ad76bf6e7735.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b3f6d482-5e18-42de-a0f2-baa60d02ab8c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b441a095-ab08-4c8d-8771-1a678336e46d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b554a46a-e88b-411d-8362-e4b63783a693.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b5772f29-ab76-4fd8-90b6-8841dcc0c4b4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b5f6dc35-fdf4-465b-bc91-3d4dda471752.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b6df2f90-8cf9-4bb1-8ec9-71a0c89f6943.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b7bb67df-d7b5-413c-9483-34b3547127ad.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b7ffcc98-4fca-4103-8c68-8020671345f2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b800cf2f-bd31-45ce-90ef-11044a266ccb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b8d90e48-18fb-4764-b31b-4773c77ce0b3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b922d766-d56f-4800-b6fb-3c81caf0a38b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b96639ae-9710-4803-8b39-9df0ba604ee2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b972ff9e-0f0d-4ec4-9846-3a09ab769eea.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b9760753-53dc-4463-827f-7ab25328d939.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b9a089be-25ca-40b5-8a57-a69956ebd8a1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!b9fb2acf-d5f8-49f4-bcf4-3bcc576a3b62.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ba401d49-e243-43b7-9f45-c82b6ce3814a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ba4f8e33-4721-4f51-ba69-41bef6d7d8a6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ba53504e-701f-4420-9c34-75998e4f512e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bb7ba32c-d61e-42b7-b8ae-e8c4386847ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bb7de660-24fc-4d72-88b1-03203e16fc38.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bb813719-a991-4ad4-b6c4-54ea1121a0fa.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bc138419-ee0e-4ba8-ad06-7b229e104dc8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bc3ab790-1d1a-498f-b870-668c925a54de.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bc66e53d-231b-4888-a46a-4ce01002dede.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bc7bc0bc-1144-4c19-a084-1d30057d9a83.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bcc03393-28e7-43db-9650-2b79bdcef35e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bd070c4c-3406-435a-8c86-c4ec56075fff.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bd79c444-2083-490e-85f9-95f701276c1c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bd946a3d-2de3-4d86-9c7d-3250c3120271.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bdf8a01d-b98d-4e22-9035-8ef6cf97f755.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!be1db8f7-31a2-48f8-9696-af290e33c783.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!be4cf1c9-df85-40c1-868e-aaee070ee786.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!be610b60-599b-492e-8ec5-f8f3e6586c7c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf0d5113-12a6-4428-ad9f-ef42cab9fbb2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf5f197d-ff0d-49ac-b23a-71a9f24002a0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf6a8ef8-9dc8-4e6e-b373-d2823c1891f8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf7194ed-55ae-4e1a-92bd-8157c6996fb6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf7b453f-f0d3-4ebe-bd90-a9d65386a9e8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bf85b825-183a-458e-9fd3-eaf4a415fc9d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!bfda8075-aef9-4372-8c0e-971b78f31c3e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c046ab99-345e-4da0-a3c8-0b8e28c8413e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c0471a4b-bafd-4a59-9d5b-9733bae2570d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c06eea48-21ea-4ff8-9e0e-4f65c2ca27be.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c09d2c8f-3484-4711-aa25-83072d1c3e14.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c0a19744-d67b-4a63-a084-45a654dbd375.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c134c4a0-ffd1-43ad-a9c9-bf5f4a2d53cd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c1436235-896b-4e82-b146-5b5e592c497d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c18984db-4fde-4f92-bdb2-3dd6b3999e6d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c195e1d3-1885-4ebe-894a-e0904ebe926e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c1a8707b-63d7-4936-b36c-d05ac2ebaa2c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c250d917-ee64-4e90-a6d2-651f2b2a2d88.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c26c228e-7235-4c28-a843-5813a313708b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c2aca3c6-d019-4b90-a7ae-bf52243a87be.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c3001c06-6095-4a91-949e-7679ea3dc2b1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c3348754-0a43-49fc-9c6a-9d3d5919bc38.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c3621a39-9518-4245-a40e-0bc8301bccd3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c4a6bd63-fd2e-4e1a-8f4c-bffff882cfc5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c594a37d-d3ff-425c-bacd-ec27840e072f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c5bd5714-fd0a-408a-8e35-fd915039e3f8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c5d427c8-f341-498b-b223-a3181e4d063a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c5f3ce90-7bc9-4566-9122-26b76f7a5b82.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c60655c1-3c28-4abe-acbf-4a1f75d0c2b1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c60e70cb-b5d3-4a55-b901-c0674e5eeb2b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c6368aa1-bd5e-4079-bcf0-b703ef01efb7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c6afec49-f553-42a7-a1e5-649f03c1a9c4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c6d378ad-cfa5-46f5-971d-2a5c4f98a58b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c78375ba-9d68-4232-855a-dc2caff25dff.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c7902733-21c6-4766-bb64-eaeeecd4db89.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c7dccfe0-bf72-41a0-b1d6-90c2f19fecc1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c7e9ef5c-6997-4cbf-83a0-3f4989843881.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c7f047f0-2e9f-4ecb-8162-63fc1896df62.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c85ad497-2928-448e-85d7-5b79822db861.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c87c6ea4-9637-48ad-9e42-0c7ba695d282.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c8d11a3f-4490-48c9-be9d-676feae9eb93.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c8e6fc0c-3c97-44f2-9a28-ddd498ae66cf.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!c9c8f194-886f-47ba-9fe6-9ff098a4f4d6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ca867141-5304-46a8-a2b4-c067b725af37.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ca89c627-c193-4f39-8364-4238cf3cc840.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cb3632d2-c7aa-4600-a10a-b7a16fce03fb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cb82ab3d-591d-494a-9979-a2727bc5626f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cb95e28e-7611-4243-98eb-bcb5d91a1440.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cb9659d4-0c9a-442d-b61d-ae5d6f068dc3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cbb66134-f183-47d2-8147-530f332ef71e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cc4f6155-951c-4d35-ab65-a1aaef2f4a18.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cc710b9d-e9c6-43c3-8199-3a1d1565cb85.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cc781b54-415b-4ced-8fc1-83dadb298354.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ccbdcb78-905b-4a3f-bf84-b574d700d827.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cd044782-4b57-4b87-a422-69263d7f8265.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cd518557-08a0-4081-83f5-d97655d92682.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cd8acfbf-98e3-4c8e-b357-ed2e91f6dab3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cde74e59-5080-4b65-8e79-01dfba4c6d18.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ce0216dd-9102-4f47-8846-d7ebeb0dcd00.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ce6c2e13-491c-4382-a3e8-6c4c05100ac3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ce7014c2-83e0-4e99-8bb2-046bdf39f048.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ce711e5a-ff55-46ab-81ae-38e10a068802.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cec78c8d-372b-4d8e-8c8e-a57272f65076.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cf510c51-11a0-4849-a72d-fbd19eed48bd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cf5f7944-dfdc-4e66-9e9c-37efe31eb558.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cfa0fb00-d325-48af-9b8e-0b6b4511b870.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!cfc61302-0225-45d3-aaab-97482ea12090.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d045de20-8e6f-4bc4-bd08-55a26d7c7389.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d053e218-2768-4ddf-bede-ad442f09b640.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d0ed4630-bb46-4a2f-adc4-e80b0b5fff96.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d10775bf-c0b8-44b2-8f66-b08087d04a2b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d18be333-3e3e-435b-89dd-427bc6363062.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d22bee42-784c-4514-9cf8-8deb26d59a47.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d23be372-cb1b-4c05-8bd2-0ee06410b4b2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d265564e-e623-4abb-a4d8-190370fb3b38.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d26ddf63-75fc-48d2-ac42-07d671ebce7f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d30ca369-1e7d-40bb-9d0d-1c8c3660e954.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d3273daf-a9b0-4959-b260-01432187448c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d33bb1c7-ac15-4216-a505-2d76262518c4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d383a4e1-6299-46cc-8663-02a9023cf9c1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d3be721c-bac2-4e28-bfdb-08aff335c0a6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d438f303-39d9-4192-9086-9f80d2758a95.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d49393c0-b749-4021-9014-e1547d92b706.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d4a89799-91c9-48db-ad06-f3f9596be9ce.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d4bf9709-af5b-4911-803c-044c4fd55e2b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d4c36ca5-37b3-4524-88d2-8dccfb78fdce.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d539f896-49b2-4f3c-91f4-a09f3880a084.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d5ad52e6-adef-4978-ad2e-9e8752b50862.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d5dce4bf-1f4b-4749-84d8-b810cc8dd696.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d61b5f7c-12e5-4bb1-a68a-7ef989aa2c4c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d6a53b5d-bddf-4ae8-a209-886e16e72ce9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d6bacf38-0765-4261-95a2-71c10352de6c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d6c44000-0ed2-41d3-9ffa-9f15695279b1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d6d26b7e-be16-4927-acfd-e7caf6eb21bb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d6d4a170-d644-4302-80d1-8f6131713b1c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d74867ce-7807-45a8-b030-35d6e64cfbe0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d74bca5a-1521-442e-87f3-3752bce676d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d7d39ea5-a57a-4c36-99a6-8dc9a6cf3997.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d8039263-c790-42e0-9259-10161305b10c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d8c19a32-07b5-4616-bf6c-0664d2c6023d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d9118d53-0acb-47f9-9475-d5ec4f8d3bc1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d933cf65-9047-4d4f-81bc-8abcd6c338ea.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d95e5f97-1a22-4ae2-b554-5dee707b4895.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!d983e058-2c7e-4711-ad92-6331e6b822c3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!da61e076-280d-4532-b76b-df3e49a99c39.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dac02dbb-8cc7-4792-b96a-de2f6bc5375c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dae742c7-dfb0-446a-a509-58e99e25c836.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!db4f2d65-2d09-4d2e-a25b-f25b4419e87a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!db9b1115-3dc3-4144-849f-f460b51d9d75.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dbd402bd-9985-4b34-98ff-221fe63786f6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dbf45ed5-7b39-4a55-9a32-3647a375b3ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dcf54a40-5ee2-45ec-9466-6acceda82493.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ddf1bd0b-814b-4282-86b3-9be7f428218d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ddfed76b-dd25-46e4-a375-dcba0138c06f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!de5b1570-b28e-494b-83d1-416e5cdea3e3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!de5bb326-f9d5-4b47-b72b-c242dc2001f3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!decab043-01e1-4e48-b3d5-4906937c4b05.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!decc785c-12d2-4519-91b5-7ee133c243fd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ded508f6-716f-47fa-af07-1bc51e02011e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!def0c346-1d37-4fb5-94f9-6a60adfcaf28.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!df4406bf-991b-4629-80bb-81b398b6efc4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!df63f51f-0b81-499b-92e6-bec76301b2a7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!dfdab292-e4e1-4ec8-9f33-5772b72e94ec.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e0a9a21a-5531-48e0-811a-a0c500d74773.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e0ba39a4-0ff0-4d7a-a9ef-a912a7eec9a5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e1b15766-67e9-4def-97fe-f85df1534ec5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e2100b51-5cd7-4fb2-9f4a-9fa53ca36631.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e25d2c90-e67e-4de1-80ef-4c3d2fc8d390.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e25e8fe0-0255-4540-9671-97a405fe5c9a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e28ba2cb-9086-4232-84c2-23edeefc39e3.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e2c7f584-bcbe-43b7-8afb-67ce6d20c12c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e2fa5556-3258-4e0e-9c89-f864f172be90.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e2fbeb66-bd5e-40b0-a8c7-fe3aa89c9322.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e380a8d3-316b-432f-aa9c-7828f76db67c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e3a1236e-d962-4a23-8a9e-1408e3bf2a3f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e488ffdd-f384-41ca-bd3a-4b39bb94d612.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e4ae4070-6afd-4265-8346-369fa1152975.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e4b752c0-eff0-401d-a638-d04e2e3b6d9e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e4fe59c3-ea66-42ed-ae48-f79502a29089.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e511c2da-ac81-46bb-80a2-cb6c96f8bdc7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e54a68fb-35ee-463e-adc3-3860b0009430.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e57f9d10-e29b-4d35-937c-ffd3d4c1f836.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e5af2e4c-6ebe-406b-8546-ed74864bc2f6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e65f0abb-6c8e-461d-9179-63f7d12f17bd.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e6cd4d3f-8fb9-4863-ba38-ba11eda1678c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e7662a5e-a03f-4cf1-b146-24016265f243.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e784d386-7e5a-46c8-9eed-c82b7b76f8f7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e79d0c3f-b28e-436a-8548-291c44971bc0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e86555a7-663b-4015-82fc-8419d18e4dfc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e865fa7d-3ef3-43c2-b795-d7800aba783f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e8f4f551-a625-4629-a761-fc8a8c43155e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e93d0da0-2748-4684-bf03-f172d66308e7.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!e9586638-033d-4bf7-bf12-1dc34049ea68.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ea24a093-a472-489b-8e23-54969e6e5301.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ea4529ac-405a-46a0-a3da-b7b3626ff077.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ea47d3eb-792a-4ba4-97c9-69f0a3c57731.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!eabdab62-a67f-4278-832b-798b43f74084.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!eb377b96-8b92-498e-a9a0-29649def6c09.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ebb7bca0-6d0d-483c-a5da-8604b9247ce6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ebbc7459-8a49-4551-815a-0cd82d4bff76.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ebf932bb-81e8-42a1-80f4-130ca6c63579.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ec199ae7-14da-43ec-9ae2-fd642f9b494d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ec326a41-3e29-42a8-b03a-0aa67a291a6f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ecbdbee3-c469-46f0-840f-2c8defa0d489.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ecd9f0ab-3e20-457c-8f1f-21fbac6b4580.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ecdd7831-ba15-4137-93e2-14339d7b0075.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ed44b30c-87cc-44e2-b2b9-d980d1804dd2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ed889161-7f2b-4e35-a2db-172ea6bd6b8b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ed9760e9-39fa-45a3-904e-89a003b24346.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ed9d3267-95c0-4fec-b687-882c98e0a990.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!edabb2ee-09b1-460f-b718-04c6578b2530.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!edadd699-5e5e-49be-a4c9-7eee94036a03.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ee0b072d-cb98-486d-95bc-a205e861ca4b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ee5a8c9c-e03c-46f5-821d-5109413a2f67.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ee65ca66-0d4e-4a8b-a7f9-825b05a6b1d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ee96c3b4-e8dd-483e-ab60-eb2d3187332a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!eeb86305-cd5e-4a08-a573-17f3f316cc84.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!eef8b7e4-8616-41d8-88c7-0cc316fdab15.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ef30f611-473d-471a-87a2-76e5ebf87e81.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ef6ad6cd-ef80-43a4-97ae-46fec076933c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f077b013-67c4-4390-bda5-b818e4369b2d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f08a25f5-8a88-41f7-8a85-bcd166612307.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0a3f6ab-cd54-4820-9378-648c1167e803.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0ab6959-16c0-43a1-a779-1061dd46318a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0bf3c1c-0589-4007-b6cc-e70bc76f4539.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0ea32a1-2c37-44a3-8266-e2983739b247.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0ed4b69-505c-4423-ad4a-f588edf85983.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f0ee301e-1140-4b84-ac93-3ceede0f5090.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f1144f3d-ed1e-42c9-aaaa-8cfc936d4961.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f1206f9b-00ec-4479-9de4-19eb62ec2ca2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f187a57f-b9ec-4409-8533-7672b56a4437.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f1fb620c-967c-4f30-878a-e17fb1ede7ac.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f244a993-0ae3-4091-b866-7a2ef326ea73.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f2956010-fcaa-4474-947a-3d77d889e3af.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f337e441-1f89-401e-b9d5-560a7f210011.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f35a9de0-3bf9-49f7-806c-d30d192a8c7d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f3790c7f-c6d9-49bf-b2ce-636236e0d46c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f3a60a02-30a7-468b-81bf-13add7646fd8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f3fd25f4-4ec1-452a-a724-9d39c00f2904.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f443ea90-2902-44fb-bbbc-66d97e3cc67c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f4558fd1-8e24-456d-b283-902f6ff29a10.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f45b1d36-ff13-412f-b17f-a64ee194df2a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f464e756-7e8a-4b18-8785-9d5f54ac25d5.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f470fb58-ca47-41cb-acdf-a615f0b82d3f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f48693d8-60e4-49b6-820e-ad6150c26965.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f4ad97d6-f54e-4d7f-bf27-61d7a4eec94c.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f4e70d71-1c25-4407-840c-0442c50fd16b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f591cd2c-4da9-44e2-ab78-4802e06bca19.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f5dbd7a0-4fcc-4497-a23d-3d6f52c1e62b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f5fd4678-6a69-493b-9a10-d66d03bc3f4a.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f60c1baf-033d-46ba-be73-dd9cce98ad58.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f61575c7-93e2-4e91-8cd8-48a6b7c95b9e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f69039d7-90b4-42b4-9950-bfd155095924.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f69253de-b613-4026-829d-b2586ed27986.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f6984628-b745-447c-ad5a-f70b6434ebc6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f6b83ee2-2cf5-49c2-873a-22ebbd5e64d2.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f6e0edc0-0912-4242-9f8d-96df82e93ae9.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f7a624dc-40ea-4412-bf05-e5aed8ba75df.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f7e17e14-747f-4ba7-bdfc-be68d898fb53.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f865a40b-c6f7-4db2-9327-ff48a524100e.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f9623569-329b-44d7-b71e-b8afb4a9e5d8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f96597bc-ca74-410c-9eab-41b5055d7f77.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!f9a24a87-d4c7-4d36-ba82-f953ec8d5ca0.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fa291d6c-434e-4ba4-abee-b26bc573a954.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fa65f5d0-cbb3-4953-85ee-fafe5b155b2f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fa97b46a-3a11-46cb-977f-e898ac1fc544.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fb8501d7-1fda-460b-b9ae-344e976f2f6d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fb918d1b-2419-4242-adba-f947d84b0f1b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fbd80379-e48b-42c6-9936-37d42f4ad4f1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fbe34067-7807-4f3b-b228-a17cc23edb78.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fbed909d-3d2b-45fc-b05d-2daf52a3c1c4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fc2334f2-952b-4b8a-9d38-ff42f758ee64.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fc346ac3-47a9-4a56-97c1-465e582c261d.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fcabe18c-b801-4c93-a700-1c39b428957f.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fcf53b6c-9b21-480b-8a7a-7200f00e83d1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fd2fd43d-f4c7-4e0e-b31c-4a9a2232b5d6.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fd389908-05d5-4505-b350-598878fe9120.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fd9cf1a1-4bcb-437f-b481-8b85c704e7dc.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fe2b9d32-94cd-436c-97bf-bc44006fc7e1.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!fe5a6674-ac51-46a6-ba84-928ec8fdf6bb.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ff20bf31-83b5-46ef-9ae5-2c15be948c22.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ff30dfd7-0c9c-47c7-b992-4fbef3b97bed.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ff76473e-e874-424f-84b4-496ae7814131.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ff95f473-3648-45cd-886c-8c700018d78b.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffa69c54-30d9-4777-bfe9-a5a3309b60a4.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffbaeac3-6204-4714-b014-2b6e4a3d2a21.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffc46a54-d0dd-4a3c-bd21-cd89d8a31b69.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffda8b8c-baf0-4938-bda5-12d30ef39fe8.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffe1fed4-8e49-4584-8f74-a1f9a58b70ed.json" />
+      <_ContentIncludedByDefault Remove="data\rooms\!ffffc7e7-4b1e-40a9-9f24-ebd95267e758.json" />
+    </ItemGroup>
+
+</Project>
diff --git a/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.http b/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.http
new file mode 100644
 index 0000000..01d5fcc
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/LibMatrix.HomeserverEmulator.http
@@ -0,0 +1,6 @@
+@LibMatrix.HomeserverEmulator_HostAddress = http://localhost:5298
+
+GET {{LibMatrix.HomeserverEmulator_HostAddress}}/weatherforecast/
+Accept: application/json
+
+###
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Program.cs b/Utilities/LibMatrix.HomeserverEmulator/Program.cs
new file mode 100644
 index 0000000..9ea6fce
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Program.cs
@@ -0,0 +1,117 @@
+using System.Net.Mime;
+using System.Text.Json.Serialization;
+using LibMatrix;
+using LibMatrix.HomeserverEmulator.Extensions;
+using LibMatrix.HomeserverEmulator.Services;
+using LibMatrix.Services;
+using Microsoft.AspNetCore.Diagnostics;
+using Microsoft.AspNetCore.Http.Timeouts;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.OpenApi.Models;
+
+var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.Configure<ApiBehaviorOptions>(options =>
+{
+    options.SuppressModelStateInvalidFilter = true;
+});
+
+builder.Services.AddControllers(options => {
+    options.MaxValidationDepth = null;
+    options.MaxIAsyncEnumerableBufferLimit = 100;
+}).AddJsonOptions(options => { options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull; });
+
+builder.Services.AddEndpointsApiExplorer();
+builder.Services.AddSwaggerGen(c => {
+    c.SwaggerDoc("v1", new OpenApiInfo() {
+        Version = "v1",
+        Title = "Rory&::LibMatrix.HomeserverEmulator",
+        Description = "Partial Matrix homeserver implementation"
+    });
+    c.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, "LibMatrix.HomeserverEmulator.xml"));
+});
+
+builder.Services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
+builder.Services.AddSingleton<HSEConfiguration>();
+builder.Services.AddSingleton<UserStore>();
+builder.Services.AddSingleton<RoomStore>();
+builder.Services.AddSingleton<MediaStore>();
+
+builder.Services.AddScoped<TokenService>();
+
+builder.Services.AddSingleton<HomeserverProviderService>();
+builder.Services.AddSingleton<HomeserverResolverService>();
+builder.Services.AddSingleton<PaginationTokenResolverService>();
+
+builder.Services.AddRequestTimeouts(x => {
+    x.DefaultPolicy = new RequestTimeoutPolicy {
+        Timeout = TimeSpan.FromMinutes(10),
+        WriteTimeoutResponse = async context => {
+            context.Response.StatusCode = 504;
+            context.Response.ContentType = "application/json";
+            await context.Response.StartAsync();
+            await context.Response.WriteAsJsonAsync(new MatrixException() {
+                ErrorCode = "M_TIMEOUT",
+                Error = "Request timed out"
+            }.GetAsJson());
+            await context.Response.CompleteAsync();
+        }
+    };
+});
+builder.Services.AddCors(options => {
+    options.AddPolicy(
+        "Open",
+        policy => policy.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod());
+});
+var app = builder.Build();
+
+// Configure the HTTP request pipeline.
+if (app.Environment.IsDevelopment() || true) {
+    app.UseSwagger();
+    app.UseSwaggerUI();
+}
+
+app.UseCors("Open");
+app.UseExceptionHandler(exceptionHandlerApp => {
+    exceptionHandlerApp.Run(async context => {
+        var exceptionHandlerPathFeature =
+            context.Features.Get<IExceptionHandlerPathFeature>();
+        if (exceptionHandlerPathFeature?.Error is not null)
+            Console.WriteLine(exceptionHandlerPathFeature.Error.ToString()!);
+
+        if (exceptionHandlerPathFeature?.Error is MatrixException mxe) {
+            context.Response.StatusCode = mxe.ErrorCode switch {
+                "M_NOT_FOUND" => StatusCodes.Status404NotFound,
+                "M_UNAUTHORIZED" => StatusCodes.Status401Unauthorized,
+                _ => StatusCodes.Status500InternalServerError
+            };
+            context.Response.ContentType = MediaTypeNames.Application.Json;
+            await context.Response.WriteAsync(mxe.GetAsJson()!);
+        }
+        else {
+            context.Response.StatusCode = StatusCodes.Status500InternalServerError;
+            context.Response.ContentType = MediaTypeNames.Application.Json;
+            await context.Response.WriteAsync(new MatrixException() {
+                ErrorCode = "M_UNKNOWN",
+                Error = exceptionHandlerPathFeature?.Error.ToString()
+            }.GetAsJson());
+        }
+    });
+});
+
+app.UseAuthorization();
+
+app.MapControllers();
+
+app.Map("/_matrix/{*_}", (HttpContext ctx, ILogger<Program> logger) => {
+    logger.LogWarning("Client hit non-existing route: {Method} {Path}{Query}", ctx.Request.Method, ctx.Request.Path, ctx.Request.Query);
+    // Console.WriteLine($"Client hit non-existing route: {ctx.Request.Method} {ctx.Request.Path}");
+    ctx.Response.StatusCode = StatusCodes.Status404NotFound;
+    ctx.Response.ContentType = MediaTypeNames.Application.Json;
+    return ctx.Response.WriteAsJsonAsync(new MatrixException() {
+        ErrorCode = MatrixException.ErrorCodes.M_UNRECOGNISED,
+        Error = "Endpoint not implemented"
+    });
+});
+
+app.Run();
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Properties/launchSettings.json b/Utilities/LibMatrix.HomeserverEmulator/Properties/launchSettings.json
new file mode 100644
 index 0000000..4ddf341
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Properties/launchSettings.json
@@ -0,0 +1,32 @@
+{
+  "$schema": "https://json.schemastore.org/launchsettings.json",
+  "iisSettings": {
+    "windowsAuthentication": false,
+    "anonymousAuthentication": true,
+    "iisExpress": {
+      "applicationUrl": "http://localhost:9169",
+      "sslPort": 44321
+    }
+  },
+  "profiles": {
+    "Development": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": false,
+      "launchUrl": "swagger",
+      "applicationUrl": "http://localhost:5298",
+      "environmentVariables": {
+        "ASPNETCORE_ENVIRONMENT": "Development"
+      }
+    },
+    "Local": {
+      "commandName": "Project",
+      "dotnetRunMessages": true,
+      "launchBrowser": false,
+      "applicationUrl": "http://localhost:5298",
+      "environmentVariables": {
+        "DOTNET_ENVIRONMENT": "Local"
+      }
+    }
+  }
+}
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs
new file mode 100644
 index 0000000..bcfb629
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/HSEConfiguration.cs
@@ -0,0 +1,59 @@
+using System.Collections;
+using System.Diagnostics.CodeAnalysis;
+using ArcaneLibs.Extensions;
+
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class HSEConfiguration {
+    private static ILogger<HSEConfiguration> _logger;
+    public static HSEConfiguration Current { get; set; }
+
+    [RequiresUnreferencedCode("Uses reflection binding")]
+    public HSEConfiguration(ILogger<HSEConfiguration> logger, IConfiguration config, HostBuilderContext host) {
+        Current = this;
+        _logger = logger;
+        logger.LogInformation("Loading configuration for environment: {}...", host.HostingEnvironment.EnvironmentName);
+        config.GetSection("HomeserverEmulator").Bind(this);
+        if (StoreData) {
+            DataStoragePath = ExpandPath(DataStoragePath ?? throw new NullReferenceException("DataStoragePath is not set"));
+            CacheStoragePath = ExpandPath(CacheStoragePath ?? throw new NullReferenceException("CacheStoragePath is not set"));
+        }
+
+        _logger.LogInformation("Configuration loaded: {}", this.ToJson());
+    }
+
+    public string CacheStoragePath { get; set; }
+
+    public string DataStoragePath { get; set; }
+
+    public bool StoreData { get; set; } = true;
+
+    public string ServerName { get; set; } = "localhost";
+    
+    public bool UnknownSyncTokenIsInitialSync { get; set; } = true;
+
+    private static string ExpandPath(string path, bool retry = true) {
+        _logger.LogInformation("Expanding path `{}`", path);
+
+        if (path.StartsWith('~')) {
+            path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), path[1..]);
+        }
+
+        Environment.GetEnvironmentVariables().Cast<DictionaryEntry>().OrderByDescending(x => x.Key.ToString()!.Length).ToList().ForEach(x => {
+            path = path.Replace($"${x.Key}", x.Value.ToString());
+        });
+
+        _logger.LogInformation("Expanded path to `{}`", path);
+        var tries = 0;
+        while (retry && path.ContainsAnyOf("~$".Split())) {
+            if (tries++ > 100)
+                throw new Exception($"Path `{path}` contains unrecognised environment variables");
+            path = ExpandPath(path, false);
+        }
+        
+        if(path.StartsWith("./"))
+            path = Path.Join(Directory.GetCurrentDirectory(), path[2..].Replace("/", Path.DirectorySeparatorChar.ToString()));
+
+        return path;
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs
new file mode 100644
 index 0000000..00f2a42
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/MediaStore.cs
@@ -0,0 +1,64 @@
+using System.Text.Json;
+using LibMatrix.Services;
+
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class MediaStore {
+    private readonly HSEConfiguration _config;
+    private readonly HomeserverResolverService _hsResolver;
+    private List<MediaInfo> index = new();
+
+    public MediaStore(HSEConfiguration config, HomeserverResolverService hsResolver) {
+        _config = config;
+        _hsResolver = hsResolver;
+        if (config.StoreData) {
+            var path = Path.Combine(config.DataStoragePath, "media");
+            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+            if (File.Exists(Path.Combine(path, "index.json")))
+                index = JsonSerializer.Deserialize<List<MediaInfo>>(File.ReadAllText(Path.Combine(path, "index.json")));
+        }
+        else
+            Console.WriteLine("Data storage is disabled, not loading rooms from disk");
+    }
+
+    // public async Task<object> UploadMedia(string userId, string mimeType, Stream stream, string? filename = null) {
+        // var mediaId = $"mxc://{Guid.NewGuid().ToString()}";
+        // var path = Path.Combine(_config.DataStoragePath, "media", mediaId);
+        // if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+        // var file = Path.Combine(path, filename ?? "file");
+        // await using var fs = File.Create(file);
+        // await stream.CopyToAsync(fs);
+        // index.Add(new() { });
+        // return media;
+    // }
+
+    public async Task<Stream> GetRemoteMedia(string serverName, string mediaId) {
+        if (_config.StoreData) {
+            var path = Path.Combine(_config.DataStoragePath, "media", serverName, mediaId);
+            if (!File.Exists(path)) {
+                var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+                if (mediaUrl is null)
+                    throw new MatrixException() {
+                        ErrorCode = "M_NOT_FOUND",
+                        Error = "Media not found"
+                    };
+                using var client = new HttpClient();
+                var stream = await client.GetStreamAsync(mediaUrl);
+                await using var fs = File.Create(path);
+                await stream.CopyToAsync(fs);
+            }
+            return new FileStream(path, FileMode.Open);
+        }
+        else {
+            var mediaUrl = await _hsResolver.ResolveMediaUri(serverName, $"mxc://{serverName}/{mediaId}");
+            if (mediaUrl is null)
+                throw new MatrixException() {
+                    ErrorCode = "M_NOT_FOUND",
+                    Error = "Media not found"
+                };
+            using var client = new HttpClient();
+            return await client.GetStreamAsync(mediaUrl);
+        }
+    }
+    public class MediaInfo { }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs
new file mode 100644
 index 0000000..0128ba6
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/PaginationTokenResolverService.cs
@@ -0,0 +1,54 @@
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class PaginationTokenResolverService(ILogger<PaginationTokenResolverService> logger, RoomStore roomStore, UserStore userStore) {
+    public async Task<long?> ResolveTokenToTimestamp(string token) {
+        logger.LogTrace("ResolveTokenToTimestamp({token})", token);
+        if (token.StartsWith('$')) {
+            //we have an event ID
+            foreach (var room in roomStore._rooms) {
+                var evt = await ResolveTokenToEvent(token, room);
+                if (evt is not null) return evt.OriginServerTs;
+            }
+
+            // event not found
+            throw new NotImplementedException();
+        }
+        else {
+            // we have a sync token 
+            foreach (var user in userStore._users) {
+                foreach (var (_, session) in user.AccessTokens) {
+                    if (!session.SyncStates.TryGetValue(token, out var syncState)) continue;
+                    long? maxTs = 0;
+                    foreach (var room in syncState.RoomPositions) {
+                        var roomObj = roomStore.GetRoomById(room.Key);
+                        if (roomObj is null)
+                            continue;
+                        var ts = roomObj.Timeline.Last().OriginServerTs;
+                        if (ts > maxTs) maxTs = ts;
+                    }
+
+                    return maxTs;
+                }
+            }
+
+            throw new NotImplementedException();
+        }
+    }
+
+    public async Task<StateEventResponse?> ResolveTokenToEvent(string token, RoomStore.Room room) {
+        if (token.StartsWith('$')) {
+            //we have an event ID
+            logger.LogTrace("ResolveTokenToEvent(EventId({token}), Room({room})): searching for event...", token, room.RoomId);
+
+            var evt = room.Timeline.SingleOrDefault(x => x.EventId == token);
+            if (evt is not null) return evt;
+            logger.LogTrace("ResolveTokenToEvent({token}, Room({room})): event not in requested room...", token, room.RoomId);
+            return null;
+        }
+        else {
+            // we have a sync token
+            logger.LogTrace("ResolveTokenToEvent(SyncToken({token}), Room({room}))", token, room.RoomId);
+            throw new NotImplementedException();
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
new file mode 100644
 index 0000000..c798cce
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/RoomStore.cs
@@ -0,0 +1,308 @@
+using System.Collections.Concurrent;
+using System.Collections.Frozen;
+using System.Collections.Immutable;
+using System.Collections.ObjectModel;
+using System.Collections.Specialized;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using ArcaneLibs;
+using ArcaneLibs.Collections;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.HomeserverEmulator.Controllers.Rooms;
+using LibMatrix.Responses;
+
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class RoomStore {
+    private readonly ILogger<RoomStore> _logger;
+    public ConcurrentBag<Room> _rooms = new();
+    private FrozenDictionary<string, Room> _roomsById = FrozenDictionary<string, Room>.Empty;
+
+    public RoomStore(ILogger<RoomStore> logger, HSEConfiguration config) {
+        _logger = logger;
+        if (config.StoreData) {
+            var path = Path.Combine(config.DataStoragePath, "rooms");
+            if (!Directory.Exists(path)) Directory.CreateDirectory(path);
+            foreach (var file in Directory.GetFiles(path)) {
+                var room = JsonSerializer.Deserialize<Room>(File.ReadAllText(file));
+                if (room is not null) _rooms.Add(room);
+            }
+        }
+        else
+            Console.WriteLine("Data storage is disabled, not loading rooms from disk");
+
+        RebuildIndexes();
+    }
+
+    private SemaphoreSlim a = new(1, 1);
+    private void RebuildIndexes() {
+        // a.Wait();
+        // lock (_roomsById)
+        // _roomsById = new ConcurrentDictionary<string, Room>(_rooms.ToDictionary(u => u.RoomId));
+        // foreach (var room in _rooms) {
+        //     _roomsById.AddOrUpdate(room.RoomId, room, (key, old) => room);
+        // }
+        //
+        // var roomsArr = _rooms.ToArray();
+        // foreach (var (id, room) in _roomsById) {
+        //     if (!roomsArr.Any(x => x.RoomId == id))
+        //         _roomsById.TryRemove(id, out _);
+        // }
+        
+        // _roomsById = new ConcurrentDictionary<string, Room>(_rooms.ToDictionary(u => u.RoomId));
+        _roomsById = _rooms.ToFrozenDictionary(u => u.RoomId);
+
+        // a.Release();
+    }
+
+    public Room? GetRoomById(string roomId, bool createIfNotExists = false) {
+        if (_roomsById.TryGetValue(roomId, out var room)) {
+            return room;
+        }
+
+        if (!createIfNotExists)
+            return null;
+
+        return CreateRoom(new() { });
+    }
+
+    public Room CreateRoom(CreateRoomRequest request, UserStore.User? user = null) {
+        var room = new Room(roomId: $"!{Guid.NewGuid().ToString()}");
+        var newCreateEvent = new StateEvent() {
+            Type = RoomCreateEventContent.EventId,
+            RawContent = new() { }
+        };
+
+        foreach (var (key, value) in request.CreationContent) {
+            newCreateEvent.RawContent[key] = value.DeepClone();
+        }
+
+        if (user != null) {
+            newCreateEvent.RawContent["creator"] = user.UserId;
+            var createEvent = room.SetStateInternal(newCreateEvent, user: user);
+            createEvent.Sender = user.UserId;
+
+            room.SetStateInternal(new() {
+                Type = RoomMemberEventContent.EventId,
+                StateKey = user.UserId,
+                TypedContent = new RoomMemberEventContent() {
+                    Membership = "join",
+                    AvatarUrl = (user.Profile.GetOrNull("avatar_url") as JsonObject)?.GetOrNull("avatar_url")?.GetValue<string>(),
+                    DisplayName = (user.Profile.GetOrNull("displayname") as string)
+                }
+            }, user: user);
+        }
+
+        if (!string.IsNullOrWhiteSpace(request.Name))
+            room.SetStateInternal(new StateEvent() {
+                Type = RoomNameEventContent.EventId,
+                TypedContent = new RoomNameEventContent() {
+                    Name = request.Name
+                }
+            });
+
+        if (!string.IsNullOrWhiteSpace(request.RoomAliasName))
+            room.SetStateInternal(new StateEvent() {
+                Type = RoomCanonicalAliasEventContent.EventId,
+                TypedContent = new RoomCanonicalAliasEventContent() {
+                    Alias = $"#{request.RoomAliasName}:localhost"
+                }
+            });
+
+        foreach (var stateEvent in request.InitialState ?? []) {
+            room.SetStateInternal(stateEvent);
+        }
+
+        _rooms.Add(room);
+        // _roomsById.TryAdd(room.RoomId, room);
+        RebuildIndexes();
+        return room;
+    }
+
+    public Room AddRoom(Room room) {
+        _rooms.Add(room);
+        RebuildIndexes();
+
+        return room;
+    }
+
+    public class Room : NotifyPropertyChanged {
+        private CancellationTokenSource _debounceCts = new();
+        private ObservableCollection<StateEventResponse> _timeline;
+        private ObservableDictionary<string, List<StateEventResponse>> _accountData;
+        private ObservableDictionary<string, ReadMarkersData> _readMarkers;
+        private FrozenSet<StateEventResponse> _stateCache;
+        private int _timelineHash;
+
+        public Room(string roomId) {
+            if (string.IsNullOrWhiteSpace(roomId)) throw new ArgumentException("Value cannot be null or whitespace.", nameof(roomId));
+            if (roomId[0] != '!') throw new ArgumentException($"Room ID must start with '!', provided value: {roomId ?? "null"}", nameof(roomId));
+            RoomId = roomId;
+            Timeline = new();
+            AccountData = new();
+            ReadMarkers = new();
+        }
+
+        public string RoomId { get; set; }
+
+        public FrozenSet<StateEventResponse> State => _timelineHash == _timeline.GetHashCode() ? _stateCache : RebuildState();
+
+        public ObservableCollection<StateEventResponse> Timeline {
+            get => _timeline;
+            set {
+                if (Equals(value, _timeline)) return;
+                _timeline = new(value);
+                _timeline.CollectionChanged += (sender, args) => {
+                    // we dont want to do this as it's rebuilt when the state is accessed
+
+                    // if (args.Action == NotifyCollectionChangedAction.Add) {
+                    //     foreach (StateEventResponse state in args.NewItems) {
+                    //         if (state.StateKey is not null)
+                    //             // we want state to be deduplicated by type and key, and we want the latest state to be the one that is returned
+                    //             RebuildState();
+                    //     }
+                    // }
+
+                    SaveDebounced();
+                };
+                // RebuildState();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableDictionary<string, List<StateEventResponse>> AccountData {
+            get => _accountData;
+            set {
+                if (Equals(value, _accountData)) return;
+                _accountData = new(value);
+                _accountData.CollectionChanged += (sender, args) => SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ImmutableList<StateEventResponse> JoinedMembers =>
+            State.Where(s => s is { Type: RoomMemberEventContent.EventId, TypedContent: RoomMemberEventContent { Membership: "join" } }).ToImmutableList();
+
+        public ObservableDictionary<string, ReadMarkersData> ReadMarkers {
+            get => _readMarkers;
+            set {
+                if (Equals(value, _readMarkers)) return;
+                _readMarkers = new(value);
+                _readMarkers.CollectionChanged += (sender, args) => SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        internal StateEventResponse SetStateInternal(StateEvent request, string? senderId = null, UserStore.User? user = null) {
+            var state = request as StateEventResponse ?? new StateEventResponse() {
+                Type = request.Type,
+                StateKey = request.StateKey ?? "",
+                EventId = "$" + Guid.NewGuid().ToString(),
+                RoomId = RoomId,
+                OriginServerTs = DateTimeOffset.Now.ToUnixTimeMilliseconds(),
+                Sender = user?.UserId ?? senderId ?? "",
+                RawContent = request.RawContent ?? (request.TypedContent is not null
+                    ? new JsonObject()
+                    : JsonSerializer.Deserialize<JsonObject>(JsonSerializer.Serialize(request.TypedContent)))
+            };
+            Timeline.Add(state);
+            if(state.StateKey != null)
+                RebuildState();
+            return state;
+        }
+
+        public StateEventResponse AddUser(string userId) {
+            var state = SetStateInternal(new() {
+                Type = RoomMemberEventContent.EventId,
+                StateKey = userId,
+                TypedContent = new RoomMemberEventContent() {
+                    Membership = "join"
+                },
+            });
+
+            state.Sender = userId;
+            return state;
+        }
+
+        // public async Task SaveDebounced() {
+            // if (!HSEConfiguration.Current.StoreData) return;
+            // await _debounceCts.CancelAsync();
+            // _debounceCts = new CancellationTokenSource();
+            // try {
+                // await Task.Delay(250, _debounceCts.Token);
+                // // Ensure all state events are in the timeline
+                // State.Where(s => !Timeline.Contains(s)).ToList().ForEach(s => Timeline.Add(s));
+                // var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
+                // Console.WriteLine($"Saving room {RoomId} to {path}!");
+                // await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+            // }
+            // catch (TaskCanceledException) { }
+        // }
+
+        private SemaphoreSlim saveSemaphore = new(1, 1);
+
+        public async Task SaveDebounced() {
+            Task.Run(async () => {
+                await saveSemaphore.WaitAsync();
+                try {
+                    var path = Path.Combine(HSEConfiguration.Current.DataStoragePath, "rooms", $"{RoomId}.json");
+                    Console.WriteLine($"Saving room {RoomId} to {path}!");
+                    await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+                }
+                finally {
+                    saveSemaphore.Release();
+                }
+            });
+        }
+
+        private SemaphoreSlim stateRebuildSemaphore = new(1, 1);
+
+        private FrozenSet<StateEventResponse> RebuildState() {
+            stateRebuildSemaphore.Wait();
+            while (true)
+                try {
+                    Console.WriteLine($"Rebuilding state for room {RoomId}");
+                    // ReSharper disable once RedundantEnumerableCastCall - This sometimes happens when the collection is modified during enumeration
+                    List<StateEventResponse>? timeline = null;
+                    lock (_timeline) {
+                        timeline = Timeline.OfType<StateEventResponse>().ToList();
+                    }
+
+                    foreach (var evt in timeline) {
+                        if (evt == null) {
+                            throw new InvalidOperationException("Event is null");
+                        }
+
+                        if (evt.EventId == null) {
+                            evt.EventId = "$" + Guid.NewGuid();
+                        }
+                        else if (!evt.EventId.StartsWith('$')) {
+                            evt.EventId = "$" + evt.EventId;
+                            Console.WriteLine($"Sanitised invalid event ID {evt.EventId}");
+                        }
+                    }
+
+                    _stateCache = timeline //.Where(s => s.Type == state.Type && s.StateKey == state.StateKey)
+                        .Where(x => x.StateKey != null)
+                        .OrderByDescending(s => s.OriginServerTs)
+                        .DistinctBy(x => (x.Type, x.StateKey))
+                        .ToFrozenSet();
+
+                    _timelineHash = _timeline.GetHashCode();
+                    stateRebuildSemaphore.Release();
+                    return _stateCache;
+                }
+                finally { }
+        }
+    }
+
+    public List<StateEventResponse> GetRoomsByMember(string userId) {
+        // return _rooms
+        // // .Where(r => r.State.Any(s => s.Type == RoomMemberEventContent.EventId && s.StateKey == userId))
+        // .Select(r => (Room: r, MemberEvent: r.State.SingleOrDefault(s => s.Type == RoomMemberEventContent.EventId && s.StateKey == userId)))
+        // .Where(r => r.MemberEvent != null)
+        // .ToDictionary(x => x.Room, x => x.MemberEvent!);
+        return _rooms.SelectMany(r => r.State.Where(s => s.Type == RoomMemberEventContent.EventId && s.StateKey == userId)).ToList();
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/TokenService.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/TokenService.cs
new file mode 100644
 index 0000000..cf79aae
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/TokenService.cs
@@ -0,0 +1,29 @@
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class TokenService{
+    public string? GetAccessTokenOrNull(HttpContext ctx) {
+        //qry
+        if (ctx.Request.Query.TryGetValue("access_token", out var token)) {
+            return token;
+        }
+        //header
+        if (ctx.Request.Headers.TryGetValue("Authorization", out var auth)) {
+            var parts = auth.ToString().Split(' ');
+            if (parts is ["Bearer", _]) {
+                return parts[1];
+            }
+        }
+        return null;
+    }
+
+    public string GetAccessToken(HttpContext ctx) {
+        return GetAccessTokenOrNull(ctx) ?? throw new MatrixException() {
+            ErrorCode = MatrixException.ErrorCodes.M_UNKNOWN_TOKEN,
+            Error = "Missing token"
+        };
+    }
+
+    public string? GenerateServerName(HttpContext ctx) {
+        return ctx.Request.Host.ToString();
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs b/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs
new file mode 100644
 index 0000000..4684b01
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/Services/UserStore.cs
@@ -0,0 +1,273 @@
+using System.Collections.Concurrent;
+using System.Collections.ObjectModel;
+using System.Text.Json;
+using System.Text.Json.Nodes;
+using ArcaneLibs;
+using ArcaneLibs.Collections;
+using ArcaneLibs.Extensions;
+using LibMatrix.EventTypes.Spec.State;
+using LibMatrix.Filters;
+using LibMatrix.Responses;
+
+namespace LibMatrix.HomeserverEmulator.Services;
+
+public class UserStore {
+    public ConcurrentBag<User> _users = new();
+    private readonly HSEConfiguration _config;
+    private readonly RoomStore _roomStore;
+
+    public UserStore(HSEConfiguration config, RoomStore roomStore) {
+        _config = config;
+        _roomStore = roomStore;
+        if (config.StoreData) {
+            var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users");
+            if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
+            foreach (var userId in Directory.GetDirectories(dataDir)) {
+                var tokensDir = Path.Combine(dataDir, userId, "tokens.json");
+                var path = Path.Combine(dataDir, userId, $"user.json");
+
+                var user = JsonSerializer.Deserialize<User>(File.ReadAllText(path));
+                user!.AccessTokens = JsonSerializer.Deserialize<ObservableDictionary<string, User.SessionInfo>>(File.ReadAllText(tokensDir))!;
+                _users.Add(user);
+            }
+
+            Console.WriteLine($"Loaded {_users.Count} users from disk");
+        }
+        else {
+            Console.WriteLine("Data storage is disabled, not loading users from disk");
+        }
+    }
+
+    public async Task<User?> GetUserById(string userId, bool createIfNotExists = false) {
+        if (_users.Any(x => x.UserId == userId))
+            return _users.First(x => x.UserId == userId);
+
+        if (!createIfNotExists)
+            return null;
+
+        return await CreateUser(userId);
+    }
+
+    public async Task<User?> GetUserByTokenOrNull(string token, bool createIfNotExists = false, string? serverName = null) {
+        if (_users.Any(x => x.AccessTokens.ContainsKey(token)))
+            return _users.First(x => x.AccessTokens.ContainsKey(token));
+
+        if (!createIfNotExists)
+            return null;
+        if (string.IsNullOrWhiteSpace(serverName)) throw new NullReferenceException("Server name was not passed");
+        var uid = $"@{Guid.NewGuid().ToString()}:{serverName}";
+        return await CreateUser(uid);
+    }
+
+    public async Task<User> GetUserByToken(string token, bool createIfNotExists = false, string? serverName = null) {
+        return await GetUserByTokenOrNull(token, createIfNotExists, serverName) ?? throw new MatrixException() {
+            ErrorCode = MatrixException.ErrorCodes.M_UNKNOWN_TOKEN,
+            Error = "Invalid token."
+        };
+    }
+
+    public async Task<User> CreateUser(string userId, Dictionary<string, object>? profile = null, string kind = "user") {
+        profile ??= new();
+        var parts = userId.Split(":");
+        var localPart = parts[0].TrimStart('@');
+        if (!profile.ContainsKey("displayname")) profile.Add("displayname", localPart);
+        if (!profile.ContainsKey("avatar_url")) profile.Add("avatar_url", null);
+        var user = new User() {
+            UserId = $"@{localPart}:{_config.ServerName}",
+            IsGuest = kind == "guest",
+            AccountData = new() {
+                new StateEventResponse() {
+                    Type = "im.vector.analytics",
+                    RawContent = new JsonObject() {
+                        ["pseudonymousAnalyticsOptIn"] = false
+                    },
+                },
+                new StateEventResponse() {
+                    Type = "im.vector.web.settings",
+                    RawContent = new JsonObject() {
+                        ["developerMode"] = true,
+                        ["alwaysShowTimestamps"] = true,
+                        ["SpotlightSearch.showNsfwPublicRooms"] = true,
+                        
+                    }
+                },
+                new() {
+                    Type = "im.vector.setting.integration_provisioning",
+                    RawContent = new JsonObject() {
+                        ["enabled"] = false
+                    }
+                },
+                new() {
+                    Type = "m.identity_server",
+                    RawContent = new JsonObject() {
+                        ["base_url"] = null
+                    }
+                },
+            }
+        };
+        user.Profile.AddRange(profile);
+        _users.Add(user);
+        if (!_roomStore._rooms.IsEmpty)
+            foreach (var item in Random.Shared.GetItems(_roomStore._rooms.ToArray(), Math.Min(_roomStore._rooms.Count, 400))) {
+                item.AddUser(userId);
+            }
+
+        int random = Random.Shared.Next(10);
+        for (int i = 0; i < random; i++) {
+            var room = _roomStore.CreateRoom(new());
+            room.AddUser(userId);
+        }
+
+        return user;
+    }
+
+    public class User : NotifyPropertyChanged {
+        public User() {
+            AccessTokens = new();
+            Filters = new();
+            Profile = new();
+            AccountData = new();
+            RoomKeys = new();
+            AuthorizedSessions = new();
+        }
+
+        private CancellationTokenSource _debounceCts = new();
+        private string _userId;
+        private ObservableDictionary<string, SessionInfo> _accessTokens;
+        private ObservableDictionary<string, SyncFilter> _filters;
+        private ObservableDictionary<string, object> _profile;
+        private ObservableCollection<StateEventResponse> _accountData;
+        private ObservableDictionary<string, RoomKeysResponse> _roomKeys;
+        private ObservableDictionary<string, AuthorizedSession> _authorizedSessions;
+
+        public string UserId {
+            get => _userId;
+            set => SetField(ref _userId, value);
+        }
+
+        public ObservableDictionary<string, SessionInfo> AccessTokens {
+            get => _accessTokens;
+            set {
+                if (value == _accessTokens) return;
+                _accessTokens = new(value);
+                _accessTokens.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableDictionary<string, SyncFilter> Filters {
+            get => _filters;
+            set {
+                if (value == _filters) return;
+                _filters = new(value);
+                _filters.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableDictionary<string, object> Profile {
+            get => _profile;
+            set {
+                if (value == _profile) return;
+                _profile = new(value);
+                _profile.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableCollection<StateEventResponse> AccountData {
+            get => _accountData;
+            set {
+                if (value == _accountData) return;
+                _accountData = new(value);
+                _accountData.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableDictionary<string, RoomKeysResponse> RoomKeys {
+            get => _roomKeys;
+            set {
+                if (value == _roomKeys) return;
+                _roomKeys = new(value);
+                _roomKeys.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public ObservableDictionary<string, AuthorizedSession> AuthorizedSessions {
+            get => _authorizedSessions;
+            set {
+                if (value == _authorizedSessions) return;
+                _authorizedSessions = new(value);
+                _authorizedSessions.CollectionChanged += async (sender, args) => await SaveDebounced();
+                OnPropertyChanged();
+            }
+        }
+
+        public bool IsGuest { get; set; }
+
+        public async Task SaveDebounced() {
+            if (!HSEConfiguration.Current.StoreData) return;
+            await _debounceCts.CancelAsync();
+            _debounceCts = new CancellationTokenSource();
+            try {
+                await Task.Delay(250, _debounceCts.Token);
+                var dataDir = Path.Combine(HSEConfiguration.Current.DataStoragePath, "users", _userId);
+                if (!Directory.Exists(dataDir)) Directory.CreateDirectory(dataDir);
+                var tokensDir = Path.Combine(dataDir, "tokens.json");
+                var path = Path.Combine(dataDir, $"user.json");
+                Console.WriteLine($"Saving user {_userId} to {path}!");
+                await File.WriteAllTextAsync(path, this.ToJson(ignoreNull: true));
+                await File.WriteAllTextAsync(tokensDir, AccessTokens.ToJson(ignoreNull: true));
+            }
+            catch (TaskCanceledException) { }
+            catch (InvalidOperationException) { } // We don't care about 100% data safety, this usually happens when something is updated while serialising
+        }
+
+        public class SessionInfo {
+            public string DeviceId { get; set; } = Guid.NewGuid().ToString();
+            public string DeviceName { get; set; } = "Unnamed device";
+            public Dictionary<string, UserSyncState> SyncStates { get; set; } = new();
+
+            public class UserSyncState {
+                public Dictionary<string, SyncRoomPosition> RoomPositions { get; set; } = new();
+                public string FilterId { get; set; }
+                public DateTime SyncStateCreated { get; set; } = DateTime.Now;
+
+                public class SyncRoomPosition {
+                    public int TimelinePosition { get; set; }
+                    public string LastTimelineEventId { get; set; }
+                    public int AccountDataPosition { get; set; }
+                    public bool Joined { get; set; }
+                }
+
+                public UserSyncState Clone() {
+                    return new() {
+                        FilterId = FilterId,
+                        RoomPositions = RoomPositions.ToDictionary(x => x.Key, x => new SyncRoomPosition() {
+                            TimelinePosition = x.Value.TimelinePosition,
+                            AccountDataPosition = x.Value.AccountDataPosition
+                        })
+                    };
+                }
+            }
+        }
+
+        public LoginResponse Login() {
+            var session = new SessionInfo();
+            AccessTokens.Add(Guid.NewGuid().ToString(), session);
+            SaveDebounced();
+            return new LoginResponse() {
+                AccessToken = AccessTokens.Keys.Last(),
+                DeviceId = session.DeviceId,
+                UserId = UserId
+            };
+        }
+
+        public class AuthorizedSession {
+            public string Homeserver { get; set; }
+            public string AccessToken { get; set; }
+        }
+    }
+}
\ No newline at end of file
diff --git a/Utilities/LibMatrix.HomeserverEmulator/appsettings.Development.json b/Utilities/LibMatrix.HomeserverEmulator/appsettings.Development.json
new file mode 100644
 index 0000000..f14522d
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/appsettings.Development.json
@@ -0,0 +1,12 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Information",
+      "Microsoft.AspNetCore.Routing": "Warning",
+      "Microsoft.AspNetCore.Mvc": "Warning"
+    }
+  },
+  "HomeserverEmulator": {
+  }
+}
diff --git a/Utilities/LibMatrix.HomeserverEmulator/appsettings.json b/Utilities/LibMatrix.HomeserverEmulator/appsettings.json
new file mode 100644
 index 0000000..b16968a
--- /dev/null
+++ b/Utilities/LibMatrix.HomeserverEmulator/appsettings.json
@@ -0,0 +1,41 @@
+{
+  "Logging": {
+    "LogLevel": {
+      "Default": "Information",
+      "Microsoft.AspNetCore": "Warning"
+    }
+  },
+  "AllowedHosts": "*",
+  // Configuration for the proxy
+  "MxApiExtensions": {
+    // WARNING: this exposes user tokens to servers listed here, which could be a security risk
+    // Only list servers you trust!
+    // Keep in mind that token conflicts can occur between servers!
+    "AuthHomeservers": [
+      "rory.gay",
+      "conduit.rory.gay"
+    ],
+    // List of administrator MXIDs for the proxy, this allows them to use administrative and debug endpoints
+    "Admins": [
+      "@emma:rory.gay",
+      "@emma:conduit.rory.gay"
+    ],
+    "FastInitialSync": {
+      "Enabled": true,
+      "UseRoomInfoCache": true
+    },
+    "Cache": {
+      "RoomInfo": {
+        "BaseTtl": "00:01:00",
+        "ExtraTtlPerState": "00:00:00.1000000"
+      }
+    },
+    "DefaultUserConfiguration": {
+      "ProtocolChanges": {
+        "DisableThreads": false,
+        "DisableVoip": false,
+        "AutoFollowTombstones": false
+      }
+    }
+  }
+}
  |