67 Commits

Author SHA1 Message Date
JonathanMcCaffrey e3284ca91e ... 2026-06-13 21:43:40 -04:00
JonathanMcCaffrey 39e3dd6528 Disabling slop features 2026-06-13 14:57:11 -04:00
JonathanMcCaffrey e9d60e3983 Agent Catalog and Maui Test 2026-06-13 14:57:11 -04:00
JonathanMcCaffrey 7310e4ed71 Agent code and restructuring 2026-06-08 14:38:00 -04:00
JonathanMcCaffrey 0feac0f0a0 Agent Tests for API, MAUI, and Slop Features 2026-06-04 10:43:01 -04:00
JonathanMcCaffrey 46150d3a69 Converting Tests back to C# but still with Playwright 2026-06-03 16:04:39 -04:00
JonathanMcCaffrey 85834466f1 CLI and Publish Tests 2026-06-02 22:02:01 -04:00
JonathanMcCaffrey 7da6f554a8 Faction border code design and colour tweaks 2026-06-02 22:02:01 -04:00
6d486f49 dc0395c7d3 Updating .NET versions 2026-06-02 22:02:01 -04:00
JonathanMcCaffrey 026aebd5ad Clearing Entity Click View on Clear and other notes 2026-06-02 22:02:01 -04:00
JonathanMcCaffrey 3974fcfb91 Removing legacy test automation 2026-06-01 09:58:44 -04:00
JonathanMcCaffrey 410e7e23b7 Added current work plan 2026-06-01 09:57:15 -04:00
JonathanMcCaffrey 6655cdeee7 Console cleanup 2026-06-01 08:22:31 -04:00
JonathanMcCaffrey 1f7a0819fc Playwright start 2026-05-31 14:33:58 -04:00
6d486f49 73f29cea08 Updating version 2026-03-23 22:14:58 -04:00
Jonathan b63d8330f7 Fixing harass calculator link 2025-08-10 18:35:36 -04:00
Jonathan ad7aabd9e0 Adding MIA footer, don't recall why it was missing 2025-06-22 22:53:23 -04:00
Jonathan 7680fae30b Removing variable service 2025-06-22 22:49:59 -04:00
Jonathan 9e9b25ae6f Removing pointless WebsiteService.cs 2025-06-22 22:46:45 -04:00
Jonathan cf3f6e647b Web page data refactor 2025-06-22 22:38:59 -04:00
Jonathan c0ea4a094e Splitting large data file for less cumbersome editing and IDE lag 2025-06-22 20:48:33 -04:00
Jonathan 1bc78306b8 Temp is depleted logic 2025-06-22 18:46:51 -04:00
Jonathan 826717c47f Harvest points can now be depleted 2025-06-21 21:10:06 -04:00
Jonathan a5964a68f8 Clean up 2025-06-21 21:09:32 -04:00
Jonathan 424fdd248a Cleanup 2025-06-21 21:09:32 -04:00
Jonathan 7ca2f82ad7 Other rider suggestions 2025-06-21 21:09:32 -04:00
Jonathan fd20f8ca7d Start of considering depleted values for Raw Ether surges and bases 2025-06-21 21:09:31 -04:00
Jonathan 5d4f141580 Removing broken link until fixed 2025-06-15 21:33:58 -04:00
Jonathan 2baa295e1f More data updates to playtest patch 2025-06-15 21:31:32 -04:00
Jonathan b8d2210cc5 Rider cleanup suggestions in calculator 2025-06-14 12:18:44 -04:00
Jonathan 8b5d5a05e4 Metadata fix on Armor Types note date 2025-06-13 18:45:04 -04:00
Jonathan 02d6e2f5e9 Additional legacy data cleanup 2025-06-13 18:44:25 -04:00
Jonathan 22d245972c Data cleanup 2025-06-13 18:43:24 -04:00
Jonathan c95ee06449 Removing all the meta agile and git stuff 2025-06-13 18:39:11 -04:00
Jonathan df5c5480d8 Removing SQL Convert project 2025-06-13 18:27:11 -04:00
Jonathan e641189c9d Removing SQL 2025-06-13 18:26:33 -04:00
Jonathan 071d2f5e35 More data fixes and added a bunch of disclaimers 2025-06-12 00:06:39 -04:00
Jonathan ff4941d38c More data, and minor updates to Build Calculator for June 2025 Playtest 2025-06-11 22:31:42 -04:00
Jonathan 4b2fe6d551 More data plus example flavour text UI 2025-06-11 20:41:31 -04:00
Jonathan b02232855d More information 2025-06-11 11:51:57 -04:00
Jonathan f5e8984ab8 More info 2025-06-10 18:27:34 -04:00
Jonathan 2ac56f9672 Atzlan data. Very WIP 2025-06-10 16:49:49 -04:00
Jonathan e464b9ecab Updated Masked Hunter Data 2025-06-10 10:39:49 -04:00
Jonathan 720a99991f Adding an out of date warning on patch text. 2025-05-02 21:47:56 -04:00
Jonathan 80f44c3931 0.0.6.10415a 2025-05-02 21:32:02 -04:00
Jonathan db48f05686 Patch 0.0.6.10322a 2025-05-02 21:29:37 -04:00
Jonathan e90621c2fd Updating to patch 0.0.6.10294a 2025-05-02 21:25:31 -04:00
Jonathan 2246847145 Clean up code formatting and enhance data immutability
Standardized spacing and removed extraneous white space across multiple files for better readability. Updated several data grids to use `readonly` for `_data` collections, improving immutability and code clarity.
2025-05-02 20:52:15 -04:00
Jonathan 3d10256b9f Updating game patch version to correct patch 2025-05-02 20:49:04 -04:00
Jonathan 1f71062691 Fixing nav name of data tables 2025-04-27 22:22:08 -04:00
Jonathan 831512a64b Add columns and pager to WeaponTable and update tool info
Added "Targets" and "Has Splash" columns as well as a pager for better data navigation in the WeaponTable. Enhanced the tool description to clarify its purpose for comparing and sorting data effectively.
2025-04-27 22:21:34 -04:00
Jonathan 8f203b2ba1 Adding data table page to navigation UI 2025-04-27 22:13:04 -04:00
Jonathan d320476084 Add tabbed DataTables with new Production, Vitality, and Movement tables 2025-04-27 22:07:52 -04:00
Jonathan e28f74b354 Refactor DataTables and cleanup redundant code
Refactored `WeaponTable` grid to use a typed parameter and improve readability. Removed outdated or unnecessary sample comments, consolidated duplicate code, and reorganized theme-related components in `PageLayout`. Simplified initialization logic and improved formatting consistency.
2025-04-27 21:45:28 -04:00
Jonathan 764192891c Add DPS calculations and columns to WeaponTable
Introduced new methods in `EntityWeaponModel` to calculate DPS for normal, light, medium, and heavy damage types. Updated `WeaponTable.razor` to display these new DPS values as additional columns for better weapon performance insights. Also fixed missing initialization of the base `Damage` property in test data.
2025-04-27 20:57:01 -04:00
Jonathan b653a00238 Add sorting, filtering, and new columns to WeaponTable
Enhanced the `MudDataGrid` in `WeaponTable` by enabling multiple sorting and filtering while adding new "Faction" and "Immortal" columns. Extended `EntityModel` and `DATA` to support faction and immortal data for the table. Added "Neutral" faction and new entity "Pyre Miner" to the data model.
2025-04-27 20:47:09 -04:00
Jonathan 25776b3b00 Adding Parent Connection for Parts 2025-04-27 20:05:18 -04:00
Jonathan cacbe6979e Start of data comparison tables 2025-04-27 19:42:47 -04:00
Jonathan e820457176 Updating Mudblazor Version 2025-04-27 19:34:50 -04:00
Jonathan 38ff4e3e89 Publish profiles 2025-03-25 00:16:26 -04:00
Jonathan 65ab4bcf05 Upgrading .net version to 8 2025-03-24 23:25:54 -04:00
Jonathan 0bb95ee9a6 Updating calculator link 2025-03-17 16:21:28 -04:00
JonathanMcCaffrey f084aedb0b Merge pull request #61 from JonathanMcCaffrey/develop
Develop
2022-09-03 15:44:25 -04:00
JonathanMcCaffrey 079ced6af7 Merge branch 'temp' into develop 2022-09-03 15:37:46 -04:00
JonathanMcCaffrey 730bff71ef Updating building health 2022-09-03 15:37:33 -04:00
JonathanMcCaffrey 01d8b383e1 Merge pull request #60 from JonathanMcCaffrey/temp
Temp
2022-09-03 15:07:14 -04:00
JonathanMcCaffrey 83ee8c3ae4 New patch data 2022-09-03 15:06:16 -04:00
668 changed files with 114252 additions and 9247 deletions
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_CALM_MUD_04916B210 }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
action: "upload"
app_location: "IGP"
app_location: "Web"
api_location: ""
output_location: "./wwwroot"
+1 -1
View File
@@ -25,7 +25,7 @@ jobs:
azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_NICE_COAST_0F8B08010 }}
repo_token: ${{ secrets.GITHUB_TOKEN }}
action: "upload"
app_location: "IGP"
app_location: "Web"
api_location: ""
output_location: "./wwwroot"
+4
View File
@@ -137,6 +137,7 @@ DocProject/Help/html
# Click-Once directory
publish/
publish_release/
# Publish Web Output
*.[Pp]ublish.xml
@@ -264,3 +265,6 @@ __pycache__/
**/.vs/
.DS_Store
publish_release/
View File
+1
View File
@@ -0,0 +1 @@
3.0
View File
+3 -3
View File
@@ -7,7 +7,7 @@
"type": "process",
"args": [
"build",
"${workspaceFolder}/IGP/IGP.csproj",
"${workspaceFolder}/Web/Web.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -19,7 +19,7 @@
"type": "process",
"args": [
"publish",
"${workspaceFolder}/IGP/IGP.csproj",
"${workspaceFolder}/Web/Web.csproj",
"/property:GenerateFullPaths=true",
"/consoleloggerparameters:NoSummary"
],
@@ -33,7 +33,7 @@
"watch",
"run",
"--project",
"${workspaceFolder}/IGP/IGP.csproj"
"${workspaceFolder}/Web/Web.csproj"
],
"problemMatcher": "$msCompile"
}
+18
View File
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<RootNamespace>API</RootNamespace>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="HotChocolate.AspNetCore" Version="16.1.2"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj"/>
</ItemGroup>
</Project>
+254
View File
@@ -0,0 +1,254 @@
using Model.Entity;
using Model.Entity.Parts;
namespace API.GraphQL.Types;
public class EntityGraphType : ObjectType<EntityModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityModel> descriptor)
{
descriptor.Name("Entity");
descriptor.Field(e => e.DataType).Name("id");
descriptor.Field(e => e.EntityType).Name("type");
descriptor.Field(e => e.IsSpeculative);
descriptor.Field(e => e.Descriptive).Name("descriptiveType");
descriptor.Ignore(e => e.EntityParts);
descriptor.Field("name")
.Resolve(ctx => ctx.Parent<EntityModel>().GetName());
descriptor.Field("factionName")
.Resolve(ctx => ctx.Parent<EntityModel>().GetFaction());
descriptor.Field("info")
.Type<EntityInfoGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Info());
descriptor.Field("production")
.Type<EntityProductionGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Production());
descriptor.Field("supply")
.Type<EntitySupplyGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Supply());
descriptor.Field("tier")
.Type<EntityTierGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Tier());
descriptor.Field("movement")
.Type<EntityMovementGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Movement());
descriptor.Field("vitality")
.Type<EntityVitalityGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Vitality());
descriptor.Field("requirements")
.Type<ListType<EntityRequirementGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Requirements());
descriptor.Field("weapons")
.Type<ListType<EntityWeaponGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Weapons());
descriptor.Field("hotkey")
.Type<EntityHotkeyGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Hotkey());
descriptor.Field("faction")
.Type<EntityFactionGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Faction());
descriptor.Field("harvest")
.Type<EntityHarvestGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().Harvest());
descriptor.Field("idAbilities")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdAbilities());
descriptor.Field("idArmies")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdArmies());
descriptor.Field("idPassives")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdPassives());
descriptor.Field("idUpgrades")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdUpgrades());
descriptor.Field("idVanguards")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdVanguards());
descriptor.Field("idPyreSpells")
.Type<ListType<EntityIdReferenceGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().IdPyreSpells());
descriptor.Field("mechanics")
.Type<ListType<EntityMechanicGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Mechanics());
descriptor.Field("passives")
.Type<ListType<EntityNamedDescGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Passives());
descriptor.Field("strategies")
.Type<ListType<EntityStrategyGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Strategies());
descriptor.Field("replaceds")
.Type<ListType<EntityVanguardReplacedGraphType>>()
.Resolve(ctx => ctx.Parent<EntityModel>().Replaceds());
descriptor.Field("vanguardAdded")
.Type<EntityVanguardAddedGraphType>()
.Resolve(ctx => ctx.Parent<EntityModel>().VanguardAdded());
}
}
public class EntityInfoGraphType : ObjectType<EntityInfoModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityInfoModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
descriptor.Field(e => e.Name);
descriptor.Field(e => e.Descriptive).Name("descriptiveType");
descriptor.Field(e => e.Description);
descriptor.Field(e => e.Notes);
descriptor.Field(e => e.FlavorText);
}
}
public class EntityProductionGraphType : ObjectType<EntityProductionModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityProductionModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntitySupplyGraphType : ObjectType<EntitySupplyModel>
{
protected override void Configure(IObjectTypeDescriptor<EntitySupplyModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityTierGraphType : ObjectType<EntityTierModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityTierModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityMovementGraphType : ObjectType<EntityMovementModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityMovementModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityVitalityGraphType : ObjectType<EntityVitalityModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityVitalityModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityRequirementGraphType : ObjectType<EntityRequirementModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityRequirementModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityWeaponGraphType : ObjectType<EntityWeaponModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityWeaponModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityHotkeyGraphType : ObjectType<EntityHotkeyModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityHotkeyModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityFactionGraphType : ObjectType<EntityFactionModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityFactionModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityHarvestGraphType : ObjectType<EntityHarvestModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityHarvestModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityIdReferenceGraphType : ObjectType<EntityIdAbilityModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityIdAbilityModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityMechanicGraphType : ObjectType<EntityMechanicModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityMechanicModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityNamedDescGraphType : ObjectType<EntityPassiveModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityPassiveModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityStrategyGraphType : ObjectType<EntityStrategyModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityStrategyModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityVanguardReplacedGraphType : ObjectType<EntityVanguardReplacedModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityVanguardReplacedModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
public class EntityVanguardAddedGraphType : ObjectType<EntityVanguardAddedModel>
{
protected override void Configure(IObjectTypeDescriptor<EntityVanguardAddedModel> descriptor)
{
descriptor.Ignore(e => e.Parent);
}
}
+32
View File
@@ -0,0 +1,32 @@
using API.GraphQL.Types;
using Model.Entity.Data;
var builder = WebApplication.CreateBuilder(args);
builder.Services
.AddGraphQLServer()
.AddQueryType(d =>
{
d.Name("Query");
d.Field("entities")
.Type<NonNullType<ListType<NonNullType<EntityGraphType>>>>()
.Resolve(ctx => EntityData.Get().Values.ToList());
d.Field("entity")
.Type<EntityGraphType>()
.Argument("id", a => a.Type<NonNullType<StringType>>())
.Resolve(ctx =>
{
var id = ctx.ArgumentValue<string>("id");
EntityData.Get().TryGetValue(id, out var entity);
return entity;
});
})
.AddType<EntityGraphType>();
var app = builder.Build();
app.MapGraphQL();
app.Run();
+12
View File
@@ -0,0 +1,12 @@
{
"profiles": {
"API": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:63192;http://localhost:63193"
}
}
}
+16
View File
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>IGP.Calculator.Cli</RootNamespace>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Services\Services.csproj"/>
<ProjectReference Include="..\Model\Model.csproj"/>
</ItemGroup>
</Project>
+155
View File
@@ -0,0 +1,155 @@
using IGP.Calculator.Cli.Services;
using Model.Entity;
using Model.Entity.Data;
using Services.Immortal;
using Services.Website;
var faction = DataType.FACTION_QRath;
var immortal = DataType.IMMORTAL_Orzum;
var attackTime = 1500;
var entityNames = new List<string>();
for (var i = 0; i < args.Length; i++)
switch (args[i].ToLower())
{
case "--faction" when i + 1 < args.Length:
var f = args[++i].ToLower();
faction = f switch
{
"qrath" => DataType.FACTION_QRath,
"aru" => DataType.FACTION_Aru,
_ => throw new Exception($"Unknown faction '{args[i]}'. Use QRath or Aru.")
};
immortal = f switch
{
"qrath" => DataType.IMMORTAL_Orzum,
"aru" => DataType.IMMORTAL_Mala,
_ => immortal
};
break;
case "--immortal" when i + 1 < args.Length:
var im = args[++i];
immortal = im switch
{
nameof(DataType.IMMORTAL_Orzum) => DataType.IMMORTAL_Orzum,
nameof(DataType.IMMORTAL_Ajari) => DataType.IMMORTAL_Ajari,
nameof(DataType.IMMORTAL_Atzlan) => DataType.IMMORTAL_Atzlan,
nameof(DataType.IMMORTAL_Mala) => DataType.IMMORTAL_Mala,
nameof(DataType.IMMORTAL_Xol) => DataType.IMMORTAL_Xol,
_ => throw new Exception($"Unknown immortal '{im}'.")
};
break;
case "--attack-time" or "-a" when i + 1 < args.Length:
attackTime = int.Parse(args[++i]);
break;
default:
entityNames.Add(args[i]);
break;
}
var toastService = new ToastService();
var storageService = new NullStorageService();
var timingService = new TimingService(storageService);
timingService.SetAttackTime(attackTime);
var buildOrderService = new BuildOrderService(toastService, timingService);
var economyService = new EconomyService();
buildOrderService.Reset(faction);
economyService.Calculate(buildOrderService, timingService, 0);
Console.WriteLine($"Faction: {(faction == DataType.FACTION_QRath ? "Q'Rath" : "Aru")}");
Console.WriteLine($"Immortal: {immortal.Replace("IMMORTAL_", "")}");
Console.WriteLine($"Attack Time: {attackTime}s");
Console.WriteLine(new string('-', 50));
foreach (var name in entityNames)
{
if (name.StartsWith("wait ", StringComparison.OrdinalIgnoreCase))
{
var seconds = int.Parse(name[5..]);
buildOrderService.AddWait(seconds);
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
Console.WriteLine($" Wait {seconds}s -> now at interval {buildOrderService.GetLastRequestInterval()}");
continue;
}
if (name.StartsWith("waitto ", StringComparison.OrdinalIgnoreCase))
{
var interval = int.Parse(name[7..]);
buildOrderService.AddWaitTo(interval);
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
Console.WriteLine($" Wait to {interval}s -> now at interval {buildOrderService.GetLastRequestInterval()}");
continue;
}
var entity = FindEntity(name, faction, immortal);
if (entity == null)
{
Console.WriteLine($" ERROR: '{name}' not found for this faction/immortal.");
continue;
}
var beforeInterval = buildOrderService.GetLastRequestInterval();
var added = buildOrderService.Add(entity, economyService);
if (added)
{
economyService.Calculate(buildOrderService, timingService, buildOrderService.GetLastRequestInterval());
var startedAt = buildOrderService.GetLastRequestInterval();
var production = entity.Production();
var completedAt = production != null ? startedAt + production.BuildTime : startedAt;
var cost = production != null
? $" [{production.Alloy}a/{production.Ether}e/{production.Pyre}p, {production.BuildTime}s]"
: "";
Console.WriteLine($" {entity.GetName(),-25} start={startedAt,4}s done={completedAt,4}s{cost}");
}
else
{
Console.WriteLine($" ERROR: Could not add '{name}'.");
var toasts = toastService.GetToasts();
if (toasts.Count > 0)
{
var lastToast = toasts[0];
Console.WriteLine($" Reason: {lastToast.Title} - {lastToast.Message}");
}
}
}
Console.WriteLine(new string('-', 50));
var lastInterval = buildOrderService.GetLastRequestInterval();
var finalEconomy = economyService.GetEconomy(timingService.GetAttackTime());
var lastEconomy = economyService.GetEconomy(lastInterval);
Console.WriteLine($"Army Attacking At: {timingService.GetAttackTime()}s");
Console.WriteLine("");
Console.WriteLine($"At attack time ({timingService.GetAttackTime()}s):");
Console.WriteLine($" Alloy: {finalEconomy.Alloy,10:F1}");
Console.WriteLine($" Ether: {finalEconomy.Ether,10:F1}");
Console.WriteLine($" Pyre: {finalEconomy.Pyre,10:F1}");
Console.WriteLine("");
Console.WriteLine($"At last build action ({lastInterval}s):");
Console.WriteLine($" Alloy: {lastEconomy.Alloy,10:F1}");
Console.WriteLine($" Ether: {lastEconomy.Ether,10:F1}");
Console.WriteLine($" Pyre: {lastEconomy.Pyre,10:F1}");
static EntityModel? FindEntity(string name, string faction, string immortal)
{
var candidates = EntityModel.GetList()
.Where(e => e.Info()?.Name?.Equals(name, StringComparison.OrdinalIgnoreCase) == true)
.Where(e => e.Faction()?.Faction == faction)
.ToList();
if (candidates.Count == 0)
candidates = EntityModel.GetList()
.Where(e => e.Info()?.Name?.Equals(name, StringComparison.OrdinalIgnoreCase) == true)
.Where(e => e.Faction() == null || e.Faction()!.Faction == DataType.FACTION_Neutral)
.ToList();
if (candidates.Count == 0) return null;
if (candidates.Count == 1) return candidates[0];
var vanguardMatch = candidates.FirstOrDefault(e => e.VanguardAdded()?.ImmortalId == immortal);
if (vanguardMatch != null) return vanguardMatch;
return candidates.FirstOrDefault(e => e.VanguardAdded() == null);
}
+33
View File
@@ -0,0 +1,33 @@
using Services;
namespace IGP.Calculator.Cli.Services;
public class NullStorageService : IStorageService
{
private readonly Dictionary<string, object?> _store = new();
public void Subscribe(Action action)
{
}
public void Unsubscribe(Action action)
{
}
public T GetValue<T>(string forKey)
{
if (_store.TryGetValue(forKey, out var value) && value is T typed)
return typed;
return default!;
}
public void SetValue<T>(string key, T value)
{
_store[key] = value;
}
public Task Load()
{
return Task.CompletedTask;
}
}
+10 -9
View File
@@ -1,9 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<RootNamespace>Components</RootNamespace>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
@@ -15,24 +16,24 @@
</PropertyGroup>
<ItemGroup>
<SupportedPlatform Include="browser" />
<SupportedPlatform Include="browser"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Markdig" Version="0.28.1" />
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="6.0.8" />
<PackageReference Include="Microsoft.Extensions.Localization" Version="7.0.0-preview.7.22376.6" />
<PackageReference Include="Markdig" Version="0.28.1"/>
<PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="8.0.14"/>
<PackageReference Include="Microsoft.Extensions.Localization" Version="8.0.14"/>
</ItemGroup>
<ItemGroup>
<Folder Include="Inputs\" />
<Folder Include="Inputs\"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
<ProjectReference Include="..\Services\Services.csproj" />
<ProjectReference Include="..\Model\Model.csproj"/>
<ProjectReference Include="..\Services\Services.csproj"/>
</ItemGroup>
<ItemGroup>
<None Remove="Inputs\" />
<None Remove="Inputs\"/>
</ItemGroup>
</Project>
+1 -2
View File
@@ -21,7 +21,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
}
+6 -8
View File
@@ -22,7 +22,7 @@
}
.devOnlyTitle {
background-color: rgba(20,20,20,0.75);
background-color: rgba(20, 20, 20, 0.75);
padding: 10px;
color: orange;
font-weight: bolder;
@@ -30,14 +30,14 @@
}
.devOnlyContent {
background-color: rgba(20,20,20,0.75);
background-color: rgba(20, 20, 20, 0.75);
width: 100%;
padding: 10px;
}
.devOnlyTitleContainer {
background: repeating-linear-gradient( 45deg, blue, blue 50px, orange 51px, orange 100px);
background: repeating-linear-gradient(45deg, blue, blue 50px, orange 51px, orange 100px);
margin-right: auto;
padding: 10px;
border-left: 6px dashed orange;
@@ -48,7 +48,7 @@
.devOnlyContentContainer {
border: 6px dashed orange;
background: repeating-linear-gradient( 45deg, blue, blue 50px, orange 51px, orange 100px);
background: repeating-linear-gradient(45deg, blue, blue 50px, orange 51px, orange 100px);
box-shadow: 5px 5px 5px blue;
padding: 20px;
}
@@ -58,11 +58,9 @@
@code {
[Inject]
NavigationManager NavigationManager { get; set; } = default!;
[Inject] NavigationManager NavigationManager { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
bool isOnDev;
@@ -69,10 +69,8 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Title { get; set; } = default!;
[Parameter] public string Title { get; set; } = default!;
}
@@ -0,0 +1,87 @@
@inject IGlossaryService glossaryService
@if (TermId != null)
{
var term = glossaryService.GetTerm(TermId);
if (term != null)
{
<div class="glossaryTooltipWrapper">
<div class="glossaryTooltipContent">
<div class="glossaryTooltipHeader">
<span class="glossaryTooltipTerm">@term.Term</span>
<span class="glossaryTooltipCategory">@term.Category</span>
</div>
<div class="glossaryTooltipBody">
@term.ShortDefinition
</div>
</div>
@ChildContent
</div>
}
}
<style>
.glossaryTooltipWrapper {
position: relative;
display: inline-block;
}
.glossaryTooltipContent {
visibility: hidden;
position: absolute;
width: 400px;
max-width: 93vw;
bottom: 100%;
margin-bottom: 8px;
padding: 12px;
z-index: 2147483647;
background-color: var(--info-secondary);
border: 1px solid var(--info-secondary-border);
border-radius: 4px;
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
left: 50%;
transform: translateX(-50%);
}
.glossaryTooltipWrapper:hover .glossaryTooltipContent {
visibility: visible;
}
.glossaryTooltipHeader {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 8px;
}
.glossaryTooltipTerm {
font-weight: 800;
font-size: 1.1rem;
}
.glossaryTooltipCategory {
font-size: 0.8rem;
opacity: 0.7;
}
.glossaryTooltipBody {
font-size: 0.9rem;
line-height: 1.4;
}
@@media only screen and (max-width: 1025px) {
.glossaryTooltipContent {
margin: auto;
margin-bottom: 20px;
position: absolute;
}
}
</style>
@code {
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public string TermId { get; set; } = default!;
}
@@ -35,7 +35,7 @@
border: 1px solid var(--info-secondary-border);
border-radius: 2px;
box-shadow: 0 3px 8px rgba(0,0,0,0.5);
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.5);
}
@@ -55,13 +55,10 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string InfoText { get; set; } = default!;
[Parameter] public string InfoText { get; set; } = default!;
[Parameter]
public int? Margin { get; set; }
[Parameter] public int? Margin { get; set; }
}
+7 -12
View File
@@ -70,13 +70,13 @@
.makingOfContainer summary {
font-weight: bold;
padding: 12px;
background-color: rgba(0,0,0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
}
.shownCode {
visibility: hidden;
padding: 12px;
background-color: rgba(0,0,0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
}
.makingOfContainer details[open] .shownCode {
@@ -97,20 +97,15 @@
@code {
[Parameter]
public RenderFragment Title { get; set; } = default!;
[Parameter] public RenderFragment Title { get; set; } = default!;
[Parameter]
public RenderFragment Description { get; set; } = default!;
[Parameter] public RenderFragment Description { get; set; } = default!;
[Parameter]
public RenderFragment Example { get; set; } = default!;
[Parameter] public RenderFragment Example { get; set; } = default!;
[Parameter]
public RenderFragment Usage { get; set; } = default!;
[Parameter] public RenderFragment Usage { get; set; } = default!;
[Parameter]
public RenderFragment Code { get; set; } = default!;
[Parameter] public RenderFragment Code { get; set; } = default!;
}
@@ -9,7 +9,7 @@
<style>
.makingOfSection {
width: 100%;
background-color: rgba(0,0,0, 0.1);
background-color: rgba(0, 0, 0, 0.1);
padding: 25px;
border-radius: 8px;
border: 2px black dashed;
@@ -22,11 +22,9 @@
@code {
[Parameter]
public string Title { get; set; } = default!;
[Parameter] public string Title { get; set; } = default!;
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
}
+1 -2
View File
@@ -15,7 +15,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
}
+2 -4
View File
@@ -18,10 +18,8 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Title { get; set; } = default!;
[Parameter] public string Title { get; set; } = default!;
}
+3 -6
View File
@@ -52,13 +52,10 @@
@code {
[Parameter]
public RenderFragment? Title { get; set; }
[Parameter] public RenderFragment? Title { get; set; }
[Parameter]
public RenderFragment? Message { get; set; }
[Parameter] public RenderFragment? Message { get; set; }
[Parameter]
public string Type { get; set; } = SeverityType.Warning;
[Parameter] public string Type { get; set; } = SeverityType.Warning;
}
+3 -4
View File
@@ -58,11 +58,10 @@ else
@code {
[Parameter]
public ToastModel? Toast { get; set; } = default!;
[Parameter] public ToastModel? Toast { get; set; }
private float removalTime = 1300;
private float fadeoutTime = 1200;
private readonly float removalTime = 1300;
private readonly float fadeoutTime = 1200;
private float Opacity()
{
+5 -10
View File
@@ -51,20 +51,15 @@
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter] public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter] public string Info { get; set; } = "";
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
[Parameter] public bool ReadOnly { get; set; }
[Parameter]
public bool Value { get; set; }
[Parameter] public bool Value { get; set; }
private string labelId = "";
+7 -12
View File
@@ -35,23 +35,18 @@
</style>
@code {
//TODO Clean up
[Parameter]
public string Label { get; set; } = default!;
[Parameter] public string Label { get; set; } = default!;
[Parameter]
public string Info { get; set; } = default!;
[Parameter] public string Info { get; set; } = default!;
[Parameter]
public RenderFragment? Display { get; set; }
[Parameter] public RenderFragment? Display { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool? ReadOnly { get; set; }
[Parameter] public bool? ReadOnly { get; set; }
[Parameter]
public string? Value { get; set; }
[Parameter] public string? Value { get; set; }
}
@@ -2,11 +2,11 @@
<div class="escapeCodeContainer">
<textarea style="background-color: #2C2E33; width: 100%; border:3px solid #A8ADB9; border-radius:1px; padding: 8px;"
rows="8"
@onchange="OnChange" />
@onchange="OnChange"/>
<textarea style="background-color: #2C2E33; width: 100%; border:3px solid #A8ADB9; border-radius:1px; padding: 8px;"
rows="8"
@bind="Output" />
@bind="Output"/>
</div>
<style>
+6 -12
View File
@@ -1,5 +1,4 @@
@using Model.MemoryTester
@using Services.Immortal
@implements IDisposable
@inject IMemoryTesterService MemoryTesterService
@@ -13,7 +12,7 @@
}
<div>
<input readonly="@MemoryQuestion.IsRevealed"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : IsSubmitted == false ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
class="formTextInput @(MemoryQuestion.IsRevealed ? "revealed" : !IsSubmitted ? "guess" : int.Parse(guess ?? string.Empty) == MemoryQuestion.Answer ? "correct" : "wrong")"
placeholder="guess..."
type="number"
value="@guess"
@@ -73,20 +72,15 @@
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter] public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter] public string Info { get; set; } = "";
[Parameter]
public EventCallback<AnswerEventArgs> OnChange { get; set; } = default!;
[Parameter] public EventCallback<AnswerEventArgs> OnChange { get; set; }
[Parameter]
public MemoryQuestionModel MemoryQuestion { get; set; } = default!;
[Parameter] public MemoryQuestionModel MemoryQuestion { get; set; } = default!;
[Parameter]
public bool IsSubmitted { get; set; }
[Parameter] public bool IsSubmitted { get; set; }
private string? guess = "";
+1 -2
View File
@@ -6,7 +6,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
+1 -2
View File
@@ -4,7 +4,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
+1 -2
View File
@@ -4,7 +4,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
+8 -16
View File
@@ -38,17 +38,13 @@
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter] public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public string Id { get; set; } = default!;
[Parameter] public string Id { get; set; } = default!;
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter] public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
void OnInputChanged(ChangeEventArgs changeEventArgs)
{
@@ -73,16 +69,12 @@
}
}
[Parameter]
public bool ReadOnly { get; set; } = false;
[Parameter] public bool ReadOnly { get; set; }
[Parameter]
public int Value { get; set; } = 0;
[Parameter] public int Value { get; set; }
[Parameter]
public int Min { get; set; } = 0;
[Parameter] public int Min { get; set; }
[Parameter]
public int Max { get; set; } = 2048;
[Parameter] public int Max { get; set; } = 2048;
}
+4 -8
View File
@@ -17,16 +17,12 @@
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter] public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter] public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
}
+10 -19
View File
@@ -11,7 +11,7 @@
type="text"
rows="@Rows"
value="@Value"
@onchange="OnChange" />
@onchange="OnChange"/>
</div>
@if (Info != "")
{
@@ -56,32 +56,23 @@
@code {
[Parameter]
public RenderFragment? FormLabelComponent { get; set; }
[Parameter] public RenderFragment? FormLabelComponent { get; set; }
[Parameter]
public RenderFragment? FormInfoComponent { get; set; }
[Parameter] public RenderFragment? FormInfoComponent { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool? ReadOnly { get; set; }
[Parameter] public bool? ReadOnly { get; set; }
[Parameter]
public string? Value { get; set; }
[Parameter] public string? Value { get; set; }
[Parameter]
public int Rows { get; set; } = 4;
[Parameter] public int Rows { get; set; } = 4;
[Parameter]
public string Label { get; set; } = "";
[Parameter] public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter] public string Info { get; set; } = "";
[Parameter]
public string Placeholder { get; set; } = "";
[Parameter] public string Placeholder { get; set; } = "";
private string labelId = "";
+9 -18
View File
@@ -52,34 +52,25 @@
@code {
[Parameter]
public string Id { get; set; } = "";
[Parameter] public string Id { get; set; } = "";
[Parameter]
public string Label { get; set; } = "";
[Parameter] public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter] public string Info { get; set; } = "";
[Parameter]
public string Placeholder { get; set; } = "";
[Parameter] public string Placeholder { get; set; } = "";
[Parameter]
public EventCallback<ChangeEventArgs> OnInput { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnInput { get; set; }
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public EventCallback OnFocus { get; set; }
[Parameter] public EventCallback OnFocus { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
[Parameter] public bool ReadOnly { get; set; }
[Parameter]
public string Value { get; set; } = "";
[Parameter] public string Value { get; set; } = "";
private string labelId = "";
+5 -10
View File
@@ -98,20 +98,15 @@
@code {
[Parameter]
public string Label { get; set; } = "";
[Parameter] public string Label { get; set; } = "";
[Parameter]
public string Info { get; set; } = "";
[Parameter] public string Info { get; set; } = "";
[Parameter]
public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter] public EventCallback<ChangeEventArgs> OnChange { get; set; }
[Parameter]
public bool ReadOnly { get; set; }
[Parameter] public bool ReadOnly { get; set; }
[Parameter]
public bool Value { get; set; }
[Parameter] public bool Value { get; set; }
private string labelId = "";
+2 -4
View File
@@ -37,10 +37,8 @@
@code {
[Parameter]
public RenderFragment? InfoQuestionComponent { get; set; }
[Parameter] public RenderFragment? InfoQuestionComponent { get; set; }
[Parameter]
public RenderFragment? InfoAnswerComponent { get; set; }
[Parameter] public RenderFragment? InfoAnswerComponent { get; set; }
}
+3 -6
View File
@@ -36,14 +36,11 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public EventCallback<EventArgs> OnClick { get; set; } = default!;
[Parameter] public EventCallback<EventArgs> OnClick { get; set; }
[Parameter]
public MyButtonType MyButtonType { get; set; } = default!;
[Parameter] public MyButtonType MyButtonType { get; set; }
private void ButtonClicked(EventArgs eventArgs)
{
+21 -22
View File
@@ -7,76 +7,75 @@
{
styleClass = "selected";
}
<button @onclick="@(e => OnChangeChoice(choice))" class="groupChoiceButton @styleClass">@choice</button>
}
</div>
</div>
<style>
.groupButtonContainerContainer {
.groupButtonContainerContainer {
margin: auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
justify-items: flex-start;
}
.groupButtonContainer {
}
.groupButtonContainer {
display: flex;
background-color: var(--background);
gap: 2px;
margin-right: auto;
border-radius: 8px;
}
}
.groupChoiceButton {
.groupChoiceButton {
background-color: var(--primary);
color: white;
padding: 12px;
border: 1px solid var(--primary);
}
}
.groupChoiceButton:hover {
.groupChoiceButton:hover {
background-color: var(--primary-hover);
border-color: var(--primary-border-hover);
}
}
.selected {
.selected {
background-color: var(--secondary);
color: white;
font-style: normal;
font-weight: bold;
}
}
.selected:hover {
.selected:hover {
background-color: var(--secondary-hover);
border-color: var(--secondary-border-hover);
}
}
.groupButtonContainer .groupChoiceButton:first-child {
.groupButtonContainer .groupChoiceButton:first-child {
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
}
}
.groupButtonContainer .groupChoiceButton:last-child {
.groupButtonContainer .groupChoiceButton:last-child {
border-top-right-radius: 8px;
border-bottom-right-radius: 8px;
}
}
</style>
@code {
[Parameter]
public string Choice { get; set; } = default!;
[Parameter] public string Choice { get; set; } = default!;
[Parameter]
public List<string> Choices { get; set; } = default!;
[Parameter] public List<string> Choices { get; set; } = default!;
[Parameter]
public EventCallback<string> OnClick { get; set; }
[Parameter] public EventCallback<string> OnClick { get; set; }
protected override void OnInitialized()
+1 -2
View File
@@ -23,7 +23,6 @@
@code {
[Parameter]
public string Href { get; set; } = "";
[Parameter] public string Href { get; set; } = "";
}
@@ -0,0 +1,145 @@
@implements IDisposable
<div class="cooldown-wrap" style="--cooldown-size: @(Size)px">
<button class="cooldown-btn"
disabled="@_isCooldown"
@onclick="HandleClick"
@onclick:preventDefault="_isCooldown">
<span class="cooldown-btn-text">@ChildContent</span>
</button>
@if (_isCooldown)
{
<div class="cooldown-overlay" style="--angle: @(_elapsedAngle)deg">
<span class="cooldown-label">@_remainingSeconds</span>
</div>
}
</div>
<style>
.cooldown-wrap {
position: relative;
display: inline-flex;
width: var(--cooldown-size, 120px);
height: var(--cooldown-size, 120px);
}
.cooldown-btn {
width: 100%;
height: 100%;
border: 2px solid var(--primary);
border-radius: 12px;
background: var(--paper);
color: var(--text-primary, #eee);
font-weight: 700;
font-size: 0.9rem;
cursor: pointer;
padding: 12px;
display: flex;
align-items: center;
justify-content: center;
transition: background 0.15s, border-color 0.15s;
line-height: 1.3;
font-family: inherit;
}
.cooldown-btn:hover:not(:disabled) {
background: var(--paper-hover);
border-color: var(--primary-hover);
}
.cooldown-btn:active:not(:disabled) {
transform: scale(0.97);
}
.cooldown-btn:disabled {
cursor: default;
}
.cooldown-btn-text {
pointer-events: none;
}
.cooldown-overlay {
position: absolute;
inset: 0;
border-radius: 12px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
user-select: none;
}
.cooldown-overlay::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background: rgba(22, 22, 24, 0.45);
mask-image: conic-gradient(transparent 0deg, transparent var(--angle), #000 var(--angle), #000 360deg);
-webkit-mask-image: conic-gradient(transparent 0deg, transparent var(--angle), #000 var(--angle), #000 360deg);
}
.cooldown-label {
font-size: 1.6rem;
font-weight: 900;
color: #999;
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.6);
pointer-events: none;
position: relative;
z-index: 1;
}
</style>
@code {
[Parameter] public RenderFragment? ChildContent { get; set; }
[Parameter] public EventCallback OnClick { get; set; }
[Parameter] public int CooldownSeconds { get; set; } = 12;
[Parameter] public int Size { get; set; } = 120;
private bool _isCooldown;
private int _elapsedAngle;
private int _remainingSeconds;
private DateTime _startTime;
private System.Timers.Timer? _timer;
private async Task HandleClick()
{
if (_isCooldown) return;
await OnClick.InvokeAsync(null);
StartCooldown();
}
private void StartCooldown()
{
_isCooldown = true;
_startTime = DateTime.UtcNow;
_elapsedAngle = 0;
_remainingSeconds = CooldownSeconds;
_timer = new System.Timers.Timer(33);
_timer.Elapsed += OnTick;
_timer.AutoReset = true;
_timer.Enabled = true;
}
private void OnTick(object? sender, System.Timers.ElapsedEventArgs e)
{
var elapsed = (DateTime.UtcNow - _startTime).TotalSeconds;
if (elapsed >= CooldownSeconds)
{
_isCooldown = false;
_timer?.Stop();
_timer?.Dispose();
_timer = null;
InvokeAsync(StateHasChanged);
return;
}
_elapsedAngle = (int)(elapsed / CooldownSeconds * 360);
_remainingSeconds = CooldownSeconds - (int)elapsed;
InvokeAsync(StateHasChanged);
}
public void Dispose()
{
if (_timer != null)
{
_timer.Stop();
_timer.Dispose();
_timer = null;
}
}
}
+1 -2
View File
@@ -23,7 +23,6 @@
@code {
[Parameter]
public string Href { get; set; } = "";
[Parameter] public string Href { get; set; } = "";
}
+2 -3
View File
@@ -14,10 +14,9 @@ else
@code {
[Parameter]
public string EntityId { get; set; } = default!;
[Parameter] public string EntityId { get; set; } = default!;
private EntityModel Entity => DATA.Get()[EntityId];
private EntityModel Entity => EntityData.Get()[EntityId];
void EntityLabelClicked()
{
@@ -0,0 +1,29 @@
@inject IGlossaryService glossaryService
@inject IGlossaryDialogService glossaryDialogService
@if (TermId == null)
{
<span>Missing term</span>
}
else
{
var term = glossaryService.GetTerm(TermId);
if (term != null)
{
<button class="glossaryLabel @term.Category.ToLowerInvariant()" @onclick="TermLabelClicked"
title="@term.ShortDefinition">
@term.Term
</button>
}
}
@code {
[Parameter] public string TermId { get; set; } = default!;
void TermLabelClicked()
{
glossaryDialogService.AddDialog(TermId);
}
}
@@ -0,0 +1,33 @@
.glossaryLabel {
font-weight: bolder;
box-shadow: 1px 1px 0 0 rgba(0, 0, 0, 0.2);
padding-right: 4px;
border: none;
background: none;
cursor: pointer;
font-family: inherit;
font-size: inherit;
text-decoration: underline;
text-decoration-style: dotted;
text-underline-offset: 2px;
}
.glossaryLabel:hover {
background-color: var(--primary-hover);
}
.resource {
color: gold;
}
.mechanic {
color: #8fc5ff;
}
.faction {
color: #da4e4e;
}
.role {
color: #87aa87;
}
+2 -4
View File
@@ -24,12 +24,10 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Href { get; set; } = "";
[Parameter] public string Href { get; set; } = "";
}
+5 -17
View File
@@ -7,15 +7,7 @@
<i class="fa-solid fa-magnifying-glass" style="margin-left: 3px; margin-right: 6px;"></i> Search...
</div>
<div class="searchHotkey">
@if (IsMac)
{
<span><i class="fa-solid fa-command"></i>K</span>
}
else
{
<span>CTRL + K</span>
}
<span>/</span>
</div>
</button>
@@ -37,24 +29,20 @@
.searchHotkey {
padding: 4px;
background-color: rgba(255,255,255,0.05);
border: 2px solid rgba(255,255,255,0.25);
background-color: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(255, 255, 255, 0.25);
border-radius: 4px;
}
</style>
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Id { get; set; } = default!;
[Parameter] public string Id { get; set; } = default!;
private string _userAgent = "";
bool IsMac => _userAgent.Contains("Mac OS");
private void ButtonClicked(EventArgs eventArgs)
{
SearchService.Show();
@@ -29,11 +29,9 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public string Id { get; set; } = default!;
[Parameter] public string Id { get; set; } = default!;
private void ButtonClicked(EventArgs eventArgs)
{
@@ -12,7 +12,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
@@ -23,7 +23,6 @@
}
@@media only screen and (min-width: 1024px) {
.lrg_container {
margin-top: 50px;
@@ -34,7 +33,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
@@ -33,7 +33,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
@@ -29,7 +29,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
+1 -2
View File
@@ -21,7 +21,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
@@ -39,7 +39,6 @@
}
@@media only screen and (min-width: 1024px) {
.layoutWithSidebar {
margin-top: 50px;
@@ -50,10 +49,8 @@
@code {
[Parameter]
public RenderFragment Sidebar { get; set; } = default!;
[Parameter] public RenderFragment Sidebar { get; set; } = default!;
[Parameter]
public RenderFragment Content { get; set; } = default!;
[Parameter] public RenderFragment Content { get; set; } = default!;
}
@@ -24,7 +24,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
}
@@ -21,7 +21,6 @@
@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }
}
@@ -3,11 +3,9 @@
@code {
[Inject]
protected HttpClient Http { get; set; } = default!;
[Inject] protected HttpClient Http { get; set; } = default!;
[Parameter]
public string MarkdownFileName { get; set; } = default!;
[Parameter] public string MarkdownFileName { get; set; } = default!;
private string MarkdownText { get; set; } = "";
@@ -62,7 +62,7 @@
}
.clickOffBackground.clickOffVisible {
visibility:visible;
visibility: visible;
}
.sectionButton {
@@ -78,7 +78,7 @@
left: 0;
width: 100vw;
height: 40px;
background-color: rgba(255,255,255,0.1);
background-color: rgba(255, 255, 255, 0.1);
}
.menuHeader {
@@ -106,11 +106,11 @@
align-items: center;
}
.sectionNav {
.sectionNav {
display: flex;
align-items: center;
height: 100%;
}
}
.websiteTitle {
font-weight: bold;
@@ -166,11 +166,9 @@
@code {
[Parameter]
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; } = default!;
[Parameter] public List<WebPageModel> WebPages { get; set; } = default!;
protected override void OnInitialized()
@@ -12,7 +12,9 @@
}
else
{
<NavLink target="@Links.GetTarget(Page.Href)" @onclick="() => { NavigationService.ChangeNavigationState(NavigationStateType.Default); NavigationService.ChangeNavigationSectionId(-1); }" href="@Page.Href" class="desktopNavLink">
<NavLink target="@Links.GetTarget(Page.Href)"
@onclick="() => { NavigationService.ChangeNavigationState(NavigationStateType.Default); NavigationService.ChangeNavigationSectionId(-1); }"
href="@Page.Href" class="desktopNavLink">
<div class="navName">
@Page.Name
</div>
@@ -65,10 +67,9 @@ else
@code {
[Parameter]
public WebPageModel Page { get; set; } = default!;
[Parameter] public WebPageModel Page { get; set; } = default!;
bool isOnPage = false;
bool isOnPage;
protected override Task OnParametersSetAsync()
{
@@ -5,6 +5,7 @@
{
continue;
}
<DesktopNavLinkComponent Page=childPage></DesktopNavLinkComponent>
}
</div>
@@ -24,7 +25,6 @@
@code {
[Parameter]
public WebSectionModel Section { get; set; } = default!;
[Parameter] public WebSectionModel Section { get; set; } = default!;
}
+12 -13
View File
@@ -2,7 +2,8 @@
<div class="mobileNavSectionsContainer">
@foreach (var webSection in WebSections)
{
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(webSection)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavSectionButton" @onclick="() => OnSectionClicked(webSection)"
@onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavSectionButtonText">
<i class="fa-solid @webSection.Icon" style="font-size: 28px;"></i>
</div>
@@ -11,7 +12,8 @@
<SearchIconButtonComponent/>
</div>
<div class="fullPageButton @(selectedSection != null)" @onclick="OnPageClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
<div class="fullPageButton @(selectedSection != null)" @onclick="OnPageClicked" @onclick:stopPropagation="false"
@onclick:preventDefault="false">
</div>
@if (selectedSection != null)
@@ -27,7 +29,9 @@
{
continue;
}
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(webPage)" @onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButton" @onclick="() => OnPageLinkClicked(webPage)"
@onclick:preventDefault="true" @onclick:stopPropagation="true">
<div class="mobileNavPageButtonText">
@webPage.Name
</div>
@@ -45,7 +49,7 @@
height: 100vh;
bottom: 0;
display: none;
background-color: rgba(0,0,0,0.6);
background-color: rgba(0, 0, 0, 0.6);
}
.fullPageButton.True {
@@ -53,11 +57,9 @@
}
.mobileFooter {
position: fixed;
background-color: rgba(0,0,0,1);
background-color: rgba(0, 0, 0, 1);
width: 100vw;
bottom: 0;
display: none;
@@ -143,11 +145,9 @@
@code {
#if NO_SQL
[Parameter]
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; } = default!;
[Parameter] public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
@@ -157,8 +157,7 @@
public DbSet<WebPageModel> WebPages { get; set; }
#endif
[Inject]
public NavigationManager NavigationManager { get; set; } = default!;
[Inject] public NavigationManager NavigationManager { get; set; } = default!;
private WebSectionModel? selectedSection;
+10 -10
View File
@@ -17,7 +17,8 @@
</div>
<div class="fullPageButton @navOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false" @onclick:preventDefault="false">
<div class="fullPageButton @navOpen" @onclick="OnNavClicked" @onclick:stopPropagation="false"
@onclick:preventDefault="false">
</div>
@@ -40,6 +41,7 @@
{
continue;
}
<NavLink href="@webPage.Href" class="tabletNavItem" @onclick="OnPageClicked">
@webPage.Name
</NavLink>
@@ -58,7 +60,7 @@
height: 100vh;
bottom: 0;
display: none;
background-color: rgba(0,0,0,0.6);
background-color: rgba(0, 0, 0, 0.6);
}
.fullPageButton.True {
@@ -71,7 +73,7 @@
.tabletNav {
position: fixed;
background-color: rgba(30,30,30,0.98);
background-color: rgba(30, 30, 30, 0.98);
display: none;
height: 100vh;
padding: 32px;
@@ -108,7 +110,7 @@
top: 0;
display: flex;
background-color: var(--accent);
border-bottom: 4px solid rgba(0,0,0,0.95);
border-bottom: 4px solid rgba(0, 0, 0, 0.95);
justify-content: space-between;
}
@@ -125,7 +127,7 @@
.tabletButton {
border: 2px solid black;
background-color: rgba(0,0,0,0.3);
background-color: rgba(0, 0, 0, 0.3);
width: 80px;
height: 100%;
display: flex;
@@ -133,7 +135,7 @@
}
.tabletButton:hover {
background-color: rgba(0,0,0,0.7);
background-color: rgba(0, 0, 0, 0.7);
}
@@ -153,11 +155,9 @@
@code {
#if NO_SQL
[Parameter]
public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter] public List<WebSectionModel> WebSections { get; set; } = default!;
[Parameter]
public List<WebPageModel> WebPages { get; set; } = default!;
[Parameter] public List<WebPageModel> WebPages { get; set; } = default!;
#else
[Parameter]
+3 -6
View File
@@ -5,14 +5,11 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Parameter]
public WebDeploymentType DeploymentType { get; set; }
[Parameter] public WebDeploymentType DeploymentType { get; set; }
[Inject]
public NavigationManager MyNavigationManager { get; set; } = default!;
[Inject] public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable;
+2 -4
View File
@@ -11,11 +11,9 @@ else
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
[Inject]
public NavigationManager MyNavigationManager { get; set; } = default!;
[Inject] public NavigationManager MyNavigationManager { get; set; } = default!;
bool isDisplayable;
+6 -32
View File
@@ -1,31 +1,6 @@
@inject IVariableService VariableService
<div class="footerContainer" xmlns="http://www.w3.org/1999/html">
<div class="footerSocials">
<a class="footerIcon" href="https://github.com/JonathanMcCaffrey/IGP-Fan-Reference/discussions" target="_blank">
<i class="fa-brands fa-github"></i>
</a>
<a class="footerIcon" href="mailto:igpfanreference@jonathanmccaffrey.com" target="_blank">
<i class="fa-solid fa-envelope"></i>
</a>
<a class="footerIcon" href="https://discord.gg/uMq8bMGeeN" target="_blank">
<i class="fa-brands fa-discord"></i>
</a>
<a class="footerIcon" href="https://www.youtube.com/channel/UCQx88d5C12yp4l7uszNYrdQ" target="_blank">
<i class="fa-brands fa-youtube"></i>
</a>
<a class="footerIcon" href="https://www.twitch.tv/jonathanmccaffrey" target="_blank">
<i class="fa-brands fa-twitch"></i>
</a>
</div>
<div class="footerContainer" xmlns="http://www.w3.org/1999/html">
<div class="footerDivider"></div>
<div class="footerLastUpdated">Website updated <a href="https://github.com/JonathanMcCaffrey/IGP-Fan-Reference/commits/main"><b>@VariableService.Variables["LastUpdated"]</b></a></div>
<div class="footerDisclaimer">
This website is fan-made and not affiliated with <b>SunSpear Games</b> in any way.
</div>
@@ -36,20 +11,19 @@
.footerIcon {
font-size: 24px;
padding: 8px;
background-color: rgba(255,255,255,0.05);
border: 2px solid rgba(255,255,255,0.1);
background-color: rgba(255, 255, 255, 0.05);
border: 2px solid rgba(255, 255, 255, 0.1);
border-radius: 6px;
line-height: 0;
}
.footerIcon:hover {
color: #8fc5ff;
background-color: rgba(200,200,255,0.1);
border: 2px solid rgba(140,140,255,0.4);
background-color: rgba(200, 200, 255, 0.1);
border: 2px solid rgba(140, 140, 255, 0.4);
}
.footerContainer {
width: 100%;
display: flex;
@@ -69,7 +43,7 @@
}
.footerDivider {
background-color: rgba(255,255,255,0.12);
background-color: rgba(255, 255, 255, 0.12);
height: 1px;
width: 128px;
margin: auto;
@@ -10,10 +10,8 @@
@code {
[Parameter]
public RenderFragment Dividee { get; set; } = default!;
[Parameter] public RenderFragment Dividee { get; set; } = default!;
[Parameter]
public RenderFragment Divider { get; set; } = default!;
[Parameter] public RenderFragment Divider { get; set; } = default!;
}
+5 -7
View File
@@ -1,4 +1,5 @@
<div style="display:flex; flex-direction:column; align-items:center;padding-right: 12px;padding-left: 4px; font-family:monospace">
<div
style="display:flex; flex-direction:column; align-items:center;padding-right: 12px;padding-left: 4px; font-family:monospace">
<div style="height: 0px;display:flex; flex-direction:row; ">
<div style="font-size: 18px; height: 0px;">
&#8721;
@@ -12,13 +13,10 @@
@code {
[Parameter]
public RenderFragment LoopEnd { get; set; } = default!;
[Parameter] public RenderFragment LoopEnd { get; set; } = default!;
[Parameter]
public RenderFragment LoopStart { get; set; } = default!;
[Parameter] public RenderFragment LoopStart { get; set; } = default!;
[Parameter]
public RenderFragment IndexSymbol { get; set; } = default!;
[Parameter] public RenderFragment IndexSymbol { get; set; } = default!;
}
+2 -3
View File
@@ -10,7 +10,7 @@
u {
text-decoration-color: inherit;
text-decoration-thickness:1px;
text-decoration-thickness: 1px;
}
.spoiler:hover {
@@ -22,7 +22,6 @@
@code {
[Parameter]
public RenderFragment ChildContent { get; set; } = default!;
[Parameter] public RenderFragment ChildContent { get; set; } = default!;
}
@@ -0,0 +1,180 @@
@inject IEntityDialogService entityDialogService
@inject NavigationManager NavigationManager
<div class="techTreeContainer" @ref="containerRef">
<svg class="techTreeSvg" width="@svgWidth" height="@svgHeight">
<!-- Edges -->
@foreach (var edge in Graph.Edges)
{
var source = Graph.Nodes.FirstOrDefault(n => n.Id == edge.SourceId);
var target = Graph.Nodes.FirstOrDefault(n => n.Id == edge.TargetId);
if (source != null && target != null)
{
var color = EdgeColor(edge.EdgeType);
var strokeWidth = edge.EdgeType == TechTreeEdgeType.Produces ? "2.5" : "1.5";
var strokeDash = edge.EdgeType == TechTreeEdgeType.RequiresProduction || edge.EdgeType == TechTreeEdgeType.RequiresResearch ? "6,3" : "";
strokeDash = edge.EdgeType == TechTreeEdgeType.Morph ? "2,2" : strokeDash;
<line x1="@(source.X + nodeWidth / 2)" y1="@(source.Y + nodeHeight / 2)"
x2="@(target.X + nodeWidth / 2)" y2="@(target.Y + nodeHeight / 2)"
stroke="@color" stroke-width="@strokeWidth"
stroke-dasharray="@strokeDash"
marker-end="url(#arrowhead-@(edge.EdgeType))"/>
}
}
<!-- Arrowhead markers -->
<defs>
@foreach (var edgeType in Graph.Edges.Select(e => e.EdgeType).Distinct())
{
<marker id="arrowhead-@edgeType" markerWidth="10" markerHeight="7" refX="10" refY="3.5" orient="auto">
<polygon points="0 0, 10 3.5, 0 7" fill="@EdgeColor(edgeType)"/>
</marker>
}
</defs>
<!-- Nodes -->
@foreach (var node in Graph.Nodes)
{
var color = NodeColor(node.Descriptive);
var isHighlighted = HighlightEntityId == node.Id;
<g class="techTreeNode" @onclick="() => OnNodeClick(node.Id)">
<rect x="@node.X" y="@node.Y" width="@nodeWidth" height="@nodeHeight" rx="6"
fill="var(--paper)" stroke="@color" stroke-width="@(isHighlighted ? 3 : 1.5)"
class="@(isHighlighted ? "highlighted" : "")"/>
<text x="@(node.X + nodeWidth / 2)" y="@(node.Y + nodeHeight / 2)"
text-anchor="middle" dominant-baseline="central"
fill="white" font-size="12" font-weight="600">
@TruncateText(node.Name, 20)
</text>
<title>@node.Name (@node.EntityType)</title>
</g>
}
</svg>
</div>
<style>
.techTreeContainer {
width: 100%;
overflow: auto;
border: 2px solid var(--paper-border);
border-radius: 8px;
background-color: var(--background);
}
.techTreeSvg {
display: block;
}
.techTreeNode {
cursor: pointer;
}
.techTreeNode rect {
transition: stroke-width 0.15s;
}
.techTreeNode rect.highlighted {
filter: drop-shadow(0 0 6px rgba(255, 255, 255, 0.5));
}
.techTreeNode:hover rect {
stroke-width: 3;
}
</style>
@code {
[Parameter] public TechTreeGraphModel Graph { get; set; } = new();
[Parameter] public string? HighlightEntityId { get; set; }
[Parameter] public EventCallback<string> OnEntitySelected { get; set; }
private ElementReference containerRef;
private const float nodeWidth = 140;
private const float nodeHeight = 36;
private const float horizontalSpacing = 60;
private const float verticalSpacing = 30;
private const float topPadding = 40;
private const float leftPadding = 40;
private float svgWidth = 800;
private float svgHeight = 600;
protected override void OnParametersSet()
{
ComputeLayout();
}
void ComputeLayout()
{
if (Graph.Nodes.Count == 0) return;
var layers = Graph.Nodes.GroupBy(n => n.Layer)
.OrderBy(g => g.Key)
.ToList();
// Simple layered layout: left to right (layers are columns)
for (var layerIdx = 0; layerIdx < layers.Count; layerIdx++)
{
var layerNodes = layers.ElementAt(layerIdx).OrderBy(n => n.Name).ToList();
var layerHeight = layerNodes.Count * (nodeHeight + verticalSpacing) - verticalSpacing;
for (var nodeIdx = 0; nodeIdx < layerNodes.Count; nodeIdx++)
{
var node = layerNodes[nodeIdx];
node.X = leftPadding + layerIdx * (nodeWidth + horizontalSpacing);
node.Y = topPadding + nodeIdx * (nodeHeight + verticalSpacing);
}
}
svgWidth = layers.Count * (nodeWidth + horizontalSpacing) + leftPadding + 100;
svgHeight = layers.Max(g => g.Count()) * (nodeHeight + verticalSpacing) + topPadding + 80;
if (svgWidth < 800) svgWidth = 800;
if (svgHeight < 400) svgHeight = 400;
}
void OnNodeClick(string entityId)
{
entityDialogService.AddDialog(entityId);
OnEntitySelected.InvokeAsync(entityId);
}
string NodeColor(string descriptive)
{
return descriptive.ToLowerInvariant() switch
{
"frontliner" => "#ff6b6b",
"skirmisher" => "#ffa502",
"support" => "#2ed573",
"generalist" => "#1e90ff",
"worker" => "#ffd43b",
"stronghold" => "#ff4757",
"upgrade" => "#a55eea",
"technology" => "#a55eea",
_ => "#8fc5ff"
};
}
string EdgeColor(string edgeType)
{
return edgeType switch
{
"Produces" => "#2ed573",
"RequiresProduction" => "#ffa502",
"RequiresResearch" => "#a55eea",
"Morph" => "#ff6b6b",
"Upgrades" => "#1e90ff",
_ => "#666"
};
}
string TruncateText(string text, int maxLength)
{
return text.Length <= maxLength ? text : text.Substring(0, maxLength - 3) + "...";
}
}
+4
View File
@@ -4,9 +4,13 @@
@using Microsoft.AspNetCore.Components.Web.Virtualization
@using Microsoft.JSInterop
@using Model.Feedback
@using Model.Glossary
@using Model.TechTree
@using Model.Website
@using Model.Website.Enums
@using Services
@using Services.Immortal
@using Services.Website
@using System.Net.Http
@using System.Net.Http.Json
@using System.Text
-29
View File
@@ -1,29 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<DefineConstants>TRACE;</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<DefineConstants>TRACE;</DefineConstants>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.8" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="6.0.8">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Model\Model.csproj" />
</ItemGroup>
</Project>
-36
View File
@@ -1,36 +0,0 @@
#if NO_SQL
#else
using Microsoft.EntityFrameworkCore;
using Model;
using Model.Doc;
using Model.Git;
using Model.Notes;
using Model.Website;
using Model.Work.Tasks;
namespace Contexts;
public class DatabaseContext : DbContext
{
public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
{
Database.EnsureCreated();
}
public DbSet<AgileSprintModel> AgileSprintModels { get; set; } = default!;
public DbSet<AgileTaskModel> AgileTaskModels { get; set; } = default!;
public DbSet<GitChangeModel> GitChangeModels { get; set; } = default!;
public DbSet<GitPatchModel> GitPatchModels { get; set; } = default!;
public DbSet<WebPageModel> WebPageModels { get; set; } = default!;
public DbSet<WebSectionModel> WebSectionModels { get; set; } = default!;
public DbSet<DocContentModel> DocContentModels { get; set; } = default!;
public DbSet<DocConnectionModel> DocConnectionModels { get; set; } = default!;
public DbSet<DocSectionModel> DocSectionModels { get; set; } = default!;
public DbSet<NoteContentModel> NoteContentModels { get; set; } = default!;
public DbSet<NoteConnectionModel> NoteConnectionModels { get; set; } = default!;
public DbSet<NoteSectionModel> NoteSectionModels { get; set; } = default!;
public DbSet<Variable> Variables { get; set; } = default!;
}
#endif
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Device.App">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
+14
View File
@@ -0,0 +1,14 @@
namespace Device;
public partial class App : Application
{
public App()
{
InitializeComponent();
}
protected override Window CreateWindow(IActivationState? activationState)
{
return new Window(new AppShell());
}
}
+15
View File
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<Shell
x:Class="Device.AppShell"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Device"
Title="Device">
<ShellContent
Title="Home"
ContentTemplate="{DataTemplate local:MainPage}"
Route="MainPage" />
</Shell>
+9
View File
@@ -0,0 +1,9 @@
namespace Device;
public partial class AppShell : Shell
{
public AppShell()
{
InitializeComponent();
}
}
+83
View File
@@ -0,0 +1,83 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">
<PropertyGroup>
<TargetFrameworks>net10.0-android</TargetFrameworks>
<TargetFrameworks Condition="!$([MSBuild]::IsOSPlatform('linux'))">$(TargetFrameworks);net10.0-ios;net10.0-maccatalyst</TargetFrameworks>
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net10.0-windows10.0.19041.0</TargetFrameworks>
<ProjectRuntimeIdentifier Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">win-x64</ProjectRuntimeIdentifier>
<!-- Note for MacCatalyst:
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
<OutputType>Exe</OutputType>
<RootNamespace>Device</RootNamespace>
<UseMaui>true</UseMaui>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- Enable XAML source generation for faster build times and improved performance.
This generates C# code from XAML at compile time instead of runtime inflation.
To disable, remove this line.
For individual files, you can override by setting Inflator metadata:
<MauiXaml Update="MyPage.xaml" Inflator="Default" /> (reverts to defaults: Runtime for Debug, XamlC for Release)
<MauiXaml Update="MyPage.xaml" Inflator="Runtime" /> (force runtime inflation) -->
<MauiXamlInflator>SourceGen</MauiXamlInflator>
<!-- Display name -->
<ApplicationTitle>Device</ApplicationTitle>
<!-- App Identifier -->
<ApplicationId>com.companyname.device</ApplicationId>
<!-- Versions -->
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
<ApplicationVersion>1</ApplicationVersion>
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
<WindowsPackageType>None</WindowsPackageType>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
</PropertyGroup>
<ItemGroup>
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4"/>
<!-- Splash Screen -->
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128"/>
<!-- Images -->
<MauiImage Include="Resources\Images\*"/>
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185"/>
<!-- Custom Fonts -->
<MauiFont Include="Resources\Fonts\*"/>
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)"/>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)"/>
<PackageReference Include="Microsoft.AspNetCore.Components.WebView.Maui" Version="$(MauiVersion)"/>
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="10.0.0"/>
<PackageReference Include="MudBlazor" Version="9.2.0"/>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Components\Components.csproj"/>
<ProjectReference Include="..\Model\Model.csproj"/>
<ProjectReference Include="..\Pages\Pages.csproj"/>
<ProjectReference Include="..\Services\Services.csproj"/>
</ItemGroup>
</Project>
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:Device"
x:Class="Device.MainPage">
<BlazorWebView x:Name="blazorWebView" HostPage="wwwroot/device.html">
<BlazorWebView.RootComponents>
<RootComponent Selector="#app" ComponentType="{x:Type local:MainRazor}" />
</BlazorWebView.RootComponents>
</BlazorWebView>
</ContentPage>
+9
View File
@@ -0,0 +1,9 @@
namespace Device;
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}
+42
View File
@@ -0,0 +1,42 @@
@inject IGlossaryDialogService GlossaryDialogService
@inject IJSRuntime JsRuntime
<MudThemeProvider IsDarkMode="true"/>
<MudDialogProvider/>
<MudSnackbarProvider/>
<Router AppAssembly="@typeof(HomePage).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)"/>
<FocusOnNavigate RouteData="@routeData" Selector="h1"/>
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>
<EntityDialogPortal/>
<GlossaryDialogPortal/>
<ToastPortal/>
<SearchPortal/>
<ConfirmationDialogPortal/>
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JsRuntime.InvokeVoidAsync("glossaryInterop.init", DotNetObjectReference.Create(this));
}
}
[JSInvokable]
public void OpenGlossaryTerm(string termId)
{
GlossaryDialogService.AddDialog(termId);
StateHasChanged();
}
}
+79
View File
@@ -0,0 +1,79 @@
using System.Text.Json;
using System.Text.Json.Serialization;
using Blazored.LocalStorage;
using Microsoft.Extensions.Logging;
using MudBlazor.Services;
using Services;
using Services.Development;
using Services.Immortal;
using Services.Website;
namespace Device;
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});
#pragma warning disable CA1416 // BlazorWebView requires Android 23+, project targets 21+
builder.Services.AddMauiBlazorWebView();
#pragma warning restore CA1416
#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
builder.Logging.AddDebug();
#endif
builder.Services.AddLocalization();
builder.Services.AddBlazoredLocalStorage(config =>
{
config.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
config.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
config.JsonSerializerOptions.IgnoreReadOnlyProperties = true;
config.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
config.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
config.JsonSerializerOptions.ReadCommentHandling = JsonCommentHandling.Skip;
config.JsonSerializerOptions.WriteIndented = false;
});
builder.Services.AddScoped<INavigationService, NavigationService>();
builder.Services.AddScoped<IKeyService, KeyService>();
builder.Services.AddScoped<IImmortalSelectionService, ImmortalSelectionService>();
builder.Services.AddScoped<IBuildComparisonService, DeprecatedBuildComparisionService>();
builder.Services.AddScoped<IBuildOrderService, BuildOrderService>();
builder.Services.AddScoped<IEconomyService, EconomyService>();
builder.Services.AddScoped<ITimingService, TimingService>();
builder.Services.AddScoped<IMemoryTesterService, MemoryTesterService>();
builder.Services.AddScoped<IEntityFilterService, EntityFilterService>();
builder.Services.AddScoped<IEntityDisplayService, EntityDisplayService>();
builder.Services.AddScoped<IEntityDialogService, EntityDialogService>();
builder.Services.AddScoped<IGlossaryService, GlossaryService>();
builder.Services.AddScoped<IGlossaryDialogService, GlossaryDialogService>();
builder.Services.AddScoped<IToastService, ToastService>();
builder.Services.AddScoped<INoteService, NoteService>();
builder.Services.AddScoped<ISearchService, SearchService>();
builder.Services.AddScoped<IStorageService, StorageService>();
builder.Services.AddScoped<IPermissionService, PermissionService>();
builder.Services.AddScoped<IEconomyComparisonService, EconomyComparisionService>();
builder.Services.AddScoped<IDataCollectionService, DataCollectionService>();
builder.Services.AddScoped<IMyDialogService, MyDialogService>();
builder.Services.AddScoped<TechTreeService>();
builder.Services.AddMudServices();
builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri("https://0.0.0.0") });
return builder.Build();
}
}
@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round"
android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
+11
View File
@@ -0,0 +1,11 @@
using Android.App;
using Android.Content.PM;
namespace Device;
[Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop,
ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode |
ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)]
public class MainActivity : MauiAppCompatActivity
{
}
@@ -0,0 +1,18 @@
using Android.App;
using Android.Runtime;
namespace Device;
[Application]
public class MainApplication : MauiApplication
{
public MainApplication(IntPtr handle, JniHandleOwnership ownership)
: base(handle, ownership)
{
}
protected override MauiApp CreateMauiApp()
{
return MauiProgram.CreateMauiApp();
}
}
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#512BD4</color>
<color name="colorPrimaryDark">#2B0B98</color>
<color name="colorAccent">#2B0B98</color>
</resources>
@@ -0,0 +1,9 @@
using Foundation;
namespace Device;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<!-- See https://aka.ms/maui-publish-app-store#add-entitlements for more information about adding entitlements.-->
<dict>
<!-- App Sandbox must be enabled to distribute a MacCatalyst app through the Mac App Store. -->
<key>com.apple.security.app-sandbox</key>
<true/>
<!-- When App Sandbox is enabled, this value is required to open outgoing network connections. -->
<key>com.apple.security.network.client</key>
<true/>
</dict>
</plist>
+40
View File
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- The Mac App Store requires you specify if the app uses encryption. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/itsappusesnonexemptencryption -->
<!-- <key>ITSAppUsesNonExemptEncryption</key> -->
<!-- Please indicate <true/> or <false/> here. -->
<!-- Specify the category for your app here. -->
<!-- Please consult https://developer.apple.com/documentation/bundleresources/information_property_list/lsapplicationcategorytype -->
<!-- <key>LSApplicationCategoryType</key> -->
<!-- <string>public.app-category.YOUR-CATEGORY-HERE</string> -->
<key>UIDeviceFamily</key>
<array>
<integer>2</integer>
</array>
<key>LSApplicationCategoryType</key>
<string>public.app-category.lifestyle</string>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>
+15
View File
@@ -0,0 +1,15 @@
using ObjCRuntime;
using UIKit;
namespace Device;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}
+8
View File
@@ -0,0 +1,8 @@
<maui:MauiWinUIApplication
x:Class="Device.WinUI.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:maui="using:Microsoft.Maui"
xmlns:local="using:Device.WinUI">
</maui:MauiWinUIApplication>
+23
View File
@@ -0,0 +1,23 @@
using Microsoft.UI.Xaml;
// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
namespace Device.WinUI;
/// <summary>
/// Provides application-specific behavior to supplement the default Application class.
/// </summary>
public partial class App : MauiWinUIApplication
{
/// <summary>
/// Initializes the singleton application object. This is the first line of authored code
/// executed, and as such is the logical equivalent of main() or WinMain().
/// </summary>
public App()
{
this.InitializeComponent();
}
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
IgnorableNamespaces="uap rescap">
<Identity Name="maui-package-name-placeholder" Publisher="CN=User Name" Version="0.0.0.0"/>
<mp:PhoneIdentity PhoneProductId="034A3819-8402-48FB-850F-9B134D4D5787"
PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>$placeholder$</DisplayName>
<PublisherDisplayName>User Name</PublisherDisplayName>
<Logo>$placeholder$.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0"/>
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.17763.0" MaxVersionTested="10.0.19041.0"/>
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App" Executable="$targetnametoken$.exe" EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="$placeholder$"
Description="$placeholder$"
Square150x150Logo="$placeholder$.png"
Square44x44Logo="$placeholder$.png"
BackgroundColor="transparent">
<uap:DefaultTile Square71x71Logo="$placeholder$.png" Wide310x150Logo="$placeholder$.png"
Square310x310Logo="$placeholder$.png"/>
<uap:SplashScreen Image="$placeholder$.png"/>
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="runFullTrust"/>
</Capabilities>
</Package>
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="Device.WinUI.app"/>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<!-- The combination of below two tags have the following effect:
1) Per-Monitor for >= Windows 10 Anniversary Update
2) System < Windows 10 Anniversary Update
-->
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2, PerMonitor
</dpiAwareness>
<longPathAware xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">true</longPathAware>
</windowsSettings>
</application>
</assembly>
+9
View File
@@ -0,0 +1,9 @@
using Foundation;
namespace Device;
[Register("AppDelegate")]
public class AppDelegate : MauiUIApplicationDelegate
{
protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp();
}
+32
View File
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>UIDeviceFamily</key>
<array>
<integer>1</integer>
<integer>2</integer>
</array>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>arm64</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UISupportedInterfaceOrientations~ipad</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>XSAppIconAssets</key>
<string>Assets.xcassets/appicon.appiconset</string>
</dict>
</plist>
+15
View File
@@ -0,0 +1,15 @@
using ObjCRuntime;
using UIKit;
namespace Device;
public class Program
{
// This is the main entry point of the application.
static void Main(string[] args)
{
// if you want to use a different Application Delegate class from "AppDelegate"
// you can specify it here.
UIApplication.Main(args, null, typeof(AppDelegate));
}
}

Some files were not shown because too many files have changed in this diff Show More