Skip to content

Commit

Permalink
Merge pull request #650 from TheTrackerCouncil/bcu-race-fixes
Browse files Browse the repository at this point in the history
BCU Async Race Fixes
  • Loading branch information
MattEqualsCoder authored Jan 16, 2025
2 parents 006e794 + e7049b6 commit d709357
Show file tree
Hide file tree
Showing 33 changed files with 93 additions and 66 deletions.
2 changes: 1 addition & 1 deletion src/TrackerCouncil.Smz3.Data/Logic/Logic.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ public bool CanWallJump(WallJumpDifficulty difficulty)

public bool CheckAgahnim(Progression items, World world, bool requireRewards)
{
return items.Agahnim || (!requireRewards && world.CanAquire(items, RewardType.Agahnim));
return items.Agahnim || (!requireRewards && world.CanAquire(items, requireRewards, RewardType.Agahnim));
}

public World World { get; }
Expand Down
4 changes: 2 additions & 2 deletions src/TrackerCouncil.Smz3.Data/WorldData/Boss.cs
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ public void UpdateAccessibility(Progression actualProgression, Progression withK
{
Accessibility = Accessibility.Unknown;
}
else if (Region.CanBeatBoss(actualProgression))
else if (Region.CanBeatBoss(actualProgression, true))
{
Accessibility = Accessibility.Available;
}
else if (Region.CanBeatBoss(withKeysProgression))
else if (Region.CanBeatBoss(withKeysProgression, true))
{
Accessibility = Accessibility.AvailableWithKeys;
}
Expand Down
2 changes: 1 addition & 1 deletion src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasBoss.cs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public void ApplyState(TrackerState? state)
/// <see langword="true"/> if the boss can be beaten; otherwise,
/// <see langword="false"/>.
/// </returns>
bool CanBeatBoss(Progression items);
bool CanBeatBoss(Progression items, bool isTracking);

Check warning on line 94 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasBoss.cs

View workflow job for this annotation

GitHub Actions / build-mac

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasBoss.CanBeatBoss(Progression, bool)' (but other parameters do)

Check warning on line 94 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasBoss.cs

View workflow job for this annotation

GitHub Actions / build-mac

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasBoss.CanBeatBoss(Progression, bool)' (but other parameters do)

Check warning on line 94 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasBoss.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasBoss.CanBeatBoss(Progression, bool)' (but other parameters do)

Check warning on line 94 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasBoss.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasBoss.CanBeatBoss(Progression, bool)' (but other parameters do)

/// <summary>
/// Returns a randomized name from the metadata for the region
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public bool HasReceivedReward
/// <see langword="true"/> if the region can be completed; otherwise,
/// <see langword="false"/>.
/// </returns>
bool CanRetrieveReward(Progression items);
bool CanRetrieveReward(Progression items, bool isTracking);

Check warning on line 86 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasReward.cs

View workflow job for this annotation

GitHub Actions / build-mac

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasReward.CanRetrieveReward(Progression, bool)' (but other parameters do)

Check warning on line 86 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasReward.cs

View workflow job for this annotation

GitHub Actions / build-mac

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasReward.CanRetrieveReward(Progression, bool)' (but other parameters do)

Check warning on line 86 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasReward.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasReward.CanRetrieveReward(Progression, bool)' (but other parameters do)

Check warning on line 86 in src/TrackerCouncil.Smz3.Data/WorldData/Regions/IHasReward.cs

View workflow job for this annotation

GitHub Actions / build

Parameter 'isTracking' has no matching param tag in the XML comment for 'IHasReward.CanRetrieveReward(Progression, bool)' (but other parameters do)

/// <summary>
/// Determines if the user can see what the reward is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ public override bool CanEnter(Progression items, bool requireRewards)
&& (items.HiJump || Logic.CanWallJump(WallJumpDifficulty.Medium) || Logic.CanFly(items));
}

public bool CanBeatBoss(Progression items)
public bool CanBeatBoss(Progression items, bool isTracking)
{
return CanEnter(items, true) && items.CardBrinstarBoss;
}

public bool CanRetrieveReward(Progression items) => CanBeatBoss(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => CanBeatBoss(items, isTracking);

public bool CanSeeReward(Progression items) => true;

Expand All @@ -77,7 +77,7 @@ public WarehouseEnergyTankRoom(KraidsLair region, IMetadataService? metadata, Tr
name: "Energy Tank, Kraid",
vanillaItem: ItemType.ETank,
access: items => items.Kraid,
relevanceRequirement: items => region.CanBeatBoss(items),
relevanceRequirement: items => region.CanBeatBoss(items, true),
memoryAddress: 0x5,
memoryFlag: 0x8,
metadata: metadata,
Expand Down Expand Up @@ -116,7 +116,7 @@ public VariaSuitRoom(KraidsLair region, IMetadataService? metadata, TrackerState
name: "Varia Suit",
vanillaItem: ItemType.Varia,
access: items => items.Kraid,
relevanceRequirement: items => region.CanBeatBoss(items),
relevanceRequirement: items => region.CanBeatBoss(items, true),
memoryAddress: 0x6,
memoryFlag: 0x1,
metadata: metadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ public override bool CanEnter(Progression items, bool requireRewards)
(World.UpperNorfairWest.CanEnter(items, true) && items.Super && Logic.CanUsePowerBombs(items) && CanPassMountDeath(items, Logic)) ||
Logic.CanAccessMaridiaPortal(items, requireRewards));

public bool CanBeatBoss(Progression items)
public bool CanBeatBoss(Progression items, bool isTracking)
=> CanEnter(items, true) && CanDefeatDraygon(items, true);

public bool CanRetrieveReward(Progression items) => CanBeatBoss(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => CanBeatBoss(items, isTracking);

public bool CanSeeReward(Progression items) => true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ public override bool CanEnter(Progression items, bool requireRewards) => items.V
))
);

public bool CanBeatBoss(Progression items)
public bool CanBeatBoss(Progression items, bool isTracking)
{
return CanEnter(items, true) && CanExit(items) && items.CardLowerNorfairBoss && Logic.CanUsePowerBombs(items) && items.Super;
}

public bool CanRetrieveReward(Progression items) => CanBeatBoss(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => CanBeatBoss(items, isTracking);

public bool CanSeeReward(Progression items) => true;

Expand Down Expand Up @@ -172,7 +172,7 @@ public RidleyTankRoom(LowerNorfairEast region, IMetadataService? metadata, Track
name: "Energy Tank, Ridley",
vanillaItem: ItemType.ETank,
access: items => items.Ridley,
relevanceRequirement: region.CanBeatBoss,
relevanceRequirement: items => region.CanBeatBoss(items, true),
memoryAddress: 0x9,
memoryFlag: 0x40,
metadata: metadata,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,14 +100,14 @@ public bool CanPassReverseForgottenHighway(Progression items)
);
}

public bool CanBeatBoss(Progression items) => CanEnter(items, true) && CanUnlockShip(items);
public bool CanBeatBoss(Progression items, bool isTracking) => CanEnter(items, true) && CanUnlockShip(items);

public bool CanUnlockShip(Progression items)
{
return items.CardWreckedShipBoss && Logic.CanPassBombPassages(items);
}

public bool CanRetrieveReward(Progression items) => CanEnter(items, true) && CanUnlockShip(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => CanEnter(items, true) && CanUnlockShip(items);

public bool CanSeeReward(Progression items) => true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return Logic.CanKillManyEnemies(items) && (items.Cape || items.MasterSword);
}

public bool CanBeatBoss(Progression items) => CanRetrieveReward(items);
public bool CanBeatBoss(Progression items, bool isTracking) => CanRetrieveReward(items, isTracking);

public bool CanRetrieveReward(Progression items)
public bool CanRetrieveReward(Progression items, bool isTracking)
{
return CanEnter(items, true) && items.Lamp && items.KeyCT >= 2 && items.Sword;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public PyramidFairyChamber(Region region, IMetadataService? metadata, TrackerSta
}

private bool CanAccessPyramidFairy(Progression items, bool requireRewards) =>
(items.BothRedCrystals || (!requireRewards && World.CanAquireAll(items, RewardType.CrystalRed))) &&
(items.BothRedCrystals || (!requireRewards && World.CanAquireAll(items, requireRewards, RewardType.CrystalRed))) &&
World.Logic.CanNavigateDarkWorld(items) && World.DarkWorldSouth.CanEnter(items, requireRewards) &&
(items.Hammer || (items.Mirror && Logic.CheckAgahnim(items, World, requireRewards)));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
Logic.CanAccessMiseryMirePortal(items) && items.Mirror;
}

public bool CanBeatBoss(Progression items) => LanmolasReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => LanmolasReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => LanmolasReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => LanmolasReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapDP);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,11 @@ public EasternPalace(World world, Config config, IMetadataService? metadata, Tra

public Location ArmosKnightsRewards { get; }

public bool CanRetrieveReward(Progression items)
=> ArmosKnightsRewards.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking)
=> ArmosKnightsRewards.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapEP);

public bool CanBeatBoss(Progression items)
=> ArmosKnightsRewards.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking)
=> ArmosKnightsRewards.IsAvailable(items, isTracking);
}
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public override bool CanEnter(Progression items, bool requireRewards)
var canEnterDDMEast = World.DarkWorldDeathMountainEast.CanEnter(items, requireRewards);
var haveEnoughCrystals = items.CrystalCount >= Config.GanonsTowerCrystalCount;
var gtOpenBeforeGanon = Config.GanonsTowerCrystalCount < Config.GanonCrystalCount;
var canBeatMetroid = World.CanDefeatBossCount(items, smBosses) >= Config.TourianBossCount;
var canBeatMetroid = World.CanDefeatBossCount(items, requireRewards, smBosses) >= Config.TourianBossCount;
return World.Logic.CanNavigateDarkWorld(items) && canEnterDDMEast && haveEnoughCrystals && (gtOpenBeforeGanon || canBeatMetroid);
}

Expand All @@ -199,8 +199,8 @@ public override bool CanFill(Item item, Progression items)
return base.CanFill(item, items);
}

public bool CanBeatBoss(Progression items) => MoldormChest.IsAvailable(items) && items.MasterSword &&
items.Contains(ItemType.SilverArrows);
public bool CanBeatBoss(Progression items, bool isTracking) => MoldormChest.IsAvailable(items) && items.MasterSword &&
items.Contains(ItemType.SilverArrows);

private bool TowerAscend(Progression items)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public HyruleCastle(World world, Config config, IMetadataService? metadata, Trac

public Boss Boss { get; set; } = null!;

public bool CanBeatBoss(Progression items) => ZeldasCell.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => ZeldasCell.IsAvailable(items);

public Location Sanctuary { get; }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return World.Logic.CanNavigateDarkWorld(items) && items.Flippers && Logic.CanLiftHeavy(items) && Logic.CanMeltFreezors(items);
}

public bool CanBeatBoss(Progression items) => KholdstareReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => KholdstareReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => KholdstareReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => KholdstareReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapIP);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public SahasrahlasHideoutRoom(Region region, IMetadataService? metadata, Tracker
name: "Sahasrahla",
vanillaItem: ItemType.Boots,
access: items => items.GreenPendant,
relevanceRequirement: items => World.CanAquire(items, RewardType.PendantGreen),
relevanceRequirement: items => World.CanAquire(items, true, RewardType.PendantGreen),
memoryAddress: 0x190,
memoryFlag: 0x10,
memoryType: LocationMemoryType.ZeldaMisc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public LightWorldNorthWest(World world, Config config, IMetadataService? metadat
name: "Master Sword Pedestal",
vanillaItem: ItemType.ProgressiveSword,
access: items => items.AllPendants,
relevanceRequirement: items => World.CanAquireAll(items, RewardType.PendantGreen, RewardType.PendantBlue, RewardType.PendantRed),
relevanceRequirement: items => World.CanAquireAll(items, true, RewardType.PendantGreen, RewardType.PendantBlue, RewardType.PendantRed),
memoryAddress: 0x80,
memoryFlag: 0x40,
memoryType: LocationMemoryType.ZeldaMisc,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,9 +170,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
(items.Boots || items.Hookshot) && World.DarkWorldMire.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => VitreousReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => VitreousReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => VitreousReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => VitreousReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapMM);
}
Original file line number Diff line number Diff line change
Expand Up @@ -185,9 +185,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return World.Logic.CanNavigateDarkWorld(items) && World.DarkWorldNorthEast.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => HelmasaurKingReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => HelmasaurKingReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => HelmasaurKingReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => HelmasaurKingReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapPD);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,9 +149,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return World.Logic.CanNavigateDarkWorld(items) && World.DarkWorldNorthWest.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => MothulaReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => MothulaReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => MothulaReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => MothulaReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapSW);
}
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return World.Logic.CanNavigateDarkWorld(items) && items.Mirror && items.Flippers && World.DarkWorldSouth.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => ArrghusReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => ArrghusReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => ArrghusReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => ArrghusReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapSP);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,9 +147,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
return World.Logic.CanNavigateDarkWorld(items) && World.DarkWorldNorthWest.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) =>BlindReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => BlindReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) =>BlindReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => BlindReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapTT);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
&& World.LightWorldDeathMountainWest.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => MoldormReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => MoldormReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => MoldormReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => MoldormReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapTH);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,9 +155,9 @@ public override bool CanEnter(Progression items, bool requireRewards)
World.LightWorldDeathMountainEast.CanEnter(items, requireRewards);
}

public bool CanBeatBoss(Progression items) => TrinexxReward.IsAvailable(items);
public bool CanBeatBoss(Progression items, bool isTracking) => TrinexxReward.IsAvailable(items, isTracking);

public bool CanRetrieveReward(Progression items) => TrinexxReward.IsAvailable(items);
public bool CanRetrieveReward(Progression items, bool isTracking) => TrinexxReward.IsAvailable(items, isTracking);

public bool CanSeeReward(Progression items) => !World.Config.ZeldaKeysanity || items.Contains(ItemType.MapTR);

Expand Down
4 changes: 2 additions & 2 deletions src/TrackerCouncil.Smz3.Data/WorldData/Reward.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ public void UpdateAccessibility(Progression actualProgression, Progression withK
{
Accessibility = Accessibility.Unknown;
}
else if (Region.CanRetrieveReward(actualProgression))
else if (Region.CanRetrieveReward(actualProgression, true))
{
Accessibility = Accessibility.Available;
}
else if (Region.CanRetrieveReward(withKeysProgression))
else if (Region.CanRetrieveReward(withKeysProgression, true))
{
Accessibility = Accessibility.AvailableWithKeys;
}
Expand Down
16 changes: 8 additions & 8 deletions src/TrackerCouncil.Smz3.Data/WorldData/World.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,25 +240,25 @@ public Location FindLocation(LocationId id)
return Locations.First(x => x.Id == id);
}

public bool CanAquire(Progression items, RewardType reward)
public bool CanAquire(Progression items, bool isTracking, RewardType reward)
{
var dungeonWithReward = Regions.OfType<IHasReward>().FirstOrDefault(x => reward == x.RewardType);
return dungeonWithReward != null && dungeonWithReward.CanRetrieveReward(items);
return dungeonWithReward != null && dungeonWithReward.CanRetrieveReward(items, isTracking);
}

public bool CanAquireAll(Progression items, params RewardType[] rewards)
public bool CanAquireAll(Progression items, bool isTracking, params RewardType[] rewards)
{
return Regions.OfType<IHasReward>().Where(x => rewards.Contains(x.RewardType)).All(x => x.CanRetrieveReward(items));
return Regions.OfType<IHasReward>().Where(x => rewards.Contains(x.RewardType)).All(x => x.CanRetrieveReward(items, isTracking));
}

public bool CanDefeatAll(Progression items, params BossType[] bosses)
public bool CanDefeatAll(Progression items, bool isTracking, params BossType[] bosses)
{
return BossRegions.Where(x => bosses.Contains(x.BossType)).All(x => x.CanBeatBoss(items));
return BossRegions.Where(x => bosses.Contains(x.BossType)).All(x => x.CanBeatBoss(items, isTracking));
}

public int CanDefeatBossCount(Progression items, params BossType[] bosses)
public int CanDefeatBossCount(Progression items, bool isTracking, params BossType[] bosses)
{
return BossRegions.Where(x => bosses.Contains(x.BossType)).Count(x => x.CanBeatBoss(items));
return BossRegions.Where(x => bosses.Contains(x.BossType)).Count(x => x.CanBeatBoss(items, isTracking));
}

public bool HasDefeated(params BossType[] bosses)
Expand Down
Loading

0 comments on commit d709357

Please sign in to comment.