From 2520a9ed945fce558fbe140acc546c1fa7f7fe69 Mon Sep 17 00:00:00 2001 From: martin Date: Sat, 18 Nov 2023 23:47:55 +0100 Subject: [PATCH 1/5] Updated dependencies and project to C# 12 Added primary constructors and many other refactorings --- BackendTests/BackendTests.csproj | 20 ++-- .../Controllers/GameControllerTests.cs | 22 ++++ BackendTests/Services/ActionServiceTests.cs | 23 +--- .../Services/WebSocketServiceTests.cs | 1 - DataAccessLayer/DataAccessLayer.csproj | 1 + pac-man-board-game/ClientApp/package.json | 2 +- .../Controllers/GameController.cs | 80 +++++++------ .../Controllers/GenericController.cs | 33 ++---- .../Controllers/PlayerController.cs | 14 +-- .../Controllers/WsController.cs | 7 +- pac-man-board-game/DTOs/DTO.cs | 50 ++++++++ .../Exceptions/GameExceptions.cs | 5 + .../Exceptions/GameNotFoundException.cs | 6 - .../Exceptions/GameNotPlayableException.cs | 6 - .../Exceptions/PlayerExceptions.cs | 3 + .../Exceptions/PlayerNotFoundException.cs | 6 - pac-man-board-game/GameStuff/Actions.cs | 2 +- pac-man-board-game/GameStuff/Items/Box.cs | 13 +- pac-man-board-game/GameStuff/Items/DiceCup.cs | 13 +- pac-man-board-game/GameStuff/Rules.cs | 2 +- .../Interfaces/IWebSocketService.cs | 10 -- pac-man-board-game/Program.cs | 2 +- pac-man-board-game/Services/ActionService.cs | 111 ++++-------------- pac-man-board-game/Services/Game.cs | 13 +- pac-man-board-game/Services/GameService.cs | 18 ++- .../Services/WebSocketService.cs | 23 ++-- pac-man-board-game/Utils/Extensions.cs | 2 +- pac-man-board-game/pac-man-board-game.csproj | 63 +++++----- 28 files changed, 266 insertions(+), 285 deletions(-) create mode 100644 pac-man-board-game/DTOs/DTO.cs create mode 100644 pac-man-board-game/Exceptions/GameExceptions.cs delete mode 100644 pac-man-board-game/Exceptions/GameNotFoundException.cs delete mode 100644 pac-man-board-game/Exceptions/GameNotPlayableException.cs create mode 100644 pac-man-board-game/Exceptions/PlayerExceptions.cs delete mode 100644 pac-man-board-game/Exceptions/PlayerNotFoundException.cs delete mode 100644 pac-man-board-game/Interfaces/IWebSocketService.cs diff --git a/BackendTests/BackendTests.csproj b/BackendTests/BackendTests.csproj index 3ad8c64..f95e2a7 100644 --- a/BackendTests/BackendTests.csproj +++ b/BackendTests/BackendTests.csproj @@ -6,25 +6,27 @@ enable false + + 12 - - - - + + + + - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/BackendTests/Controllers/GameControllerTests.cs b/BackendTests/Controllers/GameControllerTests.cs index 64b75e0..3e236cb 100644 --- a/BackendTests/Controllers/GameControllerTests.cs +++ b/BackendTests/Controllers/GameControllerTests.cs @@ -51,4 +51,26 @@ public void Run_ReturnsSame() else Assert.Fail("Result is not an ArraySegment"); } + + #region DoAction(ActionMessage message) + + [Test] + public void DoAction_NegativeAction() + { + const string data = "Nothing happens"; + var message = new ActionMessage { Action = (GameAction)(-1), Data = data }; + _controller.DoAction(message); + Assert.That(message.Data, Is.EqualTo(data)); + } + + [Test] + public void DoAction_OutOfBoundsAction() + { + const string data = "Nothing happens"; + var message = new ActionMessage { Action = (GameAction)100, Data = data }; + _controller.DoAction(message); + Assert.That(message.Data, Is.EqualTo(data)); + } + + #endregion } diff --git a/BackendTests/Services/ActionServiceTests.cs b/BackendTests/Services/ActionServiceTests.cs index 503fbd5..1c8a791 100644 --- a/BackendTests/Services/ActionServiceTests.cs +++ b/BackendTests/Services/ActionServiceTests.cs @@ -2,6 +2,7 @@ using BackendTests.TestUtils; using Microsoft.Extensions.Logging; using NSubstitute; +using pacMan.DTOs; using pacMan.Exceptions; using pacMan.GameStuff; using pacMan.GameStuff.Items; @@ -99,28 +100,6 @@ public void PlayerInfo_DataIsUsernameAndGameId() #endregion - #region DoAction(ActionMessage message) - - [Test] - public void DoAction_NegativeAction() - { - const string data = "Nothing happens"; - var message = new ActionMessage { Action = (GameAction)(-1), Data = data }; - _service.DoAction(message); - Assert.That(message.Data, Is.EqualTo(data)); - } - - [Test] - public void DoAction_OutOfBoundsAction() - { - const string data = "Nothing happens"; - var message = new ActionMessage { Action = (GameAction)100, Data = data }; - _service.DoAction(message); - Assert.That(message.Data, Is.EqualTo(data)); - } - - #endregion - #region Ready() [Test] diff --git a/BackendTests/Services/WebSocketServiceTests.cs b/BackendTests/Services/WebSocketServiceTests.cs index 2c740f0..5a712f6 100644 --- a/BackendTests/Services/WebSocketServiceTests.cs +++ b/BackendTests/Services/WebSocketServiceTests.cs @@ -1,7 +1,6 @@ using System.Net.WebSockets; using Microsoft.Extensions.Logging; using NSubstitute; -using pacMan.Interfaces; using pacMan.Services; using pacMan.Utils; diff --git a/DataAccessLayer/DataAccessLayer.csproj b/DataAccessLayer/DataAccessLayer.csproj index ae25253..dd09258 100644 --- a/DataAccessLayer/DataAccessLayer.csproj +++ b/DataAccessLayer/DataAccessLayer.csproj @@ -5,6 +5,7 @@ enable enable DAL + 12 diff --git a/pac-man-board-game/ClientApp/package.json b/pac-man-board-game/ClientApp/package.json index 55e979b..f24f8c8 100644 --- a/pac-man-board-game/ClientApp/package.json +++ b/pac-man-board-game/ClientApp/package.json @@ -43,7 +43,7 @@ "serve": "vite preview", "test": "cross-env CI=true vitest", "coverage": "vitest run --coverage", - "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}\"" + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,css,md}\"" }, "browserslist": { "production": [ diff --git a/pac-man-board-game/Controllers/GameController.cs b/pac-man-board-game/Controllers/GameController.cs index 4a289db..457700f 100644 --- a/pac-man-board-game/Controllers/GameController.cs +++ b/pac-man-board-game/Controllers/GameController.cs @@ -1,5 +1,6 @@ using System.Net.WebSockets; using Microsoft.AspNetCore.Mvc; +using pacMan.DTOs; using pacMan.Exceptions; using pacMan.GameStuff; using pacMan.GameStuff.Items; @@ -10,35 +11,26 @@ namespace pacMan.Controllers; [ApiController] [Route("api/[controller]")] -public class GameController : GenericController +public class GameController(ILogger logger, IGameService webSocketService, IActionService actionService) + : GenericController(logger, webSocketService) { - private readonly IActionService _actionService; - private readonly GameService _gameService; + [HttpGet("[action]")] + public override async Task Connect() => await base.Connect(); - public GameController(ILogger logger, GameService webSocketService, IActionService actionService) : - base(logger, webSocketService) + [HttpGet("[action]")] + public IEnumerable All() { - _gameService = webSocketService; - _actionService = actionService; + Logger.LogDebug("Returning all games"); + return webSocketService.Games; } - [HttpGet("connect")] - public override async Task Accept() => await base.Accept(); - - [HttpGet("all")] - public IEnumerable GetAllGames() - { - Logger.Log(LogLevel.Debug, "Returning all games"); - return _gameService.Games; - } - - [HttpPost("join/{gameId:guid}")] - public IActionResult JoinGame(Guid gameId, [FromBody] Player player) // TODO what if player is in a game already? + [HttpPost("[action]/{gameId:guid}")] + public IActionResult Join(Guid gameId, [FromBody] Player player) // TODO what if player is in a game already? { - Logger.Log(LogLevel.Debug, "Joining game {}", gameId); + Logger.LogDebug("Joining game {}", gameId); try { - _gameService.JoinById(gameId, player); + webSocketService.JoinById(gameId, player); return Ok("Game joined successfully"); } catch (GameNotFoundException e) @@ -51,20 +43,20 @@ public IEnumerable GetAllGames() } } - [HttpGet("exists/{gameId:guid}")] - public IActionResult GameExists(Guid gameId) + [HttpGet("[action]/{gameId:guid}")] + public IActionResult Exists(Guid gameId) { - Logger.Log(LogLevel.Debug, "Checking if game {} exists", gameId); - return _gameService.Games.Any(game => game.Id == gameId) ? Ok() : NotFound(); + Logger.LogDebug("Checking if game {} exists", gameId); + return webSocketService.Games.Any(game => game.Id == gameId) ? Ok() : NotFound(); } - [HttpPost("create")] - public IActionResult CreateGame([FromBody] CreateGameData data) + [HttpPost("[action]")] + public IActionResult Create([FromBody] CreateGameData data) { - Logger.Log(LogLevel.Debug, "Creating game"); + Logger.LogDebug("Creating game"); try { - var game = _gameService.CreateAndJoin(data.Player, data.Spawns); + var game = webSocketService.CreateAndJoin(data.Player, data.Spawns); return Created($"/{game.Id}", game); } catch (Exception e) @@ -75,7 +67,7 @@ public IActionResult CreateGame([FromBody] CreateGameData data) protected override Task Echo() { - _actionService.WebSocket = WebSocket ?? throw new NullReferenceException("WebSocket is null"); + actionService.WebSocket = WebSocket ?? throw new NullReferenceException("WebSocket is null"); return base.Echo(); } @@ -83,16 +75,16 @@ protected override ArraySegment Run(WebSocketReceiveResult result, byte[] { var stringResult = data.GetString(result.Count); - Logger.Log(LogLevel.Information, "Received: {}", stringResult); + Logger.LogInformation("Received: {}", stringResult); var action = ActionMessage.FromJson(stringResult); try { - _actionService.DoAction(action); + DoAction(action); } catch (Exception e) { - Logger.Log(LogLevel.Error, "{}", e.Message); + Logger.LogError("{}", e.Message); action = new ActionMessage { Action = GameAction.Error, Data = e.Message }; } @@ -101,15 +93,27 @@ protected override ArraySegment Run(WebSocketReceiveResult result, byte[] protected override async void Send(ArraySegment segment) { - if (_actionService.Game is not null) - _actionService.SendToAll(segment); + if (actionService.Game is not null) + actionService.SendToAll(segment); else if (WebSocket is not null) - await _gameService.Send(WebSocket, segment); + await webSocketService.Send(WebSocket, segment); } protected override ArraySegment? Disconnect() => - new ActionMessage { Action = GameAction.Disconnect, Data = _actionService.Disconnect() } + new ActionMessage { Action = GameAction.Disconnect, Data = actionService.Disconnect() } .ToArraySegment(); - protected override void SendDisconnectMessage(ArraySegment segment) => _actionService.SendToAll(segment); + protected override void SendDisconnectMessage(ArraySegment segment) => actionService.SendToAll(segment); + + public void DoAction(ActionMessage message) => + message.Data = message.Action switch + { + GameAction.RollDice => actionService.RollDice(), + GameAction.MoveCharacter => actionService.HandleMoveCharacter(message.Data), + GameAction.JoinGame => actionService.FindGame(message.Data), + GameAction.Ready => actionService.Ready(), + GameAction.NextPlayer => actionService.FindNextPlayer(), + GameAction.Disconnect => actionService.LeaveGame(), + _ => message.Data + }; } diff --git a/pac-man-board-game/Controllers/GenericController.cs b/pac-man-board-game/Controllers/GenericController.cs index 8fcee00..1a3f865 100644 --- a/pac-man-board-game/Controllers/GenericController.cs +++ b/pac-man-board-game/Controllers/GenericController.cs @@ -1,29 +1,22 @@ using System.Net.WebSockets; using Microsoft.AspNetCore.Mvc; -using pacMan.Interfaces; +using pacMan.Services; namespace pacMan.Controllers; -public abstract class GenericController : ControllerBase +public abstract class GenericController(ILogger logger, IWebSocketService webSocketService) + : ControllerBase { private const int BufferSize = 1024 * 4; - private readonly IWebSocketService _webSocketService; - protected readonly ILogger Logger; + protected readonly ILogger Logger = logger; protected WebSocket? WebSocket; - protected GenericController(ILogger logger, IWebSocketService webSocketService) - { - Logger = logger; - _webSocketService = webSocketService; - Logger.Log(LogLevel.Debug, "WebSocket Controller created"); - } - - public virtual async Task Accept() + public virtual async Task Connect() { if (HttpContext.WebSockets.IsWebSocketRequest) { using var webSocket = await HttpContext.WebSockets.AcceptWebSocketAsync(); - Logger.Log(LogLevel.Information, "WebSocket connection established to {}", HttpContext.Connection.Id); + Logger.LogInformation("WebSocket connection established to {}", HttpContext.Connection.Id); WebSocket = webSocket; await Echo(); } @@ -35,14 +28,14 @@ public virtual async Task Accept() protected virtual async Task Echo() { - if (WebSocket == null) return; + if (WebSocket is null) return; try { WebSocketReceiveResult? result; do { var buffer = new byte[BufferSize]; - result = await _webSocketService.Receive(WebSocket, buffer); + result = await webSocketService.Receive(WebSocket, buffer); if (result.CloseStatus.HasValue) break; @@ -52,21 +45,21 @@ protected virtual async Task Echo() } while (true); var disconnectSegment = Disconnect(); - if (disconnectSegment != null) + if (disconnectSegment is not null) SendDisconnectMessage((ArraySegment)disconnectSegment); - await _webSocketService.Close(WebSocket, result.CloseStatus.Value, result.CloseStatusDescription); + await webSocketService.Close(WebSocket, result.CloseStatus.Value, result.CloseStatusDescription); } catch (WebSocketException e) { - Logger.Log(LogLevel.Error, "{}", e.Message); + Logger.LogError("{}", e.Message); } } protected virtual async void Send(ArraySegment segment) { - if (WebSocket == null) return; - await _webSocketService.Send(WebSocket, segment); + if (WebSocket is null) return; + await webSocketService.Send(WebSocket, segment); } protected abstract ArraySegment Run(WebSocketReceiveResult result, byte[] data); diff --git a/pac-man-board-game/Controllers/PlayerController.cs b/pac-man-board-game/Controllers/PlayerController.cs index fa82298..dd8558a 100644 --- a/pac-man-board-game/Controllers/PlayerController.cs +++ b/pac-man-board-game/Controllers/PlayerController.cs @@ -6,21 +6,17 @@ namespace pacMan.Controllers; [ApiController] -[Route("api/[controller]")] -public class PlayerController : ControllerBase +[Route("api/[controller]/[action]")] +public class PlayerController(UserService userService) : ControllerBase { - private readonly UserService _userService; - - public PlayerController(UserService userService) => _userService = userService; - - [HttpPost("login")] + [HttpPost] public async Task Login([FromBody] User user) { - var result = await _userService.Login(user.Username, user.Password); + var result = await userService.Login(user.Username, user.Password); if (result is null) return Unauthorized("Invalid username or password"); return Ok((Player)result); } - [HttpPost("register")] + [HttpPost] public async Task Register([FromBody] User user) => throw new NotSupportedException(); } diff --git a/pac-man-board-game/Controllers/WsController.cs b/pac-man-board-game/Controllers/WsController.cs index 9767421..b340214 100644 --- a/pac-man-board-game/Controllers/WsController.cs +++ b/pac-man-board-game/Controllers/WsController.cs @@ -6,12 +6,11 @@ namespace pacMan.Controllers; [ApiController] [Route("api/[controller]")] -public class WsController : GenericController +public class WsController(ILogger logger, IWebSocketService gameService) : + GenericController(logger, gameService) { - public WsController(ILogger logger, GameService gameService) : base(logger, gameService) { } - [HttpGet] - public override async Task Accept() => await base.Accept(); + public override async Task Connect() => await base.Connect(); protected override ArraySegment Run(WebSocketReceiveResult result, byte[] data) { diff --git a/pac-man-board-game/DTOs/DTO.cs b/pac-man-board-game/DTOs/DTO.cs new file mode 100644 index 0000000..8cb82f8 --- /dev/null +++ b/pac-man-board-game/DTOs/DTO.cs @@ -0,0 +1,50 @@ +using System.Text.Json.Serialization; +using pacMan.GameStuff; +using pacMan.GameStuff.Items; + +namespace pacMan.DTOs; + +public readonly record struct JoinGameData( + [property: JsonInclude] + [property: JsonPropertyName("username")] + string Username, + [property: JsonInclude] + [property: JsonPropertyName("gameId")] + Guid GameId +) +{ + public void Deconstruct(out string username, out Guid gameId) => (username, gameId) = (Username, GameId); +} + +public readonly record struct CreateGameData( + [property: JsonInclude] + [property: JsonPropertyName("player")] + Player Player, + [property: JsonInclude] + [property: JsonPropertyName("spawns")] + Queue Spawns +); + +public readonly record struct ReadyData( + [property: JsonInclude] + [property: JsonPropertyName("allReady")] + bool AllReady, + [property: JsonInclude] + [property: JsonPropertyName("players")] + IEnumerable Players +); + +public readonly record struct MovePlayerData( + [property: JsonInclude] + [property: JsonPropertyName("players")] + List Players, + [property: JsonInclude] + [property: JsonPropertyName("ghosts")] + List Ghosts, + [property: JsonInclude] + [property: JsonPropertyName("dice")] + List Dice, + [property: JsonInclude] + [property: JsonPropertyName("eatenPellets")] + List EatenPellets +); diff --git a/pac-man-board-game/Exceptions/GameExceptions.cs b/pac-man-board-game/Exceptions/GameExceptions.cs new file mode 100644 index 0000000..2998ec2 --- /dev/null +++ b/pac-man-board-game/Exceptions/GameExceptions.cs @@ -0,0 +1,5 @@ +namespace pacMan.Exceptions; + +public class GameNotFoundException(string message = "Game not found") : Exception(message); + +public class GameNotPlayableException(string message = "Game is not allowed to be played") : Exception(message); diff --git a/pac-man-board-game/Exceptions/GameNotFoundException.cs b/pac-man-board-game/Exceptions/GameNotFoundException.cs deleted file mode 100644 index 62b3cc2..0000000 --- a/pac-man-board-game/Exceptions/GameNotFoundException.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace pacMan.Exceptions; - -public class GameNotFoundException : Exception -{ - public GameNotFoundException(string message = "Game not found") : base(message) { } -} diff --git a/pac-man-board-game/Exceptions/GameNotPlayableException.cs b/pac-man-board-game/Exceptions/GameNotPlayableException.cs deleted file mode 100644 index 6f4a840..0000000 --- a/pac-man-board-game/Exceptions/GameNotPlayableException.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace pacMan.Exceptions; - -public class GameNotPlayableException : Exception -{ - public GameNotPlayableException(string message = "Game is not allowed to be played") : base(message) { } -} diff --git a/pac-man-board-game/Exceptions/PlayerExceptions.cs b/pac-man-board-game/Exceptions/PlayerExceptions.cs new file mode 100644 index 0000000..2a3a52b --- /dev/null +++ b/pac-man-board-game/Exceptions/PlayerExceptions.cs @@ -0,0 +1,3 @@ +namespace pacMan.Exceptions; + +public class PlayerNotFoundException(string? message = "Player not found") : Exception(message); diff --git a/pac-man-board-game/Exceptions/PlayerNotFoundException.cs b/pac-man-board-game/Exceptions/PlayerNotFoundException.cs deleted file mode 100644 index ababc79..0000000 --- a/pac-man-board-game/Exceptions/PlayerNotFoundException.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace pacMan.Exceptions; - -public class PlayerNotFoundException : Exception -{ - public PlayerNotFoundException(string? message = "Player not found") : base(message) { } -} diff --git a/pac-man-board-game/GameStuff/Actions.cs b/pac-man-board-game/GameStuff/Actions.cs index 2464e25..acfd6a3 100644 --- a/pac-man-board-game/GameStuff/Actions.cs +++ b/pac-man-board-game/GameStuff/Actions.cs @@ -23,4 +23,4 @@ public class ActionMessage public static ActionMessage FromJson(string json) => JsonSerializer.Deserialize(json)!; } -public class ActionMessage : ActionMessage { } +public class ActionMessage : ActionMessage; diff --git a/pac-man-board-game/GameStuff/Items/Box.cs b/pac-man-board-game/GameStuff/Items/Box.cs index 4041e71..c0749ff 100644 --- a/pac-man-board-game/GameStuff/Items/Box.cs +++ b/pac-man-board-game/GameStuff/Items/Box.cs @@ -4,10 +4,17 @@ namespace pacMan.GameStuff.Items; public class Box : IEquatable { - [JsonPropertyName("pellets")] public int Pellets { get; init; } - [JsonPropertyName("powerPellets")] public int PowerPellet { get; init; } + [JsonInclude] + [JsonPropertyName("pellets")] + public int Pellets { get; init; } - [JsonPropertyName("colour")] public required string Colour { get; init; } + [JsonInclude] + [JsonPropertyName("powerPellets")] + public int PowerPellet { get; init; } + + [JsonInclude] + [JsonPropertyName("colour")] + public required string Colour { get; init; } public bool Equals(Box? other) { diff --git a/pac-man-board-game/GameStuff/Items/DiceCup.cs b/pac-man-board-game/GameStuff/Items/DiceCup.cs index 1e624a0..40bdf99 100644 --- a/pac-man-board-game/GameStuff/Items/DiceCup.cs +++ b/pac-man-board-game/GameStuff/Items/DiceCup.cs @@ -4,14 +4,11 @@ namespace pacMan.GameStuff.Items; public class DiceCup { - private readonly List _dices; - - public DiceCup() => - _dices = new List - { - new(), - new() - }; + private readonly List _dices = new() + { + new Dice(), + new Dice() + }; [JsonInclude] public List Values => _dices.Select(dice => dice.Value).ToList(); diff --git a/pac-man-board-game/GameStuff/Rules.cs b/pac-man-board-game/GameStuff/Rules.cs index 45d8154..5052cc4 100644 --- a/pac-man-board-game/GameStuff/Rules.cs +++ b/pac-man-board-game/GameStuff/Rules.cs @@ -1,6 +1,6 @@ namespace pacMan.GameStuff; -public class Rules +public static class Rules { public const int MinPlayers = 2; public const int MaxPlayers = 4; diff --git a/pac-man-board-game/Interfaces/IWebSocketService.cs b/pac-man-board-game/Interfaces/IWebSocketService.cs deleted file mode 100644 index 52cf1fc..0000000 --- a/pac-man-board-game/Interfaces/IWebSocketService.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System.Net.WebSockets; - -namespace pacMan.Interfaces; - -public interface IWebSocketService -{ - Task Send(WebSocket webSocket, ArraySegment segment); - Task Receive(WebSocket webSocket, byte[] buffer); - Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string? closeStatusDescription); -} diff --git a/pac-man-board-game/Program.cs b/pac-man-board-game/Program.cs index 07d04a5..4b4476e 100644 --- a/pac-man-board-game/Program.cs +++ b/pac-man-board-game/Program.cs @@ -1,5 +1,4 @@ using DAL.Database.Service; -using pacMan.Interfaces; using pacMan.Services; var builder = WebApplication.CreateBuilder(args); @@ -8,6 +7,7 @@ builder.Services.AddControllersWithViews(); builder.Services + .AddSingleton() .AddSingleton() .AddSingleton() .AddScoped() diff --git a/pac-man-board-game/Services/ActionService.cs b/pac-man-board-game/Services/ActionService.cs index 8f85c17..4ec6b5a 100644 --- a/pac-man-board-game/Services/ActionService.cs +++ b/pac-man-board-game/Services/ActionService.cs @@ -1,8 +1,7 @@ using System.Net.WebSockets; using System.Text.Json; -using System.Text.Json.Serialization; +using pacMan.DTOs; using pacMan.Exceptions; -using pacMan.GameStuff; using pacMan.GameStuff.Items; namespace pacMan.Services; @@ -11,11 +10,10 @@ public interface IActionService { Player Player { set; } Game? Game { get; set; } - WebSocket? WebSocket { set; } - void DoAction(ActionMessage message); + WebSocket WebSocket { set; } List RollDice(); List FindGame(JsonElement? jsonElement); - object? HandleMoveCharacter(JsonElement? jsonElement); + MovePlayerData HandleMoveCharacter(JsonElement? jsonElement); ReadyData Ready(); string FindNextPlayer(); List LeaveGame(); @@ -23,68 +21,45 @@ public interface IActionService List? Disconnect(); } -public class ActionService : IActionService +public class ActionService(ILogger logger, IGameService gameService) : IActionService { - private readonly GameService _gameService; - private readonly ILogger _logger; - - public ActionService(ILogger logger, GameService gameService) - { - _logger = logger; - _gameService = gameService; - } - - public WebSocket? WebSocket { private get; set; } + public WebSocket WebSocket { private get; set; } = null!; public Game? Game { get; set; } public Player? Player { get; set; } - public void DoAction(ActionMessage message) - { - message.Data = message.Action switch - { - GameAction.RollDice => RollDice(), - GameAction.MoveCharacter => HandleMoveCharacter(message.Data), - GameAction.JoinGame => FindGame(message.Data), - GameAction.Ready => Ready(), - GameAction.NextPlayer => FindNextPlayer(), - GameAction.Disconnect => LeaveGame(), - _ => message.Data - }; - } - public List RollDice() { Game?.DiceCup.Roll(); var rolls = Game?.DiceCup.Values ?? new List(); - _logger.Log(LogLevel.Information, "Rolled [{}]", string.Join(", ", rolls)); + logger.LogInformation("Rolled [{}]", string.Join(", ", rolls)); return rolls; } - public object? HandleMoveCharacter(JsonElement? jsonElement) + public MovePlayerData HandleMoveCharacter(JsonElement? jsonElement) { - if (Game != null && jsonElement.HasValue) + var data = jsonElement?.Deserialize() ?? throw new NullReferenceException("Data is null"); + if (Game is not null) { - Game.Ghosts = jsonElement.Value.GetProperty("ghosts").Deserialize>() ?? - throw new NullReferenceException("Ghosts is null"); - Game.Players = jsonElement.Value.GetProperty("players").Deserialize>() ?? - throw new NullReferenceException("Players is null"); + Game.Ghosts = data.Ghosts; + Game.Players = data.Players; } - return jsonElement; + return data; } public List FindGame(JsonElement? jsonElement) { - var data = jsonElement?.Deserialize() ?? throw new NullReferenceException("Data is null"); + var (username, gameId) = + jsonElement?.Deserialize() ?? throw new NullReferenceException("Data is null"); - var game = _gameService.Games.FirstOrDefault(game => game.Id == data.GameId) ?? - throw new GameNotFoundException($"Game was not found, id \"{data.GameId}\" does not exist"); + var game = gameService.FindGameById(gameId) ?? + throw new GameNotFoundException($"Game was not found, id \"{gameId}\" does not exist"); - var player = game.Players.Find(p => p.Username == data.Username) - ?? throw new PlayerNotFoundException($"Player \"{data.Username}\" was not found in game"); + var player = game.FindPlayerByUsername(username) ?? + throw new PlayerNotFoundException($"Player \"{username}\" was not found in game"); player.State = game.IsGameStarted ? State.InGame : State.WaitingForPlayers; // TODO doesn't work anymore Player = player; @@ -96,8 +71,10 @@ public List FindGame(JsonElement? jsonElement) public ReadyData Ready() { - if (Player == null || Game == null) + if (Player is null) throw new PlayerNotFoundException("Player not found, please create a new player"); + if (Game is null) + throw new GameNotFoundException(); var players = Game.SetReady(Player.Username).ToArray(); // TODO roll to start @@ -111,57 +88,21 @@ public ReadyData Ready() public List LeaveGame() { - if (Game == null || Player == null) throw new NullReferenceException("Game or Player is null"); + if (Game is null) throw new NullReferenceException("Game is null"); + if (Player is null) throw new NullReferenceException("Player is null"); Game.RemovePlayer(Player.Username); return Game.Players; } public List? Disconnect() { - if (Player == null) return null; + if (Player is null) return null; Player.State = State.Disconnected; - if (Game != null) Game.Connections -= SendSegment; + if (Game is not null) Game.Connections -= SendSegment; return Game?.Players; } public void SendToAll(ArraySegment segment) => Game?.SendToAll(segment); - private async Task SendSegment(ArraySegment segment) - { - if (WebSocket != null) await _gameService.Send(WebSocket, segment); - else await Task.FromCanceled(new CancellationToken(true)); - } -} - -public struct JoinGameData -{ - [JsonInclude] - [JsonPropertyName("username")] - public required string Username { get; init; } - - [JsonInclude] - [JsonPropertyName("gameId")] - public required Guid GameId { get; init; } -} - -public struct CreateGameData -{ - [JsonInclude] - [JsonPropertyName("player")] - public required Player Player { get; init; } - - [JsonInclude] - [JsonPropertyName("spawns")] - public required Queue Spawns { get; init; } -} - -public struct ReadyData -{ - [JsonInclude] - [JsonPropertyName("allReady")] - public required bool AllReady { get; init; } - - [JsonInclude] - [JsonPropertyName("players")] - public required IEnumerable Players { get; set; } + private async Task SendSegment(ArraySegment segment) => await gameService.Send(WebSocket, segment); } diff --git a/pac-man-board-game/Services/Game.cs b/pac-man-board-game/Services/Game.cs index 08d88a7..f971448 100644 --- a/pac-man-board-game/Services/Game.cs +++ b/pac-man-board-game/Services/Game.cs @@ -5,14 +5,12 @@ namespace pacMan.Services; -public class Game +public class Game(Queue spawns) { private readonly Random _random = new(); private int _currentPlayerIndex; private List _players = new(); - public Game(Queue spawns) => Spawns = spawns; - [JsonInclude] public Guid Id { get; } = Guid.NewGuid(); [JsonIgnore] @@ -36,7 +34,7 @@ public List Players [JsonIgnore] public List Ghosts { get; set; } = new(); // TODO include - [JsonIgnore] private Queue Spawns { get; } + [JsonIgnore] private Queue Spawns { get; } = spawns; [JsonIgnore] public DiceCup DiceCup { get; } = new(); // TODO include @@ -53,7 +51,7 @@ public Player NextPlayer() } catch (DivideByZeroException) { - throw new InvalidOperationException("There are no players in the game."); + throw new PlayerNotFoundException("There are no players in the game."); } return Players[_currentPlayerIndex]; @@ -107,9 +105,12 @@ public IEnumerable SetReady(string username) public bool SetAllInGame() { - if (Players.Any(player => player.State != State.Ready)) return false; + if (Players.Any(player => player.State is not State.Ready)) return false; foreach (var player in Players) player.State = State.InGame; return true; } + + public Player? FindPlayerByUsername(string username) => + Players.FirstOrDefault(player => player.Username == username); } diff --git a/pac-man-board-game/Services/GameService.cs b/pac-man-board-game/Services/GameService.cs index 2eb1d8a..c4c6cf5 100644 --- a/pac-man-board-game/Services/GameService.cs +++ b/pac-man-board-game/Services/GameService.cs @@ -4,14 +4,21 @@ namespace pacMan.Services; +public interface IGameService : IWebSocketService +{ + SynchronizedCollection Games { get; } + Game JoinById(Guid id, Player player); + Game CreateAndJoin(Player player, Queue spawns); + Game? FindGameById(Guid id); + Game? FindGameByUsername(string username); +} + /// /// The GameService class provides functionality for managing games in a WebSocket environment. It inherits from the /// WebSocketService class. /// -public class GameService : WebSocketService +public class GameService(ILogger logger) : WebSocketService(logger), IGameService { - public GameService(ILogger logger) : base(logger) { } - /// /// A thread-safe collection (SynchronizedCollection) of "Game" objects. Utilized for managing multiple game instances /// simultaneously. @@ -57,6 +64,11 @@ public Game CreateAndJoin(Player player, Queue spawns) return game; } + public Game? FindGameById(Guid id) + { + return Games.FirstOrDefault(game => game.Id == id); + } + public Game? FindGameByUsername(string username) { return Games.FirstOrDefault(game => game.Players.Exists(player => player.Username == username)); diff --git a/pac-man-board-game/Services/WebSocketService.cs b/pac-man-board-game/Services/WebSocketService.cs index 79fbad2..e4a415c 100644 --- a/pac-man-board-game/Services/WebSocketService.cs +++ b/pac-man-board-game/Services/WebSocketService.cs @@ -1,20 +1,17 @@ using System.Net.WebSockets; -using pacMan.Interfaces; using pacMan.Utils; namespace pacMan.Services; - -public class WebSocketService : IWebSocketService +public interface IWebSocketService { - protected readonly ILogger Logger; - - public WebSocketService(ILogger logger) - { - Logger = logger; - logger.Log(LogLevel.Debug, "WebSocket Service created"); - } + Task Send(WebSocket webSocket, ArraySegment segment); + Task Receive(WebSocket webSocket, byte[] buffer); + Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string? closeStatusDescription); +} +public class WebSocketService(ILogger logger) : IWebSocketService +{ public async Task Send(WebSocket webSocket, ArraySegment segment) { await webSocket.SendAsync( @@ -23,13 +20,13 @@ await webSocket.SendAsync( true, CancellationToken.None); - Logger.Log(LogLevel.Debug, "Message sent to WebSocket"); + logger.LogDebug("Message sent through WebSocket"); } public async Task Receive(WebSocket webSocket, byte[] buffer) { var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); - Logger.Log(LogLevel.Debug, + logger.LogDebug( "Message \"{}\" received from WebSocket", buffer.GetString(result.Count)); return result; @@ -42,6 +39,6 @@ await webSocket.CloseAsync( closeStatusDescription, CancellationToken.None); - Logger.Log(LogLevel.Information, "WebSocket connection closed"); + logger.LogInformation("WebSocket connection closed"); } } diff --git a/pac-man-board-game/Utils/Extensions.cs b/pac-man-board-game/Utils/Extensions.cs index 9cc7a59..fae9f58 100644 --- a/pac-man-board-game/Utils/Extensions.cs +++ b/pac-man-board-game/Utils/Extensions.cs @@ -10,7 +10,7 @@ public static string GetString(this byte[] bytes, int length) { var s = Encoding.UTF8.GetString(bytes, 0, length); // Removes invalid characters from the string - return InvalidCharacters().Replace(s, ""); + return InvalidCharacters().Replace(s, string.Empty); } public static ArraySegment ToArraySegment(this object obj) diff --git a/pac-man-board-game/pac-man-board-game.csproj b/pac-man-board-game/pac-man-board-game.csproj index 2b6af8c..dd6b581 100644 --- a/pac-man-board-game/pac-man-board-game.csproj +++ b/pac-man-board-game/pac-man-board-game.csproj @@ -13,70 +13,71 @@ pacMan enable Linux + 12 - + - all - runtime; build; native; contentfiles; analyzers; buildtransitive + all + runtime; build; native; contentfiles; analyzers; buildtransitive - + - + - .dockerignore + .dockerignore - - + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - + - + - + - - - + + + - - + + - + wwwroot\%(RecursiveDir)%(FileName)%(Extension) PreserveNewest From 9991bac6faab64d0f8f03307ee47e62245c9a744 Mon Sep 17 00:00:00 2001 From: martin Date: Wed, 6 Dec 2023 23:43:21 +0100 Subject: [PATCH 2/5] Updated dependencies. Use new array initializer in C#. Added comments to alot of methods and classes --- BackendTests/BackendTests.csproj | 4 +- .../Controllers/GameControllerTests.cs | 14 ++-- .../Controllers/PlayerControllerTests.cs | 4 + BackendTests/Game/Items/DiceCupTests.cs | 2 + BackendTests/Game/Items/DiceTests.cs | 2 + BackendTests/Services/ActionServiceTests.cs | 43 ++++------- BackendTests/Services/GameServiceTests.cs | 25 +++---- BackendTests/Services/GameTests.cs | 62 +++++----------- .../Services/WebSocketServiceTests.cs | 16 +--- BackendTests/Utils/ExtensionsTests.cs | 20 ++--- .../Database/Service/UserService.cs | 10 +-- pac-man-board-game.sln.DotSettings.user | 3 + .../src/components/gameComponent.tsx | 8 ++ .../ClientApp/src/components/gameTile.tsx | 2 +- .../ClientApp/src/game/player.ts | 5 ++ pac-man-board-game/ClientApp/src/utils/api.ts | 16 ++++ .../Controllers/GameController.cs | 56 +++++++++++++- .../Controllers/GenericController.cs | 34 ++++++++- .../Controllers/PlayerController.cs | 7 +- pac-man-board-game/GameStuff/Actions.cs | 13 ++++ pac-man-board-game/GameStuff/Character.cs | 5 +- pac-man-board-game/GameStuff/Items/Dice.cs | 9 ++- pac-man-board-game/GameStuff/Items/DiceCup.cs | 21 ++++-- pac-man-board-game/GameStuff/Items/Player.cs | 6 ++ pac-man-board-game/GameStuff/Positions.cs | 24 +++++- pac-man-board-game/GameStuff/Rules.cs | 3 + pac-man-board-game/Services/ActionService.cs | 60 ++++++++++++++- pac-man-board-game/Services/Game.cs | 74 +++++++++++++++++-- pac-man-board-game/Services/GameService.cs | 23 ++++-- .../Services/WebSocketService.cs | 32 ++++++++ pac-man-board-game/Utils/Extensions.cs | 15 ++++ pac-man-board-game/pac-man-board-game.csproj | 2 +- 32 files changed, 459 insertions(+), 161 deletions(-) diff --git a/BackendTests/BackendTests.csproj b/BackendTests/BackendTests.csproj index f95e2a7..98fa5fa 100644 --- a/BackendTests/BackendTests.csproj +++ b/BackendTests/BackendTests.csproj @@ -13,9 +13,9 @@ - + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/BackendTests/Controllers/GameControllerTests.cs b/BackendTests/Controllers/GameControllerTests.cs index 3e236cb..1f24f3a 100644 --- a/BackendTests/Controllers/GameControllerTests.cs +++ b/BackendTests/Controllers/GameControllerTests.cs @@ -11,12 +11,10 @@ namespace BackendTests.Controllers; +[TestFixture] +[TestOf(nameof(GameController))] public class GameControllerTests { - private IActionService _actionService = null!; - private GameController _controller = null!; - private GameService _gameService = null!; - [SetUp] public void Setup() { @@ -27,6 +25,10 @@ public void Setup() _controller = new GameController(Substitute.For>(), _gameService, _actionService); } + private IActionService _actionService = null!; + private GameController _controller = null!; + private GameService _gameService = null!; + [Test] public void Run_ReturnsSame() { @@ -52,8 +54,6 @@ public void Run_ReturnsSame() Assert.Fail("Result is not an ArraySegment"); } - #region DoAction(ActionMessage message) - [Test] public void DoAction_NegativeAction() { @@ -71,6 +71,4 @@ public void DoAction_OutOfBoundsAction() _controller.DoAction(message); Assert.That(message.Data, Is.EqualTo(data)); } - - #endregion } diff --git a/BackendTests/Controllers/PlayerControllerTests.cs b/BackendTests/Controllers/PlayerControllerTests.cs index 8e4cc3b..9c40686 100644 --- a/BackendTests/Controllers/PlayerControllerTests.cs +++ b/BackendTests/Controllers/PlayerControllerTests.cs @@ -1,5 +1,9 @@ +using pacMan.Controllers; + namespace BackendTests.Controllers; +[TestFixture] +[TestOf(nameof(PlayerController))] public class PlayerControllerTests { // TODO diff --git a/BackendTests/Game/Items/DiceCupTests.cs b/BackendTests/Game/Items/DiceCupTests.cs index 2c691d7..3fa27e5 100644 --- a/BackendTests/Game/Items/DiceCupTests.cs +++ b/BackendTests/Game/Items/DiceCupTests.cs @@ -2,6 +2,8 @@ namespace BackendTests.Game.Items; +[TestFixture] +[TestOf(nameof(DiceCup))] public class DiceCupTests { [Test] diff --git a/BackendTests/Game/Items/DiceTests.cs b/BackendTests/Game/Items/DiceTests.cs index 9d2313f..bd1cfcf 100644 --- a/BackendTests/Game/Items/DiceTests.cs +++ b/BackendTests/Game/Items/DiceTests.cs @@ -2,6 +2,8 @@ namespace BackendTests.Game.Items; +[TestFixture] +[TestOf(nameof(Dice))] public class DiceTests { [Test] diff --git a/BackendTests/Services/ActionServiceTests.cs b/BackendTests/Services/ActionServiceTests.cs index 1c8a791..258fe95 100644 --- a/BackendTests/Services/ActionServiceTests.cs +++ b/BackendTests/Services/ActionServiceTests.cs @@ -10,21 +10,10 @@ namespace BackendTests.Services; +[TestFixture] +[TestOf(nameof(ActionService))] public class ActionServiceTests { - private readonly Player _blackPlayer = Players.Create("black"); - private readonly Player _redPlayer = Players.Create("red"); - private readonly Player _whitePlayer = Players.Create("white"); - private ActionMessage _blackMessage = null!; - private pacMan.Services.Game _game = null!; - private GameService _gameService = null!; - private ActionMessage _redMessage = null!; - private IActionService _service = null!; - - private Queue _spawns = null!; - private ActionMessage _whiteMessage = null!; - - [SetUp] public void Setup() { @@ -37,6 +26,18 @@ public void Setup() _service = new ActionService(Substitute.For>(), _gameService); } + private readonly Player _blackPlayer = Players.Create("black"); + private readonly Player _redPlayer = Players.Create("red"); + private readonly Player _whitePlayer = Players.Create("white"); + private ActionMessage _blackMessage = null!; + private pacMan.Services.Game _game = null!; + private GameService _gameService = null!; + private ActionMessage _redMessage = null!; + private IActionService _service = null!; + + private Queue _spawns = null!; + private ActionMessage _whiteMessage = null!; + private JsonElement SerializeData(string username) => JsonDocument.Parse(JsonSerializer.Serialize( new JoinGameData { Username = username, GameId = _game.Id } @@ -51,8 +52,6 @@ private static Queue CreateQueue() => new() { At = new Position { X = 9, Y = 9 }, Direction = Direction.Right } }); - #region RollDice() - [Test] public void RollDice_ReturnsListOfIntegers() { @@ -65,10 +64,6 @@ public void RollDice_ReturnsListOfIntegers() }); } - #endregion - - #region PlayerInfo(ActionMessage message) - [Test] public void PlayerInfo_DataIsNull() { @@ -98,10 +93,6 @@ public void PlayerInfo_DataIsUsernameAndGameId() Assert.That(new List { _whitePlayer }, Is.EqualTo(players)); } - #endregion - - #region Ready() - [Test] public void Ready_PlayerIsNull() { @@ -162,10 +153,6 @@ public void Ready_TwoReady() Is.EqualTo(_blackPlayer.Username).Or.EqualTo(_whitePlayer.Username)); } - #endregion - - #region FindNextPlayer() - [Test] public void FindNextPlayer_NoPlayers() { @@ -200,6 +187,4 @@ public void FindNextPlayer_TwoPlayers() var second = _service.FindNextPlayer(); Assert.That(second, Is.EqualTo(_whitePlayer.Username)); } - - #endregion } diff --git a/BackendTests/Services/GameServiceTests.cs b/BackendTests/Services/GameServiceTests.cs index 59e9df9..7905c9d 100644 --- a/BackendTests/Services/GameServiceTests.cs +++ b/BackendTests/Services/GameServiceTests.cs @@ -3,19 +3,14 @@ using NSubstitute; using pacMan.Exceptions; using pacMan.GameStuff; -using pacMan.GameStuff.Items; using pacMan.Services; namespace BackendTests.Services; +[TestFixture] +[TestOf(nameof(GameService))] public class GameServiceTests { - private readonly DirectionalPosition _spawn3By3Up = new() - { At = new Position { X = 3, Y = 3 }, Direction = Direction.Up }; - - private GameService _service = null!; - private Queue _spawns = null!; - [SetUp] public void SetUp() { @@ -29,7 +24,11 @@ public void SetUp() }); } - #region CreateAndJoin(IPlayer player, Queue spawns) + private readonly DirectionalPosition _spawn3By3Up = new() + { At = new Position { X = 3, Y = 3 }, Direction = Direction.Up }; + + private GameService _service = null!; + private Queue _spawns = null!; [Test] public void CreateAndJoin_WhenEmpty() @@ -53,15 +52,11 @@ public void CreateAndJoin_SpawnsAreNotEqualToMaxPlayers() Assert.Throws(() => _service.CreateAndJoin(player, _spawns)); } - #endregion - - #region JoinbyId(Guid id) - [Test] public void JoinById_WhenIdNotExists() { var player = Players.Create("white"); - _service.Games.Add(new pacMan.Services.Game(_spawns) { Players = new List { player } }); + _service.Games.Add(new pacMan.Services.Game(_spawns) { Players = [player] }); Assert.Throws(() => _service.JoinById(Guid.NewGuid(), player)); } @@ -70,7 +65,7 @@ public void JoinById_WhenIdNotExists() public void JoinById_WhenIdExists() { var player = Players.Create("white"); - var game = new pacMan.Services.Game(_spawns) { Players = new List { player } }; + var game = new pacMan.Services.Game(_spawns) { Players = [player] }; _service.Games.Add(game); @@ -84,6 +79,4 @@ public void JoinById_WhenIdExists() Assert.That(_service.Games, Has.Count.EqualTo(1)); }); } - - #endregion } diff --git a/BackendTests/Services/GameTests.cs b/BackendTests/Services/GameTests.cs index fb0822f..444dc4f 100644 --- a/BackendTests/Services/GameTests.cs +++ b/BackendTests/Services/GameTests.cs @@ -6,8 +6,24 @@ namespace BackendTests.Services; +[TestFixture] +[TestOf(nameof(pacMan.Services.Game))] public class GameTests { + [SetUp] + public void Setup() + { + _spawns = new Queue( + new[] { _spawn3By3Up, _spawn7By7Left, _spawn7By7Down, _spawn7By7Right }); + + _game = new pacMan.Services.Game(_spawns); + _redPlayer = Players.Create("red"); + _bluePlayer = Players.Create("blue"); + _yellowPlayer = Players.Create("yellow"); + _greenPlayer = Players.Create("green"); + _purplePlayer = Players.Create("purple"); + } + private readonly DirectionalPosition _spawn3By3Up = new() { At = new Position { X = 3, Y = 3 }, Direction = Direction.Up }; @@ -29,20 +45,6 @@ public class GameTests private Queue _spawns = null!; private Player _yellowPlayer = null!; - [SetUp] - public void Setup() - { - _spawns = new Queue( - new[] { _spawn3By3Up, _spawn7By7Left, _spawn7By7Down, _spawn7By7Right }); - - _game = new pacMan.Services.Game(_spawns); - _redPlayer = Players.Create("red"); - _bluePlayer = Players.Create("blue"); - _yellowPlayer = Players.Create("yellow"); - _greenPlayer = Players.Create("green"); - _purplePlayer = Players.Create("purple"); - } - private void AddFullParty() { _game.AddPlayer(_bluePlayer); @@ -51,18 +53,12 @@ private void AddFullParty() _game.AddPlayer(_greenPlayer); } - #region NextPlayer() - [Test] public void NextPlayer_WhenEmpty() { Assert.Throws(() => _game.NextPlayer()); } - #endregion - - #region IsGameStarted - [Test] public void IsGameStarted_WhenEmpty() { @@ -101,10 +97,6 @@ public void IsGameStarted_WhenHalfInGame() Assert.That(_game.IsGameStarted, Is.True); } - #endregion - - #region AddPlayer(Player player) - [Test] public void AddPlayer_WhenEmpty() { @@ -157,10 +149,6 @@ public void AddPlayer_WhenGameHasStarted() Assert.Throws(() => _game.AddPlayer(_greenPlayer)); } - #endregion - - #region Sendtoall(ArraySegment segment) - [Test] public void SendToAll_WhenConnectionsIsNull() { @@ -171,7 +159,6 @@ public void SendToAll_WhenConnectionsIsNull() public void SendToAll_WhenConnectionsIsNotNull() { var counter = 0; - async Task Send(ArraySegment segment) => await Task.Run(() => counter++); _game.Connections += Send; _game.Connections += Send; @@ -182,11 +169,10 @@ public void SendToAll_WhenConnectionsIsNotNull() while (counter < 2) { } Assert.That(counter, Is.EqualTo(2)); - } + return; - #endregion - - #region SetReady(Player player) + async Task Send(ArraySegment segment) => await Task.Run(() => counter++); + } [Test] public void SetReady_ReturnsAllPlayers() @@ -222,10 +208,6 @@ public void SetReady_WhenPlayerIsNotInPlayers() Assert.Throws(() => _game.SetReady(_redPlayer.Username)); } - #endregion - - #region SetAllIngame() - [Test] public void SetAllInGame_SetsStateToInGame() { @@ -257,10 +239,6 @@ public void SetAllInGame_WhenPlayersIsEmpty() Assert.That(_game.Players, Is.Empty); } - #endregion - - #region IsGameStarted() - [Test] public void IsGameStarted_AllWaiting() { @@ -275,6 +253,4 @@ public void IsGameStarted_AllInGame() _game.Players.ForEach(player => player.State = State.InGame); Assert.That(_game.IsGameStarted, Is.True); } - - #endregion } diff --git a/BackendTests/Services/WebSocketServiceTests.cs b/BackendTests/Services/WebSocketServiceTests.cs index 5a712f6..94ff43a 100644 --- a/BackendTests/Services/WebSocketServiceTests.cs +++ b/BackendTests/Services/WebSocketServiceTests.cs @@ -6,17 +6,17 @@ namespace BackendTests.Services; +[TestFixture] +[TestOf(nameof(WebSocketService))] public class WebSocketServiceTests { - private IWebSocketService _service = null!; - [SetUp] public void SetUp() { _service = new WebSocketService(Substitute.For>()); } - #region Send(Websocket, ArraySegment) + private IWebSocketService _service = null!; [Test] public void Send_OpenWebsocket() @@ -47,10 +47,6 @@ public void Send_ClosedWebsocket() webSocket.Received().SendAsync(segment, WebSocketMessageType.Text, true, CancellationToken.None); } - #endregion - - #region Receive(Websocket, byte[]) - [Test] public void Receive_ExactBuffer() { @@ -89,10 +85,6 @@ public void Receive_CloseWebsocket() webSocket.ReceivedWithAnyArgs().ReceiveAsync(default, CancellationToken.None); } - #endregion - - #region Close(Websocket, WebSocketCloseStatus, string?) - [Test] public void Close_OpenWebsocket() { @@ -123,6 +115,4 @@ public void Close_ClosedWebsocket() webSocket.ReceivedWithAnyArgs().CloseAsync(default, default, CancellationToken.None); } - - #endregion } diff --git a/BackendTests/Utils/ExtensionsTests.cs b/BackendTests/Utils/ExtensionsTests.cs index 2d6f2bb..1077abc 100644 --- a/BackendTests/Utils/ExtensionsTests.cs +++ b/BackendTests/Utils/ExtensionsTests.cs @@ -3,9 +3,15 @@ namespace BackendTests.Utils; +[TestFixture] +[TestOf(nameof(Extensions))] public class ExtensionsTests { - #region ToArraySegment(this object obj) + [SetUp] + public void Setup() + { + _bytes = "Hello World!"u8.ToArray(); + } [Test] public void ToArraySegmentValidObject() @@ -24,18 +30,8 @@ public void ToArraySegmentNullableObject() Assert.That(segment, Has.Count.EqualTo(4)); } - #endregion - - #region GetString(this byte[] bytes, int length) - private byte[] _bytes = null!; - [SetUp] - public void Setup() - { - _bytes = "Hello World!"u8.ToArray(); - } - [Test] public void GetString_ValidByteArray() { @@ -65,6 +61,4 @@ public void GetString_LengthShorterThanByteArrayLength() { Assert.That(_bytes.GetString(_bytes.Length / 2), Is.EqualTo("Hello ")); } - - #endregion } diff --git a/DataAccessLayer/Database/Service/UserService.cs b/DataAccessLayer/Database/Service/UserService.cs index 261da69..f63ea48 100644 --- a/DataAccessLayer/Database/Service/UserService.cs +++ b/DataAccessLayer/Database/Service/UserService.cs @@ -4,8 +4,8 @@ namespace DAL.Database.Service; public class UserService { - private readonly List _users = new() - { + private readonly List _users = + [ new User { Username = "Firefox", @@ -18,10 +18,10 @@ public class UserService Password = "Chrome", Colour = "blue" } - }; + ]; - public async Task Login(string username, string password) + public Task Login(string username, string password) { - return await Task.Run(() => _users.FirstOrDefault(x => x.Username == username && x.Password == password)); + return Task.Run(() => _users.FirstOrDefault(x => x.Username == username && x.Password == password)); } } diff --git a/pac-man-board-game.sln.DotSettings.user b/pac-man-board-game.sln.DotSettings.user index cf8098b..cefe584 100644 --- a/pac-man-board-game.sln.DotSettings.user +++ b/pac-man-board-game.sln.DotSettings.user @@ -1,4 +1,7 @@  + True + 35336347-32EB-4764-A28E-3F8FF6CA54C4 + db4927dd-2e12-48a7-9a84-2b7e3e31b9c8 <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;BackendTests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> <Project Location="/home/martin/Git/Csharp/pac-man-board-game/BackendTests" Presentation="&lt;BackendTests&gt;" /> </SessionState> \ No newline at end of file diff --git a/pac-man-board-game/ClientApp/src/components/gameComponent.tsx b/pac-man-board-game/ClientApp/src/components/gameComponent.tsx index 37258d0..4679f25 100644 --- a/pac-man-board-game/ClientApp/src/components/gameComponent.tsx +++ b/pac-man-board-game/ClientApp/src/components/gameComponent.tsx @@ -14,6 +14,14 @@ import { getData } from "../utils/api" const wsService = new WebSocketService(import.meta.env.VITE_API_WS) +/** + * Represents the main game component. + * @component + * @param player - The current player. + * @param map - The current game map. + * + * @returns The rendered game component. + */ export const GameComponent: FC<{ player: Player; map: GameMap }> = ({ player, map }) => { const players = useAtomValue(playersAtom) const dice = useAtomValue(diceAtom) diff --git a/pac-man-board-game/ClientApp/src/components/gameTile.tsx b/pac-man-board-game/ClientApp/src/components/gameTile.tsx index 8e6a2c1..0f7f1fd 100644 --- a/pac-man-board-game/ClientApp/src/components/gameTile.tsx +++ b/pac-man-board-game/ClientApp/src/components/gameTile.tsx @@ -28,7 +28,7 @@ export const GameTile: FC = ({ showPath = false, }) => ( handleMoveCharacter?.(possiblePath) : undefined} onMouseEnter={possiblePath ? () => handleStartShowPath?.(possiblePath) : undefined} diff --git a/pac-man-board-game/ClientApp/src/game/player.ts b/pac-man-board-game/ClientApp/src/game/player.ts index 0c37c09..1a6e98c 100644 --- a/pac-man-board-game/ClientApp/src/game/player.ts +++ b/pac-man-board-game/ClientApp/src/game/player.ts @@ -4,6 +4,11 @@ import { getDefaultStore } from "jotai" import { currentPlayerNameAtom, playersAtom } from "../utils/state" import rules from "./rules" +/** + * Represents the different states of a game. + * + * @enum {number} + */ export enum State { waitingForPlayers, ready, diff --git a/pac-man-board-game/ClientApp/src/utils/api.ts b/pac-man-board-game/ClientApp/src/utils/api.ts index 25eaa4d..7aa8d6d 100644 --- a/pac-man-board-game/ClientApp/src/utils/api.ts +++ b/pac-man-board-game/ClientApp/src/utils/api.ts @@ -1,3 +1,11 @@ +/** + * getData is an asynchronous function that makes an API request to retrieve data. + * If the mode is test, it returns a promise that resolves to an empty array. + * + * @param path - The path of the API endpoint. + * @param headers - The headers to be included in the request. + * @returns - A promise that resolves to the response from the API. + */ export const getData: Api = async (path, { headers } = {}) => { if (import.meta.env.MODE === "test") return Promise.resolve(new Response(JSON.stringify([]))) return await fetch(import.meta.env.VITE_API_HTTP + path, { @@ -6,6 +14,14 @@ export const getData: Api = async (path, { headers } = {}) => { }) } +/** + * Makes a POST request to the API endpoint. + * + * @param path - The path of the endpoint. + * @param body - The payload of the request. + * @param headers - Additional headers for the request. + * @returns - A Promise that resolves to the Response object representing the server's response. + */ export const postData: Api = async (path, { body, headers } = {}) => { return await fetch(import.meta.env.VITE_API_HTTP + path, { method: "POST", diff --git a/pac-man-board-game/Controllers/GameController.cs b/pac-man-board-game/Controllers/GameController.cs index 457700f..522f2b6 100644 --- a/pac-man-board-game/Controllers/GameController.cs +++ b/pac-man-board-game/Controllers/GameController.cs @@ -9,14 +9,23 @@ namespace pacMan.Controllers; +/// +/// Controls the game logic and handles requests related to games. +/// [ApiController] [Route("api/[controller]")] public class GameController(ILogger logger, IGameService webSocketService, IActionService actionService) : GenericController(logger, webSocketService) { [HttpGet("[action]")] - public override async Task Connect() => await base.Connect(); + public override Task Connect() => base.Connect(); + /// + /// Retrieves all games from the WebSocketService. + /// + /// + /// An IEnumerable of Game objects representing all the games. + /// [HttpGet("[action]")] public IEnumerable All() { @@ -24,6 +33,12 @@ public IEnumerable All() return webSocketService.Games; } + /// + /// Adds a player to a game. + /// + /// The unique identifier of the game. + /// The player to be joined. + /// An IActionResult representing the result of the operation. [HttpPost("[action]/{gameId:guid}")] public IActionResult Join(Guid gameId, [FromBody] Player player) // TODO what if player is in a game already? { @@ -43,6 +58,15 @@ public IEnumerable All() } } + /// + /// Checks if a game with the specified ID exists. + /// + /// The ID of the game to check. + /// + /// Returns an representing the result of the operation. + /// If a game with the specified ID exists, returns an . + /// If a game with the specified ID doesn't exist, returns a . + /// [HttpGet("[action]/{gameId:guid}")] public IActionResult Exists(Guid gameId) { @@ -50,6 +74,16 @@ public IActionResult Exists(Guid gameId) return webSocketService.Games.Any(game => game.Id == gameId) ? Ok() : NotFound(); } + /// + /// Creates a new game and adds the specified player to it. + /// + /// The data required to create the game. + /// + /// Returns an representing the result of the operation. + /// If the game is successfully created, returns a with the game details and a location + /// URL. + /// If there is an error during creation, returns a with the error message. + /// [HttpPost("[action]")] public IActionResult Create([FromBody] CreateGameData data) { @@ -71,6 +105,14 @@ protected override Task Echo() return base.Echo(); } + /// + /// Runs the given WebSocketReceiveResult and byte array data to perform an action. + /// + /// The WebSocketReceiveResult object containing information about the received data. + /// The byte array data received from the WebSocket. + /// + /// Returns an ArraySegment object representing the action response in byte array format. + /// protected override ArraySegment Run(WebSocketReceiveResult result, byte[] data) { var stringResult = data.GetString(result.Count); @@ -91,12 +133,16 @@ protected override ArraySegment Run(WebSocketReceiveResult result, byte[] return action.ToArraySegment(); } - protected override async void Send(ArraySegment segment) + /// + /// Sends the specified data segment. + /// + /// The data segment to send. + protected override void Send(ArraySegment segment) { if (actionService.Game is not null) actionService.SendToAll(segment); else if (WebSocket is not null) - await webSocketService.Send(WebSocket, segment); + webSocketService.Send(WebSocket, segment); } protected override ArraySegment? Disconnect() => @@ -105,6 +151,10 @@ protected override async void Send(ArraySegment segment) protected override void SendDisconnectMessage(ArraySegment segment) => actionService.SendToAll(segment); + /// + /// Performs the specified action based on the given message. + /// + /// The action message containing the action to be performed. public void DoAction(ActionMessage message) => message.Data = message.Action switch { diff --git a/pac-man-board-game/Controllers/GenericController.cs b/pac-man-board-game/Controllers/GenericController.cs index 1a3f865..502e02f 100644 --- a/pac-man-board-game/Controllers/GenericController.cs +++ b/pac-man-board-game/Controllers/GenericController.cs @@ -4,13 +4,33 @@ namespace pacMan.Controllers; +/// +/// Represents a generic controller for handling WebSocket connections. +/// public abstract class GenericController(ILogger logger, IWebSocketService webSocketService) : ControllerBase { + /// + /// Buffer size used for processing data. + /// private const int BufferSize = 1024 * 4; + protected readonly ILogger Logger = logger; protected WebSocket? WebSocket; + /// + /// Establishes a WebSocket connection with the client. + /// + /// + /// This method checks if the HTTP request is a WebSocket request. If it is, it accepts the WebSocket connection, logs + /// the connection establishment, and sets the WebSocket property to + /// the accepted WebSocket instance. + /// After the connection is established, the method calls the Echo method to start echoing messages. + /// If the request is not a WebSocket request, it sets the HTTP response status code to 400 (BadRequest). + /// + /// + /// The task representing the asynchronous operation. + /// public virtual async Task Connect() { if (HttpContext.WebSockets.IsWebSocketRequest) @@ -26,6 +46,11 @@ public virtual async Task Connect() } } + /// + /// An asynchronous method that reads data from the WebSocket connection, + /// processes it, and sends back the processed data. + /// + /// A Task representing the asynchronous operation. protected virtual async Task Echo() { if (WebSocket is null) return; @@ -56,10 +81,15 @@ protected virtual async Task Echo() } } - protected virtual async void Send(ArraySegment segment) + /// + /// Sends the specified byte segment using the WebSocket connection. + /// If the WebSocket connection is null, the method does nothing. + /// + /// The byte segment to send. + protected virtual void Send(ArraySegment segment) { if (WebSocket is null) return; - await webSocketService.Send(WebSocket, segment); + webSocketService.Send(WebSocket, segment); } protected abstract ArraySegment Run(WebSocketReceiveResult result, byte[] data); diff --git a/pac-man-board-game/Controllers/PlayerController.cs b/pac-man-board-game/Controllers/PlayerController.cs index dd8558a..8ed37cc 100644 --- a/pac-man-board-game/Controllers/PlayerController.cs +++ b/pac-man-board-game/Controllers/PlayerController.cs @@ -9,6 +9,11 @@ namespace pacMan.Controllers; [Route("api/[controller]/[action]")] public class PlayerController(UserService userService) : ControllerBase { + /// + /// Logs in a user. + /// + /// The user object containing the username and password. + /// Returns an IActionResult indicating the login result. [HttpPost] public async Task Login([FromBody] User user) { @@ -18,5 +23,5 @@ public async Task Login([FromBody] User user) } [HttpPost] - public async Task Register([FromBody] User user) => throw new NotSupportedException(); + public Task Register([FromBody] User user) => throw new NotSupportedException(); } diff --git a/pac-man-board-game/GameStuff/Actions.cs b/pac-man-board-game/GameStuff/Actions.cs index acfd6a3..ea8fb12 100644 --- a/pac-man-board-game/GameStuff/Actions.cs +++ b/pac-man-board-game/GameStuff/Actions.cs @@ -3,6 +3,9 @@ namespace pacMan.GameStuff; +/// +/// Represents various actions that can be performed in a game. +/// public enum GameAction { Error, @@ -14,12 +17,22 @@ public enum GameAction Disconnect } +/// +/// Represents an action message with optional data of type . +/// Every Action may have a different type of data, or no data at all. +/// +/// The type of the data. public class ActionMessage { [JsonPropertyName("action")] public GameAction Action { get; init; } [JsonPropertyName("data")] public T? Data { get; set; } + /// + /// Parses a JSON string into an ActionMessage object. With dynamic data. + /// + /// The JSON string to deserialize. + /// An ActionMessage object populated with the deserialized data. public static ActionMessage FromJson(string json) => JsonSerializer.Deserialize(json)!; } diff --git a/pac-man-board-game/GameStuff/Character.cs b/pac-man-board-game/GameStuff/Character.cs index 66211e2..493391e 100644 --- a/pac-man-board-game/GameStuff/Character.cs +++ b/pac-man-board-game/GameStuff/Character.cs @@ -31,9 +31,12 @@ public override bool Equals(object? obj) return obj.GetType() == GetType() && Equals((Character)obj); } - public override int GetHashCode() => HashCode.Combine(Colour, Position, IsEatable, SpawnPosition, (int?)Type); + public override int GetHashCode() => HashCode.Combine(Colour, Type); } +/// +/// Represents the types of characters in a game. +/// public enum CharacterType { PacMan, diff --git a/pac-man-board-game/GameStuff/Items/Dice.cs b/pac-man-board-game/GameStuff/Items/Dice.cs index 9c593b5..5275ec9 100644 --- a/pac-man-board-game/GameStuff/Items/Dice.cs +++ b/pac-man-board-game/GameStuff/Items/Dice.cs @@ -6,7 +6,14 @@ public class Dice { private readonly Random _random = new(); - [JsonInclude] public int Value { get; private set; } + /// + /// Represents the value of the previous roll. + /// + [JsonInclude] + public int Value { get; private set; } + /// + /// Rolls a dice by generating a random number between 1 and 6 and assigns it to the 'Value' property of the dice. + /// public void Roll() => Value = _random.Next(1, 7); } diff --git a/pac-man-board-game/GameStuff/Items/DiceCup.cs b/pac-man-board-game/GameStuff/Items/DiceCup.cs index 40bdf99..e8e6cea 100644 --- a/pac-man-board-game/GameStuff/Items/DiceCup.cs +++ b/pac-man-board-game/GameStuff/Items/DiceCup.cs @@ -2,15 +2,24 @@ namespace pacMan.GameStuff.Items; +/// +/// Represents a cup containing multiple dice. +/// public class DiceCup { - private readonly List _dices = new() - { - new Dice(), - new Dice() - }; + private readonly List _dices = [new Dice(), new Dice()]; - [JsonInclude] public List Values => _dices.Select(dice => dice.Value).ToList(); + /// + /// Gets a list of integer values representing the values of the dices. + /// + /// + /// A list of integer values representing the values of the dices. + /// + [JsonInclude] + public List Values => _dices.Select(dice => dice.Value).ToList(); + /// + /// Rolls all the dice in the list. + /// public void Roll() => _dices.ForEach(dice => dice.Roll()); } diff --git a/pac-man-board-game/GameStuff/Items/Player.cs b/pac-man-board-game/GameStuff/Items/Player.cs index bbfaaa1..fcaf389 100644 --- a/pac-man-board-game/GameStuff/Items/Player.cs +++ b/pac-man-board-game/GameStuff/Items/Player.cs @@ -3,6 +3,9 @@ namespace pacMan.GameStuff.Items; +/// +/// Represents the various states of a 'Player'. +/// public enum State { WaitingForPlayers, @@ -11,6 +14,9 @@ public enum State Disconnected } +/// +/// Represents a player in the game. +/// public class Player : IEquatable, ICloneable { [JsonPropertyName("username")] public required string Username { get; init; } diff --git a/pac-man-board-game/GameStuff/Positions.cs b/pac-man-board-game/GameStuff/Positions.cs index accff30..94c8a76 100644 --- a/pac-man-board-game/GameStuff/Positions.cs +++ b/pac-man-board-game/GameStuff/Positions.cs @@ -2,6 +2,9 @@ namespace pacMan.GameStuff; +/// +/// Represents a move path consisting of a sequence of positions and a target end position with a specified direction. +/// public class MovePath : IEquatable { [JsonInclude] @@ -19,6 +22,11 @@ public bool Equals(MovePath? other) return Equals(Path, other.Path) && End.Equals(other.End) && Direction == other.Direction; } + /// + /// Converts a DirectionalPosition object to a MovePath object. + /// + /// The DirectionalPosition object to convert. + /// A MovePath object with the same End and Direction as the DirectionalPosition object. public static implicit operator MovePath(DirectionalPosition path) => new() { @@ -33,9 +41,12 @@ public override bool Equals(object? obj) return obj.GetType() == GetType() && Equals((MovePath)obj); } - public override int GetHashCode() => HashCode.Combine(Path, End, (int)Direction); + public override int GetHashCode() => HashCode.Combine(End, (int)Direction); } +/// +/// Represents a position with x and y coordinates. +/// public class Position : IEquatable { [JsonPropertyName("x")] public int X { get; init; } @@ -59,6 +70,9 @@ public override bool Equals(object? obj) public override int GetHashCode() => HashCode.Combine(X, Y); } +/// +/// Enum representing the possible directions: Left, Up, Right, and Down. +/// public enum Direction { Left, @@ -67,6 +81,9 @@ public enum Direction Down } +/// +/// Represents a directional position with a coordinate and a direction. +/// public class DirectionalPosition : IEquatable { [JsonPropertyName("at")] public required Position At { get; init; } @@ -80,6 +97,11 @@ public bool Equals(DirectionalPosition? other) return At.Equals(other.At) && Direction == other.Direction; } + /// + /// Converts a MovePath object to a DirectionalPosition object. + /// + /// The MovePath object to convert. + /// A DirectionalPosition object representing the converted MovePath object. public static explicit operator DirectionalPosition(MovePath path) => new() { diff --git a/pac-man-board-game/GameStuff/Rules.cs b/pac-man-board-game/GameStuff/Rules.cs index 5052cc4..4c5e5a2 100644 --- a/pac-man-board-game/GameStuff/Rules.cs +++ b/pac-man-board-game/GameStuff/Rules.cs @@ -1,5 +1,8 @@ namespace pacMan.GameStuff; +/// +/// The Rules class holds constant values related to the game rules. +/// public static class Rules { public const int MinPlayers = 2; diff --git a/pac-man-board-game/Services/ActionService.cs b/pac-man-board-game/Services/ActionService.cs index 4ec6b5a..9a3d193 100644 --- a/pac-man-board-game/Services/ActionService.cs +++ b/pac-man-board-game/Services/ActionService.cs @@ -21,6 +21,9 @@ public interface IActionService List? Disconnect(); } +/// +/// Provides various actions that can be performed in a game +/// public class ActionService(ILogger logger, IGameService gameService) : IActionService { public WebSocket WebSocket { private get; set; } = null!; @@ -29,15 +32,24 @@ public class ActionService(ILogger logger, IGameService gameService) : IActionSe public Player? Player { get; set; } + /// + /// Rolls the dice and returns the result. If the game is null, an empty list is returned. + /// + /// A list of integers representing the values rolled on the dice. public List RollDice() { Game?.DiceCup.Roll(); - var rolls = Game?.DiceCup.Values ?? new List(); + var rolls = Game?.DiceCup.Values ?? []; logger.LogInformation("Rolled [{}]", string.Join(", ", rolls)); return rolls; } + /// + /// Handles the movement of the character based on the provided JSON element. + /// + /// The JSON element containing the data to move the character. + /// The MovePlayerData object representing the updated character movement information. public MovePlayerData HandleMoveCharacter(JsonElement? jsonElement) { var data = jsonElement?.Deserialize() ?? throw new NullReferenceException("Data is null"); @@ -50,6 +62,14 @@ public MovePlayerData HandleMoveCharacter(JsonElement? jsonElement) return data; } + /// + /// Finds a game based on the given JSON element. + /// + /// The JSON data containing the username and gameId. + /// The list of players in the found game. + /// Thrown when the JSON data is null. + /// Thrown when the game with the given gameId does not exist. + /// Thrown when the player with the given username is not found in the game. public List FindGame(JsonElement? jsonElement) { var (username, gameId) = @@ -69,6 +89,12 @@ public List FindGame(JsonElement? jsonElement) return Game.Players; } + /// + /// Prepares the game and returns relevant data. + /// + /// Thrown when the player is not found. + /// Thrown when the game is not found. + /// A object containing information about game readiness. public ReadyData Ready() { if (Player is null) @@ -84,8 +110,22 @@ public ReadyData Ready() return new ReadyData { AllReady = allReady, Players = players }; } + /// + /// Finds the next player in the game. + /// + /// + /// The username of the next player in the game, if available. + /// + /// + /// Thrown if the game is not found. + /// public string FindNextPlayer() => Game?.NextPlayer().Username ?? throw new GameNotFoundException(); + /// + /// Removes the player from the game. + /// + /// Throws if the game or player is null. + /// A list of remaining players in the game. public List LeaveGame() { if (Game is null) throw new NullReferenceException("Game is null"); @@ -94,6 +134,13 @@ public List LeaveGame() return Game.Players; } + /// + /// Disconnects the player from the game. + /// + /// + /// Returns the list of players in the game after disconnecting the player. + /// Returns null if the player is already disconnected or is not connected to a game. + /// public List? Disconnect() { if (Player is null) return null; @@ -102,7 +149,16 @@ public List LeaveGame() return Game?.Players; } + /// + /// Sends a given byte segment to all players in the game. + /// + /// The byte segment to send. public void SendToAll(ArraySegment segment) => Game?.SendToAll(segment); - private async Task SendSegment(ArraySegment segment) => await gameService.Send(WebSocket, segment); + /// + /// Sends an array segment of bytes through the WebSocket connection. + /// + /// The array segment of bytes to send. + /// A task that represents the asynchronous send operation. + private Task SendSegment(ArraySegment segment) => gameService.Send(WebSocket, segment); } diff --git a/pac-man-board-game/Services/Game.cs b/pac-man-board-game/Services/Game.cs index f971448..c09ab9a 100644 --- a/pac-man-board-game/Services/Game.cs +++ b/pac-man-board-game/Services/Game.cs @@ -5,14 +5,21 @@ namespace pacMan.Services; +/// +/// Represents a game instance. +/// public class Game(Queue spawns) { private readonly Random _random = new(); private int _currentPlayerIndex; - private List _players = new(); + private List _players = []; [JsonInclude] public Guid Id { get; } = Guid.NewGuid(); + /// + /// Gets or sets the list of players. + /// When setting, the mutable values of the players are updated instead of replacing the list. + /// [JsonIgnore] public List Players { @@ -32,17 +39,36 @@ public List Players } } - [JsonIgnore] public List Ghosts { get; set; } = new(); // TODO include + [JsonIgnore] public List Ghosts { get; set; } = []; // TODO include - [JsonIgnore] private Queue Spawns { get; } = spawns; + /// + /// The spawn locations on the map. + /// + /// + /// A Queue of DirectionalPositions representing the spawn locations on the map. + /// + [JsonIgnore] + private Queue Spawns { get; } = spawns; [JsonIgnore] public DiceCup DiceCup { get; } = new(); // TODO include [JsonInclude] public int Count => Players.Count; // TODO edge-case when game has started but all players have disconnected, Disconnected property? - [JsonInclude] public bool IsGameStarted => Count > 0 && Players.Any(player => player.State is State.InGame); - + /// + /// Whether or not the game has started. + /// + /// + /// The game is considered started if the count is greater than zero and at least one player is in the "InGame" state. + /// + [JsonInclude] + public bool IsGameStarted => Count > 0 && Players.Any(player => player.State is State.InGame); + + /// + /// Gets the next player in the game. + /// + /// The next player. + /// Thrown when there are no players in the game. public Player NextPlayer() { try @@ -59,8 +85,22 @@ public Player NextPlayer() public void Shuffle() => Players.Sort((_, _) => _random.Next(-1, 2)); + /// + /// An event that is invoked when a message is to be sent to all connections. + /// Each player in the game should be listening to this event. + /// + /// + /// The event handler is of type which accepts an of + /// bytes and returns a . + /// This event is typically used to perform some action when something happens. + /// public event Func, Task>? Connections; + /// + /// Adds a player to the game. + /// + /// The player to be added. + /// Thrown when the game is already full or has already started. public void AddPlayer(Player player) { if (Players.Count >= Rules.MaxPlayers) @@ -84,6 +124,10 @@ public void AddPlayer(Player player) return removedPlayer; } + /// + /// Sets the spawn position and current position of the specified player's PacMan character. + /// + /// The player whose PacMan character's spawn and current positions will be set. private void SetSpawn(Player player) { if (player.PacMan.SpawnPosition is not null) return; @@ -92,8 +136,17 @@ private void SetSpawn(Player player) player.PacMan.Position = spawn; } + /// + /// Sends the specified byte segment to all connected clients. + /// + /// The byte segment to send. public void SendToAll(ArraySegment segment) => Connections?.Invoke(segment); + /// + /// Sets the state of the player with the specified username to Ready. + /// + /// The username of the player. + /// An enumerable collection of Player objects. public IEnumerable SetReady(string username) { var player = Players.FirstOrDefault(p => p.Username == username); @@ -103,6 +156,12 @@ public IEnumerable SetReady(string username) return Players; } + /// + /// Sets all players to the "InGame" state if they are currently in the "Ready" state. + /// + /// + /// Returns true if all players were successfully set to the "InGame" state, false otherwise. + /// public bool SetAllInGame() { if (Players.Any(player => player.State is not State.Ready)) return false; @@ -111,6 +170,11 @@ public bool SetAllInGame() return true; } + /// + /// Finds a player by their username. + /// + /// The username of the player to find. + /// The found Player object if a player with the given username is found; otherwise, null. public Player? FindPlayerByUsername(string username) => Players.FirstOrDefault(player => player.Username == username); } diff --git a/pac-man-board-game/Services/GameService.cs b/pac-man-board-game/Services/GameService.cs index c4c6cf5..2ca4f53 100644 --- a/pac-man-board-game/Services/GameService.cs +++ b/pac-man-board-game/Services/GameService.cs @@ -64,13 +64,20 @@ public Game CreateAndJoin(Player player, Queue spawns) return game; } - public Game? FindGameById(Guid id) - { - return Games.FirstOrDefault(game => game.Id == id); - } + /// + /// Finds a game by its ID. + /// + /// The ID of the game. + /// The game with the specified ID, or null if no game was found. + public Game? FindGameById(Guid id) => Games.FirstOrDefault(game => game.Id == id); - public Game? FindGameByUsername(string username) - { - return Games.FirstOrDefault(game => game.Players.Exists(player => player.Username == username)); - } + /// + /// Finds a game by the given username. + /// + /// The username to search for. + /// + /// The found game, if any. Returns null if no game is found. + /// + public Game? FindGameByUsername(string username) => + Games.FirstOrDefault(game => game.Players.Exists(player => player.Username == username)); } diff --git a/pac-man-board-game/Services/WebSocketService.cs b/pac-man-board-game/Services/WebSocketService.cs index e4a415c..ecbf8ef 100644 --- a/pac-man-board-game/Services/WebSocketService.cs +++ b/pac-man-board-game/Services/WebSocketService.cs @@ -10,8 +10,24 @@ public interface IWebSocketService Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string? closeStatusDescription); } +/// +/// WebSocketService class provides methods to send, receive and close a WebSocket connection. +/// public class WebSocketService(ILogger logger) : IWebSocketService { + /// + /// Sends the specified byte array as a text message through the WebSocket connection. + /// + /// The WebSocket connection. + /// The byte array to send. + /// + /// A task representing the asynchronous operation of sending the message. + /// + /// + /// This method sends the specified byte array as a text message through the WebSocket connection. + /// It uses the WebSocket.SendAsync method to send the message asynchronously. + /// After sending the message, it logs a debug message using the logger provided. + /// public async Task Send(WebSocket webSocket, ArraySegment segment) { await webSocket.SendAsync( @@ -23,6 +39,15 @@ await webSocket.SendAsync( logger.LogDebug("Message sent through WebSocket"); } + /// + /// Receives data from a websocket and logs a debug message. + /// + /// The websocket to receive data from. + /// The buffer to store the received data. + /// + /// A task representing the asynchronous operation. The result contains the + /// which contains information about the received data. + /// public async Task Receive(WebSocket webSocket, byte[] buffer) { var result = await webSocket.ReceiveAsync(new ArraySegment(buffer), CancellationToken.None); @@ -32,6 +57,13 @@ public async Task Receive(WebSocket webSocket, byte[] bu return result; } + /// + /// Closes the WebSocket connection with the specified close status and description. + /// + /// The WebSocket connection to close. + /// The status code indicating the reason for the close. + /// The optional description explaining the reason for the close. + /// A task representing the asynchronous operation. public async Task Close(WebSocket webSocket, WebSocketCloseStatus closeStatus, string? closeStatusDescription) { await webSocket.CloseAsync( diff --git a/pac-man-board-game/Utils/Extensions.cs b/pac-man-board-game/Utils/Extensions.cs index fae9f58..236ab0c 100644 --- a/pac-man-board-game/Utils/Extensions.cs +++ b/pac-man-board-game/Utils/Extensions.cs @@ -6,6 +6,12 @@ namespace pacMan.Utils; public static partial class Extensions { + /// + /// Converts the specified byte array into a string using UTF-8 encoding and then removes any invalid characters. + /// + /// The byte array to convert. + /// The number of bytes to decode. + /// The decoded string without any invalid characters. public static string GetString(this byte[] bytes, int length) { var s = Encoding.UTF8.GetString(bytes, 0, length); @@ -13,6 +19,11 @@ public static string GetString(this byte[] bytes, int length) return InvalidCharacters().Replace(s, string.Empty); } + /// + /// Converts an object to an of bytes. + /// + /// The object to convert. + /// An of bytes representing the serialized object in UTF-8 encoding. public static ArraySegment ToArraySegment(this object obj) { var json = JsonSerializer.Serialize(obj); @@ -20,6 +31,10 @@ public static ArraySegment ToArraySegment(this object obj) return new ArraySegment(bytes, 0, json.Length); } + /// + /// Retrieves a regular expression pattern that matches invalid characters. + /// + /// A regular expression pattern for matching invalid characters. [GeneratedRegex("\\p{C}+")] private static partial Regex InvalidCharacters(); } diff --git a/pac-man-board-game/pac-man-board-game.csproj b/pac-man-board-game/pac-man-board-game.csproj index dd6b581..e5ed925 100644 --- a/pac-man-board-game/pac-man-board-game.csproj +++ b/pac-man-board-game/pac-man-board-game.csproj @@ -18,7 +18,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 3e424a127e2212f844c59013ebb90814e61a4c92 Mon Sep 17 00:00:00 2001 From: Martin Berg Alstad <600878@stud.hvl.no> Date: Sun, 10 Dec 2023 15:39:26 +0100 Subject: [PATCH 3/5] Updated build target to dotnet 12. Fixed failed tests and runtime failures --- .../.idea/codeStyles/codeStyleConfig.xml | 1 + BackendTests/BackendTests.csproj | 4 +-- BackendTests/Services/ActionServiceTests.cs | 5 ++-- BackendTests/Services/GameTests.cs | 5 ++-- DataAccessLayer/DataAccessLayer.csproj | 2 +- pac-man-board-game/DTOs/DTO.cs | 30 +++++++------------ pac-man-board-game/Services/ActionService.cs | 2 +- pac-man-board-game/Services/GameService.cs | 2 +- .../Services/WebSocketService.cs | 2 +- pac-man-board-game/pac-man-board-game.csproj | 2 +- 10 files changed, 22 insertions(+), 33 deletions(-) diff --git a/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml index 79ee123..6e6eec1 100644 --- a/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml @@ -1,5 +1,6 @@ \ No newline at end of file diff --git a/BackendTests/BackendTests.csproj b/BackendTests/BackendTests.csproj index 98fa5fa..70244b5 100644 --- a/BackendTests/BackendTests.csproj +++ b/BackendTests/BackendTests.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable enable @@ -13,7 +13,7 @@ - + all diff --git a/BackendTests/Services/ActionServiceTests.cs b/BackendTests/Services/ActionServiceTests.cs index 258fe95..2bfb42d 100644 --- a/BackendTests/Services/ActionServiceTests.cs +++ b/BackendTests/Services/ActionServiceTests.cs @@ -10,8 +10,7 @@ namespace BackendTests.Services; -[TestFixture] -[TestOf(nameof(ActionService))] +[TestFixture, TestOf(nameof(ActionService))] public class ActionServiceTests { [SetUp] @@ -157,7 +156,7 @@ public void Ready_TwoReady() public void FindNextPlayer_NoPlayers() { _service.Game = new pacMan.Services.Game(new Queue()); - Assert.Throws(() => _service.FindNextPlayer()); + Assert.Throws(() => _service.FindNextPlayer()); } [Test] diff --git a/BackendTests/Services/GameTests.cs b/BackendTests/Services/GameTests.cs index 444dc4f..41f5ff8 100644 --- a/BackendTests/Services/GameTests.cs +++ b/BackendTests/Services/GameTests.cs @@ -6,8 +6,7 @@ namespace BackendTests.Services; -[TestFixture] -[TestOf(nameof(pacMan.Services.Game))] +[TestFixture, TestOf(nameof(pacMan.Services.Game))] public class GameTests { [SetUp] @@ -56,7 +55,7 @@ private void AddFullParty() [Test] public void NextPlayer_WhenEmpty() { - Assert.Throws(() => _game.NextPlayer()); + Assert.Throws(() => _game.NextPlayer()); } [Test] diff --git a/DataAccessLayer/DataAccessLayer.csproj b/DataAccessLayer/DataAccessLayer.csproj index dd09258..76ba19a 100644 --- a/DataAccessLayer/DataAccessLayer.csproj +++ b/DataAccessLayer/DataAccessLayer.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable enable DAL diff --git a/pac-man-board-game/DTOs/DTO.cs b/pac-man-board-game/DTOs/DTO.cs index 8cb82f8..1316faf 100644 --- a/pac-man-board-game/DTOs/DTO.cs +++ b/pac-man-board-game/DTOs/DTO.cs @@ -5,11 +5,9 @@ namespace pacMan.DTOs; public readonly record struct JoinGameData( - [property: JsonInclude] - [property: JsonPropertyName("username")] + [property: JsonInclude, JsonPropertyName("username"), JsonRequired] string Username, - [property: JsonInclude] - [property: JsonPropertyName("gameId")] + [property: JsonInclude, JsonPropertyName("gameId"), JsonRequired] Guid GameId ) { @@ -17,34 +15,26 @@ Guid GameId } public readonly record struct CreateGameData( - [property: JsonInclude] - [property: JsonPropertyName("player")] + [property: JsonInclude, JsonPropertyName("player"), JsonRequired] Player Player, - [property: JsonInclude] - [property: JsonPropertyName("spawns")] + [property: JsonInclude, JsonPropertyName("spawns"), JsonRequired] Queue Spawns ); public readonly record struct ReadyData( - [property: JsonInclude] - [property: JsonPropertyName("allReady")] + [property: JsonInclude, JsonPropertyName("allReady"), JsonRequired] bool AllReady, - [property: JsonInclude] - [property: JsonPropertyName("players")] + [property: JsonInclude, JsonPropertyName("players"), JsonRequired] IEnumerable Players ); public readonly record struct MovePlayerData( - [property: JsonInclude] - [property: JsonPropertyName("players")] + [property: JsonInclude, JsonPropertyName("players"), JsonRequired] List Players, - [property: JsonInclude] - [property: JsonPropertyName("ghosts")] + [property: JsonInclude, JsonPropertyName("ghosts"), JsonRequired] List Ghosts, - [property: JsonInclude] - [property: JsonPropertyName("dice")] + [property: JsonInclude, JsonPropertyName("dice"), JsonRequired] List Dice, - [property: JsonInclude] - [property: JsonPropertyName("eatenPellets")] + [property: JsonInclude, JsonPropertyName("eatenPellets"), JsonRequired] List EatenPellets ); diff --git a/pac-man-board-game/Services/ActionService.cs b/pac-man-board-game/Services/ActionService.cs index 9a3d193..0fd2172 100644 --- a/pac-man-board-game/Services/ActionService.cs +++ b/pac-man-board-game/Services/ActionService.cs @@ -24,7 +24,7 @@ public interface IActionService /// /// Provides various actions that can be performed in a game /// -public class ActionService(ILogger logger, IGameService gameService) : IActionService +public class ActionService(ILogger logger, IGameService gameService) : IActionService { public WebSocket WebSocket { private get; set; } = null!; diff --git a/pac-man-board-game/Services/GameService.cs b/pac-man-board-game/Services/GameService.cs index 2ca4f53..2fa6b03 100644 --- a/pac-man-board-game/Services/GameService.cs +++ b/pac-man-board-game/Services/GameService.cs @@ -17,7 +17,7 @@ public interface IGameService : IWebSocketService /// The GameService class provides functionality for managing games in a WebSocket environment. It inherits from the /// WebSocketService class. /// -public class GameService(ILogger logger) : WebSocketService(logger), IGameService +public class GameService(ILogger logger) : WebSocketService(logger), IGameService { /// /// A thread-safe collection (SynchronizedCollection) of "Game" objects. Utilized for managing multiple game instances diff --git a/pac-man-board-game/Services/WebSocketService.cs b/pac-man-board-game/Services/WebSocketService.cs index ecbf8ef..a348fea 100644 --- a/pac-man-board-game/Services/WebSocketService.cs +++ b/pac-man-board-game/Services/WebSocketService.cs @@ -13,7 +13,7 @@ public interface IWebSocketService /// /// WebSocketService class provides methods to send, receive and close a WebSocket connection. /// -public class WebSocketService(ILogger logger) : IWebSocketService +public class WebSocketService(ILogger logger) : IWebSocketService { /// /// Sends the specified byte array as a text message through the WebSocket connection. diff --git a/pac-man-board-game/pac-man-board-game.csproj b/pac-man-board-game/pac-man-board-game.csproj index e5ed925..8c03a07 100644 --- a/pac-man-board-game/pac-man-board-game.csproj +++ b/pac-man-board-game/pac-man-board-game.csproj @@ -1,7 +1,7 @@ - net7.0 + net8.0 enable true Latest From f41d9985d9138bf5bd167a6125e820aab722ed13 Mon Sep 17 00:00:00 2001 From: Martin Berg Alstad <600878@stud.hvl.no> Date: Thu, 21 Dec 2023 11:46:41 +0100 Subject: [PATCH 4/5] Updated dependencies. Replaced deprecated coverage package with new --- .../.idea/codeStyles/codeStyleConfig.xml | 1 - pac-man-board-game/ClientApp/package.json | 34 +- pac-man-board-game/ClientApp/pnpm-lock.yaml | 1264 ++++++++++------- pac-man-board-game/pac-man-board-game.csproj | 4 +- 4 files changed, 781 insertions(+), 522 deletions(-) diff --git a/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml b/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml index 6e6eec1..79ee123 100644 --- a/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml +++ b/.idea/.idea.pac-man-board-game/.idea/codeStyles/codeStyleConfig.xml @@ -1,6 +1,5 @@ \ No newline at end of file diff --git a/pac-man-board-game/ClientApp/package.json b/pac-man-board-game/ClientApp/package.json index f24f8c8..b4882bc 100644 --- a/pac-man-board-game/ClientApp/package.json +++ b/pac-man-board-game/ClientApp/package.json @@ -5,32 +5,32 @@ "dependencies": { "@emotion/react": "^11.11.1", "@headlessui/react": "^1.7.17", - "@heroicons/react": "^2.0.18", - "jotai": "^2.5.0", - "jotai-devtools": "^0.7.0", + "@heroicons/react": "^2.1.1", + "jotai": "^2.6.0", + "jotai-devtools": "^0.7.1", "oidc-client": "^1.11.5", "react": "^18.2.0", "react-dom": "^18.2.0", - "react-router-dom": "^6.17.0", + "react-router-dom": "^6.21.0", "web-vitals": "^3.5.0" }, "devDependencies": { - "@types/react": "^18.2.33", - "@types/react-dom": "^18.2.14", - "@vitejs/plugin-react": "^4.1.0", - "@vitest/coverage-c8": "^0.33.0", + "@types/react": "^18.2.45", + "@types/react-dom": "^18.2.18", + "@vitejs/plugin-react": "^4.2.1", + "@vitest/coverage-v8": "^1.1.0", "autoprefixer": "^10.4.16", "cross-env": "^7.0.3", "happy-dom": "^12.10.3", - "postcss": "^8.4.31", - "prettier": "^3.0.3", - "tailwindcss": "^3.3.5", - "typescript": "^5.2.2", - "vite": "^4.5.0", - "vite-plugin-node-polyfills": "^0.15.0", - "vite-plugin-svgr": "^4.1.0", - "vite-tsconfig-paths": "^4.2.1", - "vitest": "^0.34.6" + "postcss": "^8.4.32", + "prettier": "^3.1.1", + "tailwindcss": "^3.4.0", + "typescript": "^5.3.3", + "vite": "^5.0.10", + "vite-plugin-node-polyfills": "^0.17.0", + "vite-plugin-svgr": "^4.2.0", + "vite-tsconfig-paths": "^4.2.2", + "vitest": "^1.1.0" }, "resolutions": { "css-what": "^5.0.1", diff --git a/pac-man-board-game/ClientApp/pnpm-lock.yaml b/pac-man-board-game/ClientApp/pnpm-lock.yaml index 6778874..c0f938f 100644 --- a/pac-man-board-game/ClientApp/pnpm-lock.yaml +++ b/pac-man-board-game/ClientApp/pnpm-lock.yaml @@ -14,19 +14,19 @@ importers: dependencies: '@emotion/react': specifier: ^11.11.1 - version: 11.11.1(@types/react@18.2.33)(react@18.2.0) + version: 11.11.1(@types/react@18.2.45)(react@18.2.0) '@headlessui/react': specifier: ^1.7.17 version: 1.7.17(react-dom@18.2.0)(react@18.2.0) '@heroicons/react': - specifier: ^2.0.18 - version: 2.0.18(react@18.2.0) + specifier: ^2.1.1 + version: 2.1.1(react@18.2.0) jotai: - specifier: ^2.5.0 - version: 2.5.0(@types/react@18.2.33)(react@18.2.0) + specifier: ^2.6.0 + version: 2.6.0(@types/react@18.2.45)(react@18.2.0) jotai-devtools: - specifier: ^0.7.0 - version: 0.7.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) + specifier: ^0.7.1 + version: 0.7.1(@emotion/react@11.11.1)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1) oidc-client: specifier: ^1.11.5 version: 1.11.5 @@ -37,27 +37,27 @@ importers: specifier: ^18.2.0 version: 18.2.0(react@18.2.0) react-router-dom: - specifier: ^6.17.0 - version: 6.17.0(react-dom@18.2.0)(react@18.2.0) + specifier: ^6.21.0 + version: 6.21.0(react-dom@18.2.0)(react@18.2.0) web-vitals: specifier: ^3.5.0 version: 3.5.0 devDependencies: '@types/react': - specifier: ^18.2.33 - version: 18.2.33 + specifier: ^18.2.45 + version: 18.2.45 '@types/react-dom': - specifier: ^18.2.14 - version: 18.2.14 + specifier: ^18.2.18 + version: 18.2.18 '@vitejs/plugin-react': - specifier: ^4.1.0 - version: 4.1.0(vite@4.5.0) - '@vitest/coverage-c8': - specifier: ^0.33.0 - version: 0.33.0(vitest@0.34.6) + specifier: ^4.2.1 + version: 4.2.1(vite@5.0.10) + '@vitest/coverage-v8': + specifier: ^1.1.0 + version: 1.1.0(vitest@1.1.0) autoprefixer: specifier: ^10.4.16 - version: 10.4.16(postcss@8.4.31) + version: 10.4.16(postcss@8.4.32) cross-env: specifier: ^7.0.3 version: 7.0.3 @@ -65,32 +65,32 @@ importers: specifier: ^12.10.3 version: 12.10.3 postcss: - specifier: ^8.4.31 - version: 8.4.31 + specifier: ^8.4.32 + version: 8.4.32 prettier: - specifier: ^3.0.3 - version: 3.0.3 + specifier: ^3.1.1 + version: 3.1.1 tailwindcss: - specifier: ^3.3.5 - version: 3.3.5 + specifier: ^3.4.0 + version: 3.4.0 typescript: - specifier: ^5.2.2 - version: 5.2.2 + specifier: ^5.3.3 + version: 5.3.3 vite: - specifier: ^4.5.0 - version: 4.5.0(@types/node@20.4.5) + specifier: ^5.0.10 + version: 5.0.10 vite-plugin-node-polyfills: - specifier: ^0.15.0 - version: 0.15.0(vite@4.5.0) + specifier: ^0.17.0 + version: 0.17.0(vite@5.0.10) vite-plugin-svgr: - specifier: ^4.1.0 - version: 4.1.0(vite@4.5.0) + specifier: ^4.2.0 + version: 4.2.0(vite@5.0.10) vite-tsconfig-paths: - specifier: ^4.2.1 - version: 4.2.1(typescript@5.2.2)(vite@4.5.0) + specifier: ^4.2.2 + version: 4.2.2(typescript@5.3.3)(vite@5.0.10) vitest: - specifier: ^0.34.6 - version: 0.34.6(happy-dom@12.10.3) + specifier: ^1.1.0 + version: 1.1.0(happy-dom@12.10.3) packages: @@ -114,11 +114,24 @@ packages: '@babel/highlight': 7.22.20 chalk: 2.4.2 + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/highlight': 7.23.4 + chalk: 2.4.2 + dev: true + /@babel/compat-data@7.22.9: resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} engines: {node: '>=6.9.0'} dev: true + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/core@7.23.2: resolution: {integrity: sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ==} engines: {node: '>=6.9.0'} @@ -142,6 +155,29 @@ packages: - supports-color dev: true + /@babel/core@7.23.6: + resolution: {integrity: sha512-FxpRyGjrMJXh7X3wGLGhNDCRiwpWEF74sKjTLDJSG5Kyvow3QZaG0Adbqzi9ZrVjTWpsX+2cxWXD71NMg93kdw==} + engines: {node: '>=6.9.0'} + dependencies: + '@ampproject/remapping': 2.2.1 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.23.6) + '@babel/helpers': 7.23.6 + '@babel/parser': 7.23.6 + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 + convert-source-map: 2.0.0 + debug: 4.3.4 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/generator@7.23.0: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} @@ -152,6 +188,16 @@ packages: jsesc: 2.5.2 dev: true + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/types': 7.23.6 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 + dev: true + /@babel/helper-compilation-targets@7.22.15: resolution: {integrity: sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==} engines: {node: '>=6.9.0'} @@ -163,6 +209,17 @@ packages: semver: 6.3.1 dev: true + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.22.2 + lru-cache: 5.1.1 + semver: 6.3.1 + dev: true + /@babel/helper-environment-visitor@7.22.20: resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} @@ -173,21 +230,21 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@babel/template': 7.22.15 - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-module-imports@7.22.15: resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-module-imports@7.22.5: @@ -211,6 +268,20 @@ packages: '@babel/helper-validator-identifier': 7.22.20 dev: true + /@babel/helper-module-transforms@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + dependencies: + '@babel/core': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-simple-access': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/helper-validator-identifier': 7.22.20 + dev: true + /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} engines: {node: '>=6.9.0'} @@ -220,20 +291,25 @@ packages: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.23.6 dev: true /@babel/helper-string-parser@7.22.5: resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} engines: {node: '>=6.9.0'} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} @@ -243,6 +319,11 @@ packages: engines: {node: '>=6.9.0'} dev: true + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} + engines: {node: '>=6.9.0'} + dev: true + /@babel/helpers@7.23.2: resolution: {integrity: sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==} engines: {node: '>=6.9.0'} @@ -254,6 +335,17 @@ packages: - supports-color dev: true + /@babel/helpers@7.23.6: + resolution: {integrity: sha512-wCfsbN4nBidDRhpDhvcKlzHWCTlgJYUUdSJfzXb2NuBssDSIjc3xcb+znA7l+zYsFljAcGM0aFkN40cR3lXiGA==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/template': 7.22.15 + '@babel/traverse': 7.23.6 + '@babel/types': 7.23.6 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/highlight@7.22.20: resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} engines: {node: '>=6.9.0'} @@ -262,6 +354,15 @@ packages: chalk: 2.4.2 js-tokens: 4.0.0 + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-validator-identifier': 7.22.20 + chalk: 2.4.2 + js-tokens: 4.0.0 + dev: true + /@babel/parser@7.23.0: resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} @@ -270,23 +371,31 @@ packages: '@babel/types': 7.23.0 dev: true - /@babel/plugin-transform-react-jsx-self@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g==} + /@babel/parser@7.23.6: + resolution: {integrity: sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.23.6 + dev: true + + /@babel/plugin-transform-react-jsx-self@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-qXRvbeKDSfwnlJnanVRp0SfuWE5DQhwQr5xtLBzp56Wabyo+4CMosF6Kfp+eOD/4FYpql64XVJ2W0pVLlJZxOQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx-source@7.22.5(@babel/core@7.23.2): - resolution: {integrity: sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w==} + /@babel/plugin-transform-react-jsx-source@7.23.3(@babel/core@7.23.6): + resolution: {integrity: sha512-91RS0MDnAWDNvGC6Wio5XYkyWI39FMFO+JK9+4AlgaTH+yWwVTsw7/sn6LK0lH7c5F+TFkpv/3LfCJ1Ydwof/g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.23.2 + '@babel/core': 7.23.6 '@babel/helper-plugin-utils': 7.22.5 dev: true @@ -297,13 +406,20 @@ packages: regenerator-runtime: 0.13.11 dev: false + /@babel/runtime@7.23.6: + resolution: {integrity: sha512-zHd0eUrf5GZoOWVCXp6koAKQTfZV07eit6bGPmJgnZdnSAvvZee6zniW2XMF7Cmc4ISOOnPy3QaSiIJGJkVEDQ==} + engines: {node: '>=6.9.0'} + dependencies: + regenerator-runtime: 0.14.1 + dev: false + /@babel/template@7.22.15: resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.13 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 dev: true /@babel/traverse@7.23.2: @@ -324,6 +440,24 @@ packages: - supports-color dev: true + /@babel/traverse@7.23.6: + resolution: {integrity: sha512-czastdK1e8YByZqezMPFiZ8ahwVMh/ESl9vPgvgdB9AmFMGP5jfpFax74AQgl5zj4XHzqeYAg2l8PuUeRS1MgQ==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + debug: 4.3.4 + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + dev: true + /@babel/types@7.23.0: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} engines: {node: '>=6.9.0'} @@ -332,6 +466,15 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 + /@babel/types@7.23.6: + resolution: {integrity: sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: true + /@bcoe/v8-coverage@0.2.3: resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} dev: true @@ -370,7 +513,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.1(@types/react@18.2.33)(react@18.2.0): + /@emotion/react@11.11.1(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' @@ -386,7 +529,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.33 + '@types/react': 18.2.45 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -425,8 +568,17 @@ packages: resolution: {integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==} dev: false - /@esbuild/android-arm64@0.18.17: - resolution: {integrity: sha512-9np+YYdNDed5+Jgr1TdWBsozZ85U1Oa3xW0c7TWqH0y2aGghXtZsuT8nYRbzOMcl0bXZXjOGbksoTtVOlWrRZg==} + /@esbuild/aix-ppc64@0.19.10: + resolution: {integrity: sha512-Q+mk96KJ+FZ30h9fsJl+67IjNJm3x2eX+GBWGmocAKgzp27cowCOOqSdscX80s0SpdFXZnIv/+1xD1EctFx96Q==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + requiresBuild: true + dev: true + optional: true + + /@esbuild/android-arm64@0.19.10: + resolution: {integrity: sha512-1X4CClKhDgC3by7k8aOWZeBXQX8dHT5QAMCAQDArCLaYfkppoARvh0fit3X2Qs+MXDngKcHv6XXyQCpY0hkK1Q==} engines: {node: '>=12'} cpu: [arm64] os: [android] @@ -434,8 +586,8 @@ packages: dev: true optional: true - /@esbuild/android-arm@0.18.17: - resolution: {integrity: sha512-wHsmJG/dnL3OkpAcwbgoBTTMHVi4Uyou3F5mf58ZtmUyIKfcdA7TROav/6tCzET4A3QW2Q2FC+eFneMU+iyOxg==} + /@esbuild/android-arm@0.19.10: + resolution: {integrity: sha512-7W0bK7qfkw1fc2viBfrtAEkDKHatYfHzr/jKAHNr9BvkYDXPcC6bodtm8AyLJNNuqClLNaeTLuwURt4PRT9d7w==} engines: {node: '>=12'} cpu: [arm] os: [android] @@ -443,8 +595,8 @@ packages: dev: true optional: true - /@esbuild/android-x64@0.18.17: - resolution: {integrity: sha512-O+FeWB/+xya0aLg23hHEM2E3hbfwZzjqumKMSIqcHbNvDa+dza2D0yLuymRBQQnC34CWrsJUXyH2MG5VnLd6uw==} + /@esbuild/android-x64@0.19.10: + resolution: {integrity: sha512-O/nO/g+/7NlitUxETkUv/IvADKuZXyH4BHf/g/7laqKC4i/7whLpB0gvpPc2zpF0q9Q6FXS3TS75QHac9MvVWw==} engines: {node: '>=12'} cpu: [x64] os: [android] @@ -452,8 +604,8 @@ packages: dev: true optional: true - /@esbuild/darwin-arm64@0.18.17: - resolution: {integrity: sha512-M9uJ9VSB1oli2BE/dJs3zVr9kcCBBsE883prage1NWz6pBS++1oNn/7soPNS3+1DGj0FrkSvnED4Bmlu1VAE9g==} + /@esbuild/darwin-arm64@0.19.10: + resolution: {integrity: sha512-YSRRs2zOpwypck+6GL3wGXx2gNP7DXzetmo5pHXLrY/VIMsS59yKfjPizQ4lLt5vEI80M41gjm2BxrGZ5U+VMA==} engines: {node: '>=12'} cpu: [arm64] os: [darwin] @@ -461,8 +613,8 @@ packages: dev: true optional: true - /@esbuild/darwin-x64@0.18.17: - resolution: {integrity: sha512-XDre+J5YeIJDMfp3n0279DFNrGCXlxOuGsWIkRb1NThMZ0BsrWXoTg23Jer7fEXQ9Ye5QjrvXpxnhzl3bHtk0g==} + /@esbuild/darwin-x64@0.19.10: + resolution: {integrity: sha512-alfGtT+IEICKtNE54hbvPg13xGBe4GkVxyGWtzr+yHO7HIiRJppPDhOKq3zstTcVf8msXb/t4eavW3jCDpMSmA==} engines: {node: '>=12'} cpu: [x64] os: [darwin] @@ -470,8 +622,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-arm64@0.18.17: - resolution: {integrity: sha512-cjTzGa3QlNfERa0+ptykyxs5A6FEUQQF0MuilYXYBGdBxD3vxJcKnzDlhDCa1VAJCmAxed6mYhA2KaJIbtiNuQ==} + /@esbuild/freebsd-arm64@0.19.10: + resolution: {integrity: sha512-dMtk1wc7FSH8CCkE854GyGuNKCewlh+7heYP/sclpOG6Cectzk14qdUIY5CrKDbkA/OczXq9WesqnPl09mj5dg==} engines: {node: '>=12'} cpu: [arm64] os: [freebsd] @@ -479,8 +631,8 @@ packages: dev: true optional: true - /@esbuild/freebsd-x64@0.18.17: - resolution: {integrity: sha512-sOxEvR8d7V7Kw8QqzxWc7bFfnWnGdaFBut1dRUYtu+EIRXefBc/eIsiUiShnW0hM3FmQ5Zf27suDuHsKgZ5QrA==} + /@esbuild/freebsd-x64@0.19.10: + resolution: {integrity: sha512-G5UPPspryHu1T3uX8WiOEUa6q6OlQh6gNl4CO4Iw5PS+Kg5bVggVFehzXBJY6X6RSOMS8iXDv2330VzaObm4Ag==} engines: {node: '>=12'} cpu: [x64] os: [freebsd] @@ -488,8 +640,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm64@0.18.17: - resolution: {integrity: sha512-c9w3tE7qA3CYWjT+M3BMbwMt+0JYOp3vCMKgVBrCl1nwjAlOMYzEo+gG7QaZ9AtqZFj5MbUc885wuBBmu6aADQ==} + /@esbuild/linux-arm64@0.19.10: + resolution: {integrity: sha512-QxaouHWZ+2KWEj7cGJmvTIHVALfhpGxo3WLmlYfJ+dA5fJB6lDEIg+oe/0//FuyVHuS3l79/wyBxbHr0NgtxJQ==} engines: {node: '>=12'} cpu: [arm64] os: [linux] @@ -497,8 +649,8 @@ packages: dev: true optional: true - /@esbuild/linux-arm@0.18.17: - resolution: {integrity: sha512-2d3Lw6wkwgSLC2fIvXKoMNGVaeY8qdN0IC3rfuVxJp89CRfA3e3VqWifGDfuakPmp90+ZirmTfye1n4ncjv2lg==} + /@esbuild/linux-arm@0.19.10: + resolution: {integrity: sha512-j6gUW5aAaPgD416Hk9FHxn27On28H4eVI9rJ4az7oCGTFW48+LcgNDBN+9f8rKZz7EEowo889CPKyeaD0iw9Kg==} engines: {node: '>=12'} cpu: [arm] os: [linux] @@ -506,8 +658,8 @@ packages: dev: true optional: true - /@esbuild/linux-ia32@0.18.17: - resolution: {integrity: sha512-1DS9F966pn5pPnqXYz16dQqWIB0dmDfAQZd6jSSpiT9eX1NzKh07J6VKR3AoXXXEk6CqZMojiVDSZi1SlmKVdg==} + /@esbuild/linux-ia32@0.19.10: + resolution: {integrity: sha512-4ub1YwXxYjj9h1UIZs2hYbnTZBtenPw5NfXCRgEkGb0b6OJ2gpkMvDqRDYIDRjRdWSe/TBiZltm3Y3Q8SN1xNg==} engines: {node: '>=12'} cpu: [ia32] os: [linux] @@ -515,8 +667,8 @@ packages: dev: true optional: true - /@esbuild/linux-loong64@0.18.17: - resolution: {integrity: sha512-EvLsxCk6ZF0fpCB6w6eOI2Fc8KW5N6sHlIovNe8uOFObL2O+Mr0bflPHyHwLT6rwMg9r77WOAWb2FqCQrVnwFg==} + /@esbuild/linux-loong64@0.19.10: + resolution: {integrity: sha512-lo3I9k+mbEKoxtoIbM0yC/MZ1i2wM0cIeOejlVdZ3D86LAcFXFRdeuZmh91QJvUTW51bOK5W2BznGNIl4+mDaA==} engines: {node: '>=12'} cpu: [loong64] os: [linux] @@ -524,8 +676,8 @@ packages: dev: true optional: true - /@esbuild/linux-mips64el@0.18.17: - resolution: {integrity: sha512-e0bIdHA5p6l+lwqTE36NAW5hHtw2tNRmHlGBygZC14QObsA3bD4C6sXLJjvnDIjSKhW1/0S3eDy+QmX/uZWEYQ==} + /@esbuild/linux-mips64el@0.19.10: + resolution: {integrity: sha512-J4gH3zhHNbdZN0Bcr1QUGVNkHTdpijgx5VMxeetSk6ntdt+vR1DqGmHxQYHRmNb77tP6GVvD+K0NyO4xjd7y4A==} engines: {node: '>=12'} cpu: [mips64el] os: [linux] @@ -533,8 +685,8 @@ packages: dev: true optional: true - /@esbuild/linux-ppc64@0.18.17: - resolution: {integrity: sha512-BAAilJ0M5O2uMxHYGjFKn4nJKF6fNCdP1E0o5t5fvMYYzeIqy2JdAP88Az5LHt9qBoUa4tDaRpfWt21ep5/WqQ==} + /@esbuild/linux-ppc64@0.19.10: + resolution: {integrity: sha512-tgT/7u+QhV6ge8wFMzaklOY7KqiyitgT1AUHMApau32ZlvTB/+efeCtMk4eXS+uEymYK249JsoiklZN64xt6oQ==} engines: {node: '>=12'} cpu: [ppc64] os: [linux] @@ -542,8 +694,8 @@ packages: dev: true optional: true - /@esbuild/linux-riscv64@0.18.17: - resolution: {integrity: sha512-Wh/HW2MPnC3b8BqRSIme/9Zhab36PPH+3zam5pqGRH4pE+4xTrVLx2+XdGp6fVS3L2x+DrsIcsbMleex8fbE6g==} + /@esbuild/linux-riscv64@0.19.10: + resolution: {integrity: sha512-0f/spw0PfBMZBNqtKe5FLzBDGo0SKZKvMl5PHYQr3+eiSscfJ96XEknCe+JoOayybWUFQbcJTrk946i3j9uYZA==} engines: {node: '>=12'} cpu: [riscv64] os: [linux] @@ -551,8 +703,8 @@ packages: dev: true optional: true - /@esbuild/linux-s390x@0.18.17: - resolution: {integrity: sha512-j/34jAl3ul3PNcK3pfI0NSlBANduT2UO5kZ7FCaK33XFv3chDhICLY8wJJWIhiQ+YNdQ9dxqQctRg2bvrMlYgg==} + /@esbuild/linux-s390x@0.19.10: + resolution: {integrity: sha512-pZFe0OeskMHzHa9U38g+z8Yx5FNCLFtUnJtQMpwhS+r4S566aK2ci3t4NCP4tjt6d5j5uo4h7tExZMjeKoehAA==} engines: {node: '>=12'} cpu: [s390x] os: [linux] @@ -560,8 +712,8 @@ packages: dev: true optional: true - /@esbuild/linux-x64@0.18.17: - resolution: {integrity: sha512-QM50vJ/y+8I60qEmFxMoxIx4de03pGo2HwxdBeFd4nMh364X6TIBZ6VQ5UQmPbQWUVWHWws5MmJXlHAXvJEmpQ==} + /@esbuild/linux-x64@0.19.10: + resolution: {integrity: sha512-SpYNEqg/6pZYoc+1zLCjVOYvxfZVZj6w0KROZ3Fje/QrM3nfvT2llI+wmKSrWuX6wmZeTapbarvuNNK/qepSgA==} engines: {node: '>=12'} cpu: [x64] os: [linux] @@ -569,8 +721,8 @@ packages: dev: true optional: true - /@esbuild/netbsd-x64@0.18.17: - resolution: {integrity: sha512-/jGlhWR7Sj9JPZHzXyyMZ1RFMkNPjC6QIAan0sDOtIo2TYk3tZn5UDrkE0XgsTQCxWTTOcMPf9p6Rh2hXtl5TQ==} + /@esbuild/netbsd-x64@0.19.10: + resolution: {integrity: sha512-ACbZ0vXy9zksNArWlk2c38NdKg25+L9pr/mVaj9SUq6lHZu/35nx2xnQVRGLrC1KKQqJKRIB0q8GspiHI3J80Q==} engines: {node: '>=12'} cpu: [x64] os: [netbsd] @@ -578,8 +730,8 @@ packages: dev: true optional: true - /@esbuild/openbsd-x64@0.18.17: - resolution: {integrity: sha512-rSEeYaGgyGGf4qZM2NonMhMOP/5EHp4u9ehFiBrg7stH6BYEEjlkVREuDEcQ0LfIl53OXLxNbfuIj7mr5m29TA==} + /@esbuild/openbsd-x64@0.19.10: + resolution: {integrity: sha512-PxcgvjdSjtgPMiPQrM3pwSaG4kGphP+bLSb+cihuP0LYdZv1epbAIecHVl5sD3npkfYBZ0ZnOjR878I7MdJDFg==} engines: {node: '>=12'} cpu: [x64] os: [openbsd] @@ -587,8 +739,8 @@ packages: dev: true optional: true - /@esbuild/sunos-x64@0.18.17: - resolution: {integrity: sha512-Y7ZBbkLqlSgn4+zot4KUNYst0bFoO68tRgI6mY2FIM+b7ZbyNVtNbDP5y8qlu4/knZZ73fgJDlXID+ohY5zt5g==} + /@esbuild/sunos-x64@0.19.10: + resolution: {integrity: sha512-ZkIOtrRL8SEJjr+VHjmW0znkPs+oJXhlJbNwfI37rvgeMtk3sxOQevXPXjmAPZPigVTncvFqLMd+uV0IBSEzqA==} engines: {node: '>=12'} cpu: [x64] os: [sunos] @@ -596,8 +748,8 @@ packages: dev: true optional: true - /@esbuild/win32-arm64@0.18.17: - resolution: {integrity: sha512-bwPmTJsEQcbZk26oYpc4c/8PvTY3J5/QK8jM19DVlEsAB41M39aWovWoHtNm78sd6ip6prilxeHosPADXtEJFw==} + /@esbuild/win32-arm64@0.19.10: + resolution: {integrity: sha512-+Sa4oTDbpBfGpl3Hn3XiUe4f8TU2JF7aX8cOfqFYMMjXp6ma6NJDztl5FDG8Ezx0OjwGikIHw+iA54YLDNNVfw==} engines: {node: '>=12'} cpu: [arm64] os: [win32] @@ -605,8 +757,8 @@ packages: dev: true optional: true - /@esbuild/win32-ia32@0.18.17: - resolution: {integrity: sha512-H/XaPtPKli2MhW+3CQueo6Ni3Avggi6hP/YvgkEe1aSaxw+AeO8MFjq8DlgfTd9Iz4Yih3QCZI6YLMoyccnPRg==} + /@esbuild/win32-ia32@0.19.10: + resolution: {integrity: sha512-EOGVLK1oWMBXgfttJdPHDTiivYSjX6jDNaATeNOaCOFEVcfMjtbx7WVQwPSE1eIfCp/CaSF2nSrDtzc4I9f8TQ==} engines: {node: '>=12'} cpu: [ia32] os: [win32] @@ -614,8 +766,8 @@ packages: dev: true optional: true - /@esbuild/win32-x64@0.18.17: - resolution: {integrity: sha512-fGEb8f2BSA3CW7riJVurug65ACLuQAzKq0SSqkY2b2yHHH0MzDfbLyKIGzHwOI/gkHcxM/leuSW6D5w/LMNitA==} + /@esbuild/win32-x64@0.19.10: + resolution: {integrity: sha512-whqLG6Sc70AbU73fFYvuYzaE4MNMBIlR1Y/IrUeOXFrWHxBEjjbZaQ3IXIQS8wJdAzue2GwYZCjOrgrU1oUHoA==} engines: {node: '>=12'} cpu: [x64] os: [win32] @@ -676,8 +828,8 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /@heroicons/react@2.0.18(react@18.2.0): - resolution: {integrity: sha512-7TyMjRrZZMBPa+/5Y8lN0iyvUU/01PeMGX2+RE7cQWpEUIcb4QotzUObFkJDejj/HUH4qjP/eQ0gzzKs2f+6Yw==} + /@heroicons/react@2.1.1(react@18.2.0): + resolution: {integrity: sha512-JyyN9Lo66kirbCMuMMRPtJxtKJoIsXKS569ebHGGRKbl8s4CtUfLnyKJxteA+vIKySocO4s1SkTkGS4xtG/yEA==} peerDependencies: react: '>= 16' dependencies: @@ -689,8 +841,8 @@ packages: engines: {node: '>=8'} dev: true - /@jest/schemas@29.6.0: - resolution: {integrity: sha512-rxLjXyJBTL4LQeJW3aKo0M/+GkCOXsO+8i9Iu7eDb6KwtP65ayoDsitrdPBtujxQ88k4wI2FNYfa6TOGwSn6cQ==} + /@jest/schemas@29.6.3: + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@sinclair/typebox': 0.27.8 @@ -730,7 +882,7 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@mantine/core@6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0): + /@mantine/core@6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-Kx4RrRfv0I+cOCIcsq/UA2aWcYLyXgW3aluAuW870OdXnbII6qg7RW28D+r9D76SHPxWFKwIKwmcucAG08Divg==} peerDependencies: '@mantine/hooks': 6.0.21 @@ -744,8 +896,8 @@ packages: '@radix-ui/react-scroll-area': 1.0.2(react-dom@18.2.0)(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-remove-scroll: 2.5.6(@types/react@18.2.33)(react@18.2.0) - react-textarea-autosize: 8.3.4(@types/react@18.2.33)(react@18.2.0) + react-remove-scroll: 2.5.6(@types/react@18.2.45)(react@18.2.0) + react-textarea-autosize: 8.3.4(@types/react@18.2.45)(react@18.2.0) transitivePeerDependencies: - '@emotion/react' - '@types/react' @@ -767,7 +919,7 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@mantine/core': 6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) + '@mantine/core': 6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) '@mantine/hooks': 6.0.21(react@18.2.0) '@mantine/utils': 6.0.21(react@18.2.0) prism-react-renderer: 1.3.5(react@18.2.0) @@ -782,7 +934,7 @@ packages: react: '>=16.8.0' react-dom: '>=16.8.0' dependencies: - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.45)(react@18.2.0) clsx: 1.1.1 csstype: 3.0.9 react: 18.2.0 @@ -930,47 +1082,33 @@ packages: react: 18.2.0 dev: false - /@redux-devtools/extension@3.2.5(redux@4.2.1): - resolution: {integrity: sha512-UhyDF7WmdnCrN1s++YC4sdQCo0z6YUnoB2eCh15nXDDq3QH1jDju1144UNRU6Nvi4inxhaIum4m9BXVYWVC1ng==} + /@redux-devtools/extension@3.3.0(redux@4.2.1): + resolution: {integrity: sha512-X34S/rC8S/M1BIrkYD1mJ5f8vlH0BDqxXrs96cvxSBo4FhMdbhU+GUGsmNYov1xjSyLMHgo8NYrUG8bNX7525g==} peerDependencies: - redux: ^3.1.0 || ^4.0.0 + redux: ^3.1.0 || ^4.0.0 || ^5.0.0 dependencies: - '@babel/runtime': 7.22.6 - immutable: 4.3.1 + '@babel/runtime': 7.23.6 + immutable: 4.3.4 redux: 4.2.1 dev: false - /@remix-run/router@1.10.0: - resolution: {integrity: sha512-Lm+fYpMfZoEucJ7cMxgt4dYt8jLfbpwRCzAjm9UgSLOkmlqo9gupxt6YX3DY0Fk155NT9l17d/ydi+964uS9Lw==} + /@remix-run/router@1.14.0: + resolution: {integrity: sha512-WOHih+ClN7N8oHk9N4JUiMxQJmRVaOxcg8w7F/oHUXzJt920ekASLI/7cYX8XkntDWRhLZtsk6LbGrkgOAvi5A==} engines: {node: '>=14.0.0'} dev: false - /@rollup/plugin-inject@5.0.3: - resolution: {integrity: sha512-411QlbL+z2yXpRWFXSmw/teQRMkXcAAC8aYTemc15gwJRpvEVDQwoe+N/HTFD8RFG8+88Bme9DK2V9CVm7hJdA==} + /@rollup/plugin-inject@5.0.5: + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} engines: {node: '>=14.0.0'} peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 - peerDependenciesMeta: - rollup: - optional: true - dependencies: - '@rollup/pluginutils': 5.0.2 - estree-walker: 2.0.2 - magic-string: 0.27.0 - dev: true - - /@rollup/pluginutils@5.0.2: - resolution: {integrity: sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0 + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 peerDependenciesMeta: rollup: optional: true dependencies: - '@types/estree': 1.0.1 + '@rollup/pluginutils': 5.0.5 estree-walker: 2.0.2 - picomatch: 2.3.1 + magic-string: 0.30.5 dev: true /@rollup/pluginutils@5.0.5: @@ -987,6 +1125,110 @@ packages: picomatch: 2.3.1 dev: true + /@rollup/rollup-android-arm-eabi@4.9.1: + resolution: {integrity: sha512-6vMdBZqtq1dVQ4CWdhFwhKZL6E4L1dV6jUjuBvsavvNJSppzi6dLBbuV+3+IyUREaj9ZFvQefnQm28v4OCXlig==} + cpu: [arm] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-android-arm64@4.9.1: + resolution: {integrity: sha512-Jto9Fl3YQ9OLsTDWtLFPtaIMSL2kwGyGoVCmPC8Gxvym9TCZm4Sie+cVeblPO66YZsYH8MhBKDMGZ2NDxuk/XQ==} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-arm64@4.9.1: + resolution: {integrity: sha512-LtYcLNM+bhsaKAIGwVkh5IOWhaZhjTfNOkGzGqdHvhiCUVuJDalvDxEdSnhFzAn+g23wgsycmZk1vbnaibZwwA==} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-darwin-x64@4.9.1: + resolution: {integrity: sha512-KyP/byeXu9V+etKO6Lw3E4tW4QdcnzDG/ake031mg42lob5tN+5qfr+lkcT/SGZaH2PdW4Z1NX9GHEkZ8xV7og==} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm-gnueabihf@4.9.1: + resolution: {integrity: sha512-Yqz/Doumf3QTKplwGNrCHe/B2p9xqDghBZSlAY0/hU6ikuDVQuOUIpDP/YcmoT+447tsZTmirmjgG3znvSCR0Q==} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-gnu@4.9.1: + resolution: {integrity: sha512-u3XkZVvxcvlAOlQJ3UsD1rFvLWqu4Ef/Ggl40WAVCuogf4S1nJPHh5RTgqYFpCOvuGJ7H5yGHabjFKEZGExk5Q==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-arm64-musl@4.9.1: + resolution: {integrity: sha512-0XSYN/rfWShW+i+qjZ0phc6vZ7UWI8XWNz4E/l+6edFt+FxoEghrJHjX1EY/kcUGCnZzYYRCl31SNdfOi450Aw==} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-riscv64-gnu@4.9.1: + resolution: {integrity: sha512-LmYIO65oZVfFt9t6cpYkbC4d5lKHLYv5B4CSHRpnANq0VZUQXGcCPXHzbCXCz4RQnx7jvlYB1ISVNCE/omz5cw==} + cpu: [riscv64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-gnu@4.9.1: + resolution: {integrity: sha512-kr8rEPQ6ns/Lmr/hiw8sEVj9aa07gh1/tQF2Y5HrNCCEPiCBGnBUt9tVusrcBBiJfIt1yNaXN6r1CCmpbFEDpg==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-linux-x64-musl@4.9.1: + resolution: {integrity: sha512-t4QSR7gN+OEZLG0MiCgPqMWZGwmeHhsM4AkegJ0Kiy6TnJ9vZ8dEIwHw1LcZKhbHxTY32hp9eVCMdR3/I8MGRw==} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-arm64-msvc@4.9.1: + resolution: {integrity: sha512-7XI4ZCBN34cb+BH557FJPmh0kmNz2c25SCQeT9OiFWEgf8+dL6ZwJ8f9RnUIit+j01u07Yvrsuu1rZGxJCc51g==} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-ia32-msvc@4.9.1: + resolution: {integrity: sha512-yE5c2j1lSWOH5jp+Q0qNL3Mdhr8WuqCNVjc6BxbVfS5cAS6zRmdiw7ktb8GNpDCEUJphILY6KACoFoRtKoqNQg==} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: true + optional: true + + /@rollup/rollup-win32-x64-msvc@4.9.1: + resolution: {integrity: sha512-PyJsSsafjmIhVgaI1Zdj7m8BB8mMckFah/xbpplObyHfiXzKcI5UOUXRyOdHW7nz4DpMCuzLnF7v5IWHenCwYA==} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: true + optional: true + /@sinclair/typebox@0.27.8: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true @@ -1116,8 +1358,8 @@ packages: - supports-color dev: true - /@types/babel__core@7.20.3: - resolution: {integrity: sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA==} + /@types/babel__core@7.20.5: + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} dependencies: '@babel/parser': 7.23.0 '@babel/types': 7.23.0 @@ -1149,16 +1391,6 @@ packages: resolution: {integrity: sha512-oYO/U4VD1DavwrKuCSQWdLG+5K22SLPem2OQaHmFcQuwHoVeGC+JGVRji2MUqZUAIQZHEonOeVfAX09hYiLsdg==} dev: false - /@types/chai-subset@1.3.3: - resolution: {integrity: sha512-frBecisrNGz+F4T6bcc+NLeolfiojh5FxW2klu669+8BARtyQv2C/GkNW6FUodVe4BroGMP/wER/YDGc7rEllw==} - dependencies: - '@types/chai': 4.3.5 - dev: true - - /@types/chai@4.3.5: - resolution: {integrity: sha512-mEo1sAde+UCE6b2hxn332f1g1E8WfYRu6p5SvTKr2ZKC1f7gFJXk4h5PyGP9Dt6gCaG8y8XhwnXWC6Iy2cmBng==} - dev: true - /@types/estree@1.0.1: resolution: {integrity: sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==} dev: true @@ -1171,10 +1403,6 @@ packages: resolution: {integrity: sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ==} dev: false - /@types/node@20.4.5: - resolution: {integrity: sha512-rt40Nk13II9JwQBdeYqmbn2Q6IVTA5uPhvSO+JVqdXw/6/4glI6oR9ezty/A9Hg5u7JH4OmYmuQ+XvjKm0Datg==} - dev: true - /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: false @@ -1182,14 +1410,14 @@ packages: /@types/prop-types@15.7.5: resolution: {integrity: sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==} - /@types/react-dom@18.2.14: - resolution: {integrity: sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ==} + /@types/react-dom@18.2.18: + resolution: {integrity: sha512-TJxDm6OfAX2KJWJdMEVTwWke5Sc/E/RlnPGvGfS0W7+6ocy2xhDVQVh/KvC2Uf7kACs+gDytdusDSdWfWkaNzw==} dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 dev: true - /@types/react@18.2.33: - resolution: {integrity: sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg==} + /@types/react@18.2.45: + resolution: {integrity: sha512-TtAxCNrlrBp8GoeEp1npd5g+d/OejJHFxS3OWmrPBMFaVQMSN0OFySozJio5BHxTuTeug00AVXVAjfDSfk+lUg==} dependencies: '@types/prop-types': 15.7.5 '@types/scheduler': 0.16.3 @@ -1198,75 +1426,85 @@ packages: /@types/scheduler@0.16.3: resolution: {integrity: sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==} - /@vitejs/plugin-react@4.1.0(vite@4.5.0): - resolution: {integrity: sha512-rM0SqazU9iqPUraQ2JlIvReeaxOoRj6n+PzB1C0cBzIbd8qP336nC39/R9yPi3wVcah7E7j/kdU1uCUqMEU4OQ==} + /@vitejs/plugin-react@4.2.1(vite@5.0.10): + resolution: {integrity: sha512-oojO9IDc4nCUUi8qIR11KoQm0XFFLIwsRBwHRR4d/88IWghn1y6ckz/bJ8GHDCsYEJee8mDzqtJxh15/cisJNQ==} engines: {node: ^14.18.0 || >=16.0.0} peerDependencies: - vite: ^4.2.0 + vite: ^4.2.0 || ^5.0.0 dependencies: - '@babel/core': 7.23.2 - '@babel/plugin-transform-react-jsx-self': 7.22.5(@babel/core@7.23.2) - '@babel/plugin-transform-react-jsx-source': 7.22.5(@babel/core@7.23.2) - '@types/babel__core': 7.20.3 + '@babel/core': 7.23.6 + '@babel/plugin-transform-react-jsx-self': 7.23.3(@babel/core@7.23.6) + '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.6) + '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 4.5.0(@types/node@20.4.5) + vite: 5.0.10 transitivePeerDependencies: - supports-color dev: true - /@vitest/coverage-c8@0.33.0(vitest@0.34.6): - resolution: {integrity: sha512-DaF1zJz4dcOZS4k/neiQJokmOWqsGXwhthfmUdPGorXIQHjdPvV6JQSYhQDI41MyI8c+IieQUdIDs5XAMHtDDw==} + /@vitest/coverage-v8@1.1.0(vitest@1.1.0): + resolution: {integrity: sha512-kHQRk70vTdXAyQY2C0vKOHPyQD/R6IUzcGdO4vCuyr4alE5Yg1+Sk2jSdjlIrTTXdcNEs+ReWVM09mmSFJpzyQ==} peerDependencies: - vitest: '>=0.30.0 <1' + vitest: ^1.0.0 dependencies: '@ampproject/remapping': 2.2.1 - c8: 7.14.0 - magic-string: 0.30.2 + '@bcoe/v8-coverage': 0.2.3 + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.1.6 + magic-string: 0.30.5 + magicast: 0.3.2 picocolors: 1.0.0 - std-env: 3.3.3 - vitest: 0.34.6(happy-dom@12.10.3) + std-env: 3.6.0 + test-exclude: 6.0.0 + v8-to-istanbul: 9.2.0 + vitest: 1.1.0(happy-dom@12.10.3) + transitivePeerDependencies: + - supports-color dev: true - /@vitest/expect@0.34.6: - resolution: {integrity: sha512-QUzKpUQRc1qC7qdGo7rMK3AkETI7w18gTCUrsNnyjjJKYiuUB9+TQK3QnR1unhCnWRC0AbKv2omLGQDF/mIjOw==} + /@vitest/expect@1.1.0: + resolution: {integrity: sha512-9IE2WWkcJo2BR9eqtY5MIo3TPmS50Pnwpm66A6neb2hvk/QSLfPXBz2qdiwUOQkwyFuuXEUj5380CbwfzW4+/w==} dependencies: - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 + '@vitest/spy': 1.1.0 + '@vitest/utils': 1.1.0 chai: 4.3.10 dev: true - /@vitest/runner@0.34.6: - resolution: {integrity: sha512-1CUQgtJSLF47NnhN+F9X2ycxUP0kLHQ/JWvNHbeBfwW8CzEGgeskzNnHDyv1ieKTltuR6sdIHV+nmR6kPxQqzQ==} + /@vitest/runner@1.1.0: + resolution: {integrity: sha512-zdNLJ00pm5z/uhbWF6aeIJCGMSyTyWImy3Fcp9piRGvueERFlQFbUwCpzVce79OLm2UHk9iwaMSOaU9jVHgNVw==} dependencies: - '@vitest/utils': 0.34.6 - p-limit: 4.0.0 + '@vitest/utils': 1.1.0 + p-limit: 5.0.0 pathe: 1.1.1 dev: true - /@vitest/snapshot@0.34.6: - resolution: {integrity: sha512-B3OZqYn6k4VaN011D+ve+AA4whM4QkcwcrwaKwAbyyvS/NB1hCWjFIBQxAQQSQir9/RtyAAGuq+4RJmbn2dH4w==} + /@vitest/snapshot@1.1.0: + resolution: {integrity: sha512-5O/wyZg09V5qmNmAlUgCBqflvn2ylgsWJRRuPrnHEfDNT6tQpQ8O1isNGgo+VxofISHqz961SG3iVvt3SPK/QQ==} dependencies: - magic-string: 0.30.2 + magic-string: 0.30.5 pathe: 1.1.1 - pretty-format: 29.6.2 + pretty-format: 29.7.0 dev: true - /@vitest/spy@0.34.6: - resolution: {integrity: sha512-xaCvneSaeBw/cz8ySmF7ZwGvL0lBjfvqc1LpQ/vcdHEvpLn3Ff1vAvjw+CoGn0802l++5L/pxb7whwcWAw+DUQ==} + /@vitest/spy@1.1.0: + resolution: {integrity: sha512-sNOVSU/GE+7+P76qYo+VXdXhXffzWZcYIPQfmkiRxaNCSPiLANvQx5Mx6ZURJ/ndtEkUJEpvKLXqAYTKEY+lTg==} dependencies: - tinyspy: 2.1.1 + tinyspy: 2.2.0 dev: true - /@vitest/utils@0.34.6: - resolution: {integrity: sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A==} + /@vitest/utils@1.1.0: + resolution: {integrity: sha512-z+s510fKmYz4Y41XhNs3vcuFTFhcij2YF7F8VQfMEYAAUfqQh0Zfg7+w9xdgFGhPf3tX3TicAe+8BDITk6ampQ==} dependencies: - diff-sequences: 29.4.3 - loupe: 2.3.6 - pretty-format: 29.6.2 + diff-sequences: 29.6.3 + loupe: 2.3.7 + pretty-format: 29.7.0 dev: true - /acorn-walk@8.2.0: - resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} + /acorn-walk@8.3.1: + resolution: {integrity: sha512-TgUZgYvqZprrl7YldZNoa9OciCAyZR+Ejm9eXzKCmjsF5IKp/wgQ7Z/ZpjpGTIUPwrHQIcYeI8qDh4PsEwxMbw==} engines: {node: '>=0.4.0'} dev: true @@ -1282,11 +1520,6 @@ packages: hasBin: true dev: true - /ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - /ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -1298,6 +1531,7 @@ packages: engines: {node: '>=8'} dependencies: color-convert: 2.0.1 + dev: false /ansi-styles@5.2.0: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} @@ -1353,7 +1587,7 @@ packages: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true - /autoprefixer@10.4.16(postcss@8.4.31): + /autoprefixer@10.4.16(postcss@8.4.32): resolution: {integrity: sha512-7vd3UC6xKp0HLfua5IjZlcXvGAGy7cBAXTg2lyQ/8WpNhd6SiZ8Be+xm3FyBSYJx5GKcpRCzBh7RH4/0dnY+uQ==} engines: {node: ^10 || ^12 || >=14} hasBin: true @@ -1365,7 +1599,7 @@ packages: fraction.js: 4.3.7 normalize-range: 0.1.2 picocolors: 1.0.0 - postcss: 8.4.31 + postcss: 8.4.32 postcss-value-parser: 4.2.0 dev: true @@ -1498,6 +1732,17 @@ packages: update-browserslist-db: 1.0.11(browserslist@4.21.10) dev: true + /browserslist@4.22.2: + resolution: {integrity: sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + dependencies: + caniuse-lite: 1.0.30001570 + electron-to-chromium: 1.4.615 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.22.2) + dev: true + /buffer-xor@1.0.3: resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} dev: true @@ -1520,25 +1765,6 @@ packages: resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} dev: true - /c8@7.14.0: - resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} - engines: {node: '>=10.12.0'} - hasBin: true - dependencies: - '@bcoe/v8-coverage': 0.2.3 - '@istanbuljs/schema': 0.1.3 - find-up: 5.0.0 - foreground-child: 2.0.0 - istanbul-lib-coverage: 3.2.0 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.1.6 - rimraf: 3.0.2 - test-exclude: 6.0.0 - v8-to-istanbul: 9.1.0 - yargs: 16.2.0 - yargs-parser: 20.2.9 - dev: true - /cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -1569,6 +1795,10 @@ packages: resolution: {integrity: sha512-A2E3U//MBwbJVzebddm1YfNp7Nud5Ip+IPn4BozBmn4KqVX7AvluoIDFWjsv5OkGnKUXQVmMSoMKLa3ScCblcQ==} dev: true + /caniuse-lite@1.0.30001570: + resolution: {integrity: sha512-+3e0ASu4sw1SWaoCtvPeyXp+5PsjigkSt8OXZbF9StH5pQWbxEjLAZE3n8Aup5udop1uRiKA7a4utUk/uoSpUw==} + dev: true + /chai@4.3.10: resolution: {integrity: sha512-0UXG04VuVbruMUYbJ6JctvH0YnC/4q3/AkT18q4NaITo91CUm0liMS9VqzT9vZhVQ/1eqPanMWjBM+Juhfb/9g==} engines: {node: '>=4'} @@ -1616,7 +1846,7 @@ packages: normalize-path: 3.0.0 readdirp: 3.6.0 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true /cipher-base@1.0.4: @@ -1630,14 +1860,6 @@ packages: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} dev: false - /cliui@7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - /clsx@1.1.1: resolution: {integrity: sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==} engines: {node: '>=6'} @@ -1653,12 +1875,14 @@ packages: engines: {node: '>=7.0.0'} dependencies: color-name: 1.1.4 + dev: false /color-name@1.1.3: resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} /color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false /color-string@1.9.1: resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} @@ -1693,6 +1917,7 @@ packages: /convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + dev: false /convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} @@ -1856,8 +2081,8 @@ packages: resolution: {integrity: sha512-IayShXAgj/QMXgB0IWmKx+rOPuGMhqm5w6jvFxmVenXKIzRqTAAsbBPT3kWQeGANj3jGgvcvv4yK6SxqYmikgw==} dev: false - /diff-sequences@29.4.3: - resolution: {integrity: sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA==} + /diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dev: true @@ -1889,6 +2114,10 @@ packages: resolution: {integrity: sha512-shUVy6Eawp33dFBFIoYbIwLHrX0IZ857AlH9ug2o4rvbWmpaCUdBpQ5Zw39HRrfzAFm4APJE9V+E2A/WB0YqJw==} dev: true + /electron-to-chromium@1.4.615: + resolution: {integrity: sha512-/bKPPcgZVUziECqDc+0HkT87+0zhaWSZHNXqF8FLd2lQcptpmUFwoCSWjCdOng9Gdq+afKArPdEg/0ZW461Eng==} + dev: true + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: @@ -1901,10 +2130,6 @@ packages: minimalistic-crypto-utils: 1.0.1 dev: true - /emoji-regex@8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - /entities@4.5.0: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} @@ -1919,34 +2144,35 @@ packages: resolution: {integrity: sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==} dev: true - /esbuild@0.18.17: - resolution: {integrity: sha512-1GJtYnUxsJreHYA0Y+iQz2UEykonY66HNWOb0yXYZi9/kNrORUEHVg87eQsCtqh59PEJ5YVZJO98JHznMJSWjg==} + /esbuild@0.19.10: + resolution: {integrity: sha512-S1Y27QGt/snkNYrRcswgRFqZjaTG5a5xM3EQo97uNBnH505pdzSNe/HLBq1v0RO7iK/ngdbhJB6mDAp0OK+iUA==} engines: {node: '>=12'} hasBin: true requiresBuild: true optionalDependencies: - '@esbuild/android-arm': 0.18.17 - '@esbuild/android-arm64': 0.18.17 - '@esbuild/android-x64': 0.18.17 - '@esbuild/darwin-arm64': 0.18.17 - '@esbuild/darwin-x64': 0.18.17 - '@esbuild/freebsd-arm64': 0.18.17 - '@esbuild/freebsd-x64': 0.18.17 - '@esbuild/linux-arm': 0.18.17 - '@esbuild/linux-arm64': 0.18.17 - '@esbuild/linux-ia32': 0.18.17 - '@esbuild/linux-loong64': 0.18.17 - '@esbuild/linux-mips64el': 0.18.17 - '@esbuild/linux-ppc64': 0.18.17 - '@esbuild/linux-riscv64': 0.18.17 - '@esbuild/linux-s390x': 0.18.17 - '@esbuild/linux-x64': 0.18.17 - '@esbuild/netbsd-x64': 0.18.17 - '@esbuild/openbsd-x64': 0.18.17 - '@esbuild/sunos-x64': 0.18.17 - '@esbuild/win32-arm64': 0.18.17 - '@esbuild/win32-ia32': 0.18.17 - '@esbuild/win32-x64': 0.18.17 + '@esbuild/aix-ppc64': 0.19.10 + '@esbuild/android-arm': 0.19.10 + '@esbuild/android-arm64': 0.19.10 + '@esbuild/android-x64': 0.19.10 + '@esbuild/darwin-arm64': 0.19.10 + '@esbuild/darwin-x64': 0.19.10 + '@esbuild/freebsd-arm64': 0.19.10 + '@esbuild/freebsd-x64': 0.19.10 + '@esbuild/linux-arm': 0.19.10 + '@esbuild/linux-arm64': 0.19.10 + '@esbuild/linux-ia32': 0.19.10 + '@esbuild/linux-loong64': 0.19.10 + '@esbuild/linux-mips64el': 0.19.10 + '@esbuild/linux-ppc64': 0.19.10 + '@esbuild/linux-riscv64': 0.19.10 + '@esbuild/linux-s390x': 0.19.10 + '@esbuild/linux-x64': 0.19.10 + '@esbuild/netbsd-x64': 0.19.10 + '@esbuild/openbsd-x64': 0.19.10 + '@esbuild/sunos-x64': 0.19.10 + '@esbuild/win32-arm64': 0.19.10 + '@esbuild/win32-ia32': 0.19.10 + '@esbuild/win32-x64': 0.19.10 dev: true /escalade@3.1.1: @@ -1979,6 +2205,21 @@ packages: safe-buffer: 5.2.1 dev: true + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.1.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: true + /fast-glob@3.3.1: resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} engines: {node: '>=8.6.0'} @@ -2021,14 +2262,6 @@ packages: is-callable: 1.2.7 dev: true - /foreground-child@2.0.0: - resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} - engines: {node: '>=8.0.0'} - dependencies: - cross-spawn: 7.0.3 - signal-exit: 3.0.7 - dev: true - /fraction.js@4.3.7: resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==} dev: true @@ -2037,8 +2270,8 @@ packages: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true - /fsevents@2.3.2: - resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==} + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true @@ -2053,11 +2286,6 @@ packages: engines: {node: '>=6.9.0'} dev: true - /get-caller-file@2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - /get-func-name@2.0.2: resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} dev: true @@ -2076,6 +2304,11 @@ packages: engines: {node: '>=6'} dev: false + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: true + /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -2213,6 +2446,11 @@ packages: resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} dev: true + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: true + /iconv-lite@0.6.3: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} @@ -2224,8 +2462,8 @@ packages: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} dev: true - /immutable@4.3.1: - resolution: {integrity: sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A==} + /immutable@4.3.4: + resolution: {integrity: sha512-fsXeu4J4i6WNWSikpI88v/PcVflZz+6kMhUfIwc5SY+poQRPnaf5V7qds6SUyUN3cVxEzuCab7QIoLOQ+DQ1wA==} dev: false /import-fresh@3.3.0: @@ -2289,11 +2527,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /is-fullwidth-code-point@3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - /is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -2321,6 +2554,11 @@ packages: engines: {node: '>=0.12.0'} dev: true + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: true + /is-typed-array@1.1.12: resolution: {integrity: sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==} engines: {node: '>= 0.4'} @@ -2337,8 +2575,8 @@ packages: engines: {node: '>=10'} dev: true - /istanbul-lib-coverage@3.2.0: - resolution: {integrity: sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==} + /istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} dev: true @@ -2346,11 +2584,22 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} dependencies: - istanbul-lib-coverage: 3.2.0 + istanbul-lib-coverage: 3.2.2 make-dir: 4.0.0 supports-color: 7.2.0 dev: true + /istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + dependencies: + debug: 4.3.4 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + dev: true + /istanbul-reports@3.1.6: resolution: {integrity: sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg==} engines: {node: '>=8'} @@ -2368,23 +2617,23 @@ packages: hasBin: true dev: true - /jotai-devtools@0.7.0(@emotion/react@11.11.1)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): - resolution: {integrity: sha512-rMcNusiJ3YtvbVkUF6RrUa1mJZbcH7Cs6MGULHllTQ/+4/kKtWtEPXUMdwxyJ33Sdx/L0Al8b0g0NpLOPUr0zA==} + /jotai-devtools@0.7.1(@emotion/react@11.11.1)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)(redux@4.2.1): + resolution: {integrity: sha512-Uqz5LOXSNkVBYG7HEauYtguTJyndX5kMVtFSYsqcNrCr2H53okxMwZnRg5n7WOy9uHyi1+a5xa1omjpIH6lGbA==} engines: {node: '>=14.0.0'} peerDependencies: '@emotion/react': '>=11.0.0' react: '>=17.0.0' dependencies: - '@emotion/react': 11.11.1(@types/react@18.2.33)(react@18.2.0) - '@mantine/core': 6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.33)(react-dom@18.2.0)(react@18.2.0) + '@emotion/react': 11.11.1(@types/react@18.2.45)(react@18.2.0) + '@mantine/core': 6.0.21(@emotion/react@11.11.1)(@mantine/hooks@6.0.21)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0) '@mantine/hooks': 6.0.21(react@18.2.0) '@mantine/prism': 6.0.21(@mantine/core@6.0.21)(@mantine/hooks@6.0.21)(react-dom@18.2.0)(react@18.2.0) - '@redux-devtools/extension': 3.2.5(redux@4.2.1) + '@redux-devtools/extension': 3.3.0(redux@4.2.1) javascript-stringify: 2.1.0 jsondiffpatch: 0.5.0 react: 18.2.0 react-error-boundary: 4.0.11(react@18.2.0) - react-json-tree: 0.18.0(@types/react@18.2.33)(react@18.2.0) + react-json-tree: 0.18.0(@types/react@18.2.45)(react@18.2.0) react-resizable-panels: 0.0.54(react-dom@18.2.0)(react@18.2.0) transitivePeerDependencies: - '@types/react' @@ -2392,8 +2641,8 @@ packages: - redux dev: false - /jotai@2.5.0(@types/react@18.2.33)(react@18.2.0): - resolution: {integrity: sha512-iPJDFrhNw3KU4o4SSAESeZoW+nM1L/76VULXZWF23qmivBEcbAQjiF5n1W4Hn5dXAol4tmtEYe4HH7d9emEz0Q==} + /jotai@2.6.0(@types/react@18.2.45)(react@18.2.0): + resolution: {integrity: sha512-Vt6hsc04Km4j03l+Ax+Sc+FVft5cRJhqgxt6GTz6GM2eM3DyX3CdBdzcG0z2FrlZToL1/0OAkqDghIyARWnSuQ==} engines: {node: '>=12.20.0'} peerDependencies: '@types/react': '>=17.0.0' @@ -2404,7 +2653,7 @@ packages: react: optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 dev: false @@ -2455,9 +2704,12 @@ packages: /lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - /local-pkg@0.4.3: - resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 dev: true /locate-path@6.0.0: @@ -2480,6 +2732,13 @@ packages: /loupe@2.3.6: resolution: {integrity: sha512-RaPMZKiMy8/JruncMU5Bt6na1eftNoo++R4Y+N2FrxkDVTrGvcyzFTsaGif4QTeKESheMGegbhw6iUAq+5A8zA==} + deprecated: Please upgrade to 2.3.7 which fixes GHSA-4q6p-r6v2-jvc5 + dependencies: + get-func-name: 2.0.2 + dev: true + + /loupe@2.3.7: + resolution: {integrity: sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA==} dependencies: get-func-name: 2.0.2 dev: true @@ -2503,18 +2762,19 @@ packages: yallist: 4.0.0 dev: true - /magic-string@0.27.0: - resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + /magic-string@0.30.5: + resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} dependencies: '@jridgewell/sourcemap-codec': 1.4.15 dev: true - /magic-string@0.30.2: - resolution: {integrity: sha512-lNZdu7pewtq/ZvWUp9Wpf/x7WzMTsR26TWV03BRZrXFsv+BI6dy8RAiKgm1uM/kyR0rCfUcqvOlXKG66KhIGug==} - engines: {node: '>=12'} + /magicast@0.3.2: + resolution: {integrity: sha512-Fjwkl6a0syt9TFN0JSYpOybxiMCkYNEeOTnOTNRbjphirLakznZXAqrXgj/7GG3D1dvETONNwrBfinvAbpunDg==} dependencies: - '@jridgewell/sourcemap-codec': 1.4.15 + '@babel/parser': 7.23.6 + '@babel/types': 7.23.6 + source-map-js: 1.0.2 dev: true /make-dir@4.0.0: @@ -2532,6 +2792,10 @@ packages: safe-buffer: 5.2.1 dev: true + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: true + /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -2553,6 +2817,11 @@ packages: brorand: 1.1.0 dev: true + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: true + /minimalistic-assert@1.0.1: resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} dev: true @@ -2567,13 +2836,13 @@ packages: brace-expansion: 1.1.11 dev: true - /mlly@1.4.0: - resolution: {integrity: sha512-ua8PAThnTwpprIaU47EPeZ/bPUVp2QYBbWMphUQpVdBI3Lgqzm5KZQ45Agm3YJedHXaIHl6pBGabaLSUPPSptg==} + /mlly@1.4.2: + resolution: {integrity: sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg==} dependencies: acorn: 8.10.0 pathe: 1.1.1 pkg-types: 1.0.3 - ufo: 1.2.0 + ufo: 1.3.2 dev: true /ms@2.1.2: @@ -2588,8 +2857,8 @@ packages: thenify-all: 1.6.0 dev: true - /nanoid@3.3.6: - resolution: {integrity: sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==} + /nanoid@3.3.7: + resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true dev: true @@ -2605,6 +2874,10 @@ packages: resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} dev: true + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} + dev: true + /node-stdlib-browser@1.2.0: resolution: {integrity: sha512-VSjFxUhRhkyed8AtLwSCkMrJRfQ3e2lGtG3sP6FEgaLKBBbxM/dLfjRe1+iLhjvyLFW3tBQ8+c0pcOtXGbAZJg==} engines: {node: '>=10'} @@ -2648,6 +2921,13 @@ packages: engines: {node: '>=0.10.0'} dev: true + /npm-run-path@5.1.0: + resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: true + /object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2691,6 +2971,13 @@ packages: wrappy: 1.0.2 dev: true + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: true + /os-browserify@0.3.0: resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} dev: true @@ -2702,9 +2989,9 @@ packages: yocto-queue: 0.1.0 dev: true - /p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + /p-limit@5.0.0: + resolution: {integrity: sha512-/Eaoq+QyLSiXQ4lyYV23f14mZRQcXnxfHrN0vCai+ak9G0pp9iEQukIIZq5NccEvwRB8PUnZT0KsOoDCINS1qQ==} + engines: {node: '>=18'} dependencies: yocto-queue: 1.0.0 dev: true @@ -2764,6 +3051,11 @@ packages: engines: {node: '>=8'} dev: true + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: true + /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -2820,33 +3112,33 @@ packages: resolution: {integrity: sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A==} dependencies: jsonc-parser: 3.2.0 - mlly: 1.4.0 + mlly: 1.4.2 pathe: 1.1.1 dev: true - /postcss-import@15.1.0(postcss@8.4.31): + /postcss-import@15.1.0(postcss@8.4.32): resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==} engines: {node: '>=14.0.0'} peerDependencies: postcss: ^8.0.0 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.2 dev: true - /postcss-js@4.0.1(postcss@8.4.31): + /postcss-js@4.0.1(postcss@8.4.32): resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 dependencies: camelcase-css: 2.0.1 - postcss: 8.4.31 + postcss: 8.4.32 dev: true - /postcss-load-config@4.0.1(postcss@8.4.31): + /postcss-load-config@4.0.1(postcss@8.4.32): resolution: {integrity: sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA==} engines: {node: '>= 14'} peerDependencies: @@ -2859,17 +3151,17 @@ packages: optional: true dependencies: lilconfig: 2.1.0 - postcss: 8.4.31 + postcss: 8.4.32 yaml: 2.3.1 dev: true - /postcss-nested@6.0.1(postcss@8.4.31): + /postcss-nested@6.0.1(postcss@8.4.32): resolution: {integrity: sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ==} engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 dependencies: - postcss: 8.4.31 + postcss: 8.4.32 postcss-selector-parser: 6.0.13 dev: true @@ -2885,26 +3177,26 @@ packages: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} dev: true - /postcss@8.4.31: - resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + /postcss@8.4.32: + resolution: {integrity: sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==} engines: {node: ^10 || ^12 || >=14} dependencies: - nanoid: 3.3.6 + nanoid: 3.3.7 picocolors: 1.0.0 source-map-js: 1.0.2 dev: true - /prettier@3.0.3: - resolution: {integrity: sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==} + /prettier@3.1.1: + resolution: {integrity: sha512-22UbSzg8luF4UuZtzgiUOfcGM8s4tjBv6dJRT7j275NXsy2jb4aJa4NNveul5x4eqlF1wuhuR2RElK71RvmVaw==} engines: {node: '>=14'} hasBin: true dev: true - /pretty-format@29.6.2: - resolution: {integrity: sha512-1q0oC8eRveTg5nnBEWMXAU2qpv65Gnuf2eCQzSjxpWFkPaPARwqZZDGuNE0zPAZfTCHzIk3A8dIjwlQKKLphyg==} + /pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 29.6.0 + '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 react-is: 18.2.0 dev: true @@ -3004,7 +3296,7 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: true - /react-json-tree@0.18.0(@types/react@18.2.33)(react@18.2.0): + /react-json-tree@0.18.0(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-Qe6HKSXrr++n9Y31nkRJ3XvQMATISpqigH1vEKhLwB56+nk5thTP0ITThpjxY6ZG/ubpVq/aEHIcyLP/OPHxeA==} peerDependencies: '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 @@ -3012,7 +3304,7 @@ packages: dependencies: '@babel/runtime': 7.22.6 '@types/lodash': 4.14.196 - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 react-base16-styling: 0.9.1 dev: false @@ -3022,7 +3314,7 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-remove-scroll-bar@2.3.4(@types/react@18.2.33)(react@18.2.0): + /react-remove-scroll-bar@2.3.4(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==} engines: {node: '>=10'} peerDependencies: @@ -3032,13 +3324,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 - react-style-singleton: 2.2.1(@types/react@18.2.33)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.45)(react@18.2.0) tslib: 2.6.1 dev: false - /react-remove-scroll@2.5.6(@types/react@18.2.33)(react@18.2.0): + /react-remove-scroll@2.5.6(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==} engines: {node: '>=10'} peerDependencies: @@ -3048,13 +3340,13 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 - react-remove-scroll-bar: 2.3.4(@types/react@18.2.33)(react@18.2.0) - react-style-singleton: 2.2.1(@types/react@18.2.33)(react@18.2.0) + react-remove-scroll-bar: 2.3.4(@types/react@18.2.45)(react@18.2.0) + react-style-singleton: 2.2.1(@types/react@18.2.45)(react@18.2.0) tslib: 2.6.1 - use-callback-ref: 1.3.0(@types/react@18.2.33)(react@18.2.0) - use-sidecar: 1.1.2(@types/react@18.2.33)(react@18.2.0) + use-callback-ref: 1.3.0(@types/react@18.2.45)(react@18.2.0) + use-sidecar: 1.1.2(@types/react@18.2.45)(react@18.2.0) dev: false /react-resizable-panels@0.0.54(react-dom@18.2.0)(react@18.2.0): @@ -3067,30 +3359,30 @@ packages: react-dom: 18.2.0(react@18.2.0) dev: false - /react-router-dom@6.17.0(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-qWHkkbXQX+6li0COUUPKAUkxjNNqPJuiBd27dVwQGDNsuFBdMbrS6UZ0CLYc4CsbdLYTckn4oB4tGDuPZpPhaQ==} + /react-router-dom@6.21.0(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-1dUdVj3cwc1npzJaf23gulB562ESNvxf7E4x8upNJycqyUm5BRRZ6dd3LrlzhtLaMrwOCO8R0zoiYxdaJx4LlQ==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' react-dom: '>=16.8' dependencies: - '@remix-run/router': 1.10.0 + '@remix-run/router': 1.14.0 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) - react-router: 6.17.0(react@18.2.0) + react-router: 6.21.0(react@18.2.0) dev: false - /react-router@6.17.0(react@18.2.0): - resolution: {integrity: sha512-YJR3OTJzi3zhqeJYADHANCGPUu9J+6fT5GLv82UWRGSxu6oJYCKVmxUcaBQuGm9udpWmPsvpme/CdHumqgsoaA==} + /react-router@6.21.0(react@18.2.0): + resolution: {integrity: sha512-hGZ0HXbwz3zw52pLZV3j3+ec+m/PQ9cTpBvqjFQmy2XVUWGn5MD+31oXHb6dVTxYzmAeaiUBYjkoNz66n3RGCg==} engines: {node: '>=14.0.0'} peerDependencies: react: '>=16.8' dependencies: - '@remix-run/router': 1.10.0 + '@remix-run/router': 1.14.0 react: 18.2.0 dev: false - /react-style-singleton@2.2.1(@types/react@18.2.33)(react@18.2.0): + /react-style-singleton@2.2.1(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} engines: {node: '>=10'} peerDependencies: @@ -3100,14 +3392,14 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 get-nonce: 1.0.1 invariant: 2.2.4 react: 18.2.0 tslib: 2.6.1 dev: false - /react-textarea-autosize@8.3.4(@types/react@18.2.33)(react@18.2.0): + /react-textarea-autosize@8.3.4(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==} engines: {node: '>=10'} peerDependencies: @@ -3116,7 +3408,7 @@ packages: '@babel/runtime': 7.22.6 react: 18.2.0 use-composed-ref: 1.3.0(react@18.2.0) - use-latest: 1.2.1(@types/react@18.2.33)(react@18.2.0) + use-latest: 1.2.1(@types/react@18.2.45)(react@18.2.0) transitivePeerDependencies: - '@types/react' dev: false @@ -3153,17 +3445,16 @@ packages: /redux@4.2.1: resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} dependencies: - '@babel/runtime': 7.22.6 + '@babel/runtime': 7.23.6 dev: false /regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} dev: false - /require-directory@2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true + /regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + dev: false /resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} @@ -3182,13 +3473,6 @@ packages: engines: {iojs: '>=1.0.0', node: '>=0.10.0'} dev: true - /rimraf@3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - /ripemd160@2.0.2: resolution: {integrity: sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==} dependencies: @@ -3196,12 +3480,25 @@ packages: inherits: 2.0.4 dev: true - /rollup@3.27.2: - resolution: {integrity: sha512-YGwmHf7h2oUHkVBT248x0yt6vZkYQ3/rvE5iQuVBh3WO8GcJ6BNeOkpoX1yMHIiBm18EMLjBPIoUDkhgnyxGOQ==} - engines: {node: '>=14.18.0', npm: '>=8.0.0'} + /rollup@4.9.1: + resolution: {integrity: sha512-pgPO9DWzLoW/vIhlSoDByCzcpX92bKEorbgXuZrqxByte3JFk2xSW2JEeAcyLc9Ru9pqcNNW+Ob7ntsk2oT/Xw==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true optionalDependencies: - fsevents: 2.3.2 + '@rollup/rollup-android-arm-eabi': 4.9.1 + '@rollup/rollup-android-arm64': 4.9.1 + '@rollup/rollup-darwin-arm64': 4.9.1 + '@rollup/rollup-darwin-x64': 4.9.1 + '@rollup/rollup-linux-arm-gnueabihf': 4.9.1 + '@rollup/rollup-linux-arm64-gnu': 4.9.1 + '@rollup/rollup-linux-arm64-musl': 4.9.1 + '@rollup/rollup-linux-riscv64-gnu': 4.9.1 + '@rollup/rollup-linux-x64-gnu': 4.9.1 + '@rollup/rollup-linux-x64-musl': 4.9.1 + '@rollup/rollup-win32-arm64-msvc': 4.9.1 + '@rollup/rollup-win32-ia32-msvc': 4.9.1 + '@rollup/rollup-win32-x64-msvc': 4.9.1 + fsevents: 2.3.3 dev: true /run-parallel@1.2.0: @@ -3278,8 +3575,9 @@ packages: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} dev: true - /signal-exit@3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} dev: true /simple-swizzle@0.2.2: @@ -3305,12 +3603,17 @@ packages: engines: {node: '>=0.10.0'} dev: false + /source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + dev: true + /stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} dev: true - /std-env@3.3.3: - resolution: {integrity: sha512-Rz6yejtVyWnVjC1RFvNmYL10kgjC49EOghxWn0RFqlCHGFpQx+Xe7yW3I4ceK1SGrWIGMjD5Kbue8W/udkbMJg==} + /std-env@3.6.0: + resolution: {integrity: sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg==} dev: true /stream-browserify@3.0.0: @@ -3329,30 +3632,19 @@ packages: xtend: 4.0.2 dev: true - /string-width@4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 dev: true - /strip-ansi@6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} dev: true - /strip-literal@1.0.1: - resolution: {integrity: sha512-QZTsipNpa2Ppr6v1AmJHESqJ3Uz247MUS0OjrnnZjFAvEoWqxuyFuXn2xLgMtRnijJShAa1HL0gtJyUs7u7n3Q==} + /strip-literal@1.3.0: + resolution: {integrity: sha512-PugKzOsyXpArk0yWmUwqOZecSO0GH0bPoctLcqNDH9J04pVW3lflYE0ujElBGTloevcxF5MofAOZ7C5l2b+wLg==} dependencies: acorn: 8.10.0 dev: true @@ -3399,8 +3691,8 @@ packages: resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==} dev: false - /tailwindcss@3.3.5: - resolution: {integrity: sha512-5SEZU4J7pxZgSkv7FP1zY8i2TIAOooNZ1e/OGtxIEv6GltpoiXUqWvLy89+a10qYTB1N5Ifkuw9lqQkN9sscvA==} + /tailwindcss@3.4.0: + resolution: {integrity: sha512-VigzymniH77knD1dryXbyxR+ePHihHociZbXnLZHUyzf2MMs2ZVqlUrZ3FvpXP8pno9JzmILt1sZPD19M3IxtA==} engines: {node: '>=14.0.0'} hasBin: true dependencies: @@ -3418,11 +3710,11 @@ packages: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.0.0 - postcss: 8.4.31 - postcss-import: 15.1.0(postcss@8.4.31) - postcss-js: 4.0.1(postcss@8.4.31) - postcss-load-config: 4.0.1(postcss@8.4.31) - postcss-nested: 6.0.1(postcss@8.4.31) + postcss: 8.4.32 + postcss-import: 15.1.0(postcss@8.4.32) + postcss-js: 4.0.1(postcss@8.4.32) + postcss-load-config: 4.0.1(postcss@8.4.32) + postcss-nested: 6.0.1(postcss@8.4.32) postcss-selector-parser: 6.0.13 resolve: 1.22.2 sucrase: 3.34.0 @@ -3459,17 +3751,17 @@ packages: setimmediate: 1.0.5 dev: true - /tinybench@2.5.0: - resolution: {integrity: sha512-kRwSG8Zx4tjF9ZiyH4bhaebu+EDz1BOx9hOigYHlUW4xxI/wKIUQUqo018UlU4ar6ATPBsaMrdbKZ+tmPdohFA==} + /tinybench@2.5.1: + resolution: {integrity: sha512-65NKvSuAVDP/n4CqH+a9w2kTlLReS9vhsAP06MWx+/89nMinJyB2icyl58RIcqCmIggpojIGeuJGhjU1aGMBSg==} dev: true - /tinypool@0.7.0: - resolution: {integrity: sha512-zSYNUlYSMhJ6Zdou4cJwo/p7w5nmAH17GRfU/ui3ctvjXFErXXkruT4MWW6poDeXgCaIBlGLrfU6TbTXxyGMww==} + /tinypool@0.8.1: + resolution: {integrity: sha512-zBTCK0cCgRROxvs9c0CGK838sPkeokNGdQVUUwHAbynHFlmyJYj825f/oRs528HaIJ97lo0pLIlDUzwN+IorWg==} engines: {node: '>=14.0.0'} dev: true - /tinyspy@2.1.1: - resolution: {integrity: sha512-XPJL2uSzcOyBMky6OFrusqWlzfFrXtE0hPuMgW8A2HmaqrPo4ZQHRN/V0QXN3FSjKxpsbRrFc5LI7KOwBsT1/w==} + /tinyspy@2.2.0: + resolution: {integrity: sha512-d2eda04AN/cPOR89F7Xv5bK/jrQEhmcLFe6HFldoeO9AJtps+fqEnh486vnT/8y4bw38pSyxDcTCAq+Ks2aJTg==} engines: {node: '>=14.0.0'} dev: true @@ -3488,7 +3780,7 @@ packages: resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==} dev: true - /tsconfck@2.1.2(typescript@5.2.2): + /tsconfck@2.1.2(typescript@5.3.3): resolution: {integrity: sha512-ghqN1b0puy3MhhviwO2kGF8SeMDNhEbnKxjK7h6+fvY9JAxqvXi8y5NAHSQv687OVboS2uZIByzGd45/YxrRHg==} engines: {node: ^14.13.1 || ^16 || >=18} hasBin: true @@ -3498,7 +3790,7 @@ packages: typescript: optional: true dependencies: - typescript: 5.2.2 + typescript: 5.3.3 dev: true /tslib@2.6.1: @@ -3513,14 +3805,14 @@ packages: engines: {node: '>=4'} dev: true - /typescript@5.2.2: - resolution: {integrity: sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==} + /typescript@5.3.3: + resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} engines: {node: '>=14.17'} hasBin: true dev: true - /ufo@1.2.0: - resolution: {integrity: sha512-RsPyTbqORDNDxqAdQPQBpgqhWle1VcTSou/FraClYlHf6TZnQcGslpLcAphNR+sQW4q5lLWLbOsRlh9j24baQg==} + /ufo@1.3.2: + resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true /update-browserslist-db@1.0.11(browserslist@4.21.10): @@ -3534,6 +3826,17 @@ packages: picocolors: 1.0.0 dev: true + /update-browserslist-db@1.0.13(browserslist@4.22.2): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + dependencies: + browserslist: 4.22.2 + escalade: 3.1.1 + picocolors: 1.0.0 + dev: true + /url@0.11.1: resolution: {integrity: sha512-rWS3H04/+mzzJkv0eZ7vEDGiQbgquI1fGfOad6zKvgYQi1SzMmhl7c/DdRGxhaWrVH6z0qWITo8rpnxK/RfEhA==} dependencies: @@ -3541,7 +3844,7 @@ packages: qs: 6.11.2 dev: true - /use-callback-ref@1.3.0(@types/react@18.2.33)(react@18.2.0): + /use-callback-ref@1.3.0(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==} engines: {node: '>=10'} peerDependencies: @@ -3551,7 +3854,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 tslib: 2.6.1 dev: false @@ -3564,7 +3867,7 @@ packages: react: 18.2.0 dev: false - /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.33)(react@18.2.0): + /use-isomorphic-layout-effect@1.1.2(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} peerDependencies: '@types/react': '*' @@ -3573,11 +3876,11 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 dev: false - /use-latest@1.2.1(@types/react@18.2.33)(react@18.2.0): + /use-latest@1.2.1(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} peerDependencies: '@types/react': '*' @@ -3586,12 +3889,12 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 react: 18.2.0 - use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.33)(react@18.2.0) + use-isomorphic-layout-effect: 1.1.2(@types/react@18.2.45)(react@18.2.0) dev: false - /use-sidecar@1.1.2(@types/react@18.2.33)(react@18.2.0): + /use-sidecar@1.1.2(@types/react@18.2.45)(react@18.2.0): resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} engines: {node: '>=10'} peerDependencies: @@ -3601,7 +3904,7 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.33 + '@types/react': 18.2.45 detect-node-es: 1.1.0 react: 18.2.0 tslib: 2.6.1 @@ -3621,26 +3924,25 @@ packages: which-typed-array: 1.1.11 dev: true - /v8-to-istanbul@9.1.0: - resolution: {integrity: sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA==} + /v8-to-istanbul@9.2.0: + resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} dependencies: '@jridgewell/trace-mapping': 0.3.18 '@types/istanbul-lib-coverage': 2.0.4 - convert-source-map: 1.9.0 + convert-source-map: 2.0.0 dev: true - /vite-node@0.34.6(@types/node@20.4.5): - resolution: {integrity: sha512-nlBMJ9x6n7/Amaz6F3zJ97EBwR2FkzhBRxF5e+jE6LA3yi6Wtc2lyTij1OnDMIr34v5g/tVQtsVAzhT0jc5ygA==} - engines: {node: '>=v14.18.0'} + /vite-node@1.1.0: + resolution: {integrity: sha512-jV48DDUxGLEBdHCQvxL1mEh7+naVy+nhUUUaPAZLd3FJgXuxQiewHcfeZebbJ6onDqNGkP4r3MhQ342PRlG81Q==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true dependencies: cac: 6.7.14 debug: 4.3.4 - mlly: 1.4.0 pathe: 1.1.1 picocolors: 1.0.0 - vite: 4.5.0(@types/node@20.4.5) + vite: 5.0.10 transitivePeerDependencies: - '@types/node' - less @@ -3652,36 +3954,36 @@ packages: - terser dev: true - /vite-plugin-node-polyfills@0.15.0(vite@4.5.0): - resolution: {integrity: sha512-IF9aTSPV9zebrcC6ezJA3Ym4r4U1C3jKUAnG16Sq7+UPtisNEOcNOAu3p5wcgFFOuuUwAUjQlIeJHMcnSXXemQ==} + /vite-plugin-node-polyfills@0.17.0(vite@5.0.10): + resolution: {integrity: sha512-iPmPn7376e5u6QvoTSJa16hf5Q0DFwHFXJk2uYpsNlmI3JdPms7hWyh55o+OysJ5jo9J5XPhLC9sMOYifwFd1w==} peerDependencies: - vite: ^2.0.0 || ^3.0.0 || ^4.0.0 + vite: ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 dependencies: - '@rollup/plugin-inject': 5.0.3 + '@rollup/plugin-inject': 5.0.5 buffer-polyfill: /buffer@6.0.3 node-stdlib-browser: 1.2.0 process: 0.11.10 - vite: 4.5.0(@types/node@20.4.5) + vite: 5.0.10 transitivePeerDependencies: - rollup dev: true - /vite-plugin-svgr@4.1.0(vite@4.5.0): - resolution: {integrity: sha512-v7Qic+FWmCChgQNGSI4V8X63OEYsdUoLt66iqIcHozq9bfK/Dwmr0V+LBy1NE8CE98Y8HouEBJ+pto4AMfN5xw==} + /vite-plugin-svgr@4.2.0(vite@5.0.10): + resolution: {integrity: sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==} peerDependencies: - vite: ^2.6.0 || 3 || 4 + vite: ^2.6.0 || 3 || 4 || 5 dependencies: '@rollup/pluginutils': 5.0.5 '@svgr/core': 8.1.0 '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0) - vite: 4.5.0(@types/node@20.4.5) + vite: 5.0.10 transitivePeerDependencies: - rollup - supports-color dev: true - /vite-tsconfig-paths@4.2.1(typescript@5.2.2)(vite@4.5.0): - resolution: {integrity: sha512-GNUI6ZgPqT3oervkvzU+qtys83+75N/OuDaQl7HmOqFTb0pjZsuARrRipsyJhJ3enqV8beI1xhGbToR4o78nSQ==} + /vite-tsconfig-paths@4.2.2(typescript@5.3.3)(vite@5.0.10): + resolution: {integrity: sha512-dq0FjyxHHDnp0uS3P12WEOX2W7NeuLzX9AWP38D7Zw2CTbFErapwQVlCiT5DMJcVWKQ1MMdTe92PZl/rBQ7qcw==} peerDependencies: vite: '*' peerDependenciesMeta: @@ -3690,19 +3992,19 @@ packages: dependencies: debug: 4.3.4 globrex: 0.1.2 - tsconfck: 2.1.2(typescript@5.2.2) - vite: 4.5.0(@types/node@20.4.5) + tsconfck: 2.1.2(typescript@5.3.3) + vite: 5.0.10 transitivePeerDependencies: - supports-color - typescript dev: true - /vite@4.5.0(@types/node@20.4.5): - resolution: {integrity: sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==} - engines: {node: ^14.18.0 || >=16.0.0} + /vite@5.0.10: + resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': '>= 14' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' @@ -3725,30 +4027,29 @@ packages: terser: optional: true dependencies: - '@types/node': 20.4.5 - esbuild: 0.18.17 - postcss: 8.4.31 - rollup: 3.27.2 + esbuild: 0.19.10 + postcss: 8.4.32 + rollup: 4.9.1 optionalDependencies: - fsevents: 2.3.2 + fsevents: 2.3.3 dev: true - /vitest@0.34.6(happy-dom@12.10.3): - resolution: {integrity: sha512-+5CALsOvbNKnS+ZHMXtuUC7nL8/7F1F2DnHGjSsszX8zCjWSSviphCb/NuS9Nzf4Q03KyyDRBAXhF/8lffME4Q==} - engines: {node: '>=v14.18.0'} + /vitest@1.1.0(happy-dom@12.10.3): + resolution: {integrity: sha512-oDFiCrw7dd3Jf06HoMtSRARivvyjHJaTxikFxuqJjO76U436PqlVw1uLn7a8OSPrhSfMGVaRakKpA2lePdw79A==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' - '@vitest/browser': '*' - '@vitest/ui': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': ^1.0.0 + '@vitest/ui': ^1.0.0 happy-dom: '*' jsdom: '*' - playwright: '*' - safaridriver: '*' - webdriverio: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@types/node': + optional: true '@vitest/browser': optional: true '@vitest/ui': @@ -3757,37 +4058,28 @@ packages: optional: true jsdom: optional: true - playwright: - optional: true - safaridriver: - optional: true - webdriverio: - optional: true dependencies: - '@types/chai': 4.3.5 - '@types/chai-subset': 1.3.3 - '@types/node': 20.4.5 - '@vitest/expect': 0.34.6 - '@vitest/runner': 0.34.6 - '@vitest/snapshot': 0.34.6 - '@vitest/spy': 0.34.6 - '@vitest/utils': 0.34.6 - acorn: 8.10.0 - acorn-walk: 8.2.0 + '@vitest/expect': 1.1.0 + '@vitest/runner': 1.1.0 + '@vitest/snapshot': 1.1.0 + '@vitest/spy': 1.1.0 + '@vitest/utils': 1.1.0 + acorn-walk: 8.3.1 cac: 6.7.14 chai: 4.3.10 debug: 4.3.4 + execa: 8.0.1 happy-dom: 12.10.3 - local-pkg: 0.4.3 - magic-string: 0.30.2 + local-pkg: 0.5.0 + magic-string: 0.30.5 pathe: 1.1.1 picocolors: 1.0.0 - std-env: 3.3.3 - strip-literal: 1.0.1 - tinybench: 2.5.0 - tinypool: 0.7.0 - vite: 4.5.0(@types/node@20.4.5) - vite-node: 0.34.6(@types/node@20.4.5) + std-env: 3.6.0 + strip-literal: 1.3.0 + tinybench: 2.5.1 + tinypool: 0.8.1 + vite: 5.0.10 + vite-node: 1.1.0 why-is-node-running: 2.2.2 transitivePeerDependencies: - less @@ -3852,15 +4144,6 @@ packages: stackback: 0.0.2 dev: true - /wrap-ansi@7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} dev: true @@ -3870,11 +4153,6 @@ packages: engines: {node: '>=0.4'} dev: true - /y18n@5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} dev: true @@ -3893,24 +4171,6 @@ packages: engines: {node: '>= 14'} dev: true - /yargs-parser@20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - - /yargs@16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/pac-man-board-game/pac-man-board-game.csproj b/pac-man-board-game/pac-man-board-game.csproj index 8c03a07..caa7b8e 100644 --- a/pac-man-board-game/pac-man-board-game.csproj +++ b/pac-man-board-game/pac-man-board-game.csproj @@ -18,11 +18,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + From e0b4c91d338ca1cc6458d8563e402e79e6a0fc65 Mon Sep 17 00:00:00 2001 From: martin Date: Sun, 7 Jan 2024 23:52:32 +0100 Subject: [PATCH 5/5] Fixed vite deprecation warning. Added types for node --- pac-man-board-game.sln.DotSettings.user | 4 +- pac-man-board-game/ClientApp/package.json | 2 + pac-man-board-game/ClientApp/pnpm-lock.yaml | 41 +++++++++++++------ .../{postcss.config.js => postcss.config.cjs} | 0 ...tailwind.config.js => tailwind.config.cjs} | 0 pac-man-board-game/Dockerfile | 4 +- 6 files changed, 33 insertions(+), 18 deletions(-) rename pac-man-board-game/ClientApp/{postcss.config.js => postcss.config.cjs} (100%) rename pac-man-board-game/ClientApp/{tailwind.config.js => tailwind.config.cjs} (100%) diff --git a/pac-man-board-game.sln.DotSettings.user b/pac-man-board-game.sln.DotSettings.user index cefe584..3b6af26 100644 --- a/pac-man-board-game.sln.DotSettings.user +++ b/pac-man-board-game.sln.DotSettings.user @@ -2,6 +2,4 @@ True 35336347-32EB-4764-A28E-3F8FF6CA54C4 db4927dd-2e12-48a7-9a84-2b7e3e31b9c8 - <SessionState ContinuousTestingMode="0" IsActive="True" Name="All tests from &lt;BackendTests&gt;" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session"> - <Project Location="/home/martin/Git/Csharp/pac-man-board-game/BackendTests" Presentation="&lt;BackendTests&gt;" /> -</SessionState> \ No newline at end of file + \ No newline at end of file diff --git a/pac-man-board-game/ClientApp/package.json b/pac-man-board-game/ClientApp/package.json index b4882bc..313005d 100644 --- a/pac-man-board-game/ClientApp/package.json +++ b/pac-man-board-game/ClientApp/package.json @@ -2,6 +2,7 @@ "name": "pac_man_board_game", "version": "0.1.1", "private": true, + "type": "module", "dependencies": { "@emotion/react": "^11.11.1", "@headlessui/react": "^1.7.17", @@ -15,6 +16,7 @@ "web-vitals": "^3.5.0" }, "devDependencies": { + "@types/node": "^20.10.7", "@types/react": "^18.2.45", "@types/react-dom": "^18.2.18", "@vitejs/plugin-react": "^4.2.1", diff --git a/pac-man-board-game/ClientApp/pnpm-lock.yaml b/pac-man-board-game/ClientApp/pnpm-lock.yaml index c0f938f..b656deb 100644 --- a/pac-man-board-game/ClientApp/pnpm-lock.yaml +++ b/pac-man-board-game/ClientApp/pnpm-lock.yaml @@ -43,6 +43,9 @@ importers: specifier: ^3.5.0 version: 3.5.0 devDependencies: + '@types/node': + specifier: ^20.10.7 + version: 20.10.7 '@types/react': specifier: ^18.2.45 version: 18.2.45 @@ -78,7 +81,7 @@ importers: version: 5.3.3 vite: specifier: ^5.0.10 - version: 5.0.10 + version: 5.0.10(@types/node@20.10.7) vite-plugin-node-polyfills: specifier: ^0.17.0 version: 0.17.0(vite@5.0.10) @@ -90,7 +93,7 @@ importers: version: 4.2.2(typescript@5.3.3)(vite@5.0.10) vitest: specifier: ^1.1.0 - version: 1.1.0(happy-dom@12.10.3) + version: 1.1.0(@types/node@20.10.7)(happy-dom@12.10.3) packages: @@ -1403,6 +1406,12 @@ packages: resolution: {integrity: sha512-22y3o88f4a94mKljsZcanlNWPzO0uBsBdzLAngf2tp533LzZcQzb6+eZPJ+vCTt+bqF2XnvT9gejTLsAcJAJyQ==} dev: false + /@types/node@20.10.7: + resolution: {integrity: sha512-fRbIKb8C/Y2lXxB5eVMj4IU7xpdox0Lh8bUPEdtLysaylsml1hOOx1+STloRs/B9nf7C6kPRmmg/V7aQW7usNg==} + dependencies: + undici-types: 5.26.5 + dev: true + /@types/parse-json@4.0.0: resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} dev: false @@ -1437,7 +1446,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.6) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.0.10 + vite: 5.0.10(@types/node@20.10.7) transitivePeerDependencies: - supports-color dev: true @@ -1460,7 +1469,7 @@ packages: std-env: 3.6.0 test-exclude: 6.0.0 v8-to-istanbul: 9.2.0 - vitest: 1.1.0(happy-dom@12.10.3) + vitest: 1.1.0(@types/node@20.10.7)(happy-dom@12.10.3) transitivePeerDependencies: - supports-color dev: true @@ -3815,6 +3824,10 @@ packages: resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} dev: true + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: true + /update-browserslist-db@1.0.11(browserslist@4.21.10): resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} hasBin: true @@ -3933,7 +3946,7 @@ packages: convert-source-map: 2.0.0 dev: true - /vite-node@1.1.0: + /vite-node@1.1.0(@types/node@20.10.7): resolution: {integrity: sha512-jV48DDUxGLEBdHCQvxL1mEh7+naVy+nhUUUaPAZLd3FJgXuxQiewHcfeZebbJ6onDqNGkP4r3MhQ342PRlG81Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -3942,7 +3955,7 @@ packages: debug: 4.3.4 pathe: 1.1.1 picocolors: 1.0.0 - vite: 5.0.10 + vite: 5.0.10(@types/node@20.10.7) transitivePeerDependencies: - '@types/node' - less @@ -3963,7 +3976,7 @@ packages: buffer-polyfill: /buffer@6.0.3 node-stdlib-browser: 1.2.0 process: 0.11.10 - vite: 5.0.10 + vite: 5.0.10(@types/node@20.10.7) transitivePeerDependencies: - rollup dev: true @@ -3976,7 +3989,7 @@ packages: '@rollup/pluginutils': 5.0.5 '@svgr/core': 8.1.0 '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0) - vite: 5.0.10 + vite: 5.0.10(@types/node@20.10.7) transitivePeerDependencies: - rollup - supports-color @@ -3993,13 +4006,13 @@ packages: debug: 4.3.4 globrex: 0.1.2 tsconfck: 2.1.2(typescript@5.3.3) - vite: 5.0.10 + vite: 5.0.10(@types/node@20.10.7) transitivePeerDependencies: - supports-color - typescript dev: true - /vite@5.0.10: + /vite@5.0.10(@types/node@20.10.7): resolution: {integrity: sha512-2P8J7WWgmc355HUMlFrwofacvr98DAjoE52BfdbwQtyLH06XKwaL/FMnmKM2crF0iX4MpmMKoDlNCB1ok7zHCw==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -4027,6 +4040,7 @@ packages: terser: optional: true dependencies: + '@types/node': 20.10.7 esbuild: 0.19.10 postcss: 8.4.32 rollup: 4.9.1 @@ -4034,7 +4048,7 @@ packages: fsevents: 2.3.3 dev: true - /vitest@1.1.0(happy-dom@12.10.3): + /vitest@1.1.0(@types/node@20.10.7)(happy-dom@12.10.3): resolution: {integrity: sha512-oDFiCrw7dd3Jf06HoMtSRARivvyjHJaTxikFxuqJjO76U436PqlVw1uLn7a8OSPrhSfMGVaRakKpA2lePdw79A==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -4059,6 +4073,7 @@ packages: jsdom: optional: true dependencies: + '@types/node': 20.10.7 '@vitest/expect': 1.1.0 '@vitest/runner': 1.1.0 '@vitest/snapshot': 1.1.0 @@ -4078,8 +4093,8 @@ packages: strip-literal: 1.3.0 tinybench: 2.5.1 tinypool: 0.8.1 - vite: 5.0.10 - vite-node: 1.1.0 + vite: 5.0.10(@types/node@20.10.7) + vite-node: 1.1.0(@types/node@20.10.7) why-is-node-running: 2.2.2 transitivePeerDependencies: - less diff --git a/pac-man-board-game/ClientApp/postcss.config.js b/pac-man-board-game/ClientApp/postcss.config.cjs similarity index 100% rename from pac-man-board-game/ClientApp/postcss.config.js rename to pac-man-board-game/ClientApp/postcss.config.cjs diff --git a/pac-man-board-game/ClientApp/tailwind.config.js b/pac-man-board-game/ClientApp/tailwind.config.cjs similarity index 100% rename from pac-man-board-game/ClientApp/tailwind.config.js rename to pac-man-board-game/ClientApp/tailwind.config.cjs diff --git a/pac-man-board-game/Dockerfile b/pac-man-board-game/Dockerfile index cf33e21..f2f6153 100644 --- a/pac-man-board-game/Dockerfile +++ b/pac-man-board-game/Dockerfile @@ -1,9 +1,9 @@ -FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS base +FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 80 EXPOSE 443 -FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build +FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \ && apt-get install -y \