diff --git a/.Lib9c.StateService/Lib9c.StateService.csproj b/.Lib9c.StateService/Lib9c.StateService.csproj index f4385886e..c3e36d7a0 100644 --- a/.Lib9c.StateService/Lib9c.StateService.csproj +++ b/.Lib9c.StateService/Lib9c.StateService.csproj @@ -3,13 +3,14 @@ net6.0 enable + Exe enable - + diff --git a/.Lib9c.Tests/Action/ClaimStakeReward1Test.cs b/.Lib9c.Tests/Action/ClaimStakeReward1Test.cs index 642c9cdd3..f5323c626 100644 --- a/.Lib9c.Tests/Action/ClaimStakeReward1Test.cs +++ b/.Lib9c.Tests/Action/ClaimStakeReward1Test.cs @@ -33,6 +33,8 @@ public ClaimStakeReward1Test(ITestOutputHelper outputHelper) _initialState = new MockStateDelta(); var sheets = TableSheetsImporter.ImportSheets(); + sheets[nameof(StakeRegularRewardSheet)] = + ClaimStakeReward.V2.StakeRegularRewardSheetCsv; foreach (var (key, value) in sheets) { _initialState = _initialState diff --git a/.Lib9c.Tests/Action/ClaimStakeReward2Test.cs b/.Lib9c.Tests/Action/ClaimStakeReward2Test.cs index 3f69b9995..a7ded3b61 100644 --- a/.Lib9c.Tests/Action/ClaimStakeReward2Test.cs +++ b/.Lib9c.Tests/Action/ClaimStakeReward2Test.cs @@ -34,6 +34,8 @@ public ClaimStakeReward2Test(ITestOutputHelper outputHelper) _initialState = new MockStateDelta(); var sheets = TableSheetsImporter.ImportSheets(); + sheets[nameof(StakeRegularRewardSheet)] = + ClaimStakeReward.V2.StakeRegularRewardSheetCsv; foreach (var (key, value) in sheets) { _initialState = _initialState diff --git a/.Lib9c.Tests/Action/ClaimStakeReward3Test.cs b/.Lib9c.Tests/Action/ClaimStakeReward3Test.cs index 08be99851..1fb8cc626 100644 --- a/.Lib9c.Tests/Action/ClaimStakeReward3Test.cs +++ b/.Lib9c.Tests/Action/ClaimStakeReward3Test.cs @@ -1,7 +1,8 @@ -#nullable enable - namespace Lib9c.Tests.Action { +#nullable enable + + using System.Collections.Generic; using System.Linq; using Lib9c.Tests.Util; using Libplanet.Action.State; @@ -10,6 +11,7 @@ namespace Lib9c.Tests.Action using Nekoyume.Action; using Nekoyume.Helper; using Nekoyume.Model.State; + using Nekoyume.TableData; using Serilog; using Xunit; using Xunit.Abstractions; @@ -35,7 +37,14 @@ public ClaimStakeReward3Test(ITestOutputHelper outputHelper) _avatarAddr, _initialStatesWithAvatarStateV1, _initialStatesWithAvatarStateV2) = InitializeUtil.InitializeStates( - agentAddr: _agentAddr); + agentAddr: _agentAddr, + sheetsOverride: new Dictionary + { + { + nameof(StakeRegularRewardSheet), + ClaimStakeReward.V2.StakeRegularRewardSheetCsv + }, + }); _ncg = _initialStatesWithAvatarStateV1.GetGoldCurrency(); } diff --git a/.Lib9c.Tests/Action/ClaimStakeReward4Test.cs b/.Lib9c.Tests/Action/ClaimStakeReward4Test.cs index a2c11cb94..a0134072e 100644 --- a/.Lib9c.Tests/Action/ClaimStakeReward4Test.cs +++ b/.Lib9c.Tests/Action/ClaimStakeReward4Test.cs @@ -1,7 +1,8 @@ -#nullable enable - namespace Lib9c.Tests.Action { +#nullable enable + + using System.Collections.Generic; using System.Linq; using Lib9c.Tests.Util; using Libplanet.Action.State; @@ -10,6 +11,7 @@ namespace Lib9c.Tests.Action using Nekoyume.Action; using Nekoyume.Helper; using Nekoyume.Model.State; + using Nekoyume.TableData; using Serilog; using Xunit; using Xunit.Abstractions; @@ -35,7 +37,14 @@ public ClaimStakeReward4Test(ITestOutputHelper outputHelper) _avatarAddr, _initialStatesWithAvatarStateV1, _initialStatesWithAvatarStateV2) = InitializeUtil.InitializeStates( - agentAddr: _agentAddr); + agentAddr: _agentAddr, + sheetsOverride: new Dictionary + { + { + nameof(StakeRegularRewardSheet), + ClaimStakeReward.V2.StakeRegularRewardSheetCsv + }, + }); _ncg = _initialStatesWithAvatarStateV1.GetGoldCurrency(); } diff --git a/.Lib9c.Tests/Action/ClaimStakeReward5Test.cs b/.Lib9c.Tests/Action/ClaimStakeReward5Test.cs new file mode 100644 index 000000000..dcab60fdb --- /dev/null +++ b/.Lib9c.Tests/Action/ClaimStakeReward5Test.cs @@ -0,0 +1,316 @@ +namespace Lib9c.Tests.Action +{ +#nullable enable + + using System.Collections.Generic; + using System.Linq; + using Lib9c.Tests.Util; + using Libplanet.Action.State; + using Libplanet.Crypto; + using Libplanet.Types.Assets; + using Nekoyume.Action; + using Nekoyume.Helper; + using Nekoyume.Model.State; + using Nekoyume.TableData; + using Serilog; + using Xunit; + using Xunit.Abstractions; + + public class ClaimStakeReward5Test + { + private const string AgentAddressHex = "0x0000000001000000000100000000010000000001"; + private readonly Address _agentAddr = new Address(AgentAddressHex); + private readonly Address _avatarAddr; + private readonly IAccountStateDelta _initialStatesWithAvatarStateV1; + private readonly IAccountStateDelta _initialStatesWithAvatarStateV2; + private readonly Currency _ncg; + + public ClaimStakeReward5Test(ITestOutputHelper outputHelper) + { + Log.Logger = new LoggerConfiguration() + .MinimumLevel.Verbose() + .WriteTo.TestOutput(outputHelper) + .CreateLogger(); + ( + _, + _, + _avatarAddr, + _initialStatesWithAvatarStateV1, + _initialStatesWithAvatarStateV2) = InitializeUtil.InitializeStates( + agentAddr: _agentAddr, + sheetsOverride: new Dictionary + { + { + nameof(StakeRegularRewardSheet), + ClaimStakeReward.V2.StakeRegularRewardSheetCsv + }, + }); + _ncg = _initialStatesWithAvatarStateV1.GetGoldCurrency(); + } + + [Fact] + public void Serialization() + { + var action = new ClaimStakeReward5(_avatarAddr); + var deserialized = new ClaimStakeReward5(); + deserialized.LoadPlainValue(action.PlainValue); + Assert.Equal(action.AvatarAddress, deserialized.AvatarAddress); + } + + [Theory] + [InlineData( + ClaimStakeReward2.ObsoletedIndex, + 100L, + null, + ClaimStakeReward2.ObsoletedIndex + StakeState.LockupInterval, + 40, + 4, + 0, + null, + null, + 0L + )] + [InlineData( + ClaimStakeReward2.ObsoletedIndex, + 6000L, + null, + ClaimStakeReward2.ObsoletedIndex + StakeState.LockupInterval, + 4800, + 36, + 4, + null, + null, + 0L + )] + // Calculate rune start from hard fork index + [InlineData( + 0L, + 6000L, + 0L, + ClaimStakeReward2.ObsoletedIndex + StakeState.LockupInterval, + 136800, + 1026, + 3, + null, + null, + 0L + )] + // Stake reward v2 + // Stake before v2, prev. receive v1, receive v1 & v2 + [InlineData( + StakeState.StakeRewardSheetV2Index - StakeState.RewardInterval * 2, + 50L, + StakeState.StakeRewardSheetV2Index - StakeState.RewardInterval, + StakeState.StakeRewardSheetV2Index + 1, + 5, + 1, + 0, + null, + null, + 0L + )] + // Stake before v2, prev. receive v2, receive v2 + [InlineData( + StakeState.StakeRewardSheetV2Index - StakeState.RewardInterval, + 50L, + StakeState.StakeRewardSheetV2Index, + StakeState.StakeRewardSheetV2Index + StakeState.RewardInterval, + 5, + 1, + 0, + null, + null, + 0L + )] + // Stake after v2, no prev. receive, receive v2 + [InlineData( + StakeState.StakeRewardSheetV2Index, + 6000L, + null, + StakeState.StakeRewardSheetV2Index + StakeState.RewardInterval, + 1200, + 9, + 1, + null, + null, + 0L + )] + // stake after v2, prev. receive v2, receive v2 + [InlineData( + StakeState.StakeRewardSheetV2Index, + 50L, + StakeState.StakeRewardSheetV2Index + StakeState.RewardInterval, + StakeState.StakeRewardSheetV2Index + StakeState.RewardInterval * 2, + 5, + 1, + 0, + null, + null, + 0L + )] + // stake before currency as reward, non prev. + [InlineData( + StakeState.CurrencyAsRewardStartIndex - StakeState.RewardInterval * 2, + 10_000_000L, + null, + StakeState.CurrencyAsRewardStartIndex + StakeState.RewardInterval, + 3_000_000, + 37_506, + 4_998, + AgentAddressHex, + "GARAGE", + 100_000L + )] + // stake before currency as reward, prev. + [InlineData( + StakeState.CurrencyAsRewardStartIndex - StakeState.RewardInterval * 2, + 10_000_000L, + StakeState.CurrencyAsRewardStartIndex - StakeState.RewardInterval, + StakeState.CurrencyAsRewardStartIndex + StakeState.RewardInterval, + 2_000_000, + 25_004, + 3_332, + AgentAddressHex, + "GARAGE", + 100_000L + )] + // test tx(c46cf83c46bc106372015a5020d6b9f15dc733819a6dc3fde37d9b5625fc3d93) + [InlineData( + 7_009_561L, + 10_000_000L, + 7_110_390L, + 7_160_778L, + 1_000_000, + 12_502, + 1_666, + null, + null, + 0)] + public void Execute_Success( + long startedBlockIndex, + long stakeAmount, + long? previousRewardReceiveIndex, + long blockIndex, + int expectedHourglass, + int expectedApStone, + int expectedRune, + string expectedCurrencyAddrHex, + string expectedCurrencyTicker, + long expectedCurrencyAmount) + { + Execute( + _initialStatesWithAvatarStateV1, + _agentAddr, + _avatarAddr, + startedBlockIndex, + stakeAmount, + previousRewardReceiveIndex, + blockIndex, + expectedHourglass, + expectedApStone, + expectedRune, + expectedCurrencyAddrHex, + expectedCurrencyTicker, + expectedCurrencyAmount); + + Execute( + _initialStatesWithAvatarStateV2, + _agentAddr, + _avatarAddr, + startedBlockIndex, + stakeAmount, + previousRewardReceiveIndex, + blockIndex, + expectedHourglass, + expectedApStone, + expectedRune, + expectedCurrencyAddrHex, + expectedCurrencyTicker, + expectedCurrencyAmount); + } + + private void Execute( + IAccountStateDelta prevState, + Address agentAddr, + Address avatarAddr, + long startedBlockIndex, + long stakeAmount, + long? previousRewardReceiveIndex, + long blockIndex, + int expectedHourglass, + int expectedApStone, + int expectedRune, + string expectedCurrencyAddrHex, + string expectedCurrencyTicker, + long expectedCurrencyAmount) + { + var context = new ActionContext(); + var stakeStateAddr = StakeState.DeriveAddress(agentAddr); + var initialStakeState = new StakeState(stakeStateAddr, startedBlockIndex); + if (!(previousRewardReceiveIndex is null)) + { + initialStakeState.Claim((long)previousRewardReceiveIndex); + } + + prevState = prevState + .SetState(stakeStateAddr, initialStakeState.Serialize()) + .MintAsset(context, stakeStateAddr, _ncg * stakeAmount); + + var action = new ClaimStakeReward5(avatarAddr); + var states = action.Execute(new ActionContext + { + PreviousState = prevState, + Signer = agentAddr, + BlockIndex = blockIndex, + }); + + var avatarState = states.GetAvatarStateV2(avatarAddr); + if (expectedHourglass > 0) + { + Assert.Equal( + expectedHourglass, + avatarState.inventory.Items.First(x => x.item.Id == 400000).count); + } + else + { + Assert.DoesNotContain(avatarState.inventory.Items, x => x.item.Id == 400000); + } + + if (expectedApStone > 0) + { + Assert.Equal( + expectedApStone, + avatarState.inventory.Items.First(x => x.item.Id == 500000).count); + } + else + { + Assert.DoesNotContain(avatarState.inventory.Items, x => x.item.Id == 500000); + } + + if (expectedRune > 0) + { + Assert.Equal( + expectedRune * RuneHelper.StakeRune, + states.GetBalance(avatarAddr, RuneHelper.StakeRune)); + } + else + { + Assert.Equal( + 0 * RuneHelper.StakeRune, + states.GetBalance(avatarAddr, RuneHelper.StakeRune)); + } + + if (!string.IsNullOrEmpty(expectedCurrencyAddrHex)) + { + var addr = new Address(expectedCurrencyAddrHex); + var currency = Currencies.GetMinterlessCurrency(expectedCurrencyTicker); + Assert.Equal( + expectedCurrencyAmount * currency, + states.GetBalance(addr, currency)); + } + + Assert.True(states.TryGetStakeState(agentAddr, out StakeState stakeState)); + Assert.Equal(blockIndex, stakeState.ReceivedBlockIndex); + } + } +} diff --git a/.Lib9c.Tests/Action/Factory/ClaimStakeRewardFactoryTest.cs b/.Lib9c.Tests/Action/Factory/ClaimStakeRewardFactoryTest.cs index 95b624a7c..326d99c63 100644 --- a/.Lib9c.Tests/Action/Factory/ClaimStakeRewardFactoryTest.cs +++ b/.Lib9c.Tests/Action/Factory/ClaimStakeRewardFactoryTest.cs @@ -46,7 +46,9 @@ public static IEnumerable GetAllClaimStakeRewardV1() [InlineData(ClaimStakeReward3.ObsoleteBlockIndex, typeof(ClaimStakeReward3))] [InlineData(ClaimStakeReward3.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward4))] [InlineData(ClaimStakeReward4.ObsoleteBlockIndex, typeof(ClaimStakeReward4))] - [InlineData(ClaimStakeReward4.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward))] + [InlineData(ClaimStakeReward4.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward5))] + [InlineData(ClaimStakeReward5.ObsoleteBlockIndex, typeof(ClaimStakeReward5))] + [InlineData(ClaimStakeReward5.ObsoleteBlockIndex + 1, typeof(ClaimStakeReward))] [InlineData(long.MaxValue, typeof(ClaimStakeReward))] public void Create_ByBlockIndex_Success( long blockIndex, diff --git a/.Lib9c.Tests/Action/Scenario/AuraScenarioTest.cs b/.Lib9c.Tests/Action/Scenario/AuraScenarioTest.cs new file mode 100644 index 000000000..1c847fda0 --- /dev/null +++ b/.Lib9c.Tests/Action/Scenario/AuraScenarioTest.cs @@ -0,0 +1,116 @@ +namespace Lib9c.Tests.Action.Scenario +{ + using System; + using System.Collections.Generic; + using System.Linq; + using Bencodex.Types; + using Libplanet.Action.State; + using Libplanet.Crypto; + using Libplanet.Types.Assets; + using Nekoyume; + using Nekoyume.Action; + using Nekoyume.Model; + using Nekoyume.Model.EnumType; + using Nekoyume.Model.Item; + using Nekoyume.Model.Skill; + using Nekoyume.Model.Stat; + using Nekoyume.Model.State; + using Nekoyume.TableData; + using Xunit; + using static SerializeKeys; + + public class AuraScenarioTest + { + [Fact] + public void HackAndSlash() + { + var agentAddress = new PrivateKey().ToAddress(); + var agentState = new AgentState(agentAddress); + var avatarAddress = new PrivateKey().ToAddress(); + var rankingMapAddress = avatarAddress.Derive("ranking_map"); + var sheets = TableSheetsImporter.ImportSheets(); + var tableSheets = new TableSheets(sheets); + agentState.avatarAddresses.Add(0, avatarAddress); + var gameConfigState = new GameConfigState(sheets[nameof(GameConfigSheet)]); + var avatarState = new AvatarState( + avatarAddress, + agentAddress, + 0, + tableSheets.GetAvatarSheets(), + gameConfigState, + rankingMapAddress + ); + + var auraRow = + tableSheets.EquipmentItemSheet.Values.First(r => r.ItemSubType == ItemSubType.Aura); + var aura = ItemFactory.CreateItemUsable(auraRow, Guid.NewGuid(), 0L); + aura.StatsMap.AddStatAdditionalValue(StatType.CRI, 1); + var skillRow = tableSheets.SkillSheet[800001]; + var skill = SkillFactory.Get(skillRow, 0, 100, 0, StatType.NONE); + aura.Skills.Add(skill); + avatarState.inventory.AddItem(aura); + + IAccountStateDelta initialState = new Tests.Action.MockStateDelta() + .SetState(agentAddress, agentState.Serialize()) + .SetState(avatarAddress, avatarState.SerializeV2()) + .SetState( + avatarAddress.Derive(LegacyInventoryKey), + avatarState.inventory.Serialize()) + .SetState( + avatarAddress.Derive(LegacyWorldInformationKey), + avatarState.worldInformation.Serialize()) + .SetState( + avatarAddress.Derive(LegacyQuestListKey), + avatarState.questList.Serialize()) + .SetState( + Addresses.GoldCurrency, + new GoldCurrencyState(Currency.Legacy("NCG", 2, minters: null)).Serialize()) + .SetState(gameConfigState.address, gameConfigState.Serialize()); + foreach (var (key, value) in sheets) + { + initialState = initialState + .SetState(Addresses.TableSheet.Derive(key), value.Serialize()); + } + + var itemSlotStateAddress = ItemSlotState.DeriveAddress(avatarAddress, BattleType.Adventure); + Assert.Null(initialState.GetState(itemSlotStateAddress)); + + var has = new HackAndSlash + { + StageId = 1, + AvatarAddress = avatarAddress, + Equipments = new List + { + aura.ItemId, + }, + Costumes = new List(), + Foods = new List(), + WorldId = 1, + RuneInfos = new List(), + }; + + var nextState = has.Execute(new ActionContext + { + BlockIndex = 2, + PreviousState = initialState, + Random = new TestRandom(), + Signer = agentAddress, + }); + + var nextAvatarState = nextState.GetAvatarStateV2(avatarAddress); + Assert.True(nextAvatarState.worldInformation.IsStageCleared(1)); + var equippedItem = Assert.IsType(nextAvatarState.inventory.Equipments.First()); + Assert.True(equippedItem.equipped); + var rawItemSlot = Assert.IsType(nextState.GetState(itemSlotStateAddress)); + var itemSlotState = new ItemSlotState(rawItemSlot); + var equipmentId = itemSlotState.Equipments.Single(); + Assert.Equal(aura.ItemId, equipmentId); + var player = new Player(avatarState, tableSheets.GetSimulatorSheets()); + var equippedPlayer = new Player(nextAvatarState, tableSheets.GetSimulatorSheets()); + Assert.Null(player.aura); + Assert.NotNull(equippedPlayer.aura); + Assert.Equal(player.ATK + 1, equippedPlayer.ATK); + Assert.Equal(player.CRI + 1, equippedPlayer.CRI); + } + } +} diff --git a/.Lib9c.Tests/Model/PlayerTest.cs b/.Lib9c.Tests/Model/PlayerTest.cs index a126b4872..499ccbf04 100644 --- a/.Lib9c.Tests/Model/PlayerTest.cs +++ b/.Lib9c.Tests/Model/PlayerTest.cs @@ -162,6 +162,55 @@ public void UseDoubleAttack(SkillCategory skillCategory) Assert.Single(simulator.Log.OfType()); } + [Fact] + public void UseAuraSkill() + { + var defaultAttack = SkillFactory.GetV1( + _tableSheets.SkillSheet.Values.First(r => r.Id == GameConfig.DefaultAttackId), + 100, + 100 + ); + var skillRow = _tableSheets.SkillSheet[800001]; + var skill = SkillFactory.Get(skillRow, 0, 100, 0, StatType.NONE); + + var simulator = new StageSimulator( + _random, + _avatarState, + new List(), + null, + new List(), + 1, + 1, + _tableSheets.StageSheet[1], + _tableSheets.StageWaveSheet[1], + false, + 20, + _tableSheets.GetSimulatorSheets(), + _tableSheets.EnemySkillSheet, + _tableSheets.CostumeStatSheet, + StageSimulator.GetWaveRewards( + _random, + _tableSheets.StageSheet[1], + _tableSheets.MaterialItemSheet) + ); + var player = simulator.Player; + var enemy = new Enemy(player, _tableSheets.CharacterSheet.Values.First(), 1); + player.Targets.Add(enemy); + simulator.Characters = new SimplePriorityQueue(); + simulator.Characters.Enqueue(enemy, 0); + player.InitAI(); + player.OverrideSkill(skill); + player.AddSkill(defaultAttack); + Assert.Equal(2, player.Skills.Count()); + var prevAtk = player.ATK; + var prevDef = player.DEF; + player.Tick(); + Assert.NotEmpty(simulator.Log); + Assert.Equal(nameof(WaveTurnEnd), simulator.Log.Last().GetType().Name); + Assert.Equal(prevAtk + prevAtk * 0.3, player.ATK); + Assert.Equal(prevDef - prevDef * 0.2, player.DEF); + } + [Fact] public void SetCostumeStat() { diff --git a/.Lib9c.Tests/TableData/StakeRegularRewardSheetTest.cs b/.Lib9c.Tests/TableData/StakeRegularRewardSheetTest.cs index 676168478..ba26d1a16 100644 --- a/.Lib9c.Tests/TableData/StakeRegularRewardSheetTest.cs +++ b/.Lib9c.Tests/TableData/StakeRegularRewardSheetTest.cs @@ -14,13 +14,13 @@ public class StakeRegularRewardSheetTest public StakeRegularRewardSheetTest() { - const string TableContent = @"level,required_gold,item_id,rate + const string tableContent = @"level,required_gold,item_id,rate 0,0,0,0 1,10,400000,50 1,10,500000,50"; _sheet = new StakeRegularRewardSheet(); - _sheet.Set(TableContent); + _sheet.Set(tableContent); #pragma warning disable CS0618 // Use of obsolete method Currency.Legacy(): https://github.com/planetarium/lib9c/discussions/1319 _currency = Currency.Legacy("NCG", 2, null); @@ -57,20 +57,19 @@ public void SetToSheet() var patchedSheet = new StakeRegularRewardSheet(); const string tableContentWithRune = - @"level,required_gold,item_id,rate,type,currency_ticker + @"level,required_gold,item_id,rate,type,currency_ticker,currency_decimal_places,decimal_rate 1,50,400000,10,Item 1,50,500000,800,Item 1,50,20001,6000,Rune -1,50,,100,Currency,NCG -1,50,,100,Currency,CRYSTAL -1,50,,100,Currency,GARAGE +1,50,,,Currency,CRYSTAL,18,0.1 +1,50,,100,Currency,GARAGE,18, "; patchedSheet.Set(tableContentWithRune); Assert.Single(patchedSheet); row = patchedSheet[1]; Assert.Equal(50, row.RequiredGold); - Assert.Equal(6, row.Rewards.Count); - for (var i = 0; i < 6; i++) + Assert.Equal(5, row.Rewards.Count); + for (var i = 0; i < 5; i++) { reward = row.Rewards[i]; var itemId = i switch @@ -80,7 +79,6 @@ public void SetToSheet() 2 => 20001, 3 => 0, 4 => 0, - 5 => 0, _ => throw new ArgumentOutOfRangeException() }; var rate = i switch @@ -88,9 +86,8 @@ public void SetToSheet() 0 => 10, 1 => 800, 2 => 6000, - 3 => 100, + 3 => 0, 4 => 100, - 5 => 100, _ => throw new ArgumentOutOfRangeException() }; var rewardType = i switch @@ -100,7 +97,6 @@ public void SetToSheet() 2 => StakeRegularRewardSheet.StakeRewardType.Rune, 3 => StakeRegularRewardSheet.StakeRewardType.Currency, 4 => StakeRegularRewardSheet.StakeRewardType.Currency, - 5 => StakeRegularRewardSheet.StakeRewardType.Currency, _ => throw new ArgumentOutOfRangeException() }; var currencyTicker = i switch @@ -108,15 +104,34 @@ public void SetToSheet() 0 => null, 1 => null, 2 => null, - 3 => "NCG", - 4 => "CRYSTAL", - 5 => "GARAGE", + 3 => "CRYSTAL", + 4 => "GARAGE", + _ => throw new ArgumentOutOfRangeException() + }; + var currencyDecimalPlaces = i switch + { + 0 => (int?)null, + 1 => null, + 2 => null, + 3 => 18, + 4 => 18, + _ => throw new ArgumentOutOfRangeException() + }; + var decimalRate = i switch + { + 0 => 10m, + 1 => 800m, + 2 => 6000m, + 3 => 0.1m, + 4 => 0m, _ => throw new ArgumentOutOfRangeException() }; Assert.Equal(itemId, reward.ItemId); Assert.Equal(rate, reward.Rate); Assert.Equal(rewardType, reward.Type); Assert.Equal(currencyTicker, reward.CurrencyTicker); + Assert.Equal(currencyDecimalPlaces, reward.CurrencyDecimalPlaces); + Assert.Equal(decimalRate, reward.DecimalRate); } } diff --git a/.Lib9c.Tests/Util/InitializeUtil.cs b/.Lib9c.Tests/Util/InitializeUtil.cs index a871ee00e..734fcfacb 100644 --- a/.Lib9c.Tests/Util/InitializeUtil.cs +++ b/.Lib9c.Tests/Util/InitializeUtil.cs @@ -1,6 +1,6 @@ namespace Lib9c.Tests.Util { - using System.Collections.Immutable; + using System.Collections.Generic; using System.IO; using Lib9c.Tests.Action; using Libplanet.Action.State; @@ -23,29 +23,15 @@ IAccountStateDelta initialStatesWithAvatarStateV2 Address? adminAddr = null, Address? agentAddr = null, int avatarIndex = 0, - bool isDevEx = false - ) + bool isDevEx = false, + Dictionary sheetsOverride = null) { adminAddr ??= new PrivateKey().ToAddress(); var context = new ActionContext(); var states = new MockStateDelta().SetState( Addresses.Admin, new AdminState(adminAddr.Value, long.MaxValue).Serialize()); - var sheets = TableSheetsImporter.ImportSheets( - isDevEx - ? Path.GetFullPath("../../").Replace( - Path.Combine(".Lib9c.DevExtensions.Tests", "bin"), - Path.Combine("Lib9c", "TableCSV")) - : null - ); - foreach (var (key, value) in sheets) - { - states = states.SetState( - Addresses.TableSheet.Derive(key), - value.Serialize()); - } - var tableSheets = new TableSheets(sheets); var goldCurrency = Currency.Legacy( "NCG", 2, @@ -56,7 +42,10 @@ IAccountStateDelta initialStatesWithAvatarStateV2 .SetState(goldCurrencyState.address, goldCurrencyState.Serialize()) .MintAsset(context, goldCurrencyState.address, goldCurrency * 1_000_000_000); - var gameConfigState = new GameConfigState(sheets[nameof(GameConfigSheet)]); + var tuple = InitializeTableSheets(states, isDevEx, sheetsOverride); + states = tuple.states; + var tableSheets = new TableSheets(tuple.sheets); + var gameConfigState = new GameConfigState(tuple.sheets[nameof(GameConfigSheet)]); states = states.SetState(gameConfigState.address, gameConfigState.Serialize()); agentAddr ??= new PrivateKey().ToAddress(); @@ -94,5 +83,36 @@ IAccountStateDelta initialStatesWithAvatarStateV2 initialStatesWithAvatarStateV1, initialStatesWithAvatarStateV2); } + + private static (IAccountStateDelta states, Dictionary sheets) + InitializeTableSheets( + IAccountStateDelta states, + bool isDevEx = false, + Dictionary sheetsOverride = null) + { + var sheets = TableSheetsImporter.ImportSheets( + isDevEx + ? Path.GetFullPath("../../").Replace( + Path.Combine(".Lib9c.DevExtensions.Tests", "bin"), + Path.Combine("Lib9c", "TableCSV")) + : null + ); + if (sheetsOverride != null) + { + foreach (var (key, value) in sheetsOverride) + { + sheets[key] = value; + } + } + + foreach (var (key, value) in sheets) + { + states = states.SetState( + Addresses.TableSheet.Derive(key), + value.Serialize()); + } + + return (states, sheets); + } } } diff --git a/.Lib9c.Tools/SubCommand/Action.cs b/.Lib9c.Tools/SubCommand/Action.cs index 238417281..9b6f57bc0 100644 --- a/.Lib9c.Tools/SubCommand/Action.cs +++ b/.Lib9c.Tools/SubCommand/Action.cs @@ -1,6 +1,8 @@ using System; +using System.IO; using System.Linq; using System.Reflection; +using System.Text.Json.Nodes; using Bencodex.Types; using Cocona; using Cocona.Help; @@ -14,6 +16,12 @@ public class Action [Obsolete("This function is deprecated. Please use `NineChronicles.Headless.Executable action list` command instead.")] [Command(Description = "Lists all actions' type ids.")] public void List( + [Option( + Description = "If true, show obsoleted or will be obsoleted actions only (Actions having ActionObsolete attribute only)" + )] bool obsoleteOnly = false, + [Option( + Description = "If true, make json file with results" + )] string jsonPath = null, [Option( Description = "If true, filter obsoleted actions since the --block-index option." )] bool excludeObsolete = false, @@ -22,29 +30,53 @@ public void List( )] long blockIndex = 0 ) { - Type baseType = typeof(Nekoyume.Action.ActionBase); + var baseType = typeof(ActionBase); bool IsTarget(Type type) { - return baseType.IsAssignableFrom(type) && - type.GetCustomAttribute() is { } && - ( - !excludeObsolete || - !(type.GetCustomAttribute() is { } aoAttr) || - aoAttr.ObsoleteIndex > blockIndex - ); + if (!baseType.IsAssignableFrom(type) || + type.GetCustomAttribute() is null) + { + return false; + } + + var isObsoleteTarget = type.GetCustomAttribute() is not null; + var isObsolete = type.GetCustomAttribute() is { } attr && + attr.ObsoleteIndex <= blockIndex; + + if (obsoleteOnly) return isObsoleteTarget; + if (excludeObsolete) return !isObsolete; + + return true; } var assembly = baseType.Assembly; var typeIds = assembly.GetTypes() .Where(IsTarget) - .Select(type => type.GetCustomAttribute()?.TypeIdentifier) - .OfType() - .OrderBy(type => type); + .Select(type => ((IValue typeId, long? obsoleteAt))( + type.GetCustomAttribute()?.TypeIdentifier, + type.GetCustomAttribute()?.ObsoleteIndex + )) + .Where(type => type.typeId is Text) + .OrderBy(type => ((Text)type.typeId).Value); + + var jsonResult = new JsonArray(); + + foreach (var (typeIdValue, obsoleteAt) in typeIds) + { + var typeId = (Text)typeIdValue; + var json = new JsonObject { ["id"] = typeId.Value }; + if (obsoleteAt != null) json.Add("obsoleteAt", obsoleteAt); + jsonResult.Add(json); - foreach (Text typeId in typeIds) { Console.WriteLine(typeId.Value); } + + if (jsonPath != null) + { + using var stream = File.CreateText(jsonPath); + stream.WriteLine(jsonResult.ToString()); + } } [PrimaryCommand] diff --git a/.Libplanet b/.Libplanet index a98718721..419d7a510 160000 --- a/.Libplanet +++ b/.Libplanet @@ -1 +1 @@ -Subproject commit a987187212c0fd2aea272fe3a12bb3c27697fde3 +Subproject commit 419d7a510c09c90cfede35fc7973c0af5c10015d diff --git a/.Libplanet.Extensions.ActionEvaluatorCommonComponents/AccountStateDelta.cs b/.Libplanet.Extensions.ActionEvaluatorCommonComponents/AccountStateDelta.cs index 8a37cb91d..931e5f02a 100644 --- a/.Libplanet.Extensions.ActionEvaluatorCommonComponents/AccountStateDelta.cs +++ b/.Libplanet.Extensions.ActionEvaluatorCommonComponents/AccountStateDelta.cs @@ -18,6 +18,8 @@ public class AccountStateDelta : IAccountStateDelta private ValidatorSet? _validatorSet; private IAccountDelta _delta; + public IAccountState BaseState { get; set; } + public IImmutableSet
UpdatedAddresses => _delta.UpdatedAddresses; public IImmutableSet
StateUpdatedAddresses => _delta.StateUpdatedAddresses; @@ -121,7 +123,7 @@ public AccountStateDelta(byte[] bytes) public IValue? GetState(Address address) => _states.ContainsKey(address) ? _states[address] - : throw new NotSupportedException(); + : BaseState.GetState(address); public IReadOnlyList GetStates(IReadOnlyList
addresses) => addresses.Select(GetState).ToArray(); @@ -132,7 +134,7 @@ public FungibleAssetValue GetBalance(Address address, Currency currency) { if (!_fungibles.TryGetValue((address, currency), out BigInteger rawValue)) { - throw new NotSupportedException(); + return BaseState.GetBalance(address, currency); } return FungibleAssetValue.FromRawValue(currency, rawValue); @@ -155,7 +157,7 @@ public FungibleAssetValue GetTotalSupply(Currency currency) return FungibleAssetValue.FromRawValue(currency, totalSupplyValue); } - throw new NotSupportedException(); + return BaseState.GetTotalSupply(currency); } public IAccountStateDelta MintAsset( @@ -192,7 +194,10 @@ public IAccountStateDelta MintAsset( ), _totalSupplies.SetItem(currency, (currentTotalSupply + value).RawValue), _validatorSet - ); + ) + { + BaseState = BaseState, + }; } return new AccountStateDelta( @@ -203,7 +208,10 @@ public IAccountStateDelta MintAsset( ), _totalSupplies, _validatorSet - ); + ) + { + BaseState = BaseState, + }; } public IAccountStateDelta TransferAsset( @@ -234,7 +242,10 @@ public IAccountStateDelta TransferAsset( var balances = _fungibles .SetItem((sender, currency), senderRemains.RawValue) .SetItem((recipient, currency), recipientRemains.RawValue); - return new AccountStateDelta(_states, balances, _totalSupplies, _validatorSet); + return new AccountStateDelta(_states, balances, _totalSupplies, _validatorSet) + { + BaseState = BaseState, + }; } public IAccountStateDelta BurnAsset( @@ -273,12 +284,15 @@ public IAccountStateDelta BurnAsset( (GetTotalSupply(currency) - value).RawValue) : _totalSupplies, _validatorSet - ); + ) + { + BaseState = BaseState, + }; } public ValidatorSet GetValidatorSet() { - return _validatorSet ?? throw new NotSupportedException(); + return _validatorSet ?? BaseState.GetValidatorSet(); } public IAccountStateDelta SetValidator(Validator validator) @@ -288,6 +302,9 @@ public IAccountStateDelta SetValidator(Validator validator) _fungibles, _totalSupplies, GetValidatorSet().Update(validator) - ); + ) + { + BaseState = BaseState, + }; } } diff --git a/.Libplanet.Extensions.RemoteActionEvaluator/RemoteActionEvaluator.cs b/.Libplanet.Extensions.RemoteActionEvaluator/RemoteActionEvaluator.cs index 4fd8a3871..819011c44 100644 --- a/.Libplanet.Extensions.RemoteActionEvaluator/RemoteActionEvaluator.cs +++ b/.Libplanet.Extensions.RemoteActionEvaluator/RemoteActionEvaluator.cs @@ -39,6 +39,23 @@ public IReadOnlyList Evaluate(IPreEvaluationBlock block) var actionEvaluations = evaluationResponse.Evaluations.Select(ActionEvaluationMarshaller.Deserialize) .ToImmutableList(); + for (var i = 0; i < actionEvaluations.Count; ++i) + { + if (i > 0) + { + actionEvaluations[i].InputContext.PreviousState.BaseState = + actionEvaluations[i - 1].OutputState; + } + else + { + actionEvaluations[i].InputContext.PreviousState.BaseState = + _blockChainStates.GetBlockState(block.PreviousHash); + } + + actionEvaluations[i].OutputState.BaseState = + actionEvaluations[i].InputContext.PreviousState; + } + return actionEvaluations; } diff --git a/.github/workflows/gh-page.yml b/.github/workflows/gh-page.yml new file mode 100644 index 000000000..e7cfb9ed3 --- /dev/null +++ b/.github/workflows/gh-page.yml @@ -0,0 +1,36 @@ +name: main + +on: + push: + branches: + - development + - main + +jobs: + publish-gh-pages: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + + - name: Install Dependency + working-directory: ./Dashboard + run: yarn + + - name: Build .env + working-directory: ./Dashboard + run: | + echo "VITE_OBSOLETE_DATA_PATH=${{ secrets.VITE_OBSOLETE_DATA_PATH }}" >> .env + echo "VITE_API_PATH=${{ secrets.VITE_API_PATH }}" >> .env + + - name: Build Dashboard + working-directory: ./Dashboard + run: yarn build --outDir ../publish + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./publish + destination_dir: dashboard \ No newline at end of file diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dc2b021b9..7c05802f6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,10 +2,13 @@ name: main on: push: - branches: [] - tags: [] + branches: + - "*" + tags: + - "*" pull_request: - branches: [] + branches: + - "*" jobs: build-and-test: @@ -47,7 +50,7 @@ jobs: - name: Install dependencies run: dotnet restore - name: Build - run: dotnet build --no-restore --configuration ${{ matrix.configuration }} + run: dotnet build --self-contained=false --no-restore --configuration ${{ matrix.configuration }} - name: Test run: dotnet test --no-restore --verbosity normal --configuration ${{ matrix.configuration }} @@ -69,7 +72,7 @@ jobs: sed -i -E 's|\[MaybeNullWhen\(false\)] out TValue value|out TValue value|' Lib9c/TableData/Sheet.cs sed -i -E 's|public bool TryGetValue\(TKey key, out TValue value, bool throwException\)|public bool TryGetValue\(TKey key, out TValue? value, bool throwException\)|' Lib9c/TableData/Sheet.cs - name: build - run: dotnet build + run: dotnet build --self-contained=false release: if: github.ref_type == 'tag' && startsWith(github.ref_name, 'v') @@ -84,13 +87,14 @@ jobs: set -evx curl -o /tmp/web-flow.gpg "$WEB_FLOW_KEY_URL" gpg --import /tmp/web-flow.gpg + # shellcheck disable=SC2126 if ! git verify-commit "$GITHUB_REF_NAME" && \ [[ "$( git cat-file -p "$GITHUB_REF_NAME" \ | grep -Ei '^parent\s+[0-9a-f]{40}$' | wc -l )" -lt 2 ]]; then echo "::error title=Invalid tag commit::Tags must refer to a merge" \ "commit or a commit signed by GitHub web-flow" \ "($WEB_FLOW_KEY_URL). The tag $GITHUB_REF_NAME refers to " \ - "a commit $(git rev-parse $GITHUB_REF_NAME) which is neither" \ + "a commit $(git rev-parse "$GITHUB_REF_NAME") which is neither" \ "a merge commit nor signed by GitHub web-flow." exit 1 fi @@ -104,12 +108,19 @@ jobs: run: | mkdir publish dotnet run --property WarningLevel=0 --project .Lib9c.Tools/Lib9c.Tools.csproj -- action list > publish/all_action_type_ids.txt + dotnet run --property WarningLevel=0 --project .Lib9c.Tools/Lib9c.Tools.csproj -- action list --obsolete-only --json-path=publish/obsolete_action_types.json - name: Publish available action type ids uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./publish destination_dir: ${{ github.ref_name }} + - name: Publish available action type ids for latest + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./publish + destination_dir: latest update-submodule: if: github.ref_type == 'branch' && startsWith(github.ref_name, 'release/') diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 647840aef..81138cdc0 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,9 @@ name: publish on: push: - branches: main + branches: + - development + - main jobs: nuget: @@ -21,8 +23,8 @@ jobs: project_suffix=dev.${{ github.sha }} dotnet_args="$dotnet_args --version-suffix $project_suffix" fi - dotnet build $dotnet_args - dotnet pack $dotnet_args + dotnet build "$dotnet_args" + dotnet pack "$dotnet_args" - name: push if: github.event_name != 'pull_request' run: | @@ -33,3 +35,27 @@ jobs: fi env: NUGET_API_KEY: ${{ secrets.NUGET_API_KEY }} + s3-lib9c-stateservice: + strategy: + matrix: + runtime: ["osx-arm64", "linux-arm64", "linux-x64", "win-x64"] + name: Publish Lib9c.StateService (${{ matrix.runtime }}) + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: true + - uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.400 + - name: Publish Lib9c.StateService + run: dotnet publish ./.Lib9c.StateService/Lib9c.StateService.csproj -o out -r ${{ matrix.runtime }} + - name: Compress the build result + run: zip -r ../${{ matrix.runtime }}.zip . + working-directory: ./out + - name: Upload S3 + run: aws s3 cp ${{ matrix.runtime }}.zip s3://9c-dx/lib9c-stateservices/${{ github.sha }}/ + env: + AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }} + AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + AWS_REGION: "us-east-2" diff --git a/.github/workflows/validate-github-actions-workflows.yml b/.github/workflows/validate-github-actions-workflows.yml new file mode 100644 index 000000000..bd0fc58f8 --- /dev/null +++ b/.github/workflows/validate-github-actions-workflows.yml @@ -0,0 +1,18 @@ +name: validate GitHub Actions workflows +on: + push: + paths: + - .github/workflows/* + + pull_request: + paths: + - .github/workflows/* + +jobs: + validate-github-actions-workflows: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: | + bash <(curl https://raw.githubusercontent.com/rhysd/actionlint/main/scripts/download-actionlint.bash) + ./actionlint diff --git a/Dashboard/.env.example b/Dashboard/.env.example new file mode 100644 index 000000000..64a1c017a --- /dev/null +++ b/Dashboard/.env.example @@ -0,0 +1,2 @@ +VITE_OBSOLETE_DATA_PATH=https://raw.githubusercontent.com/planetarium/lib9c/development/.github/exports/obsolete-actions.json +VITE_API_PATH=https://sample-api-server.test diff --git a/Dashboard/.eslintrc.cjs b/Dashboard/.eslintrc.cjs new file mode 100644 index 000000000..d6c953795 --- /dev/null +++ b/Dashboard/.eslintrc.cjs @@ -0,0 +1,18 @@ +module.exports = { + root: true, + env: { browser: true, es2020: true }, + extends: [ + 'eslint:recommended', + 'plugin:@typescript-eslint/recommended', + 'plugin:react-hooks/recommended', + ], + ignorePatterns: ['dist', '.eslintrc.cjs'], + parser: '@typescript-eslint/parser', + plugins: ['react-refresh'], + rules: { + 'react-refresh/only-export-components': [ + 'warn', + { allowConstantExport: true }, + ], + }, +} diff --git a/Dashboard/.gitignore b/Dashboard/.gitignore new file mode 100644 index 000000000..50c8dda2a --- /dev/null +++ b/Dashboard/.gitignore @@ -0,0 +1,26 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? + +.env diff --git a/Dashboard/.prettier.config.js b/Dashboard/.prettier.config.js new file mode 100644 index 000000000..7f32912d7 --- /dev/null +++ b/Dashboard/.prettier.config.js @@ -0,0 +1,3 @@ +module.exports = { + plugins: ['prettier-plugin-tailwindscss'], +}; diff --git a/Dashboard/README.md b/Dashboard/README.md new file mode 100644 index 000000000..e858cb393 --- /dev/null +++ b/Dashboard/README.md @@ -0,0 +1,13 @@ +# Lib9c Dashboard + +Lib9c Dashboard is web application provides Lib9c's various information (etc. Action Obsoletion, ...). + +## Quick Start + +1. Copy `.env.example` with name `.env` and fill with valid value. +2. Run `yarn install` +3. Run `yarn dev` + +## Build + +Just run `yarn build` then result of build will be created at `/dist` \ No newline at end of file diff --git a/Dashboard/index.html b/Dashboard/index.html new file mode 100644 index 000000000..1eec27cde --- /dev/null +++ b/Dashboard/index.html @@ -0,0 +1,13 @@ + + + + + + + Obsolete Dashboard + + +
+ + + diff --git a/Dashboard/package.json b/Dashboard/package.json new file mode 100644 index 000000000..c1e743568 --- /dev/null +++ b/Dashboard/package.json @@ -0,0 +1,39 @@ +{ + "name": "dashboard", + "private": true, + "version": "0.0.0", + "type": "module", + "homepage": "http://planetarium.github.io/lib9c/dashboard", + "scripts": { + "dev": "vite", + "predeploy": "yarn build", + "deploy": "gh-pages -d build", + "build": "tsc && vite build", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "preview": "vite preview" + }, + "dependencies": { + "@tanstack/react-query": "^4.32.0", + "axios": "^1.4.0", + "react": "^18.2.0", + "react-dom": "^18.2.0" + }, + "devDependencies": { + "@types/react": "^18.2.15", + "@types/react-dom": "^18.2.7", + "@typescript-eslint/eslint-plugin": "^6.0.0", + "@typescript-eslint/parser": "^6.0.0", + "@vitejs/plugin-react": "^4.0.3", + "autoprefixer": "^10.4.14", + "eslint": "^8.45.0", + "eslint-plugin-react-hooks": "^4.6.0", + "eslint-plugin-react-refresh": "^0.4.3", + "gh-pages": "^5.0.0", + "postcss": "^8.4.27", + "prettier": "^3.0.0", + "prettier-plugin-tailwindcss": "^0.4.1", + "tailwindcss": "^3.3.3", + "typescript": "^5.0.2", + "vite": "^4.4.5" + } +} diff --git a/Dashboard/postcss.config.js b/Dashboard/postcss.config.js new file mode 100644 index 000000000..2e7af2b7f --- /dev/null +++ b/Dashboard/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/Dashboard/src/App.tsx b/Dashboard/src/App.tsx new file mode 100644 index 000000000..1acd67c38 --- /dev/null +++ b/Dashboard/src/App.tsx @@ -0,0 +1,84 @@ +import { useQueries } from "@tanstack/react-query"; +import axios from "axios"; +import { useMemo } from "react"; + +interface Block { index: number } +interface Action { id: string, obsoleteAt: number } + +const fetchLatestBlock = async () => { + const response = await axios.get(`${import.meta.env.VITE_API_PATH}/api/blocks/latest`); + return response.data; +}; + +const fetchActions = async () => { + const response = await axios.get(import.meta.env.VITE_OBSOLETE_DATA_PATH); + return response.data; +} + +function App() { + const [latestBlockQuery, actionsQuery] = useQueries({ + queries: [ + { queryKey: ['latestBlock'], queryFn: fetchLatestBlock }, + { queryKey: ['actions'], queryFn: fetchActions }, + ], + }); + const isLoading = latestBlockQuery.isLoading || actionsQuery.isLoading; + const isError = latestBlockQuery.isError || actionsQuery.isError; + + const currentBlock = useMemo( + () => latestBlockQuery.data?.index ?? 0, + [latestBlockQuery.data], + ); + const actions = useMemo( + () => actionsQuery.data?.sort((a, b) => b.obsoleteAt - a.obsoleteAt) ?? [], + [actionsQuery.data], + ); + + if (isLoading) return <>; + if (isError) return <>; + + const isObsoleted = (data: Action) => currentBlock > data.obsoleteAt; + + return ( +
+
+

Dashboard

+

+ You can check NineChronicles actions that will be obsoleted soon here. +

+
+ +

+ The latest block is #{currentBlock} +

+ +
+ <> +

#Block Index

+

Action ID

+

Remain blocks

+ + + {actions.map((action) => ( + <> +

+ #{action.obsoleteAt} +

+

+ {action.id} +

+

+ {isObsoleted(action) + ? Obsoleted + : {action.obsoleteAt - currentBlock} blocks remain + } +

+ + )) + } +
+
+ ); +} + +export default App; diff --git a/Dashboard/src/index.css b/Dashboard/src/index.css new file mode 100644 index 000000000..cc9a3d53c --- /dev/null +++ b/Dashboard/src/index.css @@ -0,0 +1,61 @@ +@import url("https://cdn.jsdelivr.net/gh/orioncactus/pretendard@v1.3.8/dist/web/static/pretendard.css"); + +@tailwind base; +@tailwind components; +@tailwind utilities; + +:root { + font-family: Pretendard, Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; +} + +a { + font-weight: 500; + color: #646cff; + text-decoration: inherit; +} +a:hover { + color: #535bf2; +} + +body { + margin: 0; +} + +h1 { + font-size: 3.2em; + line-height: 1.1; +} + +button { + border-radius: 8px; + border: 1px solid transparent; + padding: 0.6em 1.2em; + font-size: 1em; + font-weight: 500; + font-family: inherit; + background-color: #1a1a1a; + cursor: pointer; + transition: border-color 0.25s; +} +button:hover { + border-color: #646cff; +} +button:focus, +button:focus-visible { + outline: 4px auto -webkit-focus-ring-color; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } + a:hover { + color: #747bff; + } + button { + background-color: #f9f9f9; + } +} diff --git a/Dashboard/src/main.tsx b/Dashboard/src/main.tsx new file mode 100644 index 000000000..e2722a476 --- /dev/null +++ b/Dashboard/src/main.tsx @@ -0,0 +1,15 @@ +import React from 'react' +import ReactDOM from 'react-dom/client' +import { QueryClient, QueryClientProvider } from '@tanstack/react-query' +import App from './App.tsx' +import './index.css' + +const queryClient = new QueryClient(); + +ReactDOM.createRoot(document.getElementById('root')!).render( + + + + + , +) diff --git a/Dashboard/src/vite-env.d.ts b/Dashboard/src/vite-env.d.ts new file mode 100644 index 000000000..3ef7304c4 --- /dev/null +++ b/Dashboard/src/vite-env.d.ts @@ -0,0 +1,6 @@ +/// + +interface ImportMetaEnv { + VITE_OBSOLETE_DATA_PATH: string, + VITE_API_PATH: string, +} diff --git a/Dashboard/tailwind.config.js b/Dashboard/tailwind.config.js new file mode 100644 index 000000000..d32049f50 --- /dev/null +++ b/Dashboard/tailwind.config.js @@ -0,0 +1,12 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + './index.html', + './src/**/*.{js,ts,jsx,tsx}', + ], + theme: { + extend: {}, + }, + plugins: [], +} + diff --git a/Dashboard/tsconfig.json b/Dashboard/tsconfig.json new file mode 100644 index 000000000..a7fc6fbf2 --- /dev/null +++ b/Dashboard/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/Dashboard/tsconfig.node.json b/Dashboard/tsconfig.node.json new file mode 100644 index 000000000..42872c59f --- /dev/null +++ b/Dashboard/tsconfig.node.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true + }, + "include": ["vite.config.ts"] +} diff --git a/Dashboard/vite.config.ts b/Dashboard/vite.config.ts new file mode 100644 index 000000000..0485b8b53 --- /dev/null +++ b/Dashboard/vite.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from 'vite' +import react from '@vitejs/plugin-react' + +// https://vitejs.dev/config/ +export default defineConfig({ + base: '/lib9c/dashboard', + plugins: [react()], +}) diff --git a/Dashboard/yarn.lock b/Dashboard/yarn.lock new file mode 100644 index 000000000..185faf196 --- /dev/null +++ b/Dashboard/yarn.lock @@ -0,0 +1,2107 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + +"@alloc/quick-lru@^5.2.0": + version "5.2.0" + resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" + integrity sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw== + +"@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@babel/code-frame@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.5.tgz#234d98e1551960604f1246e6475891a570ad5658" + integrity sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ== + dependencies: + "@babel/highlight" "^7.22.5" + +"@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== + +"@babel/core@^7.22.5": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.8" + "@babel/types" "^7.22.5" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.1" + +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== + dependencies: + "@babel/types" "^7.22.5" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + +"@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.5" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + +"@babel/helper-environment-visitor@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.5.tgz#f06dd41b7c1f44e1f8da6c4055b41ab3a09a7e98" + integrity sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q== + +"@babel/helper-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.22.5.tgz#ede300828905bb15e582c037162f99d5183af1be" + integrity sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ== + dependencies: + "@babel/template" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-imports@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.5.tgz#1a8f4c9f4027d23f520bd76b364d44434a72660c" + integrity sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.5" + +"@babel/helper-plugin-utils@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + +"@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + +"@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + +"@babel/helper-validator-identifier@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.5.tgz#9544ef6a33999343c8740fa51350f30eeaaaf193" + integrity sha512-aJXu+6lErq8ltp+JhkJUfk1MTGyuA4v7f3pA+BJ5HLfNC6nAQ0Cpi9uOquUj8Hehg0aUiHzWQbOVJGao6ztBAQ== + +"@babel/helper-validator-option@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" + integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== + +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== + dependencies: + "@babel/template" "^7.22.5" + "@babel/traverse" "^7.22.6" + "@babel/types" "^7.22.5" + +"@babel/highlight@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.5.tgz#aa6c05c5407a67ebce408162b7ede789b4d22031" + integrity sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw== + dependencies: + "@babel/helper-validator-identifier" "^7.22.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== + +"@babel/plugin-transform-react-jsx-self@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.22.5.tgz#ca2fdc11bc20d4d46de01137318b13d04e481d8e" + integrity sha512-nTh2ogNUtxbiSbxaT4Ds6aXnXEipHweN9YRgOX/oNXdf0cCrGn/+2LozFa3lnPV5D90MkjhgckCPBrsoSc1a7g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/plugin-transform-react-jsx-source@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.22.5.tgz#49af1615bfdf6ed9d3e9e43e425e0b2b65d15b6c" + integrity sha512-yIiRO6yobeEIaI0RTbIr8iAK9FcBHLtZq0S89ZPjDLQXBA4xvghaKqI0etp/tF3htTM0sazJKKLz9oEiGRtu7w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + +"@babel/template@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.5.tgz#0c8c4d944509875849bd0344ff0050756eefc6ec" + integrity sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/parser" "^7.22.5" + "@babel/types" "^7.22.5" + +"@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== + dependencies: + "@babel/code-frame" "^7.22.5" + "@babel/generator" "^7.22.7" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" + "@babel/types" "^7.22.5" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.22.5.tgz#cd93eeaab025880a3a47ec881f4b096a5b786fbe" + integrity sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.5" + to-fast-properties "^2.0.0" + +"@esbuild/android-arm64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.16.tgz#34f562abc0015933aabd41b3d50d8d3359e30155" + integrity sha512-wsCqSPqLz+6Ov+OM4EthU43DyYVVyfn15S4j1bJzylDpc1r1jZFFfJQNfDuT8SlgwuqpmpJXK4uPlHGw6ve7eA== + +"@esbuild/android-arm@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.16.tgz#ef6f9aa59a79a9b9330a2e73f7eb402c6630c267" + integrity sha512-gCHjjQmA8L0soklKbLKA6pgsLk1byULuHe94lkZDzcO3/Ta+bbeewJioEn1Fr7kgy9NWNFy/C+MrBwC6I/WCug== + +"@esbuild/android-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.16.tgz#ed7444cb17542932c67b15e20528686853239cfd" + integrity sha512-ldsTXolyA3eTQ1//4DS+E15xl0H/3DTRJaRL0/0PgkqDsI0fV/FlOtD+h0u/AUJr+eOTlZv4aC9gvfppo3C4sw== + +"@esbuild/darwin-arm64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.16.tgz#3c5a083e6e08a50f478fa243939989d86be1c6bf" + integrity sha512-aBxruWCII+OtluORR/KvisEw0ALuw/qDQWvkoosA+c/ngC/Kwk0lLaZ+B++LLS481/VdydB2u6tYpWxUfnLAIw== + +"@esbuild/darwin-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.16.tgz#a8f3b61bee2807131cbe28eb164ad2b0333b59f5" + integrity sha512-6w4Dbue280+rp3LnkgmriS1icOUZDyPuZo/9VsuMUTns7SYEiOaJ7Ca1cbhu9KVObAWfmdjUl4gwy9TIgiO5eA== + +"@esbuild/freebsd-arm64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.16.tgz#9bdbb3f0e5f0842b21c9b8602e70c106174ac24c" + integrity sha512-x35fCebhe9s979DGKbVAwXUOcTmCIE32AIqB9CB1GralMIvxdnMLAw5CnID17ipEw9/3MvDsusj/cspYt2ZLNQ== + +"@esbuild/freebsd-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.16.tgz#24f73956436495cc7a5a4bf06be6b661aea6a2c1" + integrity sha512-YM98f+PeNXF3GbxIJlUsj+McUWG1irguBHkszCIwfr3BXtXZsXo0vqybjUDFfu9a8Wr7uUD/YSmHib+EeGAFlg== + +"@esbuild/linux-arm64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.16.tgz#244569757f9cbd912f5a595a8ad8144f8c915f13" + integrity sha512-XIqhNUxJiuy+zsR77+H5Z2f7s4YRlriSJKtvx99nJuG5ATuJPjmZ9n0ANgnGlPCpXGSReFpgcJ7O3SMtzIFeiQ== + +"@esbuild/linux-arm@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.16.tgz#d63923c63af534032cc5ea0b2a0b3de10f8357f5" + integrity sha512-b5ABb+5Ha2C9JkeZXV+b+OruR1tJ33ePmv9ZwMeETSEKlmu/WJ45XTTG+l6a2KDsQtJJ66qo/hbSGBtk0XVLHw== + +"@esbuild/linux-ia32@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.16.tgz#a8825ccea6309f0bccfc5d87b43163ba804c2f20" + integrity sha512-no+pfEpwnRvIyH+txbBAWtjxPU9grslmTBfsmDndj7bnBmr55rOo/PfQmRfz7Qg9isswt1FP5hBbWb23fRWnow== + +"@esbuild/linux-loong64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.16.tgz#f530e820fc3c61cf2206155b994aeab53b6d25be" + integrity sha512-Zbnczs9ZXjmo0oZSS0zbNlJbcwKXa/fcNhYQjahDs4Xg18UumpXG/lwM2lcSvHS3mTrRyCYZvJbmzYc4laRI1g== + +"@esbuild/linux-mips64el@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.16.tgz#2d47ace539257896865d243641bd6716684a1e82" + integrity sha512-YMF7hih1HVR/hQVa/ot4UVffc5ZlrzEb3k2ip0nZr1w6fnYypll9td2qcoMLvd3o8j3y6EbJM3MyIcXIVzXvQQ== + +"@esbuild/linux-ppc64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.16.tgz#d6913e7e9be9e242a6a20402800141bdbe7009f7" + integrity sha512-Wkz++LZ29lDwUyTSEnzDaaP5OveOgTU69q9IyIw9WqLRxM4BjTBjz9un4G6TOvehWpf/J3gYVFN96TjGHrbcNQ== + +"@esbuild/linux-riscv64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.16.tgz#8f33b627389c8234fe61f4636c134f17fb1d9b09" + integrity sha512-LFMKZ30tk78/mUv1ygvIP+568bwf4oN6reG/uczXnz6SvFn4e2QUFpUpZY9iSJT6Qpgstrhef/nMykIXZtZWGQ== + +"@esbuild/linux-s390x@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.16.tgz#4d44c030f78962cf410f604f92fcc1505e4afdde" + integrity sha512-3ZC0BgyYHYKfZo3AV2/66TD/I9tlSBaW7eWTEIkrQQKfJIifKMMttXl9FrAg+UT0SGYsCRLI35Gwdmm96vlOjg== + +"@esbuild/linux-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.16.tgz#8846d00e16b1e93eb488c8b4dd51c946adfc236f" + integrity sha512-xu86B3647DihHJHv/wx3NCz2Dg1gjQ8bbf9cVYZzWKY+gsvxYmn/lnVlqDRazObc3UMwoHpUhNYaZset4X8IPA== + +"@esbuild/netbsd-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.16.tgz#6514a86bd07744f3100d2813ea2fb6520d53e72e" + integrity sha512-uVAgpimx9Ffw3xowtg/7qQPwHFx94yCje+DoBx+LNm2ePDpQXHrzE+Sb0Si2VBObYz+LcRps15cq+95YM7gkUw== + +"@esbuild/openbsd-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.16.tgz#ae67ce766d58aab6c0e6037f1a76f15df4a2a5fe" + integrity sha512-6OjCQM9wf7z8/MBi6BOWaTL2AS/SZudsZtBziXMtNI8r/U41AxS9x7jn0ATOwVy08OotwkPqGRMkpPR2wcTJXA== + +"@esbuild/sunos-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.16.tgz#998efe8a58374b7351ac710455051639a6ce6a05" + integrity sha512-ZoNkruFYJp9d1LbUYCh8awgQDvB9uOMZqlQ+gGEZR7v6C+N6u7vPr86c+Chih8niBR81Q/bHOSKGBK3brJyvkQ== + +"@esbuild/win32-arm64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.16.tgz#8de33682243508eef8d4de1816df2c05adad2b21" + integrity sha512-+j4anzQ9hrs+iqO+/wa8UE6TVkKua1pXUb0XWFOx0FiAj6R9INJ+WE//1/Xo6FG1vB5EpH3ko+XcgwiDXTxcdw== + +"@esbuild/win32-ia32@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.16.tgz#95c9f4274fb3ef9e449d464ffe3e3b7fa091503b" + integrity sha512-5PFPmq3sSKTp9cT9dzvI67WNfRZGvEVctcZa1KGjDDu4n3H8k59Inbk0du1fz0KrAbKKNpJbdFXQMDUz7BG4rQ== + +"@esbuild/win32-x64@0.18.16": + version "0.18.16" + resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.16.tgz#5be58d31d0120c68af8e38b702e6937ce764cd68" + integrity sha512-sCIVrrtcWN5Ua7jYXNG1xD199IalrbfV2+0k/2Zf2OyV2FtnQnMgdzgpRAbi4AWlKJj1jkX+M+fEGPQj6BQB4w== + +"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + +"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.5.1": + version "4.6.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.6.0.tgz#5b63f0df5528a44e28aa8578d393de908cc3d4d0" + integrity sha512-uiPeRISaglZnaZk8vwrjQZ1CxogZeY/4IYft6gBOTqu1WhVXWmCmZMWxUv2Q/pxSvPdp1JPaO62kLOcOkMqWrw== + +"@eslint/eslintrc@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" + integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + +"@eslint/js@8.44.0": + version "8.44.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" + integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== + +"@humanwhocodes/config-array@^0.11.10": + version "0.11.10" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" + integrity sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ== + dependencies: + "@humanwhocodes/object-schema" "^1.2.1" + debug "^4.1.1" + minimatch "^3.0.5" + +"@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + +"@humanwhocodes/object-schema@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + +"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" + integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/sourcemap-codec@1.4.14": + version "1.4.14" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" + integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + +"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.18" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz#25783b2086daf6ff1dcb53c9249ae480e4dd4cd6" + integrity sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA== + dependencies: + "@jridgewell/resolve-uri" "3.1.0" + "@jridgewell/sourcemap-codec" "1.4.14" + +"@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + +"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + +"@tanstack/query-core@4.32.0": + version "4.32.0" + resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-4.32.0.tgz#e0f4a830283612430450c13badd353766423f523" + integrity sha512-ei4IYwL2kmlKSlCw9WgvV7PpXi0MiswVwfQRxawhJA690zWO3dU49igaQ/UMTl+Jy9jj9dK5IKAYvbX7kUvviQ== + +"@tanstack/react-query@^4.32.0": + version "4.32.0" + resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-4.32.0.tgz#701b45b149cfd4b54a68705f9100973db3ba5d5d" + integrity sha512-B8WUMcByYAH9500ENejDCATOmEZhqjtS9wsfiQ3BNa+s+yAynY8SESI8WWHhSqUmjd0pmCSFRP6BOUGSda3QXA== + dependencies: + "@tanstack/query-core" "4.32.0" + use-sync-external-store "^1.2.0" + +"@types/json-schema@^7.0.12": + version "7.0.12" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.12.tgz#d70faba7039d5fca54c83c7dbab41051d2b6f6cb" + integrity sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA== + +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + +"@types/react-dom@^18.2.7": + version "18.2.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== + dependencies: + "@types/react" "*" + +"@types/react@*", "@types/react@^18.2.15": + version "18.2.15" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.15.tgz#14792b35df676c20ec3cf595b262f8c615a73066" + integrity sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/scheduler@*": + version "0.16.3" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.3.tgz#cef09e3ec9af1d63d2a6cc5b383a737e24e6dcf5" + integrity sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ== + +"@types/semver@^7.5.0": + version "7.5.0" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.0.tgz#591c1ce3a702c45ee15f47a42ade72c2fd78978a" + integrity sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw== + +"@typescript-eslint/eslint-plugin@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.1.0.tgz#96f3ca6615717659d06c9f7161a1d14ab0c49c66" + integrity sha512-qg7Bm5TyP/I7iilGyp6DRqqkt8na00lI6HbjWZObgk3FFSzH5ypRwAHXJhJkwiRtTcfn+xYQIMOR5kJgpo6upw== + dependencies: + "@eslint-community/regexpp" "^4.5.1" + "@typescript-eslint/scope-manager" "6.1.0" + "@typescript-eslint/type-utils" "6.1.0" + "@typescript-eslint/utils" "6.1.0" + "@typescript-eslint/visitor-keys" "6.1.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.4" + natural-compare "^1.4.0" + natural-compare-lite "^1.4.0" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/parser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.1.0.tgz#3135bf65dca5340d8650703eb8cb83113e156ee5" + integrity sha512-hIzCPvX4vDs4qL07SYzyomamcs2/tQYXg5DtdAfj35AyJ5PIUqhsLf4YrEIFzZcND7R2E8tpQIZKayxg8/6Wbw== + dependencies: + "@typescript-eslint/scope-manager" "6.1.0" + "@typescript-eslint/types" "6.1.0" + "@typescript-eslint/typescript-estree" "6.1.0" + "@typescript-eslint/visitor-keys" "6.1.0" + debug "^4.3.4" + +"@typescript-eslint/scope-manager@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.1.0.tgz#a6cdbe11630614f8c04867858a42dd56590796ed" + integrity sha512-AxjgxDn27hgPpe2rQe19k0tXw84YCOsjDJ2r61cIebq1t+AIxbgiXKvD4999Wk49GVaAcdJ/d49FYel+Pp3jjw== + dependencies: + "@typescript-eslint/types" "6.1.0" + "@typescript-eslint/visitor-keys" "6.1.0" + +"@typescript-eslint/type-utils@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.1.0.tgz#21cc6c3bc1980b03f9eb4e64580d0c5be6f08215" + integrity sha512-kFXBx6QWS1ZZ5Ni89TyT1X9Ag6RXVIVhqDs0vZE/jUeWlBv/ixq2diua6G7ece6+fXw3TvNRxP77/5mOMusx2w== + dependencies: + "@typescript-eslint/typescript-estree" "6.1.0" + "@typescript-eslint/utils" "6.1.0" + debug "^4.3.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/types@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.1.0.tgz#2d607c62827bb416ada5c96ebfa2ef84e45a8dfa" + integrity sha512-+Gfd5NHCpDoHDOaU/yIF3WWRI2PcBRKKpP91ZcVbL0t5tQpqYWBs3z/GGhvU+EV1D0262g9XCnyqQh19prU0JQ== + +"@typescript-eslint/typescript-estree@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.1.0.tgz#ea382f6482ba698d7e993a88ce5391ea7a66c33d" + integrity sha512-nUKAPWOaP/tQjU1IQw9sOPCDavs/iU5iYLiY/6u7gxS7oKQoi4aUxXS1nrrVGTyBBaGesjkcwwHkbkiD5eBvcg== + dependencies: + "@typescript-eslint/types" "6.1.0" + "@typescript-eslint/visitor-keys" "6.1.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.5.4" + ts-api-utils "^1.0.1" + +"@typescript-eslint/utils@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.1.0.tgz#1641843792b4e3451cc692e2c73055df8b26f453" + integrity sha512-wp652EogZlKmQoMS5hAvWqRKplXvkuOnNzZSE0PVvsKjpexd/XznRVHAtrfHFYmqaJz0DFkjlDsGYC9OXw+OhQ== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + "@types/json-schema" "^7.0.12" + "@types/semver" "^7.5.0" + "@typescript-eslint/scope-manager" "6.1.0" + "@typescript-eslint/types" "6.1.0" + "@typescript-eslint/typescript-estree" "6.1.0" + semver "^7.5.4" + +"@typescript-eslint/visitor-keys@6.1.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.1.0.tgz#d2b84dff6b58944d3257ea03687e269a788c73be" + integrity sha512-yQeh+EXhquh119Eis4k0kYhj9vmFzNpbhM3LftWQVwqVjipCkwHBQOZutcYW+JVkjtTG9k8nrZU1UoNedPDd1A== + dependencies: + "@typescript-eslint/types" "6.1.0" + eslint-visitor-keys "^3.4.1" + +"@vitejs/plugin-react@^4.0.3": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-4.0.3.tgz#007d27ad5ef1eac4bf8c29e168ba9be2203c371b" + integrity sha512-pwXDog5nwwvSIzwrvYYmA2Ljcd/ZNlcsSG2Q9CNDBwnsd55UGAyr2doXtB5j+2uymRCnCfExlznzzSFbBRcoCg== + dependencies: + "@babel/core" "^7.22.5" + "@babel/plugin-transform-react-jsx-self" "^7.22.5" + "@babel/plugin-transform-react-jsx-source" "^7.22.5" + react-refresh "^0.14.0" + +acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + +acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + +ajv@^6.10.0, ajv@^6.12.4: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + +ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A== + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +arg@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" + integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg== + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + +async@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" + integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + +autoprefixer@^10.4.14: + version "10.4.14" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.14.tgz#e28d49902f8e759dd25b153264e862df2705f79d" + integrity sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ== + dependencies: + browserslist "^4.21.5" + caniuse-lite "^1.0.30001464" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +axios@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f" + integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browserslist@^4.21.5, browserslist@^4.21.9: + version "4.21.9" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" + integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== + dependencies: + caniuse-lite "^1.0.30001503" + electron-to-chromium "^1.4.431" + node-releases "^2.0.12" + update-browserslist-db "^1.0.11" + +callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + +camelcase-css@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503: + version "1.0.30001517" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8" + integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA== + +chalk@^2.0.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + +commander@^2.18.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + +cross-spawn@^7.0.2: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + +cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + +csstype@^3.0.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + +didyoumean@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037" + integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw== + +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + +dlv@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dlv/-/dlv-1.1.3.tgz#5c198a8a11453596e751494d49874bc7732f2e79" + integrity sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA== + +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + +electron-to-chromium@^1.4.431: + version "1.4.468" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.468.tgz#3cbf64ad67d9f12bfe69fefe5eb1935ec4f6ab7a" + integrity sha512-6M1qyhaJOt7rQtNti1lBA0GwclPH+oKCmsra/hkcWs5INLxfXXD/dtdnaKUYQu/pjOBP/8Osoe4mAcNvvzoFag== + +email-addresses@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/email-addresses/-/email-addresses-5.0.0.tgz#7ae9e7f58eef7d5e3e2c2c2d3ea49b78dc854fa6" + integrity sha512-4OIPYlA6JXqtVn8zpHpGiI7vE6EQOAg16aGnDMIAlZVinnoZ8208tW1hAbjWydgN/4PLTT9q+O1K6AH/vALJGw== + +esbuild@^0.18.10: + version "0.18.16" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.16.tgz#bbeb058c556152bcbff4e8168e7c93020ccf09c3" + integrity sha512-1xLsOXrDqwdHxyXb/x/SOyg59jpf/SH7YMvU5RNSU7z3TInaASNJWNFJ6iRvLvLETZMasF3d1DdZLg7sgRimRQ== + optionalDependencies: + "@esbuild/android-arm" "0.18.16" + "@esbuild/android-arm64" "0.18.16" + "@esbuild/android-x64" "0.18.16" + "@esbuild/darwin-arm64" "0.18.16" + "@esbuild/darwin-x64" "0.18.16" + "@esbuild/freebsd-arm64" "0.18.16" + "@esbuild/freebsd-x64" "0.18.16" + "@esbuild/linux-arm" "0.18.16" + "@esbuild/linux-arm64" "0.18.16" + "@esbuild/linux-ia32" "0.18.16" + "@esbuild/linux-loong64" "0.18.16" + "@esbuild/linux-mips64el" "0.18.16" + "@esbuild/linux-ppc64" "0.18.16" + "@esbuild/linux-riscv64" "0.18.16" + "@esbuild/linux-s390x" "0.18.16" + "@esbuild/linux-x64" "0.18.16" + "@esbuild/netbsd-x64" "0.18.16" + "@esbuild/openbsd-x64" "0.18.16" + "@esbuild/sunos-x64" "0.18.16" + "@esbuild/win32-arm64" "0.18.16" + "@esbuild/win32-ia32" "0.18.16" + "@esbuild/win32-x64" "0.18.16" + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + +escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +eslint-plugin-react-hooks@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + +eslint-plugin-react-refresh@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-refresh/-/eslint-plugin-react-refresh-0.4.3.tgz#59dae8c00a119f06ea16b1d3e6891df3775947c7" + integrity sha512-Hh0wv8bUNY877+sI0BlCUlsS0TYYQqvzEwJsJJPM2WF4RnTStSnSR3zdJYa2nPOJgg3UghXi54lVyMSmpCalzA== + +eslint-scope@^7.2.0: + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.1.tgz#936821d3462675f25a18ac5fd88a67cc15b393bd" + integrity sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + +eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz#c22c48f48942d08ca824cc526211ae400478a994" + integrity sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA== + +eslint@^8.45.0: + version "8.45.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.45.0.tgz#bab660f90d18e1364352c0a6b7c6db8edb458b78" + integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.4.0" + "@eslint/eslintrc" "^2.1.0" + "@eslint/js" "8.44.0" + "@humanwhocodes/config-array" "^0.11.10" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.0" + eslint-visitor-keys "^3.4.1" + espree "^9.6.0" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + +espree@^9.6.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + +esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + +esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + +estraverse@^5.1.0, estraverse@^5.2.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + +esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + +fast-glob@^3.2.12, fast-glob@^3.2.9: + version "3.3.1" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" + integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + +fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + +fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + +fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + +file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha512-lc1bnsSr4L4Bdif8Xb/qrtokGbq5zlsms/CYH8PP+WtCkGNF65DPiQY8vG3SakEdRn8Dlnm+gW/qWKKjS5sZzQ== + +filenamify@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-4.3.0.tgz#62391cb58f02b09971c9d4f9d63b3cf9aba03106" + integrity sha512-hcFKyUG57yWGAzu1CMt/dPzYZuv+jAJUT85bL8mrXvNe6hWj6yEHEc4EdcgiA6Z3oi1/9wXJdZPXF2dZNgwgOg== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.1" + trim-repeated "^1.0.0" + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + +find-up@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat-cache@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.0.4.tgz#61b0338302b2fe9f957dcc32fc2a87f1c3048b11" + integrity sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg== + dependencies: + flatted "^3.1.0" + rimraf "^3.0.2" + +flatted@^3.1.0: + version "3.2.7" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" + integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== + +follow-redirects@^1.15.0: + version "1.15.2" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" + integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + +form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + +fs-extra@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" + integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== + +gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + +gh-pages@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/gh-pages/-/gh-pages-5.0.0.tgz#e0893272a0e33f0453e53a3c017c33b91ddd6394" + integrity sha512-Nqp1SjkPIB94Xw/3yYNTUL+G2dxlhjvv1zeN/4kMC1jfViTEqhtVz/Ba1zSXHuvXCN9ADNS1dN4r5/J/nZWEQQ== + dependencies: + async "^3.2.4" + commander "^2.18.0" + email-addresses "^5.0.0" + filenamify "^4.3.0" + find-cache-dir "^3.3.1" + fs-extra "^8.1.0" + globby "^6.1.0" + +glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + +glob@7.1.6: + version "7.1.6" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" + integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +glob@^7.0.3, glob@^7.1.3: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + +globals@^13.19.0: + version "13.20.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== + dependencies: + type-fest "^0.20.2" + +globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + +globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + +graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +has@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== + dependencies: + function-bind "^1.1.1" + +ignore@^5.2.0, ignore@^5.2.4: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + +import-fresh@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-core-module@^2.11.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.12.1.tgz#0c0b6885b6f80011c71541ce15c8d66cf5a4f9fd" + integrity sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg== + dependencies: + has "^1.0.3" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + +jiti@^1.18.2: + version "1.19.1" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.1.tgz#fa99e4b76a23053e0e7cde098efe1704a14c16f1" + integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + +js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + +json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + +json5@^2.2.2: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + integrity sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg== + optionalDependencies: + graceful-fs "^4.1.6" + +levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + +lilconfig@^2.0.5, lilconfig@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + +lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + +locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +loose-envify@^1.1.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + +lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + +make-dir@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + +merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + +micromatch@^4.0.4, micromatch@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + +mime-types@^2.1.12: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + +minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + +nanoid@^3.3.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" + integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + +natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + +node-releases@^2.0.12: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + +object-hash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/object-hash/-/object-hash-3.0.0.tgz#73f97f753e7baffc0e2cc9d6e079079744ac82e9" + integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + +p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + +parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + +picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + +pirates@^4.0.1: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + +pkg-dir@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + +postcss-import@^15.1.0: + version "15.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.1.0.tgz#41c64ed8cc0e23735a9698b3249ffdbf704adc70" + integrity sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + +postcss-js@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== + dependencies: + camelcase-css "^2.0.1" + +postcss-load-config@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-4.0.1.tgz#152383f481c2758274404e4962743191d73875bd" + integrity sha512-vEJIc8RdiBRu3oRAI0ymerOn+7rPuMvRXslTvZUKZonDHFIczxztIyJ1urxM1x9JXEikvpWWTUUqal5j/8QgvA== + dependencies: + lilconfig "^2.0.5" + yaml "^2.1.1" + +postcss-nested@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/postcss-nested/-/postcss-nested-6.0.1.tgz#f83dc9846ca16d2f4fa864f16e9d9f7d0961662c" + integrity sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ== + dependencies: + postcss-selector-parser "^6.0.11" + +postcss-selector-parser@^6.0.11: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-value-parser@^4.0.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + +postcss@^8.4.23, postcss@^8.4.26, postcss@^8.4.27: + version "8.4.27" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.27.tgz#234d7e4b72e34ba5a92c29636734349e0d9c3057" + integrity sha512-gY/ACJtJPSmUFPDCHtX78+01fHa64FaU4zaaWfuh1MhGJISufJAH4cun6k/8fwsHYeK4UQmENQK+tRLCFJE8JQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + +prettier-plugin-tailwindcss@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/prettier-plugin-tailwindcss/-/prettier-plugin-tailwindcss-0.4.1.tgz#f7ed664199540978b2cbd037bac3a337d6689e86" + integrity sha512-hwn2EiJmv8M+AW4YDkbjJ6HlZCTzLyz1QlySn9sMuKV/Px0fjwldlB7tol8GzdgqtkdPtzT3iJ4UzdnYXP25Ag== + +prettier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" + integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== + +proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + +punycode@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + +queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + +react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + +react-refresh@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e" + integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== + +react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + +read-cache@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" + integrity sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA== + dependencies: + pify "^2.3.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + +resolve@^1.1.7, resolve@^1.22.2: + version "1.22.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.2.tgz#0ed0943d4e301867955766c9f3e1ae6d01c6845f" + integrity sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g== + dependencies: + is-core-module "^2.11.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + +rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + +rollup@^3.25.2: + version "3.26.3" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.26.3.tgz#bbc8818cadd0aebca348dbb3d68d296d220967b8" + integrity sha512-7Tin0C8l86TkpcMtXvQu6saWH93nhG3dGQ1/+l5V2TDMceTxO7kDiK6GzbfLWNNxqJXm591PcEZUozZm51ogwQ== + optionalDependencies: + fsevents "~2.3.2" + +run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + +scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + +semver@^6.0.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + +semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + +slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + +source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + +strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +strip-outer@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.1.tgz#b2fd2abf6604b9d1e6013057195df836b8a9d631" + integrity sha512-k55yxKHwaXnpYGsOzg4Vl8+tDrWylxDEpknGjhTiZB8dFRU5rTo9CAzeycivxV3s+zlTKwrs6WxMxR95n26kwg== + dependencies: + escape-string-regexp "^1.0.2" + +sucrase@^3.32.0: + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== + dependencies: + "@jridgewell/gen-mapping" "^0.3.2" + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + +supports-color@^5.3.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +tailwindcss@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf" + integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== + dependencies: + "@alloc/quick-lru" "^5.2.0" + arg "^5.0.2" + chokidar "^3.5.3" + didyoumean "^1.2.2" + dlv "^1.1.3" + fast-glob "^3.2.12" + glob-parent "^6.0.2" + is-glob "^4.0.3" + jiti "^1.18.2" + lilconfig "^2.1.0" + micromatch "^4.0.5" + normalize-path "^3.0.0" + object-hash "^3.0.0" + picocolors "^1.0.0" + postcss "^8.4.23" + postcss-import "^15.1.0" + postcss-js "^4.0.1" + postcss-load-config "^4.0.1" + postcss-nested "^6.0.1" + postcss-selector-parser "^6.0.11" + resolve "^1.22.2" + sucrase "^3.32.0" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA== + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + +to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha512-pkonvlKk8/ZuR0D5tLW8ljt5I8kmxp2XKymhepUeOdCEfKpZaktSArkLHZt76OB1ZvO9bssUsDty4SWhLvZpLg== + dependencies: + escape-string-regexp "^1.0.2" + +ts-api-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.0.1.tgz#8144e811d44c749cd65b2da305a032510774452d" + integrity sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A== + +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.yarnpkg.com/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + +type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + +typescript@^5.0.2: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +update-browserslist-db@^1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.11.tgz#9a2a641ad2907ae7b3616506f4b977851db5b940" + integrity sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + +uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + +use-sync-external-store@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + +util-deprecate@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +vite@^4.4.5: + version "4.4.6" + resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.6.tgz#97a0a43868ec773fd88980d7c323c80233521cf1" + integrity sha512-EY6Mm8vJ++S3D4tNAckaZfw3JwG3wa794Vt70M6cNJ6NxT87yhq7EC8Rcap3ahyHdo8AhCmV9PTk+vG1HiYn1A== + dependencies: + esbuild "^0.18.10" + postcss "^8.4.26" + rollup "^3.25.2" + optionalDependencies: + fsevents "~2.3.2" + +which@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + +yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + +yaml@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.1.tgz#02fe0975d23cd441242aa7204e09fc28ac2ac33b" + integrity sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ== + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/Lib9c/Action/ClaimStakeReward.cs b/Lib9c/Action/ClaimStakeReward.cs index a3e191359..cd642cc57 100644 --- a/Lib9c/Action/ClaimStakeReward.cs +++ b/Lib9c/Action/ClaimStakeReward.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; +using System.Globalization; using Bencodex.Types; using Lib9c; using Lib9c.Abstractions; @@ -18,12 +19,12 @@ namespace Nekoyume.Action { /// - /// Hard forked at https://github.com/planetarium/lib9c/pull/1458 + /// Hard forked at https://github.com/planetarium/lib9c/pull/2071 /// [ActionType(ActionTypeText)] public class ClaimStakeReward : GameAction, IClaimStakeReward, IClaimStakeRewardV1 { - private const string ActionTypeText = "claim_stake_reward5"; + private const string ActionTypeText = "claim_stake_reward6"; /// /// This is the version 1 of the stake reward sheet. @@ -35,22 +36,22 @@ public static class V1 public const int MaxLevel = 5; public const string StakeRegularRewardSheetCsv = - @"level,required_gold,item_id,rate,type -1,50,400000,10,Item -1,50,500000,800,Item -1,50,20001,6000,Rune -2,500,400000,8,Item -2,500,500000,800,Item -2,500,20001,6000,Rune -3,5000,400000,5,Item -3,5000,500000,800,Item -3,5000,20001,6000,Rune -4,50000,400000,5,Item -4,50000,500000,800,Item -4,50000,20001,6000,Rune -5,500000,400000,5,Item -5,500000,500000,800,Item -5,500000,20001,6000,Rune"; + @"level,required_gold,item_id,rate,type,currency_ticker,currency_decimal_places,decimal_rate +1,50,400000,,Item,,,10 +1,50,500000,,Item,,,800 +1,50,20001,,Rune,,,6000 +2,500,400000,,Item,,,8 +2,500,500000,,Item,,,800 +2,500,20001,,Rune,,,6000 +3,5000,400000,,Item,,,5 +3,5000,500000,,Item,,,800 +3,5000,20001,,Rune,,,6000 +4,50000,400000,,Item,,,5 +4,50000,500000,,Item,,,800 +4,50000,20001,,Rune,,,6000 +5,500000,400000,,Item,,,5 +5,500000,500000,,Item,,,800 +5,500000,20001,,Rune,,,6000"; public const string StakeRegularFixedRewardSheetCsv = @"level,required_gold,item_id,count @@ -92,11 +93,86 @@ public static StakeRegularFixedRewardSheet StakeRegularFixedRewardSheet } } - // NOTE: Use this when the or - // is patched. - // public static class V2 - // { - // } + /// + /// This is the version 2 of the stake reward sheet. + /// The version 2 is used for calculating the reward for the stake + /// that is accumulated before the table patch. + /// + public static class V2 + { + public const int MaxLevel = 7; + + public const string StakeRegularRewardSheetCsv = + @"level,required_gold,item_id,rate,type,currency_ticker +1,50,400000,10,Item, +1,50,500000,800,Item, +1,50,20001,6000,Rune, +2,500,400000,8,Item, +2,500,500000,800,Item, +2,500,20001,6000,Rune, +3,5000,400000,5,Item, +3,5000,500000,800,Item, +3,5000,20001,6000,Rune, +4,50000,400000,5,Item, +4,50000,500000,800,Item, +4,50000,20001,6000,Rune, +5,500000,400000,5,Item, +5,500000,500000,800,Item, +5,500000,20001,6000,Rune, +6,5000000,400000,10,Item, +6,5000000,500000,800,Item, +6,5000000,20001,6000,Rune, +6,5000000,800201,100,Item, +7,10000000,400000,10,Item, +7,10000000,500000,800,Item, +7,10000000,20001,6000,Rune, +7,10000000,600201,50,Item, +7,10000000,800201,50,Item, +7,10000000,,100,Currency,GARAGE +"; + + public const string StakeRegularFixedRewardSheetCsv = + @"level,required_gold,item_id,count +1,50,500000,1 +2,500,500000,2 +3,5000,500000,2 +4,50000,500000,2 +5,500000,500000,2 +6,5000000,500000,2 +7,10000000,500000,2 +"; + + private static StakeRegularRewardSheet _stakeRegularRewardSheet; + private static StakeRegularFixedRewardSheet _stakeRegularFixedRewardSheet; + + public static StakeRegularRewardSheet StakeRegularRewardSheet + { + get + { + if (_stakeRegularRewardSheet is null) + { + _stakeRegularRewardSheet = new StakeRegularRewardSheet(); + _stakeRegularRewardSheet.Set(StakeRegularRewardSheetCsv); + } + + return _stakeRegularRewardSheet; + } + } + + public static StakeRegularFixedRewardSheet StakeRegularFixedRewardSheet + { + get + { + if (_stakeRegularFixedRewardSheet is null) + { + _stakeRegularFixedRewardSheet = new StakeRegularFixedRewardSheet(); + _stakeRegularFixedRewardSheet.Set(StakeRegularFixedRewardSheetCsv); + } + + return _stakeRegularFixedRewardSheet; + } + } + } internal Address AvatarAddress { get; private set; } @@ -179,15 +255,23 @@ public override IAccountStateDelta Execute(IActionContext context) stakeState.CalculateAccumulatedItemRewards( context.BlockIndex, out var itemV1Step, - out var itemV2Step); + out var itemV2Step, + out var itemV3Step); stakeState.CalculateAccumulatedRuneRewards( context.BlockIndex, out var runeV1Step, - out var runeV2Step); + out var runeV2Step, + out var runeV3Step); stakeState.CalculateAccumulatedCurrencyRewards( context.BlockIndex, out var currencyV1Step, - out var currencyV2Step); + out var currencyV2Step, + out var currencyV3Step); + stakeState.CalculateAccumulatedCurrencyCrystalRewards( + context.BlockIndex, + out var currencyCrystalV1Step, + out var currencyCrystalV2Step, + out var currencyCrystalV3Step); if (itemV1Step > 0) { var v1Level = Math.Min(level, V1.MaxLevel); @@ -202,17 +286,16 @@ public override IAccountStateDelta Execute(IActionContext context) itemV1Step, runeV1Step, currencyV1Step, + currencyCrystalV1Step, fixedRewardV1, regularRewardV1); } if (itemV2Step > 0) { - var regularFixedReward = - states.TryGetSheet(out var fixedRewardSheet) - ? fixedRewardSheet[level].Rewards - : new List(); - var regularReward = sheets.GetSheet()[level].Rewards; + var v2Level = Math.Min(level, V2.MaxLevel); + var fixedRewardV2 = V2.StakeRegularFixedRewardSheet[v2Level].Rewards; + var regularRewardV2 = V2.StakeRegularRewardSheet[v2Level].Rewards; states = ProcessReward( context, states, @@ -222,6 +305,25 @@ public override IAccountStateDelta Execute(IActionContext context) itemV2Step, runeV2Step, currencyV2Step, + currencyCrystalV2Step, + fixedRewardV2, + regularRewardV2); + } + + if (itemV3Step > 0) + { + var regularFixedReward = GetRegularFixedRewardInfos(states, level); + var regularReward = sheets.GetSheet()[level].Rewards; + states = ProcessReward( + context, + states, + ref avatarState, + itemSheet, + stakedAmount, + itemV3Step, + runeV3Step, + currencyV3Step, + currencyCrystalV3Step, regularFixedReward, regularReward); } @@ -247,81 +349,124 @@ public override IAccountStateDelta Execute(IActionContext context) avatarState.inventory.Serialize()); } + private static List GetRegularFixedRewardInfos( + IAccountState states, + int level) + { + return states.TryGetSheet(out var fixedRewardSheet) + ? fixedRewardSheet[level].Rewards + : new List(); + } + private IAccountStateDelta ProcessReward( IActionContext context, IAccountStateDelta states, ref AvatarState avatarState, ItemSheet itemSheet, - FungibleAssetValue stakedAmount, + FungibleAssetValue stakedFav, int itemRewardStep, int runeRewardStep, int currencyRewardStep, + int currencyCrystalRewardStep, List fixedReward, List regularReward) { - var stakedCurrency = stakedAmount.Currency; - // Regular Reward foreach (var reward in regularReward) { + var rateFav = FungibleAssetValue.Parse( + stakedFav.Currency, + reward.DecimalRate.ToString(CultureInfo.InvariantCulture)); + var rewardQuantityForSingleStep = stakedFav.DivRem(rateFav, out _); + if (rewardQuantityForSingleStep <= 0) + { + continue; + } + switch (reward.Type) { case StakeRegularRewardSheet.StakeRewardType.Item: - var (quantity, _) = stakedAmount.DivRem(stakedCurrency * reward.Rate); - if (quantity < 1) + { + if (itemRewardStep == 0) { - // If the quantity is zero, it doesn't add the item into inventory. continue; } - ItemSheet.Row row = itemSheet[reward.ItemId]; - ItemBase item = row is MaterialItemSheet.Row materialRow + var itemRow = itemSheet[reward.ItemId]; + var item = itemRow is MaterialItemSheet.Row materialRow ? ItemFactory.CreateTradableMaterial(materialRow) - : ItemFactory.CreateItem(row, context.Random); - avatarState.inventory.AddItem(item, (int)quantity * itemRewardStep); + : ItemFactory.CreateItem(itemRow, context.Random); + var majorUnit = (int)rewardQuantityForSingleStep * itemRewardStep; + if (majorUnit < 1) + { + continue; + } + + avatarState.inventory.AddItem(item, majorUnit); break; + } case StakeRegularRewardSheet.StakeRewardType.Rune: - var runeReward = runeRewardStep * - RuneHelper.CalculateStakeReward(stakedAmount, reward.Rate); - if (runeReward < 1 * RuneHelper.StakeRune) + { + if (runeRewardStep == 0) + { + continue; + } + + var majorUnit = rewardQuantityForSingleStep * runeRewardStep; + if (majorUnit < 1) { continue; } + var runeReward = RuneHelper.StakeRune * majorUnit; states = states.MintAsset(context, AvatarAddress, runeReward); break; + } case StakeRegularRewardSheet.StakeRewardType.Currency: + { if (string.IsNullOrEmpty(reward.CurrencyTicker)) { throw new NullReferenceException("currency ticker is null or empty"); } - var rewardCurrency = - Currencies.GetMinterlessCurrency(reward.CurrencyTicker); - var rewardCurrencyQuantity = - stakedAmount.DivRem(reward.Rate * stakedAmount.Currency).Quotient; - if (rewardCurrencyQuantity <= 0) + var isCrystal = reward.CurrencyTicker == Currencies.Crystal.Ticker; + if (isCrystal + ? currencyCrystalRewardStep == 0 + : currencyRewardStep == 0) { continue; } + var rewardCurrency = reward.CurrencyDecimalPlaces == null + ? Currencies.GetMinterlessCurrency(reward.CurrencyTicker) + : Currency.Uncapped( + reward.CurrencyTicker, + Convert.ToByte(reward.CurrencyDecimalPlaces.Value), + minters: null); + var majorUnit = isCrystal + ? rewardQuantityForSingleStep * currencyCrystalRewardStep + : rewardQuantityForSingleStep * currencyRewardStep; + var rewardFav = rewardCurrency * majorUnit; states = states.MintAsset( context, context.Signer, - rewardCurrencyQuantity * currencyRewardStep * rewardCurrency); + rewardFav); break; + } default: - break; + throw new ArgumentException( + $"Can't handle reward type: {reward.Type}", + nameof(regularReward)); } } // Fixed Reward foreach (var reward in fixedReward) { - ItemSheet.Row row = itemSheet[reward.ItemId]; - ItemBase item = row is MaterialItemSheet.Row materialRow + var itemRow = itemSheet[reward.ItemId]; + var item = itemRow is MaterialItemSheet.Row materialRow ? ItemFactory.CreateTradableMaterial(materialRow) - : ItemFactory.CreateItem(row, context.Random); + : ItemFactory.CreateItem(itemRow, context.Random); avatarState.inventory.AddItem(item, reward.Count * itemRewardStep); } diff --git a/Lib9c/Action/ClaimStakeReward5.cs b/Lib9c/Action/ClaimStakeReward5.cs new file mode 100644 index 000000000..4c02fb458 --- /dev/null +++ b/Lib9c/Action/ClaimStakeReward5.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using Bencodex.Types; +using Lib9c; +using Lib9c.Abstractions; +using Libplanet.Action; +using Libplanet.Action.State; +using Libplanet.Crypto; +using Libplanet.Types.Assets; +using Nekoyume.Extensions; +using Nekoyume.Helper; +using Nekoyume.Model.Item; +using Nekoyume.Model.State; +using Nekoyume.TableData; +using static Lib9c.SerializeKeys; + +namespace Nekoyume.Action +{ + /// + /// Hard forked at https://github.com/planetarium/lib9c/pull/1458 + /// + [ActionType(ActionTypeText)] + [ActionObsolete(ObsoleteBlockIndex)] + public class ClaimStakeReward5 : GameAction, IClaimStakeReward, IClaimStakeRewardV1 + { + private const string ActionTypeText = "claim_stake_reward5"; + public const long ObsoleteBlockIndex = ActionObsoleteConfig.V200060ObsoleteIndex; + + /// + /// This is the version 1 of the stake reward sheet. + /// The version 1 is used for calculating the reward for the stake + /// that is accumulated before the table patch. + /// + public static class V1 + { + public const int MaxLevel = 5; + + public const string StakeRegularRewardSheetCsv = + @"level,required_gold,item_id,rate,type +1,50,400000,10,Item +1,50,500000,800,Item +1,50,20001,6000,Rune +2,500,400000,8,Item +2,500,500000,800,Item +2,500,20001,6000,Rune +3,5000,400000,5,Item +3,5000,500000,800,Item +3,5000,20001,6000,Rune +4,50000,400000,5,Item +4,50000,500000,800,Item +4,50000,20001,6000,Rune +5,500000,400000,5,Item +5,500000,500000,800,Item +5,500000,20001,6000,Rune"; + + public const string StakeRegularFixedRewardSheetCsv = + @"level,required_gold,item_id,count +1,50,500000,1 +2,500,500000,2 +3,5000,500000,2 +4,50000,500000,2 +5,500000,500000,2"; + + private static StakeRegularRewardSheet _stakeRegularRewardSheet; + private static StakeRegularFixedRewardSheet _stakeRegularFixedRewardSheet; + + public static StakeRegularRewardSheet StakeRegularRewardSheet + { + get + { + if (_stakeRegularRewardSheet is null) + { + _stakeRegularRewardSheet = new StakeRegularRewardSheet(); + _stakeRegularRewardSheet.Set(StakeRegularRewardSheetCsv); + } + + return _stakeRegularRewardSheet; + } + } + + public static StakeRegularFixedRewardSheet StakeRegularFixedRewardSheet + { + get + { + if (_stakeRegularFixedRewardSheet is null) + { + _stakeRegularFixedRewardSheet = new StakeRegularFixedRewardSheet(); + _stakeRegularFixedRewardSheet.Set(StakeRegularFixedRewardSheetCsv); + } + + return _stakeRegularFixedRewardSheet; + } + } + } + + // NOTE: Use this when the or + // is patched. + // public static class V2 + // { + // } + + internal Address AvatarAddress { get; private set; } + + Address IClaimStakeRewardV1.AvatarAddress => AvatarAddress; + + public ClaimStakeReward5(Address avatarAddress) : this() + { + AvatarAddress = avatarAddress; + } + + public ClaimStakeReward5() + { + } + + protected override IImmutableDictionary PlainValueInternal => + ImmutableDictionary.Empty + .Add(AvatarAddressKey, AvatarAddress.Serialize()); + + protected override void LoadPlainValueInternal( + IImmutableDictionary plainValue) + { + AvatarAddress = plainValue[AvatarAddressKey].ToAddress(); + } + + public override IAccountStateDelta Execute(IActionContext context) + { + CheckObsolete(ObsoleteBlockIndex, context); + context.UseGas(1); + if (context.Rehearsal) + { + return context.PreviousState; + } + + var states = context.PreviousState; + var addressesHex = GetSignerAndOtherAddressesHex(context, AvatarAddress); + if (!states.TryGetStakeState(context.Signer, out var stakeState)) + { + throw new FailedLoadStateException( + ActionTypeText, + addressesHex, + typeof(StakeState), + StakeState.DeriveAddress(context.Signer)); + } + + if (!stakeState.IsClaimable(context.BlockIndex, out _, out _)) + { + throw new RequiredBlockIndexException( + ActionTypeText, + addressesHex, + context.BlockIndex); + } + + if (!states.TryGetAvatarStateV2( + context.Signer, + AvatarAddress, + out var avatarState, + out var migrationRequired)) + { + throw new FailedLoadStateException( + ActionTypeText, + addressesHex, + typeof(AvatarState), + AvatarAddress); + } + + var sheets = states.GetSheets(sheetTypes: new[] + { + typeof(StakeRegularRewardSheet), + typeof(ConsumableItemSheet), + typeof(CostumeItemSheet), + typeof(EquipmentItemSheet), + typeof(MaterialItemSheet), + }); + + var currency = states.GetGoldCurrency(); + var stakedAmount = states.GetBalance(stakeState.address, currency); + var stakeRegularRewardSheet = sheets.GetSheet(); + var level = + stakeRegularRewardSheet.FindLevelByStakedAmount(context.Signer, stakedAmount); + var itemSheet = sheets.GetItemSheet(); + stakeState.CalculateAccumulatedItemRewardsV3( + context.BlockIndex, + out var itemV1Step, + out var itemV2Step); + stakeState.CalculateAccumulatedRuneRewardsV3( + context.BlockIndex, + out var runeV1Step, + out var runeV2Step); + stakeState.CalculateAccumulatedCurrencyRewardsV2( + context.BlockIndex, + out var currencyV1Step, + out var currencyV2Step); + if (itemV1Step > 0) + { + var v1Level = Math.Min(level, V1.MaxLevel); + var fixedRewardV1 = V1.StakeRegularFixedRewardSheet[v1Level].Rewards; + var regularRewardV1 = V1.StakeRegularRewardSheet[v1Level].Rewards; + states = ProcessReward( + context, + states, + ref avatarState, + itemSheet, + stakedAmount, + itemV1Step, + runeV1Step, + currencyV1Step, + fixedRewardV1, + regularRewardV1); + } + + if (itemV2Step > 0) + { + var regularFixedReward = + states.TryGetSheet(out var fixedRewardSheet) + ? fixedRewardSheet[level].Rewards + : new List(); + var regularReward = sheets.GetSheet()[level].Rewards; + states = ProcessReward( + context, + states, + ref avatarState, + itemSheet, + stakedAmount, + itemV2Step, + runeV2Step, + currencyV2Step, + regularFixedReward, + regularReward); + } + + stakeState.Claim(context.BlockIndex); + + if (migrationRequired) + { + states = states + .SetState(avatarState.address, avatarState.SerializeV2()) + .SetState( + avatarState.address.Derive(LegacyWorldInformationKey), + avatarState.worldInformation.Serialize()) + .SetState( + avatarState.address.Derive(LegacyQuestListKey), + avatarState.questList.Serialize()); + } + + return states + .SetState(stakeState.address, stakeState.Serialize()) + .SetState( + avatarState.address.Derive(LegacyInventoryKey), + avatarState.inventory.Serialize()); + } + + private IAccountStateDelta ProcessReward( + IActionContext context, + IAccountStateDelta states, + ref AvatarState avatarState, + ItemSheet itemSheet, + FungibleAssetValue stakedAmount, + int itemRewardStep, + int runeRewardStep, + int currencyRewardStep, + List fixedReward, + List regularReward) + { + var stakedCurrency = stakedAmount.Currency; + + // Regular Reward + foreach (var reward in regularReward) + { + switch (reward.Type) + { + case StakeRegularRewardSheet.StakeRewardType.Item: + var (quantity, _) = stakedAmount.DivRem(stakedCurrency * reward.Rate); + if (quantity < 1) + { + // If the quantity is zero, it doesn't add the item into inventory. + continue; + } + + ItemSheet.Row row = itemSheet[reward.ItemId]; + ItemBase item = row is MaterialItemSheet.Row materialRow + ? ItemFactory.CreateTradableMaterial(materialRow) + : ItemFactory.CreateItem(row, context.Random); + avatarState.inventory.AddItem(item, (int)quantity * itemRewardStep); + break; + case StakeRegularRewardSheet.StakeRewardType.Rune: + var runeReward = runeRewardStep * + RuneHelper.CalculateStakeReward(stakedAmount, reward.Rate); + if (runeReward < 1 * RuneHelper.StakeRune) + { + continue; + } + + states = states.MintAsset(context, AvatarAddress, runeReward); + break; + case StakeRegularRewardSheet.StakeRewardType.Currency: + if (string.IsNullOrEmpty(reward.CurrencyTicker)) + { + throw new NullReferenceException("currency ticker is null or empty"); + } + + var rewardCurrency = + Currencies.GetMinterlessCurrency(reward.CurrencyTicker); + var rewardCurrencyQuantity = + stakedAmount.DivRem(reward.Rate * stakedAmount.Currency).Quotient; + if (rewardCurrencyQuantity <= 0) + { + continue; + } + + states = states.MintAsset( + context, + context.Signer, + rewardCurrencyQuantity * currencyRewardStep * rewardCurrency); + break; + default: + break; + } + } + + // Fixed Reward + foreach (var reward in fixedReward) + { + ItemSheet.Row row = itemSheet[reward.ItemId]; + ItemBase item = row is MaterialItemSheet.Row materialRow + ? ItemFactory.CreateTradableMaterial(materialRow) + : ItemFactory.CreateItem(row, context.Random); + avatarState.inventory.AddItem(item, reward.Count * itemRewardStep); + } + + return states; + } + } +} diff --git a/Lib9c/Action/Factory/ClaimStakeRewardFactory.cs b/Lib9c/Action/Factory/ClaimStakeRewardFactory.cs index ad15a4ed5..ccd06aaff 100644 --- a/Lib9c/Action/Factory/ClaimStakeRewardFactory.cs +++ b/Lib9c/Action/Factory/ClaimStakeRewardFactory.cs @@ -11,11 +11,16 @@ public static IClaimStakeReward CreateByBlockIndex( long blockIndex, Address avatarAddress) { - if (blockIndex > ClaimStakeReward4.ObsoleteBlockIndex) + if (blockIndex > ClaimStakeReward5.ObsoleteBlockIndex) { return new ClaimStakeReward(avatarAddress); } + if (blockIndex > ClaimStakeReward4.ObsoleteBlockIndex) + { + return new ClaimStakeReward5(avatarAddress); + } + if (blockIndex > ClaimStakeReward3.ObsoleteBlockIndex) { return new ClaimStakeReward4(avatarAddress); @@ -41,7 +46,8 @@ public static IClaimStakeReward CreateByVersion( 2 => new ClaimStakeReward2(avatarAddress), 3 => new ClaimStakeReward3(avatarAddress), 4 => new ClaimStakeReward4(avatarAddress), - 5 => new ClaimStakeReward(avatarAddress), + 5 => new ClaimStakeReward5(avatarAddress), + 6 => new ClaimStakeReward(avatarAddress), _ => throw new ArgumentOutOfRangeException( $"Invalid version: {version}"), }; diff --git a/Lib9c/ActionObsoleteConfig.cs b/Lib9c/ActionObsoleteConfig.cs index 3d0aa1e19..12636e4fc 100644 --- a/Lib9c/ActionObsoleteConfig.cs +++ b/Lib9c/ActionObsoleteConfig.cs @@ -70,6 +70,14 @@ public static class ActionObsoleteConfig public const long V200040ObsoleteIndex = 7_330_000L; + // NOTE: + // Target Release Date: 2023-08-17T12:00:00 + // Current Datetime(Block Index): 2023-08-09T20:30:00(7,521,470) + // Seconds Per Block: 9.5 + // Estimated Release Block Index: 7,591,385 + // 7,521,470 + (8 * 24 - 7.5) * 60 * 60 / 9.5 = 7,521,470 + 69,915 = 7,591,385 + public const long V200060ObsoleteIndex = 7_649_999L; + // While v200020, the action obsolete wasn't work well. // So other previous `V*ObsoletedIndex`s lost its meaning and // this block index will replace them. diff --git a/Lib9c/Battle/CPHelper.cs b/Lib9c/Battle/CPHelper.cs index 90a78356c..4aede072d 100644 --- a/Lib9c/Battle/CPHelper.cs +++ b/Lib9c/Battle/CPHelper.cs @@ -20,9 +20,22 @@ public static int TotalCP( CostumeStatSheet costumeStatSheet) { var levelStatsCp = GetStatsCP(row.ToStats(level), level); - var equipmentsCp = equipments.Sum(GetCP); - var costumeCp = costumes.Sum(c => GetCP(c, costumeStatSheet)); - var runeCp = runeOptions.Sum(x => x.Cp); + var equipmentsCp = 0; + var costumeCp = 0; + var runeCp = 0; + + foreach (var equipment in equipments) + { + equipmentsCp += GetCP(equipment); + } + foreach (var costume in costumes) + { + costumeCp += GetCP(costume, costumeStatSheet); + } + foreach (var runeOption in runeOptions) + { + runeCp += runeOption.Cp; + } var totalCp = DecimalToInt(levelStatsCp + equipmentsCp + costumeCp + runeCp); return totalCp; } @@ -113,7 +126,13 @@ public static int GetCP(ITradableItem tradableItem, CostumeStatSheet sheet) private static decimal GetStatsCP(IStats stats, int characterLevel = 1) { var statTuples = stats.GetStats(true); - return statTuples.Sum(tuple => GetStatCP(tuple.statType, tuple.value, characterLevel)); + decimal cp = 0m; + foreach (var tuple in statTuples) + { + cp += GetStatCP(tuple.statType, tuple.value, characterLevel); + } + + return cp; } public static decimal GetStatCP(StatType statType, decimal statValue, int characterLevel = 1) diff --git a/Lib9c/Lib9c.csproj b/Lib9c/Lib9c.csproj index 9fdfd5ab1..23446b974 100644 --- a/Lib9c/Lib9c.csproj +++ b/Lib9c/Lib9c.csproj @@ -9,6 +9,7 @@ .obj Nekoyume 8 + 0.5.0 true Debug;Release AnyCPU diff --git a/Lib9c/Model/Buff/ActionBuff.cs b/Lib9c/Model/Buff/ActionBuff.cs index ae39bdce0..7f8723b36 100644 --- a/Lib9c/Model/Buff/ActionBuff.cs +++ b/Lib9c/Model/Buff/ActionBuff.cs @@ -30,7 +30,7 @@ protected ActionBuff(ActionBuff value) : base(value) public abstract BattleStatus.Skill GiveEffect( CharacterBase affectedCharacter, - int simulatorWaveTurn); + int simulatorWaveTurn, bool copyCharacter = true); public abstract BattleStatus.Arena.ArenaSkill GiveEffectForArena( ArenaCharacter affectedCharacter, diff --git a/Lib9c/Model/Buff/Bleed.cs b/Lib9c/Model/Buff/Bleed.cs index 800f9bd77..2cfb5b8f9 100644 --- a/Lib9c/Model/Buff/Bleed.cs +++ b/Lib9c/Model/Buff/Bleed.cs @@ -31,20 +31,19 @@ public override object Clone() return new Bleed(this); } - public override BattleStatus.Skill GiveEffect( - CharacterBase affectedCharacter, - int simulatorWaveTurn) + public override BattleStatus.Skill GiveEffect(CharacterBase affectedCharacter, + int simulatorWaveTurn, bool copyCharacter = true) { - var clone = (CharacterBase)affectedCharacter.Clone(); + var clone = copyCharacter ? (CharacterBase) affectedCharacter.Clone() : null; var damage = affectedCharacter.GetDamage(Power, false); affectedCharacter.CurrentHP -= damage; - + // Copy new Character with damaged. + var target = copyCharacter ? (CharacterBase) affectedCharacter.Clone() : null; var damageInfos = new List { - // Copy new Character with damaged. new BattleStatus.Skill.SkillInfo(affectedCharacter.Id, affectedCharacter.IsDead, affectedCharacter.Thorn, damage, false, SkillCategory.Debuff, simulatorWaveTurn, RowData.ElementalType, - RowData.TargetType, target: (CharacterBase)affectedCharacter.Clone()) + RowData.TargetType, target: target) }; return new Model.BattleStatus.TickDamage( diff --git a/Lib9c/Model/Character/CharacterBase.cs b/Lib9c/Model/Character/CharacterBase.cs index e60c08517..56902dd15 100644 --- a/Lib9c/Model/Character/CharacterBase.cs +++ b/Lib9c/Model/Character/CharacterBase.cs @@ -567,7 +567,7 @@ protected virtual void OnPostSkill(BattleStatus.Skill usedSkill) bool log = Simulator.LogEvent; foreach (var bleed in bleeds) { - var effect = bleed.GiveEffect(this, Simulator.WaveTurn); + var effect = bleed.GiveEffect(this, Simulator.WaveTurn, log); if (log) { Simulator.Log.Add(effect); diff --git a/Lib9c/Model/Character/EnemyPlayer.cs b/Lib9c/Model/Character/EnemyPlayer.cs index 4c2ef57f8..31e7acd67 100644 --- a/Lib9c/Model/Character/EnemyPlayer.cs +++ b/Lib9c/Model/Character/EnemyPlayer.cs @@ -49,6 +49,7 @@ EquipmentItemSetEffectSheet equipmentItemSetEffectSheet belt = null; necklace = null; ring = null; + aura = null; monsterMap = new CollectionMap(); eventMap = new CollectionMap(); hairIndex = enemyPlayerDigest.HairIndex; diff --git a/Lib9c/Model/Character/Player.cs b/Lib9c/Model/Character/Player.cs index f66bda838..41e5711a8 100644 --- a/Lib9c/Model/Character/Player.cs +++ b/Lib9c/Model/Character/Player.cs @@ -58,6 +58,7 @@ public object Clone() public Belt belt; public Necklace necklace; public Ring ring; + public Aura aura; public CollectionMap monsterMap; public CollectionMap eventMap; @@ -104,6 +105,7 @@ public Player(AvatarState avatarState, Simulator simulator) belt = null; necklace = null; ring = null; + aura = null; monsterMap = new CollectionMap(); eventMap = new CollectionMap(); monsterMapForBeforeV100310 = new CollectionMap(); @@ -135,6 +137,7 @@ EquipmentItemSetEffectSheet equipmentItemSetEffectSheet belt = null; necklace = null; ring = null; + aura = null; monsterMap = new CollectionMap(); eventMap = new CollectionMap(); monsterMapForBeforeV100310 = new CollectionMap(); @@ -165,6 +168,7 @@ EquipmentItemSetEffectSheet equipmentItemSetEffectSheet belt = null; necklace = null; ring = null; + aura = null; monsterMap = new CollectionMap(); eventMap = new CollectionMap(); monsterMapForBeforeV100310 = new CollectionMap(); @@ -214,6 +218,7 @@ protected Player(Player value) : base(value) belt = value.belt; necklace = value.necklace; ring = value.ring; + aura = value.aura; monsterMap = value.monsterMap; eventMap = value.eventMap; monsterMapForBeforeV100310 = value.monsterMapForBeforeV100310; @@ -318,6 +323,9 @@ protected void SetEquipmentStat(EquipmentItemSetEffectSheet sheet) case ItemSubType.Ring: ring = equipment as Ring; break; + case ItemSubType.Aura: + aura = equipment as Aura; + break; default: throw new RequiredBlockIndexException(); } diff --git a/Lib9c/Model/Item/Aura.cs b/Lib9c/Model/Item/Aura.cs new file mode 100644 index 000000000..6c506db29 --- /dev/null +++ b/Lib9c/Model/Item/Aura.cs @@ -0,0 +1,23 @@ +using System; +using System.Runtime.Serialization; +using Bencodex.Types; +using Nekoyume.TableData; + +namespace Nekoyume.Model.Item +{ + [Serializable] + public class Aura : Equipment + { + public Aura(EquipmentItemSheet.Row data, Guid id, long requiredBlockIndex, bool madeWithMimisbrunnrRecipe = false) : base(data, id, requiredBlockIndex, madeWithMimisbrunnrRecipe) + { + } + + public Aura(Dictionary serialized) : base(serialized) + { + } + + protected Aura(SerializationInfo info, StreamingContext _) : base(info, _) + { + } + } +} diff --git a/Lib9c/Model/Item/ItemFactory.cs b/Lib9c/Model/Item/ItemFactory.cs index 89d241a58..6035ed919 100644 --- a/Lib9c/Model/Item/ItemFactory.cs +++ b/Lib9c/Model/Item/ItemFactory.cs @@ -66,6 +66,10 @@ public static ItemUsable CreateItemUsable(ItemSheet.Row itemRow, Guid id, case ItemSubType.Ring: equipment = new Ring((EquipmentItemSheet.Row) itemRow, id, requiredBlockIndex, madeWithMimisbrunnrRecipe); break; + case ItemSubType.Aura: + equipment = new Aura((EquipmentItemSheet.Row) itemRow, id, requiredBlockIndex, + madeWithMimisbrunnrRecipe); + break; default: throw new ArgumentOutOfRangeException( itemRow.Id.ToString(CultureInfo.InvariantCulture)); @@ -146,6 +150,8 @@ public static ItemBase Deserialize(Dictionary serialized) return new Necklace(serialized); case ItemSubType.Ring: return new Ring(serialized); + case ItemSubType.Aura: + return new Aura(serialized); } break; case ItemType.Material: diff --git a/Lib9c/Model/Item/ItemType.cs b/Lib9c/Model/Item/ItemType.cs index afb353950..a4012d659 100644 --- a/Lib9c/Model/Item/ItemType.cs +++ b/Lib9c/Model/Item/ItemType.cs @@ -42,6 +42,9 @@ public enum ItemSubType // Costume Title = 18, + + // Aura + Aura = 19, } public class ItemTypeComparer : IEqualityComparer diff --git a/Lib9c/Model/Stat/Stats.cs b/Lib9c/Model/Stat/Stats.cs index 8ccb31317..da984619b 100644 --- a/Lib9c/Model/Stat/Stats.cs +++ b/Lib9c/Model/Stat/Stats.cs @@ -46,12 +46,20 @@ public void Set(StatMap statMap, params Stats[] statsArray) { if (!LegacyDecimalStatTypes.Contains(stat.StatType)) { - var sum = statsArray.Sum(s => s.GetStatAsInt(stat.StatType)); + int sum = 0; + foreach (var s in statsArray) + { + sum += s.GetStatAsInt(stat.StatType); + } stat.SetBaseValue(sum); } else { - var sum = statsArray.Sum(s => s.GetStat(stat.StatType)); + decimal sum = 0; + foreach (var s in statsArray) + { + sum += s.GetStat(stat.StatType); + } stat.SetBaseValue(sum); } } @@ -96,16 +104,24 @@ public void Set(IEnumerable statModifiers, params Stats[] baseStat var statType = statModifier.StatType; if (!LegacyDecimalStatTypes.Contains(statType)) { - var originalStatValue = - baseStats.Sum(stats => stats.GetStatAsInt(statType)); - var result = statModifier.GetModifiedValue(originalStatValue); + int originalStatValue = 0; + foreach (var stats in baseStats) + { + originalStatValue += stats.GetStatAsInt(statType); + } + + int result = statModifier.GetModifiedValue(originalStatValue); _statMap[statModifier.StatType].AddBaseValue(result); } else { - var originalStatValue = - baseStats.Sum(stats => stats.GetStat(statType)); - var result = statModifier.GetModifiedValue(originalStatValue); + decimal originalStatValue = 0; + foreach (var stats in baseStats) + { + originalStatValue += stats.GetStat(statType); + } + + decimal result = statModifier.GetModifiedValue(originalStatValue); _statMap[statModifier.StatType].AddBaseValue(result); } } diff --git a/Lib9c/Model/State/AvatarState.cs b/Lib9c/Model/State/AvatarState.cs index a9ff513a8..01fefbb2c 100644 --- a/Lib9c/Model/State/AvatarState.cs +++ b/Lib9c/Model/State/AvatarState.cs @@ -671,6 +671,9 @@ public List ValidateEquipmentsV2(List equipmentIds, long blockI ? GameConfig.RequireCharacterLevel.CharacterEquipmentSlotRing2 : int.MaxValue; break; + case ItemSubType.Aura: + requiredLevel = 1; + break; default: throw new ArgumentOutOfRangeException($"{equipment.ItemSubType} / invalid equipment type"); } diff --git a/Lib9c/Model/State/StakeState.cs b/Lib9c/Model/State/StakeState.cs index f1c0fb98e..288f9a96f 100644 --- a/Lib9c/Model/State/StakeState.cs +++ b/Lib9c/Model/State/StakeState.cs @@ -56,6 +56,12 @@ public void Achieve(int level, int step) public const long StakeRewardSheetV2Index = 6_700_000L; public const long CurrencyAsRewardStartIndex = 6_910_000L; + // NOTE: Why `ClaimStakeReward5.ObsoleteBlockIndex + 1`? + // Because we need to make sure that the reward sheet V3 is applied + // after the `ClaimStakeReward5` action is deprecated. + // And we expect the index will be 7_650_000L. + public const long StakeRewardSheetV3Index = ClaimStakeReward5.ObsoleteBlockIndex + 1; + public long CancellableBlockIndex { get; private set; } public long StartedBlockIndex { get; private set; } public long ReceivedBlockIndex { get; private set; } @@ -181,7 +187,9 @@ public int CalculateAccumulatedItemRewardsV1( } [Obsolete("Use CalculateAccumulatedItemRewards() instead.")] - public int CalculateAccumulatedItemRewardsV2(long blockIndex, out int v1Step, + public int CalculateAccumulatedItemRewardsV2( + long blockIndex, + out int v1Step, out int v2Step) { v2Step = GetRewardStepV1(blockIndex, StakeRewardSheetV2Index); @@ -189,13 +197,29 @@ public int CalculateAccumulatedItemRewardsV2(long blockIndex, out int v1Step, return v1Step + v2Step; } - public int CalculateAccumulatedItemRewards(long blockIndex, out int v1Step, out int v2Step) + [Obsolete("Use CalculateAccumulatedItemRewards() instead.")] + public int CalculateAccumulatedItemRewardsV3( + long blockIndex, + out int v1Step, + out int v2Step) { v2Step = GetRewardStep(blockIndex, StakeRewardSheetV2Index); v1Step = GetRewardStep(blockIndex, null) - v2Step; return v1Step + v2Step; } + public int CalculateAccumulatedItemRewards( + long blockIndex, + out int v1Step, + out int v2Step, + out int v3Step) + { + v3Step = GetRewardStep(blockIndex, StakeRewardSheetV3Index); + v2Step = GetRewardStep(blockIndex, StakeRewardSheetV2Index) - v3Step; + v1Step = GetRewardStep(blockIndex, null) - v2Step - v3Step; + return v1Step + v2Step + v3Step; + } + public int CalculateAccumulatedRuneRewards(long blockIndex) { return CalculateAccumulatedRuneRewardsV2(blockIndex, out _, out _); @@ -228,7 +252,8 @@ public int CalculateAccumulatedRuneRewardsV2( return v1Step + v2Step; } - public int CalculateAccumulatedRuneRewards( + [Obsolete("Use CalculateAccumulatedRuneRewards() instead.")] + public int CalculateAccumulatedRuneRewardsV3( long blockIndex, out int v1Step, out int v2Step) @@ -238,6 +263,18 @@ public int CalculateAccumulatedRuneRewards( return v1Step + v2Step; } + public int CalculateAccumulatedRuneRewards( + long blockIndex, + out int v1Step, + out int v2Step, + out int v3Step) + { + v3Step = GetRewardStep(blockIndex, StakeRewardSheetV3Index); + v2Step = GetRewardStep(blockIndex, StakeRewardSheetV2Index) - v3Step; + v1Step = GetRewardStep(blockIndex, ClaimStakeReward2.ObsoletedIndex) - v2Step - v3Step; + return v1Step + v2Step + v3Step; + } + [Obsolete("Use CalculateAccumulatedCurrencyRewards() instead.")] public int CalculateAccumulatedCurrencyRewardsV1( long blockIndex, @@ -249,7 +286,8 @@ public int CalculateAccumulatedCurrencyRewardsV1( return v2Step; } - public int CalculateAccumulatedCurrencyRewards( + [Obsolete("Use CalculateAccumulatedCurrencyRewards() instead.")] + public int CalculateAccumulatedCurrencyRewardsV2( long blockIndex, out int v1Step, out int v2Step) @@ -259,6 +297,31 @@ public int CalculateAccumulatedCurrencyRewards( return v2Step; } + public int CalculateAccumulatedCurrencyRewards( + long blockIndex, + out int v1Step, + out int v2Step, + out int v3Step) + { + v3Step = GetRewardStep(blockIndex, StakeRewardSheetV3Index); + v2Step = GetRewardStep(blockIndex, CurrencyAsRewardStartIndex) - v3Step; + v1Step = 0; + return v2Step + v3Step; + } + + public int CalculateAccumulatedCurrencyCrystalRewards( + long blockIndex, + out int v1Step, + out int v2Step, + out int v3Step) + { + // NOTE: CRYSTAL as reward is enabled from the StakeRewardSheetV3Index. + v3Step = GetRewardStep(blockIndex, StakeRewardSheetV3Index); + v2Step = 0; + v1Step = 0; + return v3Step; + } + /// /// Calculate accumulated rewards step. /// diff --git a/Lib9c/TableCSV/Item/EquipmentItemSheet.csv b/Lib9c/TableCSV/Item/EquipmentItemSheet.csv index 7b3d5d4f5..18ed960a0 100644 --- a/Lib9c/TableCSV/Item/EquipmentItemSheet.csv +++ b/Lib9c/TableCSV/Item/EquipmentItemSheet.csv @@ -173,4 +173,5 @@ id,_name,item_sub_type,grade,elemental_type,set_id,stat_type,stat_value,attack_r 11520000,블루 사파이어 반지,Ring,2,Normal,6,DEF,50,0,11520000 12001001,Special Crystal Belt,Belt,2,Normal,0,ATK,1,0,12001001 12001002,Special Crystal Necklace,Necklace,3,Normal,1,ATK,1,0,12001002 -12001003,Special Crystal Ring,Ring,4,Normal,2,ATK,1,0,12001003 \ No newline at end of file +12001003,Special Crystal Ring,Ring,4,Normal,2,ATK,1,0,12001003 +13001000,Aura,Aura,0,Normal,0,ATK,1,0,10100000 diff --git a/Lib9c/TableCSV/Item/ItemRequirementSheet.csv b/Lib9c/TableCSV/Item/ItemRequirementSheet.csv index c73e8c225..670d40f11 100644 --- a/Lib9c/TableCSV/Item/ItemRequirementSheet.csv +++ b/Lib9c/TableCSV/Item/ItemRequirementSheet.csv @@ -164,6 +164,7 @@ item_id,level,mimislevel 12001001,1,999 12001002,1,999 12001003,1,999 +13001000,1,999 10350001,325,325 10351001,305,305 10352001,305,305 @@ -274,4 +275,4 @@ item_id,level,mimislevel 400000,1,999 900104,1,999 900105,1,999 -900106,1,999 \ No newline at end of file +900106,1,999 diff --git a/Lib9c/TableCSV/StakeRegularRewardSheet.csv b/Lib9c/TableCSV/StakeRegularRewardSheet.csv index 6b737314e..7cd6ef249 100644 --- a/Lib9c/TableCSV/StakeRegularRewardSheet.csv +++ b/Lib9c/TableCSV/StakeRegularRewardSheet.csv @@ -1,26 +1,32 @@ -level,required_gold,item_id,rate,type,currency_ticker -1,50,400000,10,Item, -1,50,500000,800,Item, -1,50,20001,6000,Rune, -2,500,400000,8,Item, -2,500,500000,800,Item, -2,500,20001,6000,Rune, -3,5000,400000,5,Item, -3,5000,500000,800,Item, -3,5000,20001,6000,Rune, -4,50000,400000,5,Item, -4,50000,500000,800,Item, -4,50000,20001,6000,Rune, -5,500000,400000,5,Item, -5,500000,500000,800,Item, -5,500000,20001,6000,Rune, -6,5000000,400000,10,Item, -6,5000000,500000,800,Item, -6,5000000,20001,6000,Rune, -6,5000000,800201,100,Item, -7,10000000,400000,10,Item, -7,10000000,500000,800,Item, -7,10000000,20001,6000,Rune, -7,10000000,600201,50,Item, -7,10000000,800201,50,Item, -7,10000000,,100,Currency,GARAGE +level,required_gold,item_id,rate,type,currency_ticker,currency_decimal_places,decimal_rate +1,50,400000,,Item,,,10 +1,50,500000,,Item,,,800 +1,50,20001,,Rune,,,6000 +2,500,400000,,Item,,,4 +2,500,500000,,Item,,,600 +2,500,20001,,Rune,,,6000 +2,500,,,Currency,CRYSTAL,18,0.1 +3,5000,400000,,Item,,,2 +3,5000,500000,,Item,,,400 +3,5000,20001,,Rune,,,6000 +3,5000,,,Currency,CRYSTAL,18,0.1 +4,50000,400000,,Item,,,2 +4,50000,500000,,Item,,,400 +4,50000,20001,,Rune,,,6000 +4,50000,,,Currency,CRYSTAL,18,0.1 +5,500000,400000,,Item,,,1 +5,500000,500000,,Item,,,200 +5,500000,20001,,Rune,,,3000 +5,500000,,,Currency,CRYSTAL,18,0.1 +6,5000000,400000,,Item,,,1 +6,5000000,500000,,Item,,,200 +6,5000000,20001,,Rune,,,3000 +6,5000000,800201,,Item,,,100 +6,5000000,,,Currency,CRYSTAL,18,0.1 +7,10000000,400000,,Item,,,0.4 +7,10000000,500000,,Item,,,80 +7,10000000,20001,,Rune,,,1200 +7,10000000,600201,,Item,,,50 +7,10000000,800201,,Item,,,50 +7,10000000,,,Currency,GARAGE,18,100 +7,10000000,,,Currency,CRYSTAL,18,0.01 diff --git a/Lib9c/TableData/StakeRegularRewardSheet.cs b/Lib9c/TableData/StakeRegularRewardSheet.cs index 4ad643e10..2d3d80295 100644 --- a/Lib9c/TableData/StakeRegularRewardSheet.cs +++ b/Lib9c/TableData/StakeRegularRewardSheet.cs @@ -20,7 +20,16 @@ public class StakeRegularRewardSheet : public class RewardInfo { public readonly int ItemId; + + /// + /// The rate of reward. + /// + [Obsolete( + "This field is used from `ClaimStakeReward.V2` or earlier." + + " Use `DecimalRate` instead." + + " Deprecated this field because we need to support decimal rate.")] public readonly int Rate; + public readonly StakeRewardType Type; /// @@ -29,13 +38,29 @@ public class RewardInfo /// public readonly string CurrencyTicker; + /// + /// The decimal places of currency. + /// This field is only used when is . + /// + public readonly int? CurrencyDecimalPlaces; + + /// + /// The decimal rate of reward. + /// This field is used from `V3`(in blockchain state) or later. + /// This field is set to `Rate` when `ClaimStakeReward.V2` or earlier. + /// + public readonly decimal DecimalRate; + public RewardInfo(params string[] fields) { ItemId = ParseInt(fields[0], 0); - Rate = ParseInt(fields[1]); + Rate = ParseInt(fields[1], 0); if (fields.Length == 2) { Type = StakeRewardType.Item; + CurrencyTicker = null; + CurrencyDecimalPlaces = null; + DecimalRate = Rate; return; } @@ -43,22 +68,45 @@ public RewardInfo(params string[] fields) if (fields.Length == 3) { CurrencyTicker = null; + CurrencyDecimalPlaces = null; + DecimalRate = Rate; return; } CurrencyTicker = fields[3]; + + if (fields.Length == 4) + { + CurrencyDecimalPlaces = null; + DecimalRate = Rate; + return; + } + + CurrencyDecimalPlaces = ParseInt(fields[4], 0); + + if (fields.Length == 5) + { + DecimalRate = Rate; + return; + } + + DecimalRate = ParseDecimal(fields[5], 0m); } public RewardInfo( int itemId, - int rate, + int rate = 0, StakeRewardType type = StakeRewardType.Item, - string currencyTicker = null) + string currencyTicker = null, + int? currencyDecimalPlaces = null, + decimal decimalRate = 0m) { ItemId = itemId; Rate = rate; Type = type; CurrencyTicker = currencyTicker; + CurrencyDecimalPlaces = currencyDecimalPlaces; + DecimalRate = decimalRate; } protected bool Equals(RewardInfo other) @@ -68,7 +116,11 @@ protected bool Equals(RewardInfo other) Type == other.Type && (CurrencyTicker is null ? other.CurrencyTicker is null - : CurrencyTicker == other.CurrencyTicker); + : CurrencyTicker == other.CurrencyTicker) && + (CurrencyDecimalPlaces is null + ? other.CurrencyDecimalPlaces is null + : CurrencyDecimalPlaces == other.CurrencyDecimalPlaces) && + DecimalRate == other.DecimalRate; } public override bool Equals(object obj) @@ -84,7 +136,9 @@ public override int GetHashCode() return (ItemId * 397) ^ Rate ^ (int)Type ^ - (CurrencyTicker?.GetHashCode() ?? 0); + (CurrencyTicker?.GetHashCode() ?? 0) ^ + (CurrencyDecimalPlaces?.GetHashCode() ?? 0) ^ + DecimalRate.GetHashCode(); } }