\d+))?" +
+ @"(\-(?[0-9A-Za-z\-\.]+))?" +
+ @"(\+(?[0-9A-Za-z\-\.]+))?$",
+#if NETSTANDARD
+ RegexOptions.CultureInvariant | RegexOptions.ExplicitCapture);
+#else
+ RegexOptions.CultureInvariant | RegexOptions.Compiled | RegexOptions.ExplicitCapture);
+#endif
+
+#if !NETSTANDARD
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ ///
+ ///
+ private SemVersion(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null) throw new ArgumentNullException("info");
+ var semVersion = Parse(info.GetString("SemVersion"));
+ Major = semVersion.Major;
+ Minor = semVersion.Minor;
+ Patch = semVersion.Patch;
+ Prerelease = semVersion.Prerelease;
+ Build = semVersion.Build;
+ }
+#endif
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The major version.
+ /// The minor version.
+ /// The patch version.
+ /// The prerelease version (eg. "alpha").
+ /// The build eg ("nightly.232").
+ public SemVersion(int major, int minor = 0, int patch = 0, string prerelease = "", string build = "")
+ {
+ this.Major = major;
+ this.Minor = minor;
+ this.Patch = patch;
+
+ this.Prerelease = prerelease ?? "";
+ this.Build = build ?? "";
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The that is used to initialize
+ /// the Major, Minor, Patch and Build properties.
+ public SemVersion(Version version)
+ {
+ if (version == null)
+ throw new ArgumentNullException("version");
+
+ this.Major = version.Major;
+ this.Minor = version.Minor;
+
+ if (version.Revision >= 0)
+ {
+ this.Patch = version.Revision;
+ }
+
+ this.Prerelease = String.Empty;
+
+ if (version.Build > 0)
+ {
+ this.Build = version.Build.ToString();
+ }
+ else
+ {
+ this.Build = String.Empty;
+ }
+ }
+
+ ///
+ /// Parses the specified string to a semantic version.
+ ///
+ /// The version string.
+ /// If set to true minor and patch version are required, else they default to 0.
+ /// The SemVersion object.
+ /// When a invalid version string is passed.
+ public static SemVersion Parse(string version, bool strict = false)
+ {
+ var match = parseEx.Match(version);
+ if (!match.Success)
+ throw new ArgumentException("Invalid version.", "version");
+
+#if NETSTANDARD
+ var major = int.Parse(match.Groups["major"].Value);
+#else
+ var major = int.Parse(match.Groups["major"].Value, CultureInfo.InvariantCulture);
+#endif
+
+ var minorMatch = match.Groups["minor"];
+ int minor = 0;
+ if (minorMatch.Success)
+ {
+#if NETSTANDARD
+ minor = int.Parse(minorMatch.Value);
+#else
+ minor = int.Parse(minorMatch.Value, CultureInfo.InvariantCulture);
+#endif
+ }
+ else if (strict)
+ {
+ throw new InvalidOperationException("Invalid version (no minor version given in strict mode)");
+ }
+
+ var patchMatch = match.Groups["patch"];
+ int patch = 0;
+ if (patchMatch.Success)
+ {
+#if NETSTANDARD
+ patch = int.Parse(patchMatch.Value);
+#else
+ patch = int.Parse(patchMatch.Value, CultureInfo.InvariantCulture);
+#endif
+ }
+ else if (strict)
+ {
+ throw new InvalidOperationException("Invalid version (no patch version given in strict mode)");
+ }
+
+ var prerelease = match.Groups["pre"].Value;
+ var build = match.Groups["build"].Value;
+
+ return new SemVersion(major, minor, patch, prerelease, build);
+ }
+
+ ///
+ /// Parses the specified string to a semantic version.
+ ///
+ /// The version string.
+ /// When the method returns, contains a SemVersion instance equivalent
+ /// to the version string passed in, if the version string was valid, or null if the
+ /// version string was not valid.
+ /// If set to true minor and patch version are required, else they default to 0.
+ /// False when a invalid version string is passed, otherwise true.
+ public static bool TryParse(string version, out SemVersion semver, bool strict = false)
+ {
+ try
+ {
+ semver = Parse(version, strict);
+ return true;
+ }
+ catch (Exception)
+ {
+ semver = null;
+ return false;
+ }
+ }
+
+ ///
+ /// Tests the specified versions for equality.
+ ///
+ /// The first version.
+ /// The second version.
+ /// If versionA is equal to versionB true, else false.
+ public static bool Equals(SemVersion versionA, SemVersion versionB)
+ {
+ if (ReferenceEquals(versionA, null))
+ return ReferenceEquals(versionB, null);
+ return versionA.Equals(versionB);
+ }
+
+ ///
+ /// Compares the specified versions.
+ ///
+ /// The version to compare to.
+ /// The version to compare against.
+ /// If versionA < versionB < 0, if versionA > versionB > 0,
+ /// if versionA is equal to versionB 0.
+ public static int Compare(SemVersion versionA, SemVersion versionB)
+ {
+ if (ReferenceEquals(versionA, null))
+ return ReferenceEquals(versionB, null) ? 0 : -1;
+ return versionA.CompareTo(versionB);
+ }
+
+ ///
+ /// Make a copy of the current instance with optional altered fields.
+ ///
+ /// The major version.
+ /// The minor version.
+ /// The patch version.
+ /// The prerelease text.
+ /// The build text.
+ /// The new version object.
+ public SemVersion Change(int? major = null, int? minor = null, int? patch = null,
+ string prerelease = null, string build = null)
+ {
+ return new SemVersion(
+ major ?? this.Major,
+ minor ?? this.Minor,
+ patch ?? this.Patch,
+ prerelease ?? this.Prerelease,
+ build ?? this.Build);
+ }
+
+ ///
+ /// Gets the major version.
+ ///
+ ///
+ /// The major version.
+ ///
+ public int Major { get; private set; }
+
+ ///
+ /// Gets the minor version.
+ ///
+ ///
+ /// The minor version.
+ ///
+ public int Minor { get; private set; }
+
+ ///
+ /// Gets the patch version.
+ ///
+ ///
+ /// The patch version.
+ ///
+ public int Patch { get; private set; }
+
+ ///
+ /// Gets the pre-release version.
+ ///
+ ///
+ /// The pre-release version.
+ ///
+ public string Prerelease { get; private set; }
+
+ ///
+ /// Gets the build version.
+ ///
+ ///
+ /// The build version.
+ ///
+ public string Build { get; private set; }
+
+ ///
+ /// Returns a that represents this instance.
+ ///
+ ///
+ /// A that represents this instance.
+ ///
+ public override string ToString()
+ {
+ var version = "" + Major + "." + Minor + "." + Patch;
+ if (!String.IsNullOrEmpty(Prerelease))
+ version += "-" + Prerelease;
+ if (!String.IsNullOrEmpty(Build))
+ version += "+" + Build;
+ return version;
+ }
+
+ ///
+ /// Compares the current instance with another object of the same type and returns an integer that indicates
+ /// whether the current instance precedes, follows, or occurs in the same position in the sort order as the
+ /// other object.
+ ///
+ /// An object to compare with this instance.
+ ///
+ /// A value that indicates the relative order of the objects being compared.
+ /// The return value has these meanings: Value Meaning Less than zero
+ /// This instance precedes in the sort order.
+ /// Zero This instance occurs in the same position in the sort order as . i
+ /// Greater than zero This instance follows in the sort order.
+ ///
+ public int CompareTo(object obj)
+ {
+ return CompareTo((SemVersion)obj);
+ }
+
+ ///
+ /// Compares the current instance with another object of the same type and returns an integer that indicates
+ /// whether the current instance precedes, follows, or occurs in the same position in the sort order as the
+ /// other object.
+ ///
+ /// An object to compare with this instance.
+ ///
+ /// A value that indicates the relative order of the objects being compared.
+ /// The return value has these meanings: Value Meaning Less than zero
+ /// This instance precedes in the sort order.
+ /// Zero This instance occurs in the same position in the sort order as . i
+ /// Greater than zero This instance follows in the sort order.
+ ///
+ public int CompareTo(SemVersion other)
+ {
+ if (ReferenceEquals(other, null))
+ return 1;
+
+ var r = this.CompareByPrecedence(other);
+ if (r != 0)
+ return r;
+
+ r = CompareComponent(this.Build, other.Build);
+ return r;
+ }
+
+ ///
+ /// Compares to semantic versions by precedence. This does the same as a Equals, but ignores the build information.
+ ///
+ /// The semantic version.
+ /// true if the version precedence matches.
+ public bool PrecedenceMatches(SemVersion other)
+ {
+ return CompareByPrecedence(other) == 0;
+ }
+
+ ///
+ /// Compares to semantic versions by precedence. This does the same as a Equals, but ignores the build information.
+ ///
+ /// The semantic version.
+ ///
+ /// A value that indicates the relative order of the objects being compared.
+ /// The return value has these meanings: Value Meaning Less than zero
+ /// This instance precedes in the version precedence.
+ /// Zero This instance has the same precedence as . i
+ /// Greater than zero This instance has creater precedence as .
+ ///
+ public int CompareByPrecedence(SemVersion other)
+ {
+ if (ReferenceEquals(other, null))
+ return 1;
+
+ var r = this.Major.CompareTo(other.Major);
+ if (r != 0) return r;
+
+ r = this.Minor.CompareTo(other.Minor);
+ if (r != 0) return r;
+
+ r = this.Patch.CompareTo(other.Patch);
+ if (r != 0) return r;
+
+ r = CompareComponent(this.Prerelease, other.Prerelease, true);
+ return r;
+ }
+
+ static int CompareComponent(string a, string b, bool lower = false)
+ {
+ var aEmpty = String.IsNullOrEmpty(a);
+ var bEmpty = String.IsNullOrEmpty(b);
+ if (aEmpty && bEmpty)
+ return 0;
+
+ if (aEmpty)
+ return lower ? 1 : -1;
+ if (bEmpty)
+ return lower ? -1 : 1;
+
+ var aComps = a.Split('.');
+ var bComps = b.Split('.');
+
+ var minLen = Math.Min(aComps.Length, bComps.Length);
+ for (int i = 0; i < minLen; i++)
+ {
+ var ac = aComps[i];
+ var bc = bComps[i];
+ int anum, bnum;
+ var isanum = Int32.TryParse(ac, out anum);
+ var isbnum = Int32.TryParse(bc, out bnum);
+ int r;
+ if (isanum && isbnum)
+ {
+ r = anum.CompareTo(bnum);
+ if (r != 0) return anum.CompareTo(bnum);
+ }
+ else
+ {
+ if (isanum)
+ return -1;
+ if (isbnum)
+ return 1;
+ r = String.CompareOrdinal(ac, bc);
+ if (r != 0)
+ return r;
+ }
+ }
+
+ return aComps.Length.CompareTo(bComps.Length);
+ }
+
+ ///
+ /// Determines whether the specified is equal to this instance.
+ ///
+ /// The to compare with this instance.
+ ///
+ /// true if the specified is equal to this instance; otherwise, false.
+ ///
+ public override bool Equals(object obj)
+ {
+ if (ReferenceEquals(obj, null))
+ return false;
+
+ if (ReferenceEquals(this, obj))
+ return true;
+
+ var other = (SemVersion)obj;
+
+ return this.Major == other.Major &&
+ this.Minor == other.Minor &&
+ this.Patch == other.Patch &&
+ string.Equals(this.Prerelease, other.Prerelease, StringComparison.Ordinal) &&
+ string.Equals(this.Build, other.Build, StringComparison.Ordinal);
+ }
+
+ ///
+ /// Returns a hash code for this instance.
+ ///
+ ///
+ /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
+ ///
+ public override int GetHashCode()
+ {
+ unchecked
+ {
+ int result = this.Major.GetHashCode();
+ result = result * 31 + this.Minor.GetHashCode();
+ result = result * 31 + this.Patch.GetHashCode();
+ result = result * 31 + this.Prerelease.GetHashCode();
+ result = result * 31 + this.Build.GetHashCode();
+ return result;
+ }
+ }
+
+#if !NETSTANDARD
+ [SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
+ public void GetObjectData(SerializationInfo info, StreamingContext context)
+ {
+ if (info == null) throw new ArgumentNullException("info");
+ info.AddValue("SemVersion", ToString());
+ }
+#endif
+
+ ///
+ /// Implicit conversion from string to SemVersion.
+ ///
+ /// The semantic version.
+ /// The SemVersion object.
+ public static implicit operator SemVersion(string version)
+ {
+ return SemVersion.Parse(version);
+ }
+
+ ///
+ /// The override of the equals operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is equal to right true, else false.
+ public static bool operator ==(SemVersion left, SemVersion right)
+ {
+ return SemVersion.Equals(left, right);
+ }
+
+ ///
+ /// The override of the un-equal operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is not equal to right true, else false.
+ public static bool operator !=(SemVersion left, SemVersion right)
+ {
+ return !SemVersion.Equals(left, right);
+ }
+
+ ///
+ /// The override of the greater operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is greater than right true, else false.
+ public static bool operator >(SemVersion left, SemVersion right)
+ {
+ return SemVersion.Compare(left, right) > 0;
+ }
+
+ ///
+ /// The override of the greater than or equal operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is greater than or equal to right true, else false.
+ public static bool operator >=(SemVersion left, SemVersion right)
+ {
+ return left == right || left > right;
+ }
+
+ ///
+ /// The override of the less operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is less than right true, else false.
+ public static bool operator <(SemVersion left, SemVersion right)
+ {
+ return SemVersion.Compare(left, right) < 0;
+ }
+
+ ///
+ /// The override of the less than or equal operator.
+ ///
+ /// The left value.
+ /// The right value.
+ /// If left is less than or equal to right true, else false.
+ public static bool operator <=(SemVersion left, SemVersion right)
+ {
+ return left == right || left < right;
+ }
+ }
+}
diff --git a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
index 23ae8cebe0..d2a210cda4 100644
--- a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
+++ b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
@@ -4,8 +4,4 @@
netstandard2.0
-
-
-
-
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 2a4a3683cc..91f85b853f 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -81,7 +81,6 @@
-
2.8.0
diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj
index 7b757cdf3e..2eaf4a4744 100755
--- a/src/Umbraco.Web/Umbraco.Web.csproj
+++ b/src/Umbraco.Web/Umbraco.Web.csproj
@@ -83,7 +83,6 @@
-
1.0.5