<Project Sdk="Microsoft.NET.Sdk">

  <!-- General stuff -->
  
  <PropertyGroup>
    <TargetFrameworks>netstandard1.1;netstandard1.3;netstandard2.1;netcoreapp3.0;net5.0;net7.0</TargetFrameworks>
    <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
    <ProduceReferenceAssembly>True</ProduceReferenceAssembly>
    <DebugType>portable</DebugType>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
    <CheckNotRecommendedTargetFramework>false</CheckNotRecommendedTargetFramework>
  </PropertyGroup>
  
  <!-- NuGet package customization. -->
  
  <PropertyGroup>
    <Title>Nerd_STF</Title>
    <Version>3.0.0-beta2</Version>
    <Authors>That_One_Nerd</Authors>
    <Description>A general-purpose mathematics library for C#.</Description>
    <PackageProjectUrl>https://github.com/That-One-Nerd/Nerd_STF</PackageProjectUrl>
    <PackageIcon>Logo Square.png</PackageIcon>
    <PackageReadmeFile>README.md</PackageReadmeFile>
    <RepositoryUrl>https://github.com/That-One-Nerd/Nerd_STF</RepositoryUrl>
    <PackageLicenseExpression>MIT</PackageLicenseExpression>
    <IncludeSymbols>True</IncludeSymbols>
    <SymbolPackageFormat>snupkg</SymbolPackageFormat>
    <PackageTags>c#;csharp;c sharp;math;mathematics;mathametics;maths;color;rgb;rgba;cmyk;cmyka;hsv;hsva;calculus;linear algebra;linalg;linearalgebra;matrix;matrix2x2;matrix 2x2;matrix3x3;matrix 3x3;matrix4x4;matrix 4x4;matrix multiplication;vector;vector2d;vector3d;vector2;vector3;float2;float3;float4;int2;int3;int4;angle;geometry;vert;line;polygon;triangle;quadrilateral;sphere;circle;number system;numbersystem;complex numbers;complex;2d numbers;2dnumbers;quaternions;4d numbers;4dnumbers;equation;equations;polynomial;quadratic;linear equation</PackageTags>
    
    <!-- Sorry this is stupidly long, wish I could have linked a markdown file instead. -->
    <PackageReleaseNotes># Nerd_STF v3.0-beta2

I've added a substantial number of things in this update, mostly matrix related.

## List Tuples

In the previous beta, I introduced **Combination Indexers** for the double and int groups, however a problem was that they only returned `IEnumerable`s. So while some interesting things were supported, some things were not.

```csharp
Float4 wxyz = (1, 2, 3, 4);
IEnumerable&lt;double&gt; vals1 = wxyz["xy"]; // Yields [2, 3]

Float2 vals2 = wxyz["xy"];              // Not allowed!
```

And that kind of sucked. So I created the `ListTuple&lt;T&gt;` type. It's job is to act like a regular tuple, but be able to impliclty convert to either an `IEnumerable` or a regular `ValueTuple&lt;T&gt;`, thus allowing conversions to the double and int groups indirectly. Now, all combination indexers return a `ListTuple` instead of an `IEnumerable`.

Under the hood, the `ListTuple` actually uses an array, but you get the idea.

```csharp
Float4 wxyz = (1, 2, 3, 4);
ListTuple&lt;double&gt; vals1 = wxyz["xy"]; // Yields (2, 3)

Float2 vals2 = vals1;                 // Yields (2, 3)
IEnumerable&lt;double&gt; vals3 = vals1;    // Yields [2, 3]
```

Problem is, now the names have the potential to make much less sense.
```csharp
Float4 wxyz = (1, 2, 3, 4);
Float2 xy = wxyz["xy"];     // x &lt;- x, y &lt;- y
Float2 wz = wxyz["wz"];     // x &lt;- w, y &lt;- z
```

But whatever. You can always stick to using `IEnumerable`s if you want.

## No More `*.Abstract`

I got rid of all the `Abstract` namespaces, since they don't really make much sense in the grand scheme of things. They've all been moved to the namespace that applies to them most (eg. `INumberGroup` went to `Nerd_STF.Mathematics`, `ICombinationIndexer` went to `Nerd_STF` since it applies to more than just mathematics).

## The `Fraction` Type

This type originally went under the name of `Rational` in Nerd_STF 2.x, but that name is actually incorrect, right? So in the rework, it changed names. But it also can do much more now thanks to the `INumber` interface added in .NET 7.0. If you're using that framework or above, the fraction type is fully compatible with that type, and all the math functions in `MathE` and elsewhere that use `INumber` will work with it.

Can I just say that the `INumber` interface is really annoying to write a type for? There's so many weird casting functions and a whole lot of methods that even the .NET developers will hide in public declarations. Why have them at all?

---

And I want to change the name of the `MathE` class. I'm thinking `Math2`, but I'm open to suggestions.

## And Best of All, Matrices

Oh yeah, we're adding those things again. I haven't completed (or even started) the dynamic `Matrix` class, that will arrive in beta3. But I have the `Matrix2x2`, `Matrix3x3`, and `Matrix4x4` fully implemented. The `ToString()` methods are much better with the new implementation than previously, and the `GetHashCode()` methods give different results even if the numbers have their positions swapped (which they originally didn't do).

And it's much faster. Much, much faster. Don't get me wrong, multiplying a 4x4 matrix still requires 64 multiplications and 48 additions, which is quite a lot, but my original implementation was littered with many method calls, easily doubling the runtime. I have now super-inlined basically all of the static matrix code. And I mean, replacing all method calls with nothing but multiplication and addition for things like the determinants, the cofactors, the inverses, and more. Don't look at the source, it's really ugly.

---

That's all the major stuff in this update! I'll see you guys in beta3!

P.S. I know that the System library also includes `Vector2`, `Vector3`, and `Vector4` types. I'll add casting support for them soon.</PackageReleaseNotes>
  </PropertyGroup>

  <!-- ItemGroup customization based on framework. -->
  <!-- Mostly used to reference system packages that are not included in this version of .NET Standard. -->
  <!-- TODO: Maybe this isn't good practice, and we should define environment variables for specific features (tuples, drawing, etc) instead? -->

  <ItemGroup Condition="'$(TargetFramework)'=='netstandard1.1'">
    <PackageReference Include="System.Drawing.Primitives" Version="4.3.0" />
    <PackageReference Include="System.Net.Http" Version="4.3.4" />                <!-- Version that comes with .NET has vulnerabilities. -->
    <PackageReference Include="System.Memory" Version="4.5.5" />                  <!-- Newer versions not supported. -->
    <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />        <!-- Newer versions not supported. -->
    <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> <!-- Version that comes with .NET has vulnerabilities. -->
    <PackageReference Include="System.ValueTuple" Version="4.5.0" />
  </ItemGroup>
  
  <ItemGroup Condition="'$(TargetFramework)'=='netstandard1.3'">
    <PackageReference Include="System.Drawing.Primitives" Version="4.3.0" />
    <PackageReference Include="System.Net.Http" Version="4.3.4" />                <!-- Version that comes with .NET has vulnerabilities. -->
    <PackageReference Include="System.Memory" Version="4.5.5" />                  <!-- Newer versions not supported. -->
    <PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />        <!-- Newer versions not supported. -->
    <PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" /> <!-- Version that comes with .NET has vulnerabilities. -->
    <PackageReference Include="System.ValueTuple" Version="4.5.0" />
  </ItemGroup>
  
  <!-- PropertyGroup customization based on framework. -->
  <!-- Used to define environment variables based on features the framework supports. -->

  <PropertyGroup Condition="'$(TargetFramework)'=='net471'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='netcoreapp3.0'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER;CS8_OR_GREATER</DefineConstants>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='net5.0'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER;CS8_OR_GREATER;CS9_OR_GREATER</DefineConstants>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='net7.0'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER;CS8_OR_GREATER;CS9_OR_GREATER;CS10_OR_GREATER;CS11_OR_GREATER</DefineConstants>
    <Nullable>enable</Nullable>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='netstandard1.1'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='netstandard1.3'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER</DefineConstants>
  </PropertyGroup>

  <PropertyGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
    <DefineConstants>$(DefineConstants);CS7_OR_GREATER;CS8_OR_GREATER</DefineConstants>
    <Nullable>enable</Nullable>
  </PropertyGroup>
  
  <!-- Pack extra stuff into the NuGet package. -->

  <ItemGroup>
    <None Include="..\Extras\Logo Square.png">
      <Pack>True</Pack>
      <PackagePath>\</PackagePath>
    </None>
    <None Include="..\README.md">
      <Pack>True</Pack>
      <PackagePath>\</PackagePath>
    </None>
    <None Include="..\Changelog.md">
      <Pack>True</Pack>
      <PackagePath>\</PackagePath>
    </None>
    <None Include="..\LICENSE.md">
      <Pack>True</Pack>
      <PackagePath>\</PackagePath>
    </None>
  </ItemGroup>

</Project>
