13 Commits

Author SHA1 Message Date
Kievits Rene
592d5bb59e Merge pull request #22 from Crylia/feature/client-socket
Feature/client socket
2021-10-19 03:20:30 +02:00
Rene Schwarz
c3e28df8f9 fix the annoying hover glitch on create new module form close button and resource lookup error 2021-08-11 00:50:54 +02:00
Rene Schwarz
c86b1bc7c4 Change all icons to <Path>'s with google material icons; finish navigation bar styling and function 2021-08-10 22:41:27 +02:00
Rene Schwarz
910383775b add resharper and hover effect for modules; change navigation bar 2021-08-10 02:03:11 +02:00
Rene Schwarz
cdb86331e5 add auto module fetch on startup and finished module creation form for real now 2021-08-09 15:08:26 +02:00
Kievits Rene
f1f717a37f Merge pull request #18 from Crylia/feature/modules
finish create module form
2021-08-09 00:31:08 +02:00
Rene Schwarz
a4a944f0c6 finish create module form 2021-08-09 00:26:03 +02:00
Rene Schwarz
f8f28984a5 Added a socket client 2021-08-07 01:01:17 +02:00
Kievits Rene
58524a9514 Merge pull request #15 from Crylia/feature/cleanup-code_document-code
Issue #5
2021-08-06 12:39:12 +02:00
Rene Schwarz
4828f95ebb Issue #5 2021-08-06 12:35:46 +02:00
Kievits Rene
2240d30570 Merge pull request #14 from Crylia/feature/login
Feature/login
2021-08-06 10:42:28 +02:00
Rene Schwarz
08d08280b9 Paused autologin for now, pick up later 2021-08-06 10:40:08 +02:00
Rene Schwarz
f306e329ae changed database and implemented passwordless login 2021-08-05 22:13:45 +02:00
156 changed files with 4103 additions and 2431 deletions

Binary file not shown.

View File

@@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server_Dashboard_Socket {
/// <summary>
/// Client Socket
/// </summary>
/// <typeparam name="TProtocol">The Protocol type, either JsonMessageProtocol or XmlMessageProtocol</typeparam>
/// <typeparam name="TMessageType">The message type, either JObject or XDocument</typeparam>
public class ClientChannel<TProtocol, TMessageType> : SocketChannel<TProtocol, TMessageType>
where TProtocol : Protocol<TMessageType>, new() {
/// <summary>
/// Connect to the socket async
/// </summary>
/// <param name="endpoint">An endpoint with an IP address and port</param>
/// <returns></returns>
public async Task ConnectAsync(IPEndPoint endpoint) {
//Creates a new Socket
var socket = new Socket(endpoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
//Connects to the socket
await socket.ConnectAsync(endpoint).ConfigureAwait(false);
//Attach the socket to a network stream
Attach(socket);
}
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace Server_Dashboard_Socket {
/// <summary>
/// Generic Channel class that handles the connection and message sending / receiving
/// Inherits IDisposable to correctly cut the connection to the server
/// </summary>
/// <typeparam name="TProtocol">The Protocol type, either JsonMessageProtocol or XmlMessageProtocol</typeparam>
/// <typeparam name="TMessageType">The message type, either JObject or XDocument</typeparam>
public abstract class SocketChannel<TProtocol, TMessageType> : IDisposable
where TProtocol : Protocol<TMessageType>, new() {
protected bool isDisposable = false;
private NetworkStream networkStream;
private readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
private readonly TProtocol protocol = new TProtocol();
private Func<TMessageType, Task> messageCallback;
/// <summary>
/// Attaches the socket to a network stream that owns the socket
/// if the network stream goes down it takes the socket with it!
/// </summary>
/// <param name="socket">A Socket</param>
public void Attach(Socket socket) {
networkStream = new NetworkStream(socket, true);
_ = Task.Run(ReceiveLoop, cancellationTokenSource.Token);
}
/// <summary>
/// Takes a function with a message and sets the private member to the functions value
/// </summary>
/// <param name="callbackHandler"></param>
public void OnMessage(Func<TMessageType, Task> callbackHandler) => messageCallback = callbackHandler;
/// <summary>
/// Makes sure to close the socket
/// </summary>
public void Close() {
cancellationTokenSource.Cancel();
networkStream?.Close();
}
/// <summary>
/// Sends the message async
/// </summary>
/// <typeparam name="T">Anything as message, e.g. object or string</typeparam>
/// <param name="message">The message</param>
/// <returns></returns>
public async Task SendAsync<T>(T message) => await protocol.SendAsync(networkStream, message).ConfigureAwait(false);
/// <summary>
/// Checks for received messages
/// </summary>
/// <returns>received message</returns>
protected virtual async Task ReceiveLoop() {
while (!cancellationTokenSource.Token.IsCancellationRequested) {
var msg = await protocol.ReceiveAsync(networkStream).ConfigureAwait(false);
await messageCallback(msg).ConfigureAwait(false);
}
}
/// <summary>
/// Deconstructor sets Dispose to false
/// </summary>
~SocketChannel() => Dispose(false);
/// <summary>
/// Sets dispose to true
/// </summary>
public void Dispose() => Dispose(true);
/// <summary>
/// Disposes open sockets
/// </summary>
/// <param name="isDisposing">Is it currently disposing stuff?</param>
protected void Dispose(bool isDisposing) {
//If its not disposable
if (!isDisposable) {
//Set disposable to true
isDisposable = true;
//Close the socket
Close();
//If its closed, dispose it
networkStream?.Dispose();
//Wait with the garbage collection until the disposing is done
if (isDisposing)
GC.SuppressFinalize(this);
}
}
}
}

View File

@@ -0,0 +1,92 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading.Tasks;
using System.IO;
using System.Xml.Serialization;
using Server_Dashboard_Socket.Protocol;
using Newtonsoft.Json.Linq;
using System.Xml.Linq;
namespace Server_Dashboard_Socket {
public class SocketClient {
public SocketClient() {
//Starts the echo server for testing purposes
EchoServer echoServer = new EchoServer();
echoServer.Start();
//Start the Socket test
Start();
}
private async void Start() {
//Creates a new endpoint with the IP address and port
var endpoint = new IPEndPoint(IPAddress.Loopback, 9000);
//Creates a new Channel for the Json protocol
var channel = new ClientChannel<JsonMessageProtocol, JObject>();
//Creates a new Channel for the XDocument protocol
//var channel = new ClientChannel<XmlMessageProtocol, XDocument>();
//Callback for the message
channel.OnMessage(OnMessage);
//Connect to the Socket
await channel.ConnectAsync(endpoint).ConfigureAwait(false);
//Test message
var myMessage = new MyMessage {
IntProperty = 404,
StringProperty = "Hello World!"
};
//Send the test message
await channel.SendAsync(myMessage).ConfigureAwait(false);
}
/// <summary>
/// When it receives a message it gets converted from Json back to MyMessage
/// </summary>
/// <param name="jobject">The json to be converted back</param>
/// <returns>Task completed</returns>
private static Task OnMessage(JObject jobject) {
Console.WriteLine(Convert(jobject));
return Task.CompletedTask;
}
/// <summary>
/// When it receives a message it gets converted from XDocument back to MyMessage
/// </summary>
/// <param name="xDocument">The xml to be converted back</param>
/// <returns>Task completed</returns>
private static Task OnMessage(XDocument xDocument) {
Console.WriteLine(Convert(xDocument));
return Task.CompletedTask;
}
/// <summary>
/// Converts json to MyMessage
/// </summary>
/// <param name="jObject">The json to be converted</param>
/// <returns>MyMessage object</returns>
private static MyMessage Convert(JObject jObject) => jObject.ToObject(typeof(MyMessage)) as MyMessage;
/// <summary>
/// Converts XDocument to MyMessage
/// </summary>
/// <param name="xmlDocument">The xml to be converted</param>
/// <returns>MyMessage object</returns>
private static MyMessage Convert(XDocument xmlDocument) => new XmlSerializer(typeof(MyMessage)).Deserialize(new StringReader(xmlDocument.ToString())) as MyMessage;
}
/// <summary>
/// MyMessage test class
/// Delete later when Sockets are finished
/// </summary>
public class MyMessage {
public int IntProperty { get; set; }
public string StringProperty { get; set; }
}
}

View File

@@ -4,31 +4,56 @@ using System.Net.Sockets;
using System.Threading.Tasks; using System.Threading.Tasks;
namespace Server_Dashboard_Socket { namespace Server_Dashboard_Socket {
/// <summary>
/// Basic echo server to test the socket connection
/// </summary>
public class EchoServer { public class EchoServer {
public void Start(int port = 9565) {
/// <summary>
/// Start the socket on 127.0.0.1:9000
/// </summary>
/// <param name="port">A port that is not already in use</param>
public void Start(int port = 9000) {
//Creates a new endpoint on 127.0.0.1 and the port 9000
IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, port); IPEndPoint endPoint = new IPEndPoint(IPAddress.Loopback, port);
//Creates a new Socket on the given endpoint
Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp); Socket socket = new Socket(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
//Bind the endpoint to the socket
socket.Bind(endPoint); socket.Bind(endPoint);
//Define how many Clients you want to have connected max
socket.Listen(128); socket.Listen(128);
//Just run the Task forever
_ = Task.Run(() => DoEcho(socket)); _ = Task.Run(() => DoEcho(socket));
} }
/// <summary>
/// Listens for messages and sends them back asap
/// </summary>
/// <param name="socket">The socket to work with</param>
/// <returns>poop</returns>
private async Task DoEcho(Socket socket) { private async Task DoEcho(Socket socket) {
while (true) { while (true) {
//Listen for incoming connection requests and accept them
Socket clientSocket = await Task.Factory.FromAsync( Socket clientSocket = await Task.Factory.FromAsync(
new Func<AsyncCallback, object, IAsyncResult>(socket.BeginAccept), new Func<AsyncCallback, object, IAsyncResult>(socket.BeginAccept),
new Func<IAsyncResult, Socket>(socket.EndAccept), new Func<IAsyncResult, Socket>(socket.EndAccept),
null).ConfigureAwait(false); null).ConfigureAwait(false);
using(NetworkStream stream = new NetworkStream(clientSocket, true)) { //Create a network stream and make it the owner of the socket
byte[] buffer = new byte[1024]; //This will close the socket if the stream is closed and vice verca
while (true) { await using NetworkStream stream = new NetworkStream(clientSocket, true);
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false); //New buffer for the message in bytes
if (bytesRead == 0) byte[] buffer = new byte[1024];
break; while (true) {
await stream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false); //Read everything that comes in
} int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);
//If its 0 just leave since its a obsolete connection
if (bytesRead == 0)
break;
//Send it back to the sender
await stream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
} }
} }
} }
} }
} }

View File

@@ -0,0 +1,54 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
namespace Server_Dashboard_Socket.Protocol {
/// <summary>
/// Json serializer class
/// </summary>
public class JsonMessageProtocol : Protocol<JObject> {
//The Json serializer and the settings
private static readonly JsonSerializer serializer;
/// <summary>
/// Settings for the Json Serializer
/// </summary>
static JsonMessageProtocol() {
//Set the settings
JsonSerializerSettings settings = new JsonSerializerSettings {
Formatting = Formatting.Indented,
DateTimeZoneHandling = DateTimeZoneHandling.Utc,
ContractResolver = new DefaultContractResolver {
NamingStrategy = new CamelCaseNamingStrategy {
ProcessDictionaryKeys = false
}
}
};
settings.PreserveReferencesHandling = PreserveReferencesHandling.None;
//Creates the serializer with the settings
serializer = JsonSerializer.Create(settings);
}
//Decode the message, to Json
protected override JObject Decode(byte[] message) => JObject.Parse(Encoding.UTF8.GetString(message));
/// <summary>
/// Encode the body from Json to bytes
/// </summary>
/// <typeparam name="T">The message type e.g. object or string</typeparam>
/// <param name="message">The message to send</param>
/// <returns>message as byte[]</returns>
protected override byte[] EncodeBody<T>(T message) {
var sb = new StringBuilder();
var sw = new StringWriter(sb);
serializer.Serialize(sw, message);
return Encoding.UTF8.GetBytes(sb.ToString());
}
}
}

View File

@@ -0,0 +1,135 @@
using System;
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace Server_Dashboard_Socket {
/// <summary>
/// Generic Protocol class for Json and Xml serialization
/// </summary>
/// <typeparam name="TMessageType">JsonMessageProtocol or XmlMessageProtocol</typeparam>
public abstract class Protocol<TMessageType> {
//Header size is always 4
private const int HeaderSize = 4;
/// <summary>
/// Gets the message and checks with the header if the message is valid or not
/// important to defend against attacks with infinite long messages
/// </summary>
/// <param name="networkStream">A network stream</param>
/// <returns>MessageType e.g. Json or Xml</returns>
public async Task<TMessageType> ReceiveAsync(NetworkStream networkStream) {
//Gets the body length
int bodyLength = await ReadHeader(networkStream).ConfigureAwait(false);
//Validates the length
AssertValidMessageLength(bodyLength);
//Returns the body message type
return await ReadBody(networkStream, bodyLength).ConfigureAwait(false);
}
/// <summary>
/// Sends data Async
/// </summary>
/// <typeparam name="T">Message type e.g. object or string</typeparam>
/// <param name="networkStream">Network stream</param>
/// <param name="message">The message</param>
/// <returns></returns>
public async Task SendAsync<T>(NetworkStream networkStream, T message) {
//encodes the message to a header and body
var (header, body) = Encode(message);
//Sends the header
await networkStream.WriteAsync(header, 0, header.Length).ConfigureAwait(false);
//Sends the body
await networkStream.WriteAsync(body, 0, body.Length).ConfigureAwait(false);
}
/// <summary>
/// Reads the header and converts it to an integer
/// </summary>
/// <param name="networkStream">A network stream</param>
/// <returns>Header as Integer</returns>
private async Task<int> ReadHeader(NetworkStream networkStream) {
byte[] headerBytes = await ReadAsync(networkStream, HeaderSize).ConfigureAwait(false);
return IPAddress.HostToNetworkOrder(BitConverter.ToInt32(headerBytes));
}
/// <summary>
/// Reads the body and decodes it to a human readable string
/// </summary>
/// <param name="networkStream">A network stream</param>
/// <param name="bodyLength">Length of the body</param>
/// <returns>Decoded body</returns>
private async Task<TMessageType> ReadBody(NetworkStream networkStream, int bodyLength) {
//Reads the bytes from the stream into an array
byte[] bodyBytes = await ReadAsync(networkStream, bodyLength).ConfigureAwait(false);
//Decodes it and returns the string
return Decode(bodyBytes);
}
/// <summary>
/// Reads the network stream as long as something is readable
/// </summary>
/// <param name="networkStream">A network stream</param>
/// <param name="bytesToRead">how many bytes there are to read</param>
/// <returns>Every byte from the Stream</returns>
private async Task<byte[]> ReadAsync(NetworkStream networkStream, int bytesToRead) {
//new buffer that is as big as the content(watch out for buffer overflows)
byte[] buffer = new byte[bytesToRead];
//keep account of the bytes that are already read
int bytesRead = 0;
//White we still have something to read
while (bytesRead < bytesToRead) {
//Read it from the stream
var bytesReceived = await networkStream.ReadAsync(buffer, bytesRead, (bytesToRead - bytesRead)).ConfigureAwait(false);
//If it happens to be 0 close the socket
if (bytesReceived == 0)
throw new Exception("Socket Closed");
bytesRead += bytesReceived;
}
return buffer;
}
/// <summary>
/// Encode the message from human readable to bytes for the stream
/// </summary>
/// <typeparam name="T">The message as anything e.g. object or string</typeparam>
/// <param name="message">The message to be send</param>
/// <returns>The Header and Body as bytes[]</returns>
protected (byte[] header, byte[] body) Encode<T>(T message) {
//Creates the body bytes
var bodyBytes = EncodeBody(message);
//Creates the header bytes
var headerBytes = BitConverter.GetBytes(IPAddress.HostToNetworkOrder(bodyBytes.Length));
return (headerBytes, bodyBytes);
}
/// <summary>
/// Decode the message with the given type, json or xml
/// </summary>
/// <param name="message">The message to decode</param>
/// <returns>Decoded message</returns>
protected abstract TMessageType Decode(byte[] message);
/// <summary>
/// Validate the message length to combat attacks
/// </summary>
/// <param name="messageLength">The message length</param>
protected virtual void AssertValidMessageLength(int messageLength) {
//If its not 0 throw an exception
if (messageLength < 1)
throw new ArgumentOutOfRangeException("Invalid message length");
}
/// <summary>
/// Encode the message so it can be send via the network stream
/// </summary>
/// <typeparam name="T">Message type e.g. object or string</typeparam>
/// <param name="message">The message to be send</param>
/// <returns></returns>
protected abstract byte[] EncodeBody<T>(T message);
}
}

View File

@@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Serialization;
namespace Server_Dashboard_Socket {
/// <summary>
/// Xml serialize class
/// </summary>
public class XmlMessageProtocol : Protocol<XDocument> {
/// <summary>
/// Decodes the message from byte[] to XDocument
/// </summary>
/// <param name="message">The message to decode</param>
/// <returns>Message as XDocument</returns>
protected override XDocument Decode(byte[] message) {
//Reads the data as utf8 string
var xmlData = Encoding.UTF8.GetString(message);
//Creates a new reader
var xmlReader = XmlReader.Create(new StringReader(xmlData), new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore });
//Decodes the data to XDocument format
return XDocument.Load(xmlReader);
}
/// <summary>
/// Encode the XDocument to byte[]
/// </summary>
/// <typeparam name="T">Message type e.g. object or string</typeparam>
/// <param name="message">The message to encode</param>
/// <returns>Message as byte[]</returns>
protected override byte[] EncodeBody<T>(T message) {
//new string builder
StringBuilder sb = new StringBuilder();
//New string writer with the string builder
StringWriter sw = new StringWriter(sb);
//new xml serializer with the same type as the message
XmlSerializer xs = new XmlSerializer(typeof(T));
//Serialize the message to a regular string
xs.Serialize(sw, message);
//Return as UTF8 encoded byte array
return Encoding.UTF8.GetBytes(sb.ToString());
}
}
}

View File

@@ -5,4 +5,8 @@
<RootNamespace>Server_Dashboard_Socket</RootNamespace> <RootNamespace>Server_Dashboard_Socket</RootNamespace>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project> </Project>

View File

@@ -7,9 +7,20 @@
"targets": { "targets": {
".NETCoreApp,Version=v3.1": { ".NETCoreApp,Version=v3.1": {
"Server Dashboard Socket/1.0.0": { "Server Dashboard Socket/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.1"
},
"runtime": { "runtime": {
"Server Dashboard Socket.dll": {} "Server Dashboard Socket.dll": {}
} }
},
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.1.25517"
}
}
} }
} }
}, },
@@ -18,6 +29,13 @@
"type": "project", "type": "project",
"serviceable": false, "serviceable": false,
"sha512": "" "sha512": ""
},
"Newtonsoft.Json/13.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
"path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
} }
} }
} }

View File

@@ -1 +1 @@
40cb88c995736b43b2440aaa34383fa2c95563ea 8966ab4db41ed1e711f8adec4e833a86df6a665c

View File

@@ -6,3 +6,4 @@ C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug
C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.csproj.CoreCompileInputs.cache C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.csproj.CoreCompileInputs.cache
C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.dll C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.dll
C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.pdb C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.pdb
C:\Users\Crylia\Documents\Git\Server Dashboard\Server Dashboard Socket\obj\Debug\netcoreapp3.1\Server Dashboard Socket.csprojAssemblyReference.cache

View File

@@ -43,6 +43,12 @@
"frameworks": { "frameworks": {
"netcoreapp3.1": { "netcoreapp3.1": {
"targetAlias": "netcoreapp3.1", "targetAlias": "netcoreapp3.1",
"dependencies": {
"Newtonsoft.Json": {
"target": "Package",
"version": "[13.0.1, )"
}
},
"imports": [ "imports": [
"net461", "net461",
"net462", "net462",

View File

@@ -1,11 +1,51 @@
{ {
"version": 3, "version": 3,
"targets": { "targets": {
".NETCoreApp,Version=v3.1": {} ".NETCoreApp,Version=v3.1": {
"Newtonsoft.Json/13.0.1": {
"type": "package",
"compile": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {}
},
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {}
}
}
}
},
"libraries": {
"Newtonsoft.Json/13.0.1": {
"sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
"type": "package",
"path": "newtonsoft.json/13.0.1",
"files": [
".nupkg.metadata",
".signature.p7s",
"LICENSE.md",
"lib/net20/Newtonsoft.Json.dll",
"lib/net20/Newtonsoft.Json.xml",
"lib/net35/Newtonsoft.Json.dll",
"lib/net35/Newtonsoft.Json.xml",
"lib/net40/Newtonsoft.Json.dll",
"lib/net40/Newtonsoft.Json.xml",
"lib/net45/Newtonsoft.Json.dll",
"lib/net45/Newtonsoft.Json.xml",
"lib/netstandard1.0/Newtonsoft.Json.dll",
"lib/netstandard1.0/Newtonsoft.Json.xml",
"lib/netstandard1.3/Newtonsoft.Json.dll",
"lib/netstandard1.3/Newtonsoft.Json.xml",
"lib/netstandard2.0/Newtonsoft.Json.dll",
"lib/netstandard2.0/Newtonsoft.Json.xml",
"newtonsoft.json.13.0.1.nupkg.sha512",
"newtonsoft.json.nuspec",
"packageIcon.png"
]
}
}, },
"libraries": {},
"projectFileDependencyGroups": { "projectFileDependencyGroups": {
".NETCoreApp,Version=v3.1": [] ".NETCoreApp,Version=v3.1": [
"Newtonsoft.Json >= 13.0.1"
]
}, },
"packageFolders": { "packageFolders": {
"C:\\Users\\Crylia\\.nuget\\packages\\": {}, "C:\\Users\\Crylia\\.nuget\\packages\\": {},
@@ -50,6 +90,12 @@
"frameworks": { "frameworks": {
"netcoreapp3.1": { "netcoreapp3.1": {
"targetAlias": "netcoreapp3.1", "targetAlias": "netcoreapp3.1",
"dependencies": {
"Newtonsoft.Json": {
"target": "Package",
"version": "[13.0.1, )"
}
},
"imports": [ "imports": [
"net461", "net461",
"net462", "net462",

View File

@@ -1,8 +1,10 @@
{ {
"version": 2, "version": 2,
"dgSpecHash": "TThsag+xtSY7ctBsPwAhUX7uLjuhld1ipCW1nP987HRzxMfYvczqncYfdca/U4IfbiniWP3eJFeh7yA09+/gGA==", "dgSpecHash": "l9ApM4rx/nIquK7TUSE2VVfvhwnQ4+tycTwd5vMzM9v+MhFzGIKE8eVwCEj+r8Oe9Orh3cE/LeZlJ+t9G9ZaSg==",
"success": true, "success": true,
"projectFilePath": "C:\\Users\\Crylia\\Documents\\Git\\Server Dashboard\\Server Dashboard Socket\\Server Dashboard Socket.csproj", "projectFilePath": "C:\\Users\\Crylia\\Documents\\Git\\Server Dashboard\\Server Dashboard Socket\\Server Dashboard Socket.csproj",
"expectedPackageFiles": [], "expectedPackageFiles": [
"C:\\Users\\Crylia\\.nuget\\packages\\newtonsoft.json\\13.0.1\\newtonsoft.json.13.0.1.nupkg.sha512"
],
"logs": [] "logs": []
} }

View File

@@ -4,23 +4,31 @@
xmlns:local="clr-namespace:Server_Dashboard" xmlns:local="clr-namespace:Server_Dashboard"
xmlns:views="clr-namespace:Server_Dashboard.Views.DashboardPages" xmlns:views="clr-namespace:Server_Dashboard.Views.DashboardPages"
xmlns:modulescrud="clr-namespace:Server_Dashboard.Views.DashboardPages.ModuleCRUD" xmlns:modulescrud="clr-namespace:Server_Dashboard.Views.DashboardPages.ModuleCRUD"
xmlns:dashboardviews="clr-namespace:Server_Dashboard.Views.Dashboard"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
StartupUri="LoginWindow.xaml"> StartupUri="LoginWindow.xaml">
<Application.Resources> <Application.Resources>
<!--View Templates--> <!--View Templates-->
<DataTemplate x:Key="MainDashboardView" DataType="{x:Type local:DashboardViewModel}"> <DataTemplate DataType="{x:Type local:DashboardViewModel}">
<views:MainDashboardPage/> <views:MainDashboardPage />
</DataTemplate>
<DataTemplate DataType="{x:Type local:AnalyticsViewModel}">
<dashboardviews:AnalyticsPage />
</DataTemplate>
<DataTemplate DataType="{x:Type local:SettingsViewModel}">
<dashboardviews:SettingsPage />
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="CreateModuleView" DataType="{x:Type local:DashboardViewModel}"> <DataTemplate x:Key="CreateModuleView" DataType="{x:Type local:DashboardViewModel}">
<modulescrud:CreateModulePopup/> <modulescrud:CreateModulePopup />
</DataTemplate> </DataTemplate>
<!--Visibility converter for the login inputs--> <!--Visibility converter for the login inputs-->
<BooleanToVisibilityConverter x:Key="UserNameVisibillity"/> <BooleanToVisibilityConverter x:Key="UserNameVisibillity" />
<BooleanToVisibilityConverter x:Key="PasswordVisibillity"/> <BooleanToVisibilityConverter x:Key="PasswordVisibillity" />
<!--Fonts--> <!--Fonts-->
<FontFamily x:Key="Fontstyle" >Open Sans</FontFamily> <FontFamily x:Key="Fontstyle" >Open Sans</FontFamily>
<!--#region Colors--> <!--#region Colors-->
<!-- <!--
Material Rules: Material Rules:
@@ -41,129 +49,136 @@
Dragged = Overlay 8% + Shadow 08dp Dragged = Overlay 8% + Shadow 08dp
--> -->
<!--Material Colors--> <!--Material Colors-->
<SolidColorBrush x:Key="BackgroundSurface_00dp" Color="#121212"/> <SolidColorBrush x:Key="BackgroundSurface_00dp" Color="#121212" />
<SolidColorBrush x:Key="BackgroundSurface_01dp" Color="#1D1D1D"/> <SolidColorBrush x:Key="BackgroundSurface_01dp" Color="#1D1D1D" />
<SolidColorBrush x:Key="BackgroundSurface_02dp" Color="#202020"/> <SolidColorBrush x:Key="BackgroundSurface_02dp" Color="#202020" />
<SolidColorBrush x:Key="BackgroundSurface_03dp" Color="#252525"/> <SolidColorBrush x:Key="BackgroundSurface_03dp" Color="#252525" />
<SolidColorBrush x:Key="BackgroundSurface_04dp" Color="#262626"/> <SolidColorBrush x:Key="BackgroundSurface_04dp" Color="#262626" />
<SolidColorBrush x:Key="BackgroundSurface_06dp" Color="#2C2C2C"/> <SolidColorBrush x:Key="BackgroundSurface_06dp" Color="#2C2C2C" />
<SolidColorBrush x:Key="BackgroundSurface_08dp" Color="#2D2D2D"/> <SolidColorBrush x:Key="BackgroundSurface_08dp" Color="#2D2D2D" />
<SolidColorBrush x:Key="BackgroundSurface_12dp" Color="#323232"/> <SolidColorBrush x:Key="BackgroundSurface_12dp" Color="#323232" />
<SolidColorBrush x:Key="BackgroundSurface_16dp" Color="#343434"/> <SolidColorBrush x:Key="BackgroundSurface_16dp" Color="#343434" />
<SolidColorBrush x:Key="BackgroundSurface_24dp" Color="#363636"/> <SolidColorBrush x:Key="BackgroundSurface_24dp" Color="#363636" />
<SolidColorBrush x:Key="OnPrimarySecondaryError" Color="#000000"/> <SolidColorBrush x:Key="OnPrimarySecondaryError" Color="#000000" />
<SolidColorBrush x:Key="White" Color="#FFFFFFFF"/><!--0%--> <SolidColorBrush x:Key="White" Color="#FFFFFFFF" />
<SolidColorBrush x:Key="White12" Color="#1EFFFFFF"/><!--12%--> <!--0%-->
<SolidColorBrush x:Key="White38" Color="#60FFFFFF"/><!--38%--> <SolidColorBrush x:Key="White12" Color="#1EFFFFFF" />
<SolidColorBrush x:Key="White60" Color="#99FFFFFF"/><!--60%--> <!--12%-->
<SolidColorBrush x:Key="White87" Color="#DEFFFFFF"/><!--87%--> <SolidColorBrush x:Key="White38" Color="#60FFFFFF" />
<SolidColorBrush x:Key="ErrorRed" Color="#CF6679"/> <!--38%-->
<SolidColorBrush x:Key="White60" Color="#99FFFFFF" />
<!--60%-->
<SolidColorBrush x:Key="White87" Color="#DEFFFFFF" />
<!--87%-->
<SolidColorBrush x:Key="ErrorRed" Color="#CF6679" />
<!--Indigo--> <!--Indigo-->
<SolidColorBrush x:Key="Indigo_50 " Color="#E8EAF6"/> <SolidColorBrush x:Key="Indigo_50 " Color="#E8EAF6" />
<SolidColorBrush x:Key="Indigo_100" Color="#C5CAE9"/> <SolidColorBrush x:Key="Indigo_100" Color="#C5CAE9" />
<SolidColorBrush x:Key="Indigo_200" Color="#9FA8DA"/> <SolidColorBrush x:Key="Indigo_200" Color="#9FA8DA" />
<SolidColorBrush x:Key="Indigo_300" Color="#7986CB"/> <SolidColorBrush x:Key="Indigo_300" Color="#7986CB" />
<SolidColorBrush x:Key="Indigo_400" Color="#5C6BC0"/> <SolidColorBrush x:Key="Indigo_400" Color="#5C6BC0" />
<SolidColorBrush x:Key="Indigo_500" Color="#3F51B5"/> <SolidColorBrush x:Key="Indigo_500" Color="#3F51B5" />
<SolidColorBrush x:Key="Indigo_600" Color="#3949AB"/> <SolidColorBrush x:Key="Indigo_600" Color="#3949AB" />
<SolidColorBrush x:Key="Indigo_700" Color="#303F9F"/> <SolidColorBrush x:Key="Indigo_700" Color="#303F9F" />
<SolidColorBrush x:Key="Indigo_800" Color="#283593"/> <SolidColorBrush x:Key="Indigo_800" Color="#283593" />
<SolidColorBrush x:Key="Indigo_900" Color="#1A237E"/> <SolidColorBrush x:Key="Indigo_900" Color="#1A237E" />
<SolidColorBrush x:Key="Indigo_A100" Color="#8C9EFF"/> <SolidColorBrush x:Key="Indigo_A100" Color="#8C9EFF" />
<SolidColorBrush x:Key="Indigo_A200" Color="#536DFE"/> <SolidColorBrush x:Key="Indigo_A200" Color="#536DFE" />
<SolidColorBrush x:Key="Indigo_A400" Color="#3D5AFE"/> <SolidColorBrush x:Key="Indigo_A400" Color="#3D5AFE" />
<SolidColorBrush x:Key="Indigo_A700" Color="#304FFE"/> <SolidColorBrush x:Key="Indigo_A700" Color="#304FFE" />
<!--Yellow--> <!--Yellow-->
<SolidColorBrush x:Key="Yellow_50 " Color="#FFFDE7"/> <SolidColorBrush x:Key="Yellow_50 " Color="#FFFDE7" />
<SolidColorBrush x:Key="Yellow_100" Color="#FFF9C4"/> <SolidColorBrush x:Key="Yellow_100" Color="#FFF9C4" />
<SolidColorBrush x:Key="Yellow_200" Color="#FFF59D"/> <SolidColorBrush x:Key="Yellow_200" Color="#FFF59D" />
<SolidColorBrush x:Key="Yellow_300" Color="#FFF176"/> <SolidColorBrush x:Key="Yellow_300" Color="#FFF176" />
<SolidColorBrush x:Key="Yellow_400" Color="#FFEE58"/> <SolidColorBrush x:Key="Yellow_400" Color="#FFEE58" />
<SolidColorBrush x:Key="Yellow_500" Color="#FFEB3B"/> <SolidColorBrush x:Key="Yellow_500" Color="#FFEB3B" />
<SolidColorBrush x:Key="Yellow_600" Color="#FDD835"/> <SolidColorBrush x:Key="Yellow_600" Color="#FDD835" />
<SolidColorBrush x:Key="Yellow_700" Color="#FBC02D"/> <SolidColorBrush x:Key="Yellow_700" Color="#FBC02D" />
<SolidColorBrush x:Key="Yellow_800" Color="#F9A825"/> <SolidColorBrush x:Key="Yellow_800" Color="#F9A825" />
<SolidColorBrush x:Key="Yellow_900" Color="#F57F17"/> <SolidColorBrush x:Key="Yellow_900" Color="#F57F17" />
<SolidColorBrush x:Key="Yellow_A100" Color="#FFFF8D"/> <SolidColorBrush x:Key="Yellow_A100" Color="#FFFF8D" />
<SolidColorBrush x:Key="Yellow_A200" Color="#FFFF00"/> <SolidColorBrush x:Key="Yellow_A200" Color="#FFFF00" />
<SolidColorBrush x:Key="Yellow_A400" Color="#FFEA00"/> <SolidColorBrush x:Key="Yellow_A400" Color="#FFEA00" />
<SolidColorBrush x:Key="Yellow_A700" Color="#FFD600"/> <SolidColorBrush x:Key="Yellow_A700" Color="#FFD600" />
<!--Deep Purple--> <!--Deep Purple-->
<SolidColorBrush x:Key="DeepPurple_50 " Color="#EDE7F6"/> <SolidColorBrush x:Key="DeepPurple_50 " Color="#EDE7F6" />
<SolidColorBrush x:Key="DeepPurple_100" Color="#D1C4E9"/> <SolidColorBrush x:Key="DeepPurple_100" Color="#D1C4E9" />
<SolidColorBrush x:Key="DeepPurple_200" Color="#B39DDB"/><!--Primary--> <SolidColorBrush x:Key="DeepPurple_200" Color="#B39DDB" />
<SolidColorBrush x:Key="DeepPurple_300" Color="#9575CD"/> <!--Primary-->
<SolidColorBrush x:Key="DeepPurple_400" Color="#7E57C2"/> <SolidColorBrush x:Key="DeepPurple_300" Color="#9575CD" />
<SolidColorBrush x:Key="DeepPurple_500" Color="#673AB7"/><!--Primary Variant--> <SolidColorBrush x:Key="DeepPurple_400" Color="#7E57C2" />
<SolidColorBrush x:Key="DeepPurple_600" Color="#5E35B1"/> <SolidColorBrush x:Key="DeepPurple_500" Color="#673AB7" />
<SolidColorBrush x:Key="DeepPurple_700" Color="#512DA8"/> <!--Primary Variant-->
<SolidColorBrush x:Key="DeepPurple_800" Color="#4527A0"/> <SolidColorBrush x:Key="DeepPurple_600" Color="#5E35B1" />
<SolidColorBrush x:Key="DeepPurple_900" Color="#311B92"/> <SolidColorBrush x:Key="DeepPurple_700" Color="#512DA8" />
<SolidColorBrush x:Key="DeepPurple_A100" Color="#B388FF"/> <SolidColorBrush x:Key="DeepPurple_800" Color="#4527A0" />
<SolidColorBrush x:Key="DeepPurple_A200" Color="#7C4DFF"/> <SolidColorBrush x:Key="DeepPurple_900" Color="#311B92" />
<SolidColorBrush x:Key="DeepPurple_A400" Color="#651FFF"/> <SolidColorBrush x:Key="DeepPurple_A100" Color="#B388FF" />
<SolidColorBrush x:Key="DeepPurple_A700" Color="#6200EA"/> <SolidColorBrush x:Key="DeepPurple_A200" Color="#7C4DFF" />
<SolidColorBrush x:Key="DeepPurple_A400" Color="#651FFF" />
<SolidColorBrush x:Key="DeepPurple_A700" Color="#6200EA" />
<!--Deep Purple--> <!--Deep Purple-->
<SolidColorBrush x:Key="Teal_50 " Color="#E0F2F1"/> <SolidColorBrush x:Key="Teal_50 " Color="#E0F2F1" />
<SolidColorBrush x:Key="Teal_100" Color="#B2DFDB"/> <SolidColorBrush x:Key="Teal_100" Color="#B2DFDB" />
<SolidColorBrush x:Key="Teal_200" Color="#80CBC4"/> <SolidColorBrush x:Key="Teal_200" Color="#80CBC4" />
<SolidColorBrush x:Key="Teal_300" Color="#4DB6AC"/> <SolidColorBrush x:Key="Teal_300" Color="#4DB6AC" />
<SolidColorBrush x:Key="Teal_400" Color="#26A69A"/> <SolidColorBrush x:Key="Teal_400" Color="#26A69A" />
<SolidColorBrush x:Key="Teal_500" Color="#009688"/> <SolidColorBrush x:Key="Teal_500" Color="#009688" />
<SolidColorBrush x:Key="Teal_600" Color="#00897B"/> <SolidColorBrush x:Key="Teal_600" Color="#00897B" />
<SolidColorBrush x:Key="Teal_700" Color="#00796B"/> <SolidColorBrush x:Key="Teal_700" Color="#00796B" />
<SolidColorBrush x:Key="Teal_800" Color="#00695C"/> <SolidColorBrush x:Key="Teal_800" Color="#00695C" />
<SolidColorBrush x:Key="Teal_900" Color="#004D40"/> <SolidColorBrush x:Key="Teal_900" Color="#004D40" />
<SolidColorBrush x:Key="Teal_A100" Color="#A7FFEB"/> <SolidColorBrush x:Key="Teal_A100" Color="#A7FFEB" />
<SolidColorBrush x:Key="Teal_A200" Color="#64FFDA"/> <SolidColorBrush x:Key="Teal_A200" Color="#64FFDA" />
<SolidColorBrush x:Key="Teal_A400" Color="#1DE9B6"/> <SolidColorBrush x:Key="Teal_A400" Color="#1DE9B6" />
<SolidColorBrush x:Key="Teal_A700" Color="#00BFA5"/> <SolidColorBrush x:Key="Teal_A700" Color="#00BFA5" />
<!--#endregion--> <!--#endregion-->
<!--=================--> <!--=================-->
<!--=DEFAULT DESIGNS=--> <!--=DEFAULT DESIGNS=-->
<!--=================--> <!--=================-->
<!--Textblock default design--> <!--Textblock default design-->
<Style TargetType="{x:Type TextBlock}"> <Style TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="{StaticResource White}"/> <Setter Property="Foreground" Value="{StaticResource White}" />
<Setter Property="FontFamily" Value="{StaticResource Fontstyle}"/> <Setter Property="FontFamily" Value="{StaticResource Fontstyle}" />
</Style> </Style>
<!--Button default design--> <!--Button default design-->
<Style TargetType="{x:Type Button}"> <Style TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand"/> <Setter Property="Cursor" Value="Hand" />
<Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}"/> <Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}" />
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20" />
<Setter Property="FontFamily" Value="{StaticResource Fontstyle}"/> <Setter Property="FontFamily" Value="{StaticResource Fontstyle}" />
<Setter Property="Foreground" Value="{StaticResource DeepPurple_A100}"/> <Setter Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
<Setter Property="BorderThickness" Value="2"/> <Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="Transparent"/> <Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> <Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
<Border.Effect> <Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect> </Border.Effect>
<Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}"> <Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}">
<Border.BorderBrush> <Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush> </Border.BorderBrush>
<TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border> </Border>
</Border> </Border>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04"/> <SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -172,12 +187,12 @@
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12"/> <SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter TargetName="BackgroundOverlay" Property="BorderBrush"> <Setter TargetName="BackgroundOverlay" Property="BorderBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87"/> <SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -186,66 +201,65 @@
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style> </Style>
<!--Textbox default design--> <!--Textbox default design-->
<Style TargetType="{x:Type TextBox}"> <Style TargetType="{x:Type TextBox}">
<Setter Property="CaretBrush"> <Setter Property="CaretBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="{StaticResource Fontstyle}"/> <Setter Property="FontFamily" Value="{StaticResource Fontstyle}" />
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20" />
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground"> <Setter Property="Foreground">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}"/> <Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}" />
<Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderThickness" Value="0" />
</Style> </Style>
<!--Passwordbox default design--> <!--Passwordbox default design-->
<Style TargetType="{x:Type PasswordBox}"> <Style TargetType="{x:Type PasswordBox}">
<Setter Property="PasswordChar" Value="*"/> <Setter Property="PasswordChar" Value="*" />
<Setter Property="CaretBrush"> <Setter Property="CaretBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Arial"/> <Setter Property="FontFamily" Value="Arial" />
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20" />
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground"> <Setter Property="Foreground">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="BorderBrush"> <Setter Property="BorderBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}"/> <Setter Property="Background" Value="{StaticResource BackgroundSurface_01dp}" />
<Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderThickness" Value="0" />
</Style> </Style>
<!--Checkbox default design--> <!--Checkbox default design-->
<Style TargetType="{x:Type CheckBox}"> <Style TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels" Value="true"/> <Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="OverridesDefaultStyle" Value="true"/> <Setter Property="OverridesDefaultStyle" Value="true" />
<Setter Property="FocusVisualStyle" Value="{x:Null}"/> <Setter Property="FocusVisualStyle" Value="{x:Null}" />
<Setter Property="Foreground" Value="White"/> <Setter Property="Foreground" Value="White" />
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="Cursor" Value="Hand" />
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Effect"> <Setter Property="Effect">
<Setter.Value> <Setter.Value>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="Template"> <Setter Property="Template">
@@ -259,11 +273,11 @@
</Border> </Border>
</Border> </Border>
</BulletDecorator.Bullet> </BulletDecorator.Bullet>
<ContentPresenter Margin="4,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True"/> <ContentPresenter Margin="4,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Left" RecognizesAccessKey="True" />
</BulletDecorator> </BulletDecorator>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="false"> <Trigger Property="IsChecked" Value="false">
<Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed"/> <Setter TargetName="CheckMark" Property="Visibility" Value="Collapsed" />
</Trigger> </Trigger>
<Trigger Property="IsChecked" Value="{x:Null}"> <Trigger Property="IsChecked" Value="{x:Null}">
<Setter TargetName="CheckMark" Property="Data" Value="M 0 20 L 20 0" /> <Setter TargetName="CheckMark" Property="Data" Value="M 0 20 L 20 0" />
@@ -271,18 +285,18 @@
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background"> <Setter TargetName="Border" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04"/> <SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
<Trigger Property="IsEnabled" Value="false"> <Trigger Property="IsEnabled" Value="false">
<Setter TargetName="CheckMark" Property="Stroke" Value="#FF6C6C6C"/> <Setter TargetName="CheckMark" Property="Stroke" Value="#FF6C6C6C" />
<Setter Property="Foreground" Value="Gray"/> <Setter Property="Foreground" Value="Gray" />
</Trigger> </Trigger>
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background"> <Setter TargetName="Border" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12"/> <SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -294,18 +308,18 @@
<!--Hyperlink default design--> <!--Hyperlink default design-->
<Style TargetType="{x:Type Hyperlink}"> <Style TargetType="{x:Type Hyperlink}">
<Setter Property="TextDecorations" Value="None"/> <Setter Property="TextDecorations" Value="None" />
<Setter Property="Cursor" Value="Hand"/> <Setter Property="Cursor" Value="Hand" />
<Setter Property="Foreground"> <Setter Property="Foreground">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#64FFDA" Opacity="0.64"/> <SolidColorBrush Color="#64FFDA" Opacity="0.64" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Style.Triggers> <Style.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground"> <Setter Property="Foreground">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#64FFDA" Opacity="0.87"/> <SolidColorBrush Color="#64FFDA" Opacity="0.87" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -314,14 +328,14 @@
<!--Border default design (Makes text rendering in it crystal clear)--> <!--Border default design (Makes text rendering in it crystal clear)-->
<Style TargetType="Border"> <Style TargetType="Border">
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="UseLayoutRounding" Value="True"/> <Setter Property="UseLayoutRounding" Value="True" />
</Style> </Style>
<!--Grid default design (Makes text rendering in it crystal clear)--> <!--Grid default design (Makes text rendering in it crystal clear)-->
<Style TargetType="Grid"> <Style TargetType="Grid">
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="UseLayoutRounding" Value="True"/> <Setter Property="UseLayoutRounding" Value="True" />
</Style> </Style>
<!--================--> <!--================-->
@@ -330,32 +344,31 @@
<!--Close button design--> <!--Close button design-->
<Style x:Key="CloseButton" TargetType="{x:Type Button}"> <Style x:Key="CloseButton" TargetType="{x:Type Button}">
<Setter Property="Cursor" Value="Hand"/> <Setter Property="Cursor" Value="Hand" />
<Setter Property="Background" Value="Transparent"/> <Setter Property="Background" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True"/> <Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground"> <Setter Property="Foreground">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderThickness" Value="0" />
<Setter Property="FontSize" Value="20"/> <Setter Property="FontSize" Value="20" />
<Setter Property="Template"> <Setter Property="Template">
<Setter.Value> <Setter.Value>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<TextBlock TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center"/> <TextBlock TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border> </Border>
<ControlTemplate.Triggers> <ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="Red"/> <Setter Property="Background" Value="Red" />
<Setter Property="Foreground" Value="{StaticResource BackgroundSurface_00dp}"/> <Setter Property="Foreground" Value="{StaticResource BackgroundSurface_00dp}" />
</Trigger> </Trigger>
</ControlTemplate.Triggers> </ControlTemplate.Triggers>
</ControlTemplate> </ControlTemplate>
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Style> </Style>
</Application.Resources> </Application.Resources>
</Application> </Application>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View File

@@ -1,11 +0,0 @@
<svg width="48.00000000000001" height="48.00000000000001" xmlns="http://www.w3.org/2000/svg">
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<path fill="#ffffff" id="svg_1" fill-rule="evenodd" d="m37,47l-26,0c-2.209,0 -4,-1.791 -4,-4l0,-38c0,-2.209 1.791,-4 4,-4l18.973,0c0.002,0 0.005,0 0.007,0l0.02,0l0,0c0.32,0 0.593,0.161 0.776,0.395l9.829,9.829c0.235,0.183 0.395,0.456 0.395,0.776l0,0l0,0.021c0,0.002 0,0.003 0,0.005l0,30.974c0,2.209 -1.791,4 -4,4zm-6,-42.619l0,6.619l6.619,0l-6.619,-6.619zm8,8.619l-9,0c-0.553,0 -1,-0.448 -1,-1l0,-9l-18,0c-1.104,0 -2,0.896 -2,2l0,38c0,1.104 0.896,2 2,2l26,0c1.104,0 2,-0.896 2,-2l0,-30zm-6,26l-18,0c-0.553,0 -1,-0.447 -1,-1c0,-0.552 0.447,-1 1,-1l18,0c0.553,0 1,0.448 1,1c0,0.553 -0.447,1 -1,1zm0,-8l-18,0c-0.553,0 -1,-0.447 -1,-1c0,-0.552 0.447,-1 1,-1l18,0c0.553,0 1,0.448 1,1c0,0.553 -0.447,1 -1,1zm0,-8l-18,0c-0.553,0 -1,-0.447 -1,-1c0,-0.552 0.447,-1 1,-1l18,0c0.553,0 1,0.448 1,1c0,0.553 -0.447,1 -1,1z" clip-rule="evenodd"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -1,483 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
id="svg2"
xml:space="preserve"
width="707.96399"
height="735.98132"
viewBox="0 0 707.96399 735.98132"
sodipodi:docname="GitHub-Mark.ai"><metadata
id="metadata8"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
id="defs6"><clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath20"><path
d="M 0,551.986 H 530.973 V 0 H 0 Z"
id="path18" /></clipPath></defs><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="640"
inkscape:window-height="480"
id="namedview4" /><g
id="g10"
inkscape:groupmode="layer"
inkscape:label="GitHub-Mark"
transform="matrix(1.3333333,0,0,-1.3333333,0,735.98133)"><path
d="M 0,0 H 530.973 V 275.986 H 0 Z"
style="fill:#231f20;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path12" /><g
id="g14"><g
id="g16"
clip-path="url(#clipPath20)"><g
id="g22"
transform="translate(152.6083,444.5454)"><path
d="m 0,0 c -8.995,0 -16.288,-7.293 -16.288,-16.29 0,-7.197 4.667,-13.302 11.14,-15.457 0.815,-0.149 1.112,0.354 1.112,0.786 0,0.386 -0.014,1.411 -0.022,2.77 -4.531,-0.984 -5.487,2.184 -5.487,2.184 -0.741,1.881 -1.809,2.382 -1.809,2.382 -1.479,1.011 0.112,0.991 0.112,0.991 1.635,-0.116 2.495,-1.679 2.495,-1.679 1.453,-2.489 3.813,-1.77 4.741,-1.354 0.148,1.053 0.568,1.771 1.034,2.178 -3.617,0.411 -7.42,1.809 -7.42,8.051 0,1.778 0.635,3.232 1.677,4.371 -0.168,0.412 -0.727,2.068 0.159,4.311 0,0 1.368,0.438 4.48,-1.67 1.299,0.361 2.693,0.542 4.078,0.548 1.383,-0.006 2.777,-0.187 4.078,-0.548 3.11,2.108 4.475,1.67 4.475,1.67 0.889,-2.243 0.33,-3.899 0.162,-4.311 1.044,-1.139 1.675,-2.593 1.675,-4.371 0,-6.258 -3.809,-7.635 -7.438,-8.038 0.585,-0.503 1.106,-1.497 1.106,-3.017 0,-2.177 -0.02,-3.934 -0.02,-4.468 0,-0.436 0.293,-0.943 1.12,-0.784 6.468,2.159 11.131,8.26 11.131,15.455 C 16.291,-7.293 8.997,0 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path24" /></g><g
id="g26"
transform="translate(350.6088,493.5547)"><path
d="m 0,0 c -33.347,0 -60.388,-27.035 -60.388,-60.388 0,-26.68 17.303,-49.316 41.297,-57.301 3.018,-0.559 4.126,1.31 4.126,2.905 0,1.439 -0.056,6.197 -0.082,11.243 -16.8,-3.653 -20.345,7.125 -20.345,7.125 -2.747,6.979 -6.705,8.836 -6.705,8.836 -5.479,3.748 0.413,3.671 0.413,3.671 6.064,-0.426 9.257,-6.224 9.257,-6.224 5.386,-9.231 14.127,-6.562 17.573,-5.019 0.543,3.902 2.107,6.567 3.834,8.075 -13.413,1.526 -27.513,6.705 -27.513,29.844 0,6.592 2.359,11.98 6.222,16.209 -0.627,1.521 -2.694,7.663 0.586,15.981 0,0 5.071,1.622 16.61,-6.191 4.817,1.338 9.983,2.009 15.115,2.033 5.132,-0.024 10.302,-0.695 15.128,-2.033 11.526,7.813 16.59,6.191 16.59,6.191 3.287,-8.318 1.22,-14.46 0.593,-15.981 3.872,-4.229 6.214,-9.617 6.214,-16.209 0,-23.195 -14.127,-28.301 -27.574,-29.796 2.166,-1.874 4.096,-5.549 4.096,-11.183 0,-8.08 -0.069,-14.583 -0.069,-16.572 0,-1.608 1.086,-3.49 4.147,-2.898 23.982,7.994 41.263,30.622 41.263,57.294 C 60.388,-27.035 33.351,0 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path28" /></g><g
id="g30"
transform="translate(313.0932,406.8515)"><path
d="m 0,0 c -0.133,-0.301 -0.605,-0.391 -1.035,-0.185 -0.439,0.198 -0.684,0.607 -0.542,0.908 0.13,0.308 0.602,0.394 1.04,0.188 C -0.099,0.714 0.151,0.301 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path32" /></g><g
id="g34"
transform="translate(315.5395,404.123)"><path
d="M 0,0 C -0.288,-0.267 -0.852,-0.143 -1.233,0.279 -1.629,0.7 -1.702,1.264 -1.41,1.534 -1.113,1.801 -0.567,1.676 -0.172,1.255 0.224,0.829 0.301,0.271 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path36" /></g><g
id="g38"
transform="translate(317.9204,400.6455)"><path
d="M 0,0 C -0.37,-0.258 -0.976,-0.017 -1.35,0.52 -1.72,1.058 -1.72,1.702 -1.341,1.96 -0.967,2.218 -0.37,1.985 0.009,1.453 0.378,0.907 0.378,0.263 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path40" /></g><g
id="g42"
transform="translate(321.1821,397.2851)"><path
d="M 0,0 C -0.331,-0.365 -1.036,-0.267 -1.552,0.232 -2.08,0.718 -2.227,1.409 -1.896,1.774 -1.56,2.14 -0.851,2.037 -0.331,1.543 0.193,1.057 0.352,0.361 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path44" /></g><g
id="g46"
transform="translate(325.6821,395.334)"><path
d="m 0,0 c -0.147,-0.473 -0.825,-0.687 -1.509,-0.486 -0.683,0.207 -1.13,0.76 -0.992,1.238 0.142,0.476 0.824,0.7 1.513,0.485 C -0.306,1.031 0.142,0.481 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path48" /></g><g
id="g50"
transform="translate(330.6245,394.9726)"><path
d="m 0,0 c 0.017,-0.498 -0.563,-0.911 -1.281,-0.92 -0.722,-0.016 -1.307,0.387 -1.315,0.877 0,0.503 0.568,0.911 1.289,0.924 C -0.589,0.895 0,0.494 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path52" /></g><g
id="g54"
transform="translate(335.2231,395.7549)"><path
d="m 0,0 c 0.086,-0.485 -0.413,-0.984 -1.126,-1.117 -0.701,-0.129 -1.35,0.172 -1.439,0.653 -0.087,0.498 0.42,0.997 1.121,1.126 C -0.73,0.786 -0.091,0.494 0,0"
style="fill:#1b1817;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path56" /></g><g
id="g58"
transform="translate(224.8979,499.4882)"><path
d="M 0,0 V -0.5"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path60" /></g><g
id="g62"
transform="translate(224.8979,496.9882)"><path
d="M 0,0 V -133.993"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1"
id="path64" /></g><g
id="g66"
transform="translate(224.8979,361.9951)"><path
d="M 0,0 V -0.5"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path68" /></g><g
id="g70"
transform="translate(133.2758,347.4795)"><path
d="m 0,0 c -0.38,0.276 -0.866,0.414 -1.458,0.414 -0.24,0 -0.476,-0.024 -0.708,-0.071 -0.232,-0.049 -0.438,-0.129 -0.618,-0.24 -0.18,-0.114 -0.324,-0.263 -0.432,-0.452 -0.108,-0.187 -0.162,-0.421 -0.162,-0.701 0,-0.264 0.078,-0.478 0.234,-0.642 0.156,-0.165 0.364,-0.298 0.624,-0.402 0.26,-0.104 0.554,-0.19 0.882,-0.259 0.328,-0.067 0.662,-0.141 1.002,-0.22 0.34,-0.08 0.674,-0.175 1.002,-0.284 C 0.694,-2.964 0.988,-3.11 1.248,-3.294 1.508,-3.478 1.716,-3.71 1.872,-3.989 2.028,-4.27 2.106,-4.622 2.106,-5.046 2.106,-5.502 2.004,-5.892 1.8,-6.216 1.596,-6.54 1.334,-6.804 1.014,-7.008 0.694,-7.212 0.336,-7.36 -0.06,-7.452 -0.456,-7.544 -0.85,-7.59 -1.242,-7.59 c -0.48,0 -0.934,0.06 -1.362,0.18 -0.428,0.12 -0.804,0.302 -1.128,0.546 -0.324,0.244 -0.58,0.556 -0.768,0.936 -0.188,0.38 -0.282,0.829 -0.282,1.35 h 1.08 c 0,-0.361 0.07,-0.67 0.21,-0.93 0.14,-0.261 0.324,-0.474 0.552,-0.642 0.228,-0.167 0.494,-0.292 0.798,-0.372 0.304,-0.081 0.616,-0.12 0.936,-0.12 0.256,0 0.514,0.024 0.774,0.073 0.26,0.047 0.494,0.129 0.702,0.246 0.208,0.115 0.376,0.273 0.504,0.472 0.128,0.201 0.192,0.457 0.192,0.769 0,0.296 -0.078,0.536 -0.234,0.72 -0.156,0.183 -0.364,0.334 -0.624,0.45 -0.26,0.116 -0.554,0.21 -0.882,0.282 -0.328,0.072 -0.662,0.147 -1.002,0.223 -0.34,0.075 -0.674,0.163 -1.002,0.263 -0.328,0.1 -0.622,0.232 -0.882,0.396 -0.26,0.164 -0.468,0.376 -0.624,0.636 -0.156,0.259 -0.234,0.586 -0.234,0.978 0,0.432 0.088,0.806 0.264,1.122 0.176,0.316 0.41,0.575 0.702,0.78 0.292,0.204 0.624,0.356 0.996,0.456 0.372,0.1 0.754,0.15 1.146,0.15 0.44,0 0.848,-0.053 1.224,-0.156 C 0.19,1.114 0.52,0.95 0.804,0.725 1.088,0.502 1.312,0.22 1.476,-0.12 1.64,-0.46 1.73,-0.866 1.746,-1.338 H 0.666 C 0.602,-0.722 0.38,-0.276 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path72" /></g><g
id="g74"
transform="translate(137.5537,346.2851)"><path
d="m 0,0 v -0.912 h 0.024 c 0.464,0.705 1.132,1.057 2.004,1.057 0.384,0 0.732,-0.08 1.044,-0.241 0.312,-0.16 0.532,-0.431 0.66,-0.816 0.208,0.336 0.482,0.596 0.822,0.78 0.34,0.185 0.714,0.277 1.122,0.277 0.312,0 0.594,-0.035 0.846,-0.102 0.252,-0.068 0.468,-0.175 0.648,-0.318 0.18,-0.145 0.32,-0.33 0.42,-0.559 0.1,-0.227 0.15,-0.502 0.15,-0.822 V -6.203 H 6.72 v 4.067 c 0,0.193 -0.016,0.372 -0.048,0.54 -0.032,0.168 -0.092,0.315 -0.18,0.438 -0.088,0.125 -0.21,0.223 -0.366,0.295 -0.156,0.072 -0.358,0.107 -0.606,0.107 -0.504,0 -0.9,-0.143 -1.188,-0.431 C 4.044,-1.476 3.9,-1.859 3.9,-2.34 V -6.203 H 2.88 v 4.067 c 0,0.201 -0.018,0.384 -0.054,0.552 -0.036,0.168 -0.098,0.314 -0.186,0.438 -0.088,0.125 -0.206,0.22 -0.354,0.289 -0.148,0.068 -0.338,0.101 -0.57,0.101 -0.296,0 -0.55,-0.059 -0.762,-0.179 C 0.742,-1.056 0.57,-1.199 0.438,-1.367 0.306,-1.535 0.21,-1.709 0.15,-1.89 0.09,-2.07 0.06,-2.22 0.06,-2.34 V -6.203 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path76" /></g><g
id="g78"
transform="translate(150.1655,343.0761)"><path
d="m 0,0 c -0.208,-0.045 -0.426,-0.08 -0.654,-0.108 -0.228,-0.029 -0.458,-0.06 -0.69,-0.097 -0.232,-0.035 -0.44,-0.094 -0.624,-0.174 -0.184,-0.08 -0.334,-0.193 -0.45,-0.342 -0.116,-0.148 -0.174,-0.349 -0.174,-0.605 0,-0.168 0.034,-0.311 0.102,-0.426 0.068,-0.117 0.156,-0.211 0.264,-0.283 0.108,-0.071 0.236,-0.123 0.384,-0.155 0.148,-0.033 0.298,-0.048 0.45,-0.048 0.336,0 0.624,0.045 0.864,0.137 0.24,0.092 0.436,0.208 0.588,0.349 0.152,0.139 0.264,0.291 0.336,0.455 0.072,0.164 0.108,0.318 0.108,0.463 V 0.209 C 0.376,0.113 0.208,0.043 0,0 m 1.428,-3.127 c -0.264,0 -0.474,0.074 -0.63,0.223 -0.156,0.147 -0.234,0.389 -0.234,0.725 -0.28,-0.336 -0.606,-0.578 -0.978,-0.725 -0.372,-0.149 -0.774,-0.223 -1.206,-0.223 -0.28,0 -0.544,0.03 -0.792,0.09 -0.248,0.06 -0.466,0.16 -0.654,0.301 -0.188,0.139 -0.336,0.319 -0.444,0.539 -0.108,0.22 -0.162,0.486 -0.162,0.799 0,0.351 0.06,0.639 0.18,0.863 0.12,0.224 0.278,0.406 0.474,0.547 0.196,0.139 0.42,0.246 0.672,0.318 0.252,0.071 0.51,0.131 0.774,0.18 0.28,0.055 0.546,0.097 0.798,0.125 0.252,0.028 0.474,0.068 0.666,0.121 0.192,0.051 0.344,0.127 0.456,0.227 0.112,0.101 0.168,0.246 0.168,0.439 0,0.223 -0.042,0.403 -0.126,0.539 -0.084,0.137 -0.192,0.24 -0.324,0.312 -0.132,0.073 -0.28,0.121 -0.444,0.145 -0.164,0.023 -0.326,0.035 -0.486,0.035 -0.432,0 -0.792,-0.082 -1.08,-0.246 -0.288,-0.164 -0.444,-0.474 -0.468,-0.93 h -1.02 c 0.016,0.384 0.096,0.708 0.24,0.973 0.144,0.264 0.336,0.478 0.576,0.642 0.24,0.163 0.516,0.282 0.828,0.354 0.312,0.071 0.64,0.108 0.984,0.108 0.28,0 0.558,-0.02 0.834,-0.061 C 0.306,3.254 0.556,3.172 0.78,3.047 1.004,2.924 1.184,2.749 1.32,2.525 1.456,2.301 1.524,2.01 1.524,1.649 v -3.192 c 0,-0.24 0.014,-0.416 0.042,-0.527 0.028,-0.113 0.122,-0.168 0.282,-0.168 0.088,0 0.192,0.019 0.312,0.059 V -2.971 C 1.984,-3.074 1.74,-3.127 1.428,-3.127"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path80" /></g><path
d="m 154.354,340.082 h -1.02 v 8.567 h 1.02 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path82" /><path
d="m 157.017,340.082 h -1.02 v 8.567 h 1.02 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path84" /><g
id="g86"
transform="translate(101.854,330.9863)"><path
d="m 0,0 v 0.899 h 1.044 v 0.924 c 0,0.504 0.146,0.886 0.438,1.146 0.292,0.26 0.718,0.39 1.278,0.39 0.096,0 0.206,-0.007 0.33,-0.023 C 3.214,3.319 3.324,3.295 3.42,3.264 V 2.375 C 3.332,2.407 3.236,2.43 3.132,2.441 3.028,2.453 2.932,2.459 2.844,2.459 2.596,2.459 2.404,2.411 2.268,2.315 2.132,2.219 2.064,2.035 2.064,1.764 V 0.899 h 1.2 V 0 h -1.2 V -5.305 H 1.044 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path88" /></g><g
id="g90"
transform="translate(106.9238,327.7754)"><path
d="m 0,0 c 0.1,-0.292 0.238,-0.535 0.414,-0.732 0.176,-0.196 0.382,-0.346 0.618,-0.45 0.236,-0.103 0.486,-0.156 0.75,-0.156 0.264,0 0.514,0.053 0.75,0.156 0.236,0.104 0.442,0.254 0.618,0.45 0.176,0.197 0.314,0.44 0.414,0.732 0.1,0.292 0.15,0.626 0.15,1.002 0,0.377 -0.05,0.71 -0.15,1.002 C 3.464,2.297 3.326,2.542 3.15,2.742 2.974,2.941 2.768,3.094 2.532,3.198 2.296,3.303 2.046,3.355 1.782,3.355 1.518,3.355 1.268,3.303 1.032,3.198 0.796,3.094 0.59,2.941 0.414,2.742 0.238,2.542 0.1,2.297 0,2.004 -0.1,1.712 -0.15,1.379 -0.15,1.002 -0.15,0.626 -0.1,0.292 0,0 m -1.038,2.28 c 0.128,0.396 0.32,0.74 0.576,1.033 0.256,0.291 0.572,0.521 0.948,0.689 0.376,0.168 0.808,0.252 1.296,0.252 0.496,0 0.93,-0.084 1.302,-0.252 C 3.456,3.834 3.77,3.604 4.026,3.313 4.282,3.02 4.474,2.676 4.602,2.28 4.73,1.885 4.794,1.458 4.794,1.002 4.794,0.547 4.73,0.122 4.602,-0.27 4.474,-0.662 4.282,-1.004 4.026,-1.296 3.77,-1.588 3.456,-1.816 3.084,-1.98 2.712,-2.144 2.278,-2.226 1.782,-2.226 c -0.488,0 -0.92,0.082 -1.296,0.246 -0.376,0.164 -0.692,0.392 -0.948,0.684 -0.256,0.292 -0.448,0.634 -0.576,1.026 -0.128,0.392 -0.192,0.817 -0.192,1.272 0,0.456 0.064,0.883 0.192,1.278"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path92" /></g><g
id="g94"
transform="translate(113.8417,331.8857)"><path
d="m 0,0 v -1.308 h 0.024 c 0.248,0.504 0.552,0.875 0.912,1.116 0.36,0.24 0.816,0.351 1.368,0.336 V -0.937 C 1.896,-0.937 1.548,-0.992 1.26,-1.105 0.972,-1.216 0.74,-1.38 0.564,-1.597 0.388,-1.812 0.26,-2.074 0.18,-2.382 0.1,-2.69 0.06,-3.044 0.06,-3.444 v -2.76 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path96" /></g><g
id="g98"
transform="translate(122.7333,325.6816)"><path
d="m 0,0 v 6.096 h -2.208 v 0.816 c 0.288,0 0.568,0.022 0.84,0.066 0.272,0.043 0.518,0.125 0.738,0.247 0.22,0.119 0.406,0.283 0.558,0.491 C 0.08,7.924 0.184,8.188 0.24,8.508 H 1.02 L 1.02,0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path100" /></g><g
id="g102"
transform="translate(128.8295,330.1035)"><path
d="m 0,0 c -0.216,-0.1 -0.4,-0.236 -0.552,-0.408 -0.152,-0.172 -0.266,-0.376 -0.341,-0.611 -0.077,-0.237 -0.115,-0.487 -0.115,-0.75 0,-0.264 0.04,-0.512 0.12,-0.745 0.08,-0.232 0.194,-0.431 0.342,-0.599 0.148,-0.168 0.332,-0.303 0.552,-0.403 0.22,-0.1 0.47,-0.15 0.75,-0.15 0.28,0 0.526,0.05 0.738,0.15 0.212,0.1 0.39,0.239 0.534,0.414 0.144,0.176 0.254,0.378 0.33,0.606 0.076,0.228 0.114,0.467 0.114,0.715 0,0.263 -0.034,0.513 -0.102,0.75 C 2.302,-0.796 2.196,-0.592 2.052,-0.42 1.908,-0.248 1.728,-0.109 1.512,-0.006 1.296,0.098 1.044,0.15 0.756,0.15 0.468,0.15 0.216,0.1 0,0 M 1.848,2.838 C 1.6,3.07 1.272,3.186 0.864,3.186 0.432,3.186 0.084,3.08 -0.18,2.868 -0.444,2.656 -0.65,2.389 -0.798,2.064 -0.946,1.74 -1.048,1.391 -1.104,1.014 -1.16,0.639 -1.192,0.286 -1.2,-0.042 l 0.024,-0.024 c 0.24,0.392 0.538,0.675 0.894,0.852 0.356,0.176 0.766,0.265 1.23,0.265 0.408,0 0.774,-0.07 1.098,-0.211 C 2.37,0.7 2.642,0.506 2.862,0.258 3.082,0.01 3.253,-0.281 3.372,-0.617 3.492,-0.954 3.552,-1.318 3.552,-1.71 3.552,-2.021 3.504,-2.346 3.408,-2.682 3.312,-3.018 3.154,-3.324 2.934,-3.6 2.714,-3.876 2.422,-4.103 2.058,-4.283 1.694,-4.464 1.244,-4.554 0.708,-4.554 c -0.632,0 -1.14,0.128 -1.524,0.384 -0.384,0.256 -0.68,0.584 -0.888,0.984 -0.208,0.4 -0.346,0.84 -0.414,1.321 -0.068,0.479 -0.102,0.943 -0.102,1.391 0,0.583 0.05,1.15 0.15,1.699 0.1,0.547 0.27,1.033 0.511,1.457 C -1.32,3.106 -1,3.445 -0.6,3.702 -0.2,3.958 0.304,4.086 0.912,4.086 1.616,4.086 2.176,3.9 2.592,3.528 3.008,3.156 3.248,2.618 3.312,1.914 H 2.292 C 2.244,2.299 2.096,2.606 1.848,2.838"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path104" /></g><g
id="g106"
transform="translate(138.3159,329.6836)"><path
d="m 0,0 c -0.076,0.275 -0.192,0.521 -0.348,0.738 -0.156,0.216 -0.356,0.388 -0.6,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.876,-0.204 -0.24,-0.137 -0.436,-0.314 -0.588,-0.534 -0.152,-0.22 -0.262,-0.47 -0.33,-0.75 -0.069,-0.28 -0.102,-0.563 -0.102,-0.853 0,-0.303 0.036,-0.597 0.108,-0.88 0.071,-0.286 0.186,-0.536 0.341,-0.75 0.157,-0.217 0.358,-0.391 0.607,-0.523 0.247,-0.132 0.548,-0.198 0.9,-0.198 0.351,0 0.646,0.068 0.882,0.204 0.236,0.136 0.425,0.315 0.569,0.54 0.145,0.224 0.249,0.481 0.312,0.768 0.064,0.289 0.097,0.584 0.097,0.888 C 0.114,-0.559 0.076,-0.275 0,0 M -3.666,2.202 V 1.361 h 0.024 c 0.168,0.345 0.431,0.595 0.792,0.75 0.36,0.157 0.756,0.235 1.188,0.235 0.48,0 0.898,-0.088 1.254,-0.264 C -0.052,1.906 0.244,1.668 0.48,1.368 0.716,1.068 0.893,0.722 1.014,0.33 c 0.12,-0.392 0.18,-0.809 0.18,-1.248 0,-0.439 -0.058,-0.855 -0.175,-1.248 C 0.904,-2.559 0.727,-2.9 0.492,-3.191 0.256,-3.484 -0.041,-3.714 -0.396,-3.882 -0.753,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.153,0 -0.323,0.017 -0.511,0.048 -0.188,0.032 -0.374,0.084 -0.557,0.156 -0.184,0.073 -0.359,0.17 -0.522,0.294 -0.164,0.124 -0.302,0.279 -0.414,0.462 h -0.024 v -3.191 h -1.02 v 8.567 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path108" /></g><g
id="g110"
transform="translate(140.2172,331.8857)"><path
d="M 0,0 H 1.308 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.856 2.4,-3.348 H 4.524 L 2.796,-3.636 1.068,-6.204 H -0.168 L 2.16,-2.94 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path112" /></g><path
d="m 150.225,328.537 h -3.468 v 0.961 h 3.468 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path114" /><g
id="g116"
transform="translate(154.0771,325.6816)"><path
d="m 0,0 v 6.096 h -2.208 v 0.816 c 0.288,0 0.568,0.022 0.84,0.066 0.272,0.043 0.518,0.125 0.738,0.247 0.22,0.119 0.406,0.283 0.558,0.491 C 0.08,7.924 0.184,8.188 0.24,8.508 H 1.02 L 1.02,0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path118" /></g><g
id="g120"
transform="translate(158.1572,332.3769)"><path
d="m 0,0 c 0.112,0.369 0.286,0.686 0.522,0.955 0.236,0.268 0.53,0.478 0.882,0.629 0.352,0.152 0.752,0.228 1.2,0.228 0.368,0 0.714,-0.053 1.038,-0.162 C 3.966,1.543 4.248,1.387 4.488,1.183 4.728,0.979 4.918,0.725 5.058,0.421 5.198,0.117 5.268,-0.235 5.268,-0.635 5.268,-1.012 5.21,-1.344 5.094,-1.631 4.977,-1.92 4.824,-2.178 4.632,-2.405 4.44,-2.633 4.22,-2.84 3.972,-3.023 3.724,-3.207 3.468,-3.383 3.204,-3.551 2.94,-3.711 2.676,-3.869 2.412,-4.025 2.148,-4.182 1.906,-4.348 1.686,-4.523 1.466,-4.699 1.278,-4.889 1.122,-5.094 0.966,-5.297 0.864,-5.531 0.816,-5.795 h 4.368 v -0.9 h -5.556 c 0.04,0.504 0.13,0.933 0.27,1.29 0.14,0.356 0.318,0.666 0.534,0.93 0.216,0.264 0.46,0.496 0.732,0.696 0.272,0.199 0.556,0.387 0.852,0.564 0.36,0.224 0.676,0.43 0.948,0.617 0.272,0.188 0.498,0.379 0.678,0.571 0.18,0.191 0.316,0.4 0.408,0.624 0.092,0.223 0.138,0.483 0.138,0.78 0,0.231 -0.045,0.441 -0.132,0.63 C 3.968,0.194 3.85,0.357 3.702,0.492 3.554,0.629 3.38,0.732 3.18,0.805 2.98,0.877 2.768,0.912 2.544,0.912 2.247,0.912 1.994,0.851 1.782,0.727 1.57,0.603 1.396,0.441 1.26,0.24 1.124,0.041 1.026,-0.185 0.966,-0.437 0.906,-0.689 0.88,-0.943 0.888,-1.199 h -1.02 C -0.156,-0.768 -0.112,-0.367 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path122" /></g><g
id="g124"
transform="translate(165.7832,328.7949)"><path
d="m 0,0 c 0.02,-0.395 0.084,-0.768 0.192,-1.115 0.108,-0.348 0.282,-0.643 0.522,-0.882 0.24,-0.24 0.576,-0.36 1.008,-0.36 0.432,0 0.768,0.12 1.008,0.36 0.24,0.239 0.414,0.534 0.522,0.882 0.108,0.347 0.172,0.72 0.192,1.115 0.02,0.397 0.03,0.755 0.03,1.074 0,0.209 -0.002,0.439 -0.006,0.691 C 3.464,2.017 3.444,2.268 3.408,2.521 3.372,2.773 3.32,3.018 3.252,3.259 3.184,3.498 3.084,3.709 2.952,3.889 2.82,4.068 2.654,4.215 2.454,4.326 2.254,4.439 2.01,4.494 1.722,4.494 1.434,4.494 1.19,4.439 0.99,4.326 0.79,4.215 0.624,4.068 0.492,3.889 0.36,3.709 0.26,3.498 0.192,3.259 0.124,3.018 0.072,2.773 0.036,2.521 0,2.268 -0.02,2.017 -0.024,1.765 -0.028,1.513 -0.03,1.283 -0.03,1.074 -0.03,0.755 -0.02,0.397 0,0 m -1.086,2.035 c 0.016,0.336 0.056,0.664 0.12,0.983 0.064,0.32 0.156,0.625 0.276,0.913 0.12,0.288 0.284,0.54 0.492,0.756 C 0.01,4.902 0.272,5.074 0.588,5.203 0.904,5.33 1.282,5.395 1.722,5.395 2.162,5.395 2.54,5.33 2.856,5.203 3.172,5.074 3.434,4.902 3.642,4.687 3.85,4.471 4.014,4.219 4.134,3.931 4.254,3.643 4.346,3.338 4.41,3.018 4.474,2.699 4.514,2.371 4.53,2.035 4.546,1.699 4.554,1.375 4.554,1.062 4.554,0.75 4.546,0.427 4.53,0.091 4.514,-0.245 4.474,-0.573 4.41,-0.893 4.346,-1.213 4.254,-1.516 4.134,-1.799 4.014,-2.084 3.85,-2.334 3.642,-2.549 3.434,-2.766 3.174,-2.936 2.862,-3.059 2.55,-3.184 2.17,-3.245 1.722,-3.245 c -0.44,0 -0.818,0.061 -1.134,0.186 -0.316,0.123 -0.578,0.293 -0.786,0.51 -0.208,0.215 -0.372,0.465 -0.492,0.75 -0.12,0.283 -0.212,0.586 -0.276,0.906 -0.064,0.32 -0.104,0.648 -0.12,0.984 -0.016,0.336 -0.024,0.659 -0.024,0.971 0,0.313 0.008,0.637 0.024,0.973"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path126" /></g><g
id="g128"
transform="translate(176.3315,329.6836)"><path
d="m 0,0 c -0.076,0.275 -0.192,0.521 -0.348,0.738 -0.156,0.216 -0.356,0.388 -0.6,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.876,-0.204 -0.24,-0.137 -0.436,-0.314 -0.588,-0.534 -0.152,-0.22 -0.262,-0.47 -0.33,-0.75 -0.069,-0.28 -0.102,-0.563 -0.102,-0.853 0,-0.303 0.036,-0.597 0.108,-0.88 0.071,-0.286 0.186,-0.536 0.342,-0.75 0.156,-0.217 0.357,-0.391 0.606,-0.523 0.248,-0.132 0.548,-0.198 0.9,-0.198 0.351,0 0.646,0.068 0.882,0.204 0.236,0.136 0.425,0.315 0.57,0.54 0.144,0.224 0.248,0.481 0.312,0.768 0.063,0.289 0.096,0.584 0.096,0.888 C 0.114,-0.559 0.076,-0.275 0,0 M -3.666,2.202 V 1.361 h 0.024 c 0.168,0.345 0.431,0.595 0.792,0.75 0.36,0.157 0.756,0.235 1.188,0.235 0.48,0 0.898,-0.088 1.254,-0.264 C -0.052,1.906 0.244,1.668 0.48,1.368 0.716,1.068 0.893,0.722 1.014,0.33 1.134,-0.062 1.194,-0.479 1.194,-0.918 1.194,-1.357 1.136,-1.773 1.02,-2.166 0.904,-2.559 0.727,-2.9 0.492,-3.191 0.256,-3.484 -0.04,-3.714 -0.396,-3.882 -0.752,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.152,0 -0.323,0.017 -0.51,0.048 -0.188,0.032 -0.375,0.084 -0.558,0.156 -0.184,0.073 -0.358,0.17 -0.522,0.294 -0.164,0.124 -0.302,0.279 -0.414,0.462 h -0.024 v -3.191 h -1.02 v 8.567 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path130" /></g><g
id="g132"
transform="translate(178.2329,331.8857)"><path
d="M 0,0 H 1.308 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.856 2.4,-3.348 H 4.524 L 2.796,-3.636 1.068,-6.204 H -0.168 L 2.16,-2.94 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path134" /></g><g
id="g136"
transform="translate(335.6333,348.6504)"><path
d="M 0,0 V -7.607 H 4.536 V -8.568 H -1.14 l 0,8.568 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path138" /></g><g
id="g140"
transform="translate(344.3334,343.0761)"><path
d="m 0,0 c -0.209,-0.044 -0.426,-0.08 -0.654,-0.107 -0.229,-0.029 -0.459,-0.061 -0.691,-0.096 -0.231,-0.037 -0.44,-0.095 -0.624,-0.174 -0.183,-0.08 -0.334,-0.195 -0.449,-0.343 -0.117,-0.147 -0.174,-0.35 -0.174,-0.606 0,-0.168 0.034,-0.31 0.102,-0.426 0.067,-0.115 0.156,-0.209 0.264,-0.281 0.107,-0.072 0.236,-0.125 0.384,-0.156 0.148,-0.033 0.297,-0.049 0.45,-0.049 0.335,0 0.624,0.047 0.864,0.138 0.239,0.092 0.435,0.208 0.588,0.348 0.151,0.141 0.264,0.293 0.336,0.457 0.071,0.163 0.108,0.317 0.108,0.461 V 0.211 C 0.375,0.114 0.207,0.045 0,0 m 1.428,-3.125 c -0.264,0 -0.475,0.073 -0.631,0.221 -0.155,0.148 -0.233,0.39 -0.233,0.726 -0.281,-0.336 -0.607,-0.578 -0.978,-0.726 -0.373,-0.148 -0.774,-0.221 -1.207,-0.221 -0.279,0 -0.543,0.029 -0.791,0.09 -0.248,0.059 -0.467,0.16 -0.654,0.299 -0.188,0.14 -0.336,0.32 -0.444,0.541 -0.109,0.219 -0.162,0.486 -0.162,0.798 0,0.351 0.06,0.639 0.18,0.864 0.119,0.223 0.277,0.405 0.474,0.545 0.196,0.14 0.419,0.246 0.671,0.318 0.252,0.072 0.511,0.133 0.775,0.18 0.279,0.056 0.546,0.098 0.798,0.127 0.252,0.027 0.473,0.067 0.666,0.119 0.192,0.053 0.343,0.129 0.456,0.228 0.111,0.1 0.168,0.246 0.168,0.438 0,0.224 -0.042,0.404 -0.126,0.541 C 0.306,2.098 0.197,2.202 0.066,2.274 -0.066,2.346 -0.215,2.395 -0.379,2.418 -0.543,2.442 -0.705,2.455 -0.864,2.455 -1.297,2.455 -1.656,2.372 -1.944,2.209 -2.232,2.045 -2.389,1.734 -2.412,1.278 h -1.021 c 0.017,0.384 0.097,0.708 0.241,0.972 0.143,0.264 0.336,0.479 0.575,0.643 0.24,0.164 0.517,0.281 0.828,0.353 0.313,0.072 0.641,0.108 0.984,0.108 0.281,0 0.559,-0.02 0.834,-0.059 C 0.306,3.254 0.556,3.172 0.779,3.049 1.004,2.924 1.184,2.75 1.319,2.526 1.455,2.303 1.524,2.01 1.524,1.65 v -3.191 c 0,-0.24 0.013,-0.416 0.042,-0.529 0.028,-0.112 0.122,-0.168 0.282,-0.168 0.088,0 0.191,0.02 0.312,0.06 V -2.97 C 1.983,-3.074 1.74,-3.125 1.428,-3.125"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path142" /></g><g
id="g144"
transform="translate(348.3647,346.2871)"><path
d="m 0,0 v -1.309 h 0.023 c 0.249,0.504 0.553,0.876 0.913,1.117 0.36,0.239 0.816,0.351 1.369,0.335 v -1.08 C 1.897,-0.937 1.549,-0.992 1.26,-1.105 0.973,-1.217 0.74,-1.381 0.565,-1.597 0.389,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.691 0.061,-3.045 0.061,-3.445 v -2.76 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path146" /></g><g
id="g148"
transform="translate(354.4545,341.1211)"><path
d="M 0,0 C 0.236,0.139 0.426,0.323 0.57,0.551 0.715,0.779 0.82,1.037 0.889,1.325 0.956,1.613 0.99,1.901 0.99,2.189 0.99,2.461 0.959,2.729 0.895,2.994 0.83,3.258 0.729,3.496 0.588,3.707 0.448,3.92 0.266,4.09 0.043,4.217 -0.182,4.346 -0.453,4.41 -0.773,4.41 -1.102,4.41 -1.382,4.348 -1.613,4.224 -1.846,4.1 -2.035,3.934 -2.184,3.725 -2.332,3.518 -2.439,3.277 -2.508,3.006 -2.576,2.733 -2.609,2.449 -2.609,2.153 c 0,-0.28 0.027,-0.559 0.084,-0.84 0.055,-0.28 0.152,-0.534 0.287,-0.762 0.136,-0.228 0.316,-0.412 0.541,-0.551 0.223,-0.141 0.504,-0.211 0.84,-0.211 0.336,0 0.621,0.07 0.857,0.211 M 1.303,-2.791 C 0.838,-3.295 0.11,-3.547 -0.881,-3.547 c -0.289,0 -0.582,0.032 -0.883,0.096 -0.299,0.064 -0.572,0.168 -0.816,0.312 -0.244,0.145 -0.445,0.332 -0.606,0.565 -0.16,0.232 -0.248,0.515 -0.263,0.851 h 1.019 c 0.008,-0.183 0.067,-0.34 0.174,-0.467 0.109,-0.128 0.24,-0.232 0.397,-0.312 0.156,-0.08 0.326,-0.139 0.509,-0.175 0.184,-0.036 0.36,-0.053 0.528,-0.053 0.337,0 0.621,0.058 0.852,0.173 0.232,0.117 0.425,0.276 0.576,0.481 0.152,0.203 0.262,0.449 0.331,0.738 0.067,0.287 0.102,0.604 0.102,0.947 V 0.018 H 1.015 C 0.838,-0.367 0.572,-0.648 0.217,-0.828 -0.14,-1.009 -0.518,-1.099 -0.918,-1.099 c -0.464,0 -0.867,0.084 -1.211,0.252 -0.345,0.168 -0.633,0.394 -0.865,0.679 -0.231,0.283 -0.406,0.615 -0.522,0.996 -0.116,0.379 -0.173,0.781 -0.173,1.205 0,0.368 0.047,0.746 0.144,1.135 0.096,0.387 0.256,0.739 0.48,1.056 0.223,0.315 0.52,0.575 0.887,0.78 0.368,0.203 0.821,0.306 1.356,0.306 0.392,0 0.752,-0.087 1.08,-0.259 0.328,-0.172 0.584,-0.43 0.768,-0.774 h 0.013 v 0.889 h 0.959 v -5.677 c 0,-1.015 -0.232,-1.776 -0.695,-2.28"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path150" /></g><g
id="g152"
transform="translate(362.1342,344.4629)"><path
d="M 0,0 C -0.092,0.216 -0.215,0.402 -0.371,0.558 -0.527,0.714 -0.712,0.838 -0.924,0.93 -1.136,1.021 -1.369,1.068 -1.625,1.068 -1.89,1.068 -2.128,1.021 -2.34,0.93 -2.552,0.838 -2.734,0.711 -2.886,0.552 -3.037,0.392 -3.158,0.205 -3.246,-0.006 -3.334,-0.219 -3.386,-0.444 -3.401,-0.685 H 0.162 C 0.147,-0.444 0.092,-0.217 0,0 m 0.246,-3.984 c -0.464,-0.352 -1.048,-0.528 -1.752,-0.528 -0.496,0 -0.926,0.08 -1.289,0.24 -0.365,0.16 -0.671,0.383 -0.918,0.671 -0.248,0.288 -0.434,0.632 -0.558,1.033 -0.125,0.4 -0.195,0.836 -0.21,1.308 0,0.471 0.071,0.904 0.215,1.295 0.145,0.393 0.346,0.733 0.606,1.021 0.26,0.288 0.568,0.511 0.925,0.672 0.355,0.16 0.745,0.24 1.17,0.24 0.551,0 1.009,-0.114 1.374,-0.343 C 0.172,1.397 0.465,1.107 0.685,0.756 0.904,0.403 1.057,0.02 1.141,-0.396 1.225,-0.812 1.258,-1.209 1.242,-1.584 h -4.643 c -0.009,-0.272 0.024,-0.53 0.095,-0.774 0.073,-0.245 0.189,-0.46 0.349,-0.648 0.159,-0.188 0.363,-0.338 0.611,-0.451 0.248,-0.111 0.54,-0.168 0.876,-0.168 0.433,0 0.786,0.1 1.062,0.301 0.277,0.199 0.459,0.504 0.547,0.912 H 1.147 C 1.01,-3.108 0.711,-3.633 0.246,-3.984"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path154" /></g><g
id="g156"
transform="translate(365.3569,346.2871)"><path
d="m 0,0 v -1.309 h 0.023 c 0.248,0.504 0.553,0.876 0.912,1.117 0.36,0.239 0.817,0.351 1.369,0.335 v -1.08 C 1.895,-0.937 1.548,-0.992 1.26,-1.105 0.972,-1.217 0.739,-1.381 0.563,-1.597 0.388,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.691 0.06,-3.045 0.06,-3.445 v -2.76 H -0.961 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path158" /></g><g
id="g160"
transform="translate(318.2573,330.9863)"><path
d="m 0,0 v 0.9 h 1.044 v 0.924 c 0,0.504 0.145,0.887 0.438,1.147 C 1.773,3.23 2.199,3.36 2.76,3.36 2.855,3.36 2.966,3.352 3.09,3.336 3.214,3.32 3.324,3.297 3.42,3.264 V 2.377 C 3.332,2.408 3.236,2.43 3.132,2.442 3.027,2.454 2.932,2.461 2.844,2.461 2.596,2.461 2.404,2.412 2.268,2.316 2.132,2.221 2.064,2.036 2.064,1.764 V 0.9 h 1.2 V 0 h -1.2 V -5.304 H 1.044 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path162" /></g><g
id="g164"
transform="translate(323.3276,327.7773)"><path
d="m 0,0 c 0.1,-0.293 0.237,-0.537 0.414,-0.732 0.176,-0.197 0.381,-0.346 0.617,-0.451 0.237,-0.104 0.487,-0.156 0.75,-0.156 0.264,0 0.514,0.052 0.75,0.156 0.237,0.105 0.442,0.254 0.618,0.451 0.176,0.195 0.314,0.439 0.415,0.732 0.1,0.291 0.149,0.625 0.149,1.002 0,0.375 -0.049,0.709 -0.149,1.002 C 3.463,2.295 3.325,2.541 3.149,2.741 2.973,2.941 2.768,3.094 2.531,3.197 2.295,3.301 2.045,3.353 1.781,3.353 1.518,3.353 1.268,3.301 1.031,3.197 0.795,3.094 0.59,2.941 0.414,2.741 0.237,2.541 0.1,2.295 0,2.004 -0.101,1.711 -0.15,1.377 -0.15,1.002 -0.15,0.625 -0.101,0.291 0,0 m -1.039,2.279 c 0.129,0.397 0.32,0.741 0.576,1.032 0.256,0.292 0.572,0.523 0.948,0.691 0.376,0.168 0.808,0.252 1.296,0.252 0.496,0 0.93,-0.084 1.303,-0.252 C 3.455,3.834 3.77,3.603 4.025,3.311 4.281,3.02 4.473,2.676 4.602,2.279 4.73,1.883 4.793,1.457 4.793,1.002 4.793,0.545 4.73,0.121 4.602,-0.271 4.473,-0.662 4.281,-1.005 4.025,-1.297 3.77,-1.589 3.455,-1.816 3.084,-1.98 2.711,-2.145 2.277,-2.227 1.781,-2.227 c -0.488,0 -0.92,0.082 -1.296,0.247 -0.376,0.164 -0.692,0.391 -0.948,0.683 -0.256,0.292 -0.447,0.635 -0.576,1.026 -0.127,0.392 -0.191,0.816 -0.191,1.273 0,0.455 0.064,0.881 0.191,1.277"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path166" /></g><g
id="g168"
transform="translate(330.2456,331.8867)"><path
d="m 0,0 v -1.309 h 0.023 c 0.248,0.504 0.553,0.877 0.913,1.118 0.359,0.239 0.816,0.351 1.368,0.336 V -0.936 C 1.896,-0.936 1.548,-0.992 1.26,-1.103 0.972,-1.217 0.739,-1.38 0.563,-1.596 0.388,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.689 0.06,-3.044 0.06,-3.444 v -2.76 H -0.961 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path170" /></g><g
id="g172"
transform="translate(339.1362,325.6826)"><path
d="m 0,0 v 6.097 h -2.207 v 0.815 c 0.287,0 0.567,0.023 0.84,0.066 0.271,0.044 0.517,0.127 0.738,0.246 0.219,0.121 0.405,0.284 0.558,0.492 C 0.08,7.924 0.185,8.189 0.24,8.508 H 1.02 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path174" /></g><g
id="g176"
transform="translate(343.2172,332.3789)"><path
d="M 0,0 C 0.112,0.367 0.286,0.685 0.522,0.953 0.758,1.222 1.052,1.432 1.403,1.584 1.756,1.735 2.155,1.811 2.604,1.811 2.972,1.811 3.317,1.758 3.642,1.65 3.966,1.541 4.248,1.386 4.487,1.182 4.728,0.978 4.918,0.724 5.058,0.42 5.198,0.115 5.269,-0.236 5.269,-0.637 5.269,-1.012 5.21,-1.344 5.094,-1.633 4.978,-1.92 4.823,-2.178 4.632,-2.406 4.44,-2.635 4.22,-2.84 3.972,-3.024 3.724,-3.209 3.468,-3.385 3.204,-3.553 2.94,-3.713 2.676,-3.87 2.411,-4.026 2.147,-4.182 1.905,-4.349 1.687,-4.524 1.466,-4.7 1.278,-4.891 1.122,-5.094 0.966,-5.299 0.864,-5.532 0.815,-5.797 h 4.37 v -0.899 h -5.557 c 0.04,0.504 0.13,0.934 0.269,1.29 0.141,0.355 0.319,0.666 0.535,0.929 0.215,0.264 0.46,0.497 0.732,0.697 0.272,0.2 0.556,0.387 0.852,0.563 0.36,0.225 0.676,0.431 0.948,0.619 0.271,0.188 0.498,0.377 0.678,0.57 0.179,0.192 0.316,0.399 0.408,0.624 0.092,0.224 0.139,0.484 0.139,0.779 0,0.232 -0.045,0.443 -0.133,0.631 C 3.968,0.193 3.85,0.355 3.702,0.492 3.554,0.627 3.38,0.732 3.18,0.804 2.979,0.875 2.768,0.912 2.544,0.912 2.247,0.912 1.993,0.85 1.782,0.726 1.569,0.602 1.396,0.439 1.26,0.24 1.124,0.039 1.026,-0.186 0.966,-0.439 0.905,-0.691 0.88,-0.944 0.888,-1.2 h -1.02 C -0.156,-0.768 -0.112,-0.368 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path178" /></g><g
id="g180"
transform="translate(350.8432,328.7968)"><path
d="m 0,0 c 0.02,-0.396 0.084,-0.768 0.191,-1.116 0.109,-0.349 0.283,-0.642 0.523,-0.882 0.239,-0.24 0.575,-0.36 1.008,-0.36 0.432,0 0.768,0.12 1.008,0.36 0.24,0.24 0.414,0.533 0.522,0.882 0.107,0.348 0.172,0.72 0.191,1.116 0.02,0.396 0.031,0.754 0.031,1.074 0,0.207 -0.002,0.438 -0.006,0.69 C 3.463,2.016 3.443,2.268 3.408,2.52 3.371,2.771 3.32,3.018 3.252,3.258 3.184,3.498 3.084,3.707 2.951,3.888 2.82,4.068 2.654,4.213 2.453,4.326 2.254,4.437 2.01,4.494 1.722,4.494 1.434,4.494 1.189,4.437 0.99,4.326 0.789,4.213 0.623,4.068 0.492,3.888 0.359,3.707 0.26,3.498 0.191,3.258 0.123,3.018 0.072,2.771 0.035,2.52 0,2.268 -0.021,2.016 -0.024,1.764 -0.028,1.512 -0.03,1.281 -0.03,1.074 -0.03,0.754 -0.021,0.396 0,0 m -1.086,2.033 c 0.016,0.336 0.056,0.664 0.119,0.985 0.065,0.32 0.156,0.624 0.277,0.912 0.12,0.288 0.284,0.54 0.492,0.756 C 0.01,4.902 0.271,5.074 0.588,5.201 0.904,5.33 1.281,5.394 1.722,5.394 2.162,5.394 2.539,5.33 2.855,5.201 3.172,5.074 3.434,4.902 3.642,4.686 3.85,4.47 4.014,4.218 4.134,3.93 4.254,3.642 4.346,3.338 4.41,3.018 4.474,2.697 4.514,2.369 4.529,2.033 4.546,1.697 4.554,1.373 4.554,1.062 4.554,0.75 4.546,0.426 4.529,0.09 4.514,-0.246 4.474,-0.574 4.41,-0.895 4.346,-1.215 4.254,-1.517 4.134,-1.801 4.014,-2.084 3.85,-2.334 3.642,-2.551 3.434,-2.766 3.174,-2.937 2.861,-3.061 2.55,-3.184 2.17,-3.246 1.722,-3.246 c -0.441,0 -0.818,0.062 -1.134,0.185 -0.317,0.124 -0.578,0.295 -0.786,0.51 -0.208,0.217 -0.372,0.467 -0.492,0.75 -0.121,0.284 -0.212,0.586 -0.277,0.906 -0.063,0.321 -0.103,0.649 -0.119,0.985 -0.017,0.336 -0.024,0.66 -0.024,0.972 0,0.311 0.007,0.635 0.024,0.971"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path182" /></g><g
id="g184"
transform="translate(361.3911,329.6845)"><path
d="m 0,0 c -0.076,0.276 -0.192,0.522 -0.349,0.738 -0.156,0.216 -0.355,0.388 -0.599,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.877,-0.204 -0.24,-0.136 -0.435,-0.313 -0.588,-0.534 -0.152,-0.221 -0.261,-0.471 -0.33,-0.75 -0.068,-0.28 -0.101,-0.564 -0.101,-0.852 0,-0.304 0.036,-0.598 0.107,-0.882 0.073,-0.284 0.187,-0.534 0.342,-0.75 0.156,-0.216 0.358,-0.39 0.607,-0.522 0.248,-0.133 0.547,-0.198 0.9,-0.198 0.351,0 0.645,0.067 0.882,0.204 0.236,0.136 0.425,0.317 0.57,0.54 0.144,0.224 0.248,0.48 0.312,0.769 0.063,0.287 0.096,0.584 0.096,0.886 C 0.114,-0.558 0.075,-0.276 0,0 m -3.666,2.202 v -0.84 h 0.024 c 0.168,0.344 0.432,0.594 0.791,0.75 0.361,0.157 0.756,0.235 1.189,0.235 0.479,0 0.897,-0.089 1.254,-0.265 C -0.052,1.905 0.243,1.668 0.479,1.368 0.716,1.067 0.893,0.722 1.014,0.33 c 0.12,-0.392 0.18,-0.808 0.18,-1.248 0,-0.44 -0.058,-0.856 -0.174,-1.248 C 0.903,-2.558 0.728,-2.899 0.491,-3.192 0.256,-3.483 -0.04,-3.714 -0.396,-3.882 -0.753,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.152,0 -0.322,0.016 -0.51,0.048 -0.189,0.032 -0.374,0.084 -0.558,0.155 -0.184,0.073 -0.358,0.17 -0.522,0.295 -0.164,0.123 -0.302,0.278 -0.414,0.462 h -0.024 v -3.192 h -1.021 v 8.568 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path186" /></g><g
id="g188"
transform="translate(363.2924,331.8867)"><path
d="M 0,0 H 1.309 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.855 2.4,-3.349 H 4.523 L 2.796,-3.637 1.068,-6.204 h -1.236 l 2.328,3.265 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path190" /></g><g
id="g192"
transform="translate(379.1928,329.1269)"><path
d="m 0,0 v -0.816 h -2.616 v -2.628 h -0.816 v 2.628 H -6.048 V 0 h 2.616 v 2.627 h 0.816 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path194" /></g><g
id="g196"
transform="translate(152.6083,168.5454)"><path
d="m 0,0 c -8.995,0 -16.288,-7.293 -16.288,-16.29 0,-7.197 4.667,-13.302 11.14,-15.457 0.815,-0.149 1.112,0.354 1.112,0.786 0,0.386 -0.014,1.411 -0.022,2.77 -4.531,-0.984 -5.487,2.184 -5.487,2.184 -0.741,1.882 -1.809,2.383 -1.809,2.383 -1.479,1.01 0.112,0.99 0.112,0.99 1.635,-0.115 2.495,-1.679 2.495,-1.679 1.453,-2.489 3.813,-1.77 4.741,-1.353 0.148,1.052 0.568,1.77 1.034,2.177 -3.617,0.411 -7.42,1.809 -7.42,8.051 0,1.778 0.635,3.232 1.677,4.371 -0.168,0.412 -0.727,2.068 0.159,4.311 0,0 1.368,0.438 4.48,-1.67 1.299,0.362 2.693,0.542 4.078,0.548 1.383,-0.006 2.777,-0.186 4.078,-0.548 3.11,2.108 4.475,1.67 4.475,1.67 0.889,-2.243 0.33,-3.899 0.162,-4.311 1.044,-1.139 1.675,-2.593 1.675,-4.371 0,-6.258 -3.809,-7.635 -7.438,-8.038 0.585,-0.503 1.106,-1.497 1.106,-3.017 0,-2.177 -0.02,-3.934 -0.02,-4.468 0,-0.436 0.293,-0.943 1.12,-0.784 6.468,2.159 11.131,8.26 11.131,15.455 C 16.291,-7.293 8.997,0 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path198" /></g><g
id="g200"
transform="translate(350.6088,217.5547)"><path
d="m 0,0 c -33.347,0 -60.388,-27.035 -60.388,-60.388 0,-26.68 17.303,-49.316 41.297,-57.301 3.018,-0.559 4.126,1.31 4.126,2.905 0,1.439 -0.056,6.197 -0.082,11.243 -16.8,-3.653 -20.345,7.125 -20.345,7.125 -2.747,6.979 -6.705,8.836 -6.705,8.836 -5.479,3.748 0.413,3.671 0.413,3.671 6.064,-0.426 9.257,-6.224 9.257,-6.224 5.386,-9.231 14.127,-6.562 17.573,-5.019 0.543,3.902 2.107,6.567 3.834,8.075 -13.413,1.526 -27.513,6.705 -27.513,29.844 0,6.592 2.359,11.979 6.222,16.208 -0.627,1.522 -2.694,7.664 0.586,15.982 0,0 5.071,1.622 16.61,-6.191 4.817,1.338 9.983,2.009 15.115,2.033 5.132,-0.024 10.302,-0.695 15.128,-2.033 11.526,7.813 16.59,6.191 16.59,6.191 3.287,-8.318 1.22,-14.46 0.593,-15.982 3.872,-4.229 6.214,-9.616 6.214,-16.208 0,-23.195 -14.127,-28.301 -27.574,-29.796 2.166,-1.874 4.096,-5.549 4.096,-11.183 0,-8.08 -0.069,-14.583 -0.069,-16.572 0,-1.608 1.086,-3.491 4.147,-2.898 23.982,7.994 41.263,30.622 41.263,57.294 C 60.388,-27.035 33.351,0 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none"
id="path202" /></g><g
id="g204"
transform="translate(313.0932,130.8515)"><path
d="m 0,0 c -0.133,-0.301 -0.605,-0.391 -1.035,-0.184 -0.439,0.197 -0.684,0.606 -0.542,0.907 0.13,0.308 0.602,0.394 1.04,0.188 C -0.099,0.714 0.151,0.301 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path206" /></g><g
id="g208"
transform="translate(315.5395,128.123)"><path
d="M 0,0 C -0.288,-0.267 -0.852,-0.143 -1.233,0.279 -1.629,0.7 -1.702,1.264 -1.41,1.534 -1.113,1.801 -0.567,1.676 -0.172,1.255 0.224,0.829 0.301,0.27 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path210" /></g><g
id="g212"
transform="translate(317.9204,124.6455)"><path
d="M 0,0 C -0.37,-0.258 -0.976,-0.017 -1.35,0.52 -1.72,1.058 -1.72,1.702 -1.341,1.96 -0.967,2.218 -0.37,1.985 0.009,1.453 0.378,0.907 0.378,0.263 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path214" /></g><g
id="g216"
transform="translate(321.1821,121.2851)"><path
d="M 0,0 C -0.331,-0.365 -1.036,-0.267 -1.552,0.231 -2.08,0.718 -2.227,1.409 -1.896,1.774 -1.56,2.14 -0.851,2.037 -0.331,1.543 0.193,1.057 0.352,0.361 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path218" /></g><g
id="g220"
transform="translate(325.6821,119.334)"><path
d="m 0,0 c -0.147,-0.473 -0.825,-0.687 -1.509,-0.486 -0.683,0.207 -1.13,0.76 -0.992,1.238 0.142,0.477 0.824,0.7 1.513,0.485 C -0.306,1.031 0.142,0.481 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path222" /></g><g
id="g224"
transform="translate(330.6245,118.9726)"><path
d="m 0,0 c 0.017,-0.498 -0.563,-0.911 -1.281,-0.92 -0.722,-0.017 -1.307,0.387 -1.315,0.877 0,0.503 0.568,0.911 1.289,0.924 C -0.589,0.895 0,0.494 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path226" /></g><g
id="g228"
transform="translate(335.2231,119.7549)"><path
d="m 0,0 c 0.086,-0.485 -0.413,-0.984 -1.126,-1.117 -0.701,-0.129 -1.35,0.172 -1.439,0.653 -0.087,0.498 0.42,0.997 1.121,1.126 C -0.73,0.786 -0.091,0.494 0,0"
style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path230" /></g><g
id="g232"
transform="translate(224.8979,223.4882)"><path
d="M 0,0 V -0.5"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path234" /></g><g
id="g236"
transform="translate(224.8979,220.9882)"><path
d="M 0,0 V -133.993"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:1, 2;stroke-dashoffset:0;stroke-opacity:1"
id="path238" /></g><g
id="g240"
transform="translate(224.8979,85.9951)"><path
d="M 0,0 V -0.5"
style="fill:none;stroke:#3a7fc3;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
id="path242" /></g><g
id="g244"
transform="translate(133.2758,71.4795)"><path
d="m 0,0 c -0.38,0.276 -0.866,0.414 -1.458,0.414 -0.24,0 -0.476,-0.024 -0.708,-0.071 -0.232,-0.049 -0.438,-0.129 -0.618,-0.241 -0.18,-0.113 -0.324,-0.262 -0.432,-0.451 -0.108,-0.187 -0.162,-0.422 -0.162,-0.701 0,-0.264 0.078,-0.478 0.234,-0.642 0.156,-0.165 0.364,-0.298 0.624,-0.402 0.26,-0.104 0.554,-0.19 0.882,-0.259 0.328,-0.067 0.662,-0.141 1.002,-0.22 0.34,-0.08 0.674,-0.175 1.002,-0.284 C 0.694,-2.964 0.988,-3.11 1.248,-3.294 1.508,-3.478 1.716,-3.71 1.872,-3.989 2.028,-4.271 2.106,-4.622 2.106,-5.046 2.106,-5.502 2.004,-5.892 1.8,-6.216 1.596,-6.54 1.334,-6.804 1.014,-7.008 0.694,-7.212 0.336,-7.36 -0.06,-7.452 -0.456,-7.544 -0.85,-7.59 -1.242,-7.59 c -0.48,0 -0.934,0.06 -1.362,0.18 -0.428,0.12 -0.804,0.302 -1.128,0.546 -0.324,0.244 -0.58,0.556 -0.768,0.936 -0.188,0.38 -0.282,0.829 -0.282,1.35 h 1.08 c 0,-0.361 0.07,-0.67 0.21,-0.93 0.14,-0.261 0.324,-0.474 0.552,-0.642 0.228,-0.167 0.494,-0.292 0.798,-0.373 0.304,-0.08 0.616,-0.119 0.936,-0.119 0.256,0 0.514,0.024 0.774,0.073 0.26,0.046 0.494,0.128 0.702,0.246 0.208,0.115 0.376,0.273 0.504,0.472 0.128,0.201 0.192,0.457 0.192,0.769 0,0.296 -0.078,0.536 -0.234,0.72 -0.156,0.183 -0.364,0.334 -0.624,0.45 -0.26,0.116 -0.554,0.21 -0.882,0.282 -0.328,0.072 -0.662,0.147 -1.002,0.223 -0.34,0.075 -0.674,0.163 -1.002,0.263 -0.328,0.1 -0.622,0.232 -0.882,0.396 -0.26,0.164 -0.468,0.376 -0.624,0.636 -0.156,0.259 -0.234,0.586 -0.234,0.978 0,0.432 0.088,0.806 0.264,1.122 0.176,0.316 0.41,0.575 0.702,0.78 0.292,0.204 0.624,0.356 0.996,0.456 0.372,0.1 0.754,0.15 1.146,0.15 0.44,0 0.848,-0.053 1.224,-0.156 C 0.19,1.114 0.52,0.95 0.804,0.725 1.088,0.502 1.312,0.22 1.476,-0.12 1.64,-0.46 1.73,-0.866 1.746,-1.338 H 0.666 C 0.602,-0.722 0.38,-0.276 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path246" /></g><g
id="g248"
transform="translate(137.5537,70.2851)"><path
d="m 0,0 v -0.912 h 0.024 c 0.464,0.705 1.132,1.057 2.004,1.057 0.384,0 0.732,-0.081 1.044,-0.241 0.312,-0.16 0.532,-0.431 0.66,-0.816 0.208,0.336 0.482,0.596 0.822,0.78 0.34,0.185 0.714,0.277 1.122,0.277 0.312,0 0.594,-0.035 0.846,-0.102 0.252,-0.068 0.468,-0.175 0.648,-0.318 0.18,-0.145 0.32,-0.33 0.42,-0.559 0.1,-0.228 0.15,-0.502 0.15,-0.822 V -6.203 H 6.72 v 4.067 c 0,0.193 -0.016,0.372 -0.048,0.54 -0.032,0.168 -0.092,0.315 -0.18,0.438 -0.088,0.125 -0.21,0.222 -0.366,0.295 -0.156,0.072 -0.358,0.107 -0.606,0.107 -0.504,0 -0.9,-0.143 -1.188,-0.431 C 4.044,-1.476 3.9,-1.859 3.9,-2.34 V -6.203 H 2.88 v 4.067 c 0,0.2 -0.018,0.384 -0.054,0.552 -0.036,0.168 -0.098,0.314 -0.186,0.438 -0.088,0.125 -0.206,0.22 -0.354,0.289 -0.148,0.068 -0.338,0.101 -0.57,0.101 -0.296,0 -0.55,-0.059 -0.762,-0.18 C 0.742,-1.056 0.57,-1.199 0.438,-1.367 0.306,-1.535 0.21,-1.709 0.15,-1.89 0.09,-2.07 0.06,-2.22 0.06,-2.34 V -6.203 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path250" /></g><g
id="g252"
transform="translate(150.1655,67.0761)"><path
d="m 0,0 c -0.208,-0.045 -0.426,-0.08 -0.654,-0.108 -0.228,-0.029 -0.458,-0.06 -0.69,-0.097 -0.232,-0.035 -0.44,-0.094 -0.624,-0.174 -0.184,-0.08 -0.334,-0.193 -0.45,-0.342 -0.116,-0.148 -0.174,-0.349 -0.174,-0.605 0,-0.168 0.034,-0.311 0.102,-0.426 0.068,-0.117 0.156,-0.211 0.264,-0.283 0.108,-0.071 0.236,-0.123 0.384,-0.155 0.148,-0.033 0.298,-0.048 0.45,-0.048 0.336,0 0.624,0.045 0.864,0.137 0.24,0.092 0.436,0.208 0.588,0.349 0.152,0.139 0.264,0.291 0.336,0.455 0.072,0.164 0.108,0.318 0.108,0.463 V 0.209 C 0.376,0.113 0.208,0.043 0,0 m 1.428,-3.127 c -0.264,0 -0.474,0.074 -0.63,0.223 -0.156,0.147 -0.234,0.389 -0.234,0.725 -0.28,-0.336 -0.606,-0.578 -0.978,-0.725 -0.372,-0.149 -0.774,-0.223 -1.206,-0.223 -0.28,0 -0.544,0.03 -0.792,0.09 -0.248,0.06 -0.466,0.16 -0.654,0.301 -0.188,0.139 -0.336,0.319 -0.444,0.539 -0.108,0.22 -0.162,0.486 -0.162,0.799 0,0.351 0.06,0.639 0.18,0.863 0.12,0.224 0.278,0.406 0.474,0.547 0.196,0.139 0.42,0.246 0.672,0.318 0.252,0.071 0.51,0.131 0.774,0.18 0.28,0.055 0.546,0.097 0.798,0.125 0.252,0.028 0.474,0.068 0.666,0.121 0.192,0.051 0.344,0.127 0.456,0.227 0.112,0.101 0.168,0.246 0.168,0.439 0,0.223 -0.042,0.403 -0.126,0.539 -0.084,0.137 -0.192,0.24 -0.324,0.312 -0.132,0.073 -0.28,0.121 -0.444,0.145 -0.164,0.023 -0.326,0.035 -0.486,0.035 -0.432,0 -0.792,-0.082 -1.08,-0.246 -0.288,-0.164 -0.444,-0.474 -0.468,-0.93 h -1.02 c 0.016,0.384 0.096,0.708 0.24,0.973 0.144,0.264 0.336,0.478 0.576,0.642 0.24,0.163 0.516,0.282 0.828,0.354 0.312,0.071 0.64,0.108 0.984,0.108 0.28,0 0.558,-0.02 0.834,-0.061 C 0.306,3.254 0.556,3.172 0.78,3.047 1.004,2.924 1.184,2.749 1.32,2.525 1.456,2.301 1.524,2.01 1.524,1.649 v -3.192 c 0,-0.24 0.014,-0.416 0.042,-0.527 0.028,-0.113 0.122,-0.168 0.282,-0.168 0.088,0 0.192,0.019 0.312,0.059 V -2.971 C 1.984,-3.074 1.74,-3.127 1.428,-3.127"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path254" /></g><path
d="m 154.354,64.082 h -1.02 v 8.567 h 1.02 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path256" /><path
d="m 157.017,64.082 h -1.02 v 8.567 h 1.02 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path258" /><g
id="g260"
transform="translate(101.854,54.9863)"><path
d="m 0,0 v 0.899 h 1.044 v 0.924 c 0,0.504 0.146,0.886 0.438,1.146 0.292,0.26 0.718,0.39 1.278,0.39 0.096,0 0.206,-0.007 0.33,-0.023 C 3.214,3.319 3.324,3.295 3.42,3.264 V 2.375 C 3.332,2.407 3.236,2.43 3.132,2.441 3.028,2.453 2.932,2.459 2.844,2.459 2.596,2.459 2.404,2.411 2.268,2.315 2.132,2.219 2.064,2.035 2.064,1.764 V 0.899 h 1.2 V 0 h -1.2 V -5.305 H 1.044 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path262" /></g><g
id="g264"
transform="translate(106.9238,51.7754)"><path
d="m 0,0 c 0.1,-0.292 0.238,-0.535 0.414,-0.732 0.176,-0.196 0.382,-0.346 0.618,-0.45 0.236,-0.103 0.486,-0.156 0.75,-0.156 0.264,0 0.514,0.053 0.75,0.156 0.236,0.104 0.442,0.254 0.618,0.45 0.176,0.197 0.314,0.44 0.414,0.732 0.1,0.292 0.15,0.626 0.15,1.002 0,0.377 -0.05,0.71 -0.15,1.002 C 3.464,2.297 3.326,2.542 3.15,2.742 2.974,2.941 2.768,3.094 2.532,3.198 2.296,3.303 2.046,3.354 1.782,3.354 1.518,3.354 1.268,3.303 1.032,3.198 0.796,3.094 0.59,2.941 0.414,2.742 0.238,2.542 0.1,2.297 0,2.004 -0.1,1.712 -0.15,1.379 -0.15,1.002 -0.15,0.626 -0.1,0.292 0,0 m -1.038,2.28 c 0.128,0.396 0.32,0.74 0.576,1.033 0.256,0.291 0.572,0.521 0.948,0.689 0.376,0.168 0.808,0.252 1.296,0.252 0.496,0 0.93,-0.084 1.302,-0.252 C 3.456,3.834 3.77,3.604 4.026,3.313 4.282,3.02 4.474,2.676 4.602,2.28 4.73,1.885 4.794,1.458 4.794,1.002 4.794,0.547 4.73,0.122 4.602,-0.27 4.474,-0.662 4.282,-1.004 4.026,-1.296 3.77,-1.588 3.456,-1.816 3.084,-1.98 2.712,-2.144 2.278,-2.226 1.782,-2.226 c -0.488,0 -0.92,0.082 -1.296,0.246 -0.376,0.164 -0.692,0.392 -0.948,0.684 -0.256,0.292 -0.448,0.634 -0.576,1.026 -0.128,0.392 -0.192,0.817 -0.192,1.272 0,0.456 0.064,0.883 0.192,1.278"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path266" /></g><g
id="g268"
transform="translate(113.8417,55.8857)"><path
d="m 0,0 v -1.308 h 0.024 c 0.248,0.504 0.552,0.875 0.912,1.116 0.36,0.24 0.816,0.351 1.368,0.336 v -1.08 C 1.896,-0.936 1.548,-0.992 1.26,-1.104 0.972,-1.216 0.74,-1.38 0.564,-1.597 0.388,-1.811 0.26,-2.074 0.18,-2.382 0.1,-2.69 0.06,-3.044 0.06,-3.444 v -2.76 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path270" /></g><g
id="g272"
transform="translate(122.7333,49.6816)"><path
d="m 0,0 v 6.096 h -2.208 v 0.816 c 0.288,0 0.568,0.022 0.84,0.067 0.272,0.042 0.518,0.125 0.738,0.246 0.22,0.119 0.406,0.283 0.558,0.491 C 0.08,7.924 0.184,8.188 0.24,8.508 H 1.02 L 1.02,0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path274" /></g><g
id="g276"
transform="translate(128.8295,54.1035)"><path
d="M 0,0 C -0.216,-0.1 -0.4,-0.236 -0.552,-0.408 -0.704,-0.58 -0.818,-0.784 -0.893,-1.02 -0.97,-1.256 -1.008,-1.506 -1.008,-1.77 c 0,-0.263 0.04,-0.511 0.12,-0.744 0.08,-0.232 0.194,-0.431 0.342,-0.599 0.148,-0.168 0.332,-0.303 0.552,-0.403 0.22,-0.1 0.47,-0.15 0.75,-0.15 0.28,0 0.526,0.05 0.738,0.15 0.212,0.1 0.39,0.239 0.534,0.414 0.144,0.176 0.254,0.378 0.33,0.606 0.076,0.228 0.114,0.467 0.114,0.715 0,0.263 -0.034,0.513 -0.102,0.75 C 2.302,-0.796 2.196,-0.592 2.052,-0.42 1.908,-0.248 1.728,-0.109 1.512,-0.006 1.296,0.098 1.044,0.15 0.756,0.15 0.468,0.15 0.216,0.1 0,0 M 1.848,2.838 C 1.6,3.07 1.272,3.186 0.864,3.186 0.432,3.186 0.084,3.08 -0.18,2.868 -0.444,2.656 -0.65,2.389 -0.798,2.064 -0.946,1.74 -1.048,1.391 -1.104,1.014 -1.16,0.639 -1.192,0.286 -1.2,-0.042 l 0.024,-0.024 c 0.24,0.392 0.538,0.675 0.894,0.852 0.356,0.176 0.766,0.265 1.23,0.265 C 1.356,1.051 1.722,0.98 2.046,0.84 2.37,0.7 2.642,0.506 2.862,0.258 3.082,0.01 3.253,-0.281 3.372,-0.617 3.492,-0.954 3.552,-1.318 3.552,-1.71 3.552,-2.021 3.504,-2.346 3.408,-2.682 3.312,-3.018 3.154,-3.324 2.934,-3.6 2.714,-3.876 2.422,-4.104 2.058,-4.283 1.694,-4.464 1.244,-4.554 0.708,-4.554 c -0.632,0 -1.14,0.128 -1.524,0.384 -0.384,0.256 -0.68,0.584 -0.888,0.984 -0.208,0.4 -0.346,0.84 -0.414,1.321 -0.068,0.479 -0.102,0.943 -0.102,1.391 0,0.583 0.05,1.15 0.15,1.699 0.1,0.546 0.27,1.033 0.511,1.457 C -1.32,3.105 -1,3.445 -0.6,3.702 -0.2,3.958 0.304,4.086 0.912,4.086 1.616,4.086 2.176,3.9 2.592,3.528 3.008,3.156 3.248,2.618 3.312,1.914 H 2.292 C 2.244,2.299 2.096,2.605 1.848,2.838"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path278" /></g><g
id="g280"
transform="translate(138.3159,53.6836)"><path
d="m 0,0 c -0.076,0.275 -0.192,0.521 -0.348,0.738 -0.156,0.216 -0.356,0.388 -0.6,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.876,-0.204 -0.24,-0.137 -0.436,-0.314 -0.588,-0.534 -0.152,-0.22 -0.262,-0.47 -0.33,-0.75 -0.069,-0.28 -0.102,-0.564 -0.102,-0.853 0,-0.303 0.036,-0.597 0.108,-0.88 0.071,-0.286 0.186,-0.536 0.341,-0.75 0.157,-0.217 0.358,-0.391 0.607,-0.523 0.247,-0.132 0.548,-0.198 0.9,-0.198 0.351,0 0.646,0.068 0.882,0.204 0.236,0.136 0.425,0.315 0.569,0.54 0.145,0.224 0.249,0.481 0.312,0.768 0.064,0.289 0.097,0.584 0.097,0.888 C 0.114,-0.559 0.076,-0.275 0,0 M -3.666,2.202 V 1.361 h 0.024 c 0.168,0.345 0.431,0.595 0.792,0.75 0.36,0.156 0.756,0.235 1.188,0.235 0.48,0 0.898,-0.088 1.254,-0.264 C -0.052,1.906 0.244,1.668 0.48,1.368 0.716,1.068 0.893,0.722 1.014,0.33 c 0.12,-0.392 0.18,-0.809 0.18,-1.248 0,-0.44 -0.058,-0.856 -0.175,-1.248 C 0.904,-2.559 0.727,-2.9 0.492,-3.191 0.256,-3.484 -0.041,-3.714 -0.396,-3.882 -0.753,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.153,0 -0.323,0.017 -0.511,0.048 -0.188,0.032 -0.374,0.084 -0.557,0.156 -0.184,0.072 -0.359,0.17 -0.522,0.294 -0.164,0.124 -0.302,0.278 -0.414,0.462 h -0.024 v -3.191 h -1.02 v 8.567 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path282" /></g><g
id="g284"
transform="translate(140.2172,55.8857)"><path
d="M 0,0 H 1.308 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.856 2.4,-3.348 H 4.524 L 2.796,-3.636 1.068,-6.204 H -0.168 L 2.16,-2.94 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path286" /></g><path
d="m 150.225,52.537 h -3.468 v 0.961 h 3.468 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path288" /><g
id="g290"
transform="translate(154.0771,49.6816)"><path
d="m 0,0 v 6.096 h -2.208 v 0.816 c 0.288,0 0.568,0.022 0.84,0.067 0.272,0.042 0.518,0.125 0.738,0.246 0.22,0.119 0.406,0.283 0.558,0.491 C 0.08,7.924 0.184,8.188 0.24,8.508 H 1.02 L 1.02,0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path292" /></g><g
id="g294"
transform="translate(158.1572,56.3769)"><path
d="m 0,0 c 0.112,0.369 0.286,0.686 0.522,0.955 0.236,0.268 0.53,0.478 0.882,0.629 0.352,0.152 0.752,0.228 1.2,0.228 0.368,0 0.714,-0.053 1.038,-0.162 C 3.966,1.543 4.248,1.387 4.488,1.183 4.728,0.979 4.918,0.725 5.058,0.421 5.198,0.117 5.268,-0.235 5.268,-0.635 5.268,-1.012 5.21,-1.344 5.094,-1.631 4.977,-1.92 4.824,-2.178 4.632,-2.405 4.44,-2.633 4.22,-2.84 3.972,-3.023 3.724,-3.207 3.468,-3.383 3.204,-3.551 2.94,-3.711 2.676,-3.869 2.412,-4.025 2.148,-4.182 1.906,-4.348 1.686,-4.523 1.466,-4.699 1.278,-4.889 1.122,-5.094 0.966,-5.297 0.864,-5.531 0.816,-5.795 h 4.368 v -0.9 h -5.556 c 0.04,0.504 0.13,0.933 0.27,1.29 0.14,0.356 0.318,0.666 0.534,0.93 0.216,0.264 0.46,0.495 0.732,0.696 0.272,0.199 0.556,0.387 0.852,0.564 0.36,0.224 0.676,0.43 0.948,0.617 0.272,0.188 0.498,0.379 0.678,0.571 0.18,0.191 0.316,0.4 0.408,0.624 0.092,0.223 0.138,0.483 0.138,0.78 0,0.231 -0.045,0.441 -0.132,0.63 C 3.968,0.194 3.85,0.356 3.702,0.492 3.554,0.629 3.38,0.732 3.18,0.805 2.98,0.877 2.768,0.912 2.544,0.912 2.247,0.912 1.994,0.851 1.782,0.727 1.57,0.603 1.396,0.44 1.26,0.24 1.124,0.041 1.026,-0.186 0.966,-0.437 0.906,-0.689 0.88,-0.943 0.888,-1.199 h -1.02 C -0.156,-0.768 -0.112,-0.367 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path296" /></g><g
id="g298"
transform="translate(165.7832,52.7949)"><path
d="m 0,0 c 0.02,-0.396 0.084,-0.768 0.192,-1.115 0.108,-0.348 0.282,-0.643 0.522,-0.882 0.24,-0.24 0.576,-0.36 1.008,-0.36 0.432,0 0.768,0.12 1.008,0.36 0.24,0.239 0.414,0.534 0.522,0.882 0.108,0.347 0.172,0.719 0.192,1.115 0.02,0.396 0.03,0.755 0.03,1.074 0,0.209 -0.002,0.439 -0.006,0.691 C 3.464,2.017 3.444,2.268 3.408,2.52 3.372,2.773 3.32,3.018 3.252,3.259 3.184,3.498 3.084,3.709 2.952,3.889 2.82,4.068 2.654,4.215 2.454,4.326 2.254,4.438 2.01,4.494 1.722,4.494 1.434,4.494 1.19,4.438 0.99,4.326 0.79,4.215 0.624,4.068 0.492,3.889 0.36,3.709 0.26,3.498 0.192,3.259 0.124,3.018 0.072,2.773 0.036,2.52 0,2.268 -0.02,2.017 -0.024,1.765 -0.028,1.513 -0.03,1.283 -0.03,1.074 -0.03,0.755 -0.02,0.396 0,0 m -1.086,2.035 c 0.016,0.336 0.056,0.664 0.12,0.983 0.064,0.32 0.156,0.625 0.276,0.913 0.12,0.288 0.284,0.54 0.492,0.755 C 0.01,4.902 0.272,5.074 0.588,5.203 0.904,5.33 1.282,5.395 1.722,5.395 2.162,5.395 2.54,5.33 2.856,5.203 3.172,5.074 3.434,4.902 3.642,4.686 3.85,4.471 4.014,4.219 4.134,3.931 4.254,3.643 4.346,3.338 4.41,3.018 4.474,2.699 4.514,2.371 4.53,2.035 4.546,1.699 4.554,1.375 4.554,1.062 4.554,0.75 4.546,0.427 4.53,0.091 4.514,-0.245 4.474,-0.573 4.41,-0.893 4.346,-1.213 4.254,-1.516 4.134,-1.799 4.014,-2.084 3.85,-2.334 3.642,-2.549 3.434,-2.766 3.174,-2.936 2.862,-3.059 2.55,-3.184 2.17,-3.245 1.722,-3.245 c -0.44,0 -0.818,0.061 -1.134,0.186 -0.316,0.123 -0.578,0.293 -0.786,0.51 -0.208,0.215 -0.372,0.465 -0.492,0.75 -0.12,0.283 -0.212,0.586 -0.276,0.906 -0.064,0.32 -0.104,0.648 -0.12,0.984 -0.016,0.336 -0.024,0.659 -0.024,0.971 0,0.313 0.008,0.637 0.024,0.973"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path300" /></g><g
id="g302"
transform="translate(176.3315,53.6836)"><path
d="m 0,0 c -0.076,0.275 -0.192,0.521 -0.348,0.738 -0.156,0.216 -0.356,0.388 -0.6,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.876,-0.204 -0.24,-0.137 -0.436,-0.314 -0.588,-0.534 -0.152,-0.22 -0.262,-0.47 -0.33,-0.75 -0.069,-0.28 -0.102,-0.564 -0.102,-0.853 0,-0.303 0.036,-0.597 0.108,-0.88 0.071,-0.286 0.186,-0.536 0.342,-0.75 0.156,-0.217 0.357,-0.391 0.606,-0.523 0.248,-0.132 0.548,-0.198 0.9,-0.198 0.351,0 0.646,0.068 0.882,0.204 0.236,0.136 0.425,0.315 0.57,0.54 0.144,0.224 0.248,0.481 0.312,0.768 0.063,0.289 0.096,0.584 0.096,0.888 C 0.114,-0.559 0.076,-0.275 0,0 M -3.666,2.202 V 1.361 h 0.024 c 0.168,0.345 0.431,0.595 0.792,0.75 0.36,0.156 0.756,0.235 1.188,0.235 0.48,0 0.898,-0.088 1.254,-0.264 C -0.052,1.906 0.244,1.668 0.48,1.368 0.716,1.068 0.893,0.722 1.014,0.33 c 0.12,-0.392 0.18,-0.809 0.18,-1.248 0,-0.44 -0.058,-0.856 -0.174,-1.248 C 0.904,-2.559 0.727,-2.9 0.492,-3.191 0.256,-3.484 -0.04,-3.714 -0.396,-3.882 -0.752,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.152,0 -0.323,0.017 -0.51,0.048 -0.188,0.032 -0.375,0.084 -0.558,0.156 -0.184,0.072 -0.358,0.17 -0.522,0.294 -0.164,0.124 -0.302,0.278 -0.414,0.462 h -0.024 v -3.191 h -1.02 v 8.567 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path304" /></g><g
id="g306"
transform="translate(178.2329,55.8857)"><path
d="M 0,0 H 1.308 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.856 2.4,-3.348 H 4.524 L 2.796,-3.636 1.068,-6.204 H -0.168 L 2.16,-2.94 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path308" /></g><g
id="g310"
transform="translate(335.6333,72.6504)"><path
d="M 0,0 V -7.607 H 4.536 V -8.568 H -1.14 l 0,8.568 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path312" /></g><g
id="g314"
transform="translate(344.3334,67.0761)"><path
d="m 0,0 c -0.209,-0.044 -0.426,-0.08 -0.654,-0.107 -0.229,-0.029 -0.459,-0.061 -0.691,-0.096 -0.231,-0.037 -0.44,-0.095 -0.624,-0.174 -0.183,-0.08 -0.334,-0.195 -0.449,-0.343 -0.117,-0.147 -0.174,-0.35 -0.174,-0.606 0,-0.168 0.034,-0.31 0.102,-0.426 0.067,-0.115 0.156,-0.209 0.264,-0.281 0.107,-0.072 0.236,-0.125 0.384,-0.156 0.148,-0.033 0.297,-0.049 0.45,-0.049 0.335,0 0.624,0.047 0.864,0.138 0.239,0.092 0.435,0.208 0.588,0.348 0.151,0.141 0.264,0.293 0.336,0.457 0.071,0.163 0.108,0.317 0.108,0.461 V 0.211 C 0.375,0.114 0.207,0.045 0,0 m 1.428,-3.125 c -0.264,0 -0.475,0.073 -0.631,0.221 -0.155,0.148 -0.233,0.39 -0.233,0.726 -0.281,-0.336 -0.607,-0.578 -0.978,-0.726 -0.373,-0.148 -0.774,-0.221 -1.207,-0.221 -0.279,0 -0.543,0.029 -0.791,0.09 -0.248,0.059 -0.467,0.16 -0.654,0.299 -0.188,0.14 -0.336,0.32 -0.444,0.541 -0.109,0.219 -0.162,0.486 -0.162,0.798 0,0.351 0.06,0.639 0.18,0.864 0.119,0.223 0.277,0.405 0.474,0.545 0.196,0.14 0.419,0.246 0.671,0.318 0.252,0.072 0.511,0.133 0.775,0.18 0.279,0.056 0.546,0.098 0.798,0.127 0.252,0.027 0.473,0.067 0.666,0.119 0.192,0.053 0.343,0.129 0.456,0.228 0.111,0.1 0.168,0.246 0.168,0.438 0,0.224 -0.042,0.404 -0.126,0.541 C 0.306,2.098 0.197,2.202 0.066,2.274 -0.066,2.346 -0.215,2.395 -0.379,2.418 -0.543,2.442 -0.705,2.455 -0.864,2.455 -1.297,2.455 -1.656,2.372 -1.944,2.209 -2.232,2.045 -2.389,1.734 -2.412,1.278 h -1.021 c 0.017,0.384 0.097,0.708 0.241,0.972 0.143,0.264 0.336,0.479 0.575,0.643 0.24,0.164 0.517,0.281 0.828,0.353 0.313,0.072 0.641,0.108 0.984,0.108 0.281,0 0.559,-0.02 0.834,-0.059 C 0.306,3.254 0.556,3.172 0.779,3.049 1.004,2.924 1.184,2.75 1.319,2.526 1.455,2.303 1.524,2.01 1.524,1.65 v -3.191 c 0,-0.24 0.013,-0.416 0.042,-0.529 0.028,-0.112 0.122,-0.168 0.282,-0.168 0.088,0 0.191,0.02 0.312,0.06 V -2.97 C 1.983,-3.074 1.74,-3.125 1.428,-3.125"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path316" /></g><g
id="g318"
transform="translate(348.3647,70.2871)"><path
d="m 0,0 v -1.309 h 0.023 c 0.249,0.504 0.553,0.876 0.913,1.117 0.36,0.239 0.816,0.351 1.369,0.335 v -1.08 C 1.897,-0.937 1.549,-0.992 1.26,-1.105 0.973,-1.217 0.74,-1.381 0.565,-1.597 0.389,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.691 0.061,-3.045 0.061,-3.445 v -2.76 H -0.96 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path320" /></g><g
id="g322"
transform="translate(354.4545,65.1211)"><path
d="M 0,0 C 0.236,0.139 0.426,0.323 0.57,0.551 0.715,0.779 0.82,1.037 0.889,1.325 0.956,1.613 0.99,1.901 0.99,2.189 0.99,2.461 0.959,2.729 0.895,2.994 0.83,3.258 0.729,3.496 0.588,3.707 0.448,3.92 0.266,4.09 0.043,4.217 -0.182,4.346 -0.453,4.41 -0.773,4.41 -1.102,4.41 -1.382,4.348 -1.613,4.224 -1.846,4.1 -2.035,3.934 -2.184,3.725 -2.332,3.518 -2.439,3.277 -2.508,3.006 -2.576,2.733 -2.609,2.449 -2.609,2.153 c 0,-0.28 0.027,-0.559 0.084,-0.84 0.055,-0.28 0.152,-0.534 0.287,-0.762 0.136,-0.228 0.316,-0.412 0.541,-0.551 0.223,-0.141 0.504,-0.211 0.84,-0.211 0.336,0 0.621,0.07 0.857,0.211 M 1.303,-2.791 C 0.838,-3.295 0.11,-3.547 -0.881,-3.547 c -0.289,0 -0.582,0.032 -0.883,0.096 -0.299,0.064 -0.572,0.168 -0.816,0.312 -0.244,0.145 -0.445,0.332 -0.606,0.565 -0.16,0.232 -0.248,0.515 -0.263,0.851 h 1.019 c 0.008,-0.183 0.067,-0.34 0.174,-0.468 0.109,-0.127 0.24,-0.231 0.397,-0.311 0.156,-0.08 0.326,-0.139 0.509,-0.175 0.184,-0.036 0.36,-0.054 0.528,-0.054 0.337,0 0.621,0.059 0.852,0.174 0.232,0.116 0.425,0.276 0.576,0.481 0.152,0.203 0.262,0.449 0.331,0.738 0.067,0.287 0.102,0.604 0.102,0.947 V 0.018 H 1.015 C 0.838,-0.367 0.572,-0.648 0.217,-0.828 -0.14,-1.009 -0.518,-1.099 -0.918,-1.099 c -0.464,0 -0.867,0.084 -1.211,0.252 -0.345,0.168 -0.633,0.394 -0.865,0.679 -0.231,0.283 -0.406,0.615 -0.522,0.996 -0.116,0.379 -0.173,0.781 -0.173,1.205 0,0.368 0.047,0.746 0.144,1.135 0.096,0.387 0.256,0.739 0.48,1.056 0.223,0.315 0.52,0.575 0.887,0.78 0.368,0.203 0.821,0.305 1.356,0.305 0.392,0 0.752,-0.086 1.08,-0.258 0.328,-0.172 0.584,-0.43 0.768,-0.774 h 0.013 v 0.889 h 0.959 v -5.677 c 0,-1.015 -0.232,-1.776 -0.695,-2.28"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path324" /></g><g
id="g326"
transform="translate(362.1342,68.4629)"><path
d="M 0,0 C -0.092,0.216 -0.215,0.402 -0.371,0.558 -0.527,0.714 -0.712,0.838 -0.924,0.93 -1.136,1.021 -1.369,1.068 -1.625,1.068 -1.89,1.068 -2.128,1.021 -2.34,0.93 -2.552,0.838 -2.734,0.711 -2.886,0.552 -3.037,0.392 -3.158,0.205 -3.246,-0.006 -3.334,-0.219 -3.386,-0.444 -3.401,-0.685 H 0.162 C 0.147,-0.444 0.092,-0.217 0,0 m 0.246,-3.984 c -0.464,-0.352 -1.048,-0.528 -1.752,-0.528 -0.496,0 -0.926,0.08 -1.289,0.239 -0.365,0.161 -0.671,0.384 -0.918,0.672 -0.248,0.288 -0.434,0.632 -0.558,1.033 -0.125,0.4 -0.195,0.836 -0.21,1.308 0,0.471 0.071,0.903 0.215,1.295 0.145,0.393 0.346,0.733 0.606,1.021 0.26,0.288 0.568,0.511 0.925,0.671 0.355,0.161 0.745,0.241 1.17,0.241 0.551,0 1.009,-0.114 1.374,-0.343 C 0.172,1.397 0.465,1.107 0.685,0.756 0.904,0.403 1.057,0.02 1.141,-0.396 1.225,-0.812 1.258,-1.209 1.242,-1.584 h -4.643 c -0.009,-0.273 0.024,-0.53 0.095,-0.774 0.073,-0.245 0.189,-0.46 0.349,-0.648 0.159,-0.188 0.363,-0.338 0.611,-0.451 0.248,-0.111 0.54,-0.168 0.876,-0.168 0.433,0 0.786,0.1 1.062,0.301 0.277,0.199 0.459,0.504 0.547,0.912 H 1.147 C 1.01,-3.108 0.711,-3.633 0.246,-3.984"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path328" /></g><g
id="g330"
transform="translate(365.3569,70.2871)"><path
d="m 0,0 v -1.309 h 0.023 c 0.248,0.504 0.553,0.876 0.912,1.117 0.36,0.239 0.817,0.351 1.369,0.335 v -1.08 C 1.895,-0.937 1.548,-0.992 1.26,-1.105 0.972,-1.217 0.739,-1.381 0.563,-1.597 0.388,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.691 0.06,-3.045 0.06,-3.445 v -2.76 H -0.961 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path332" /></g><g
id="g334"
transform="translate(318.2573,54.9863)"><path
d="m 0,0 v 0.9 h 1.044 v 0.924 c 0,0.504 0.145,0.887 0.438,1.147 C 1.773,3.23 2.199,3.36 2.76,3.36 2.855,3.36 2.966,3.352 3.09,3.336 3.214,3.32 3.324,3.297 3.42,3.264 V 2.377 C 3.332,2.408 3.236,2.43 3.132,2.442 3.027,2.454 2.932,2.461 2.844,2.461 2.596,2.461 2.404,2.412 2.268,2.316 2.132,2.221 2.064,2.036 2.064,1.764 V 0.9 h 1.2 V 0 h -1.2 V -5.304 H 1.044 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path336" /></g><g
id="g338"
transform="translate(323.3276,51.7773)"><path
d="m 0,0 c 0.1,-0.293 0.237,-0.537 0.414,-0.732 0.176,-0.197 0.381,-0.346 0.617,-0.451 0.237,-0.104 0.487,-0.156 0.75,-0.156 0.264,0 0.514,0.052 0.75,0.156 0.237,0.105 0.442,0.254 0.618,0.451 0.176,0.195 0.314,0.439 0.415,0.732 0.1,0.291 0.149,0.625 0.149,1.002 0,0.375 -0.049,0.709 -0.149,1.002 C 3.463,2.295 3.325,2.541 3.149,2.741 2.973,2.941 2.768,3.094 2.531,3.197 2.295,3.301 2.045,3.354 1.781,3.354 1.518,3.354 1.268,3.301 1.031,3.197 0.795,3.094 0.59,2.941 0.414,2.741 0.237,2.541 0.1,2.295 0,2.004 -0.101,1.711 -0.15,1.377 -0.15,1.002 -0.15,0.625 -0.101,0.291 0,0 m -1.039,2.279 c 0.129,0.397 0.32,0.741 0.576,1.032 0.256,0.293 0.572,0.523 0.948,0.691 0.376,0.168 0.808,0.252 1.296,0.252 0.496,0 0.93,-0.084 1.303,-0.252 C 3.455,3.834 3.77,3.604 4.025,3.311 4.281,3.02 4.473,2.676 4.602,2.279 4.73,1.883 4.793,1.457 4.793,1.002 4.793,0.545 4.73,0.121 4.602,-0.27 4.473,-0.662 4.281,-1.005 4.025,-1.297 3.77,-1.589 3.455,-1.816 3.084,-1.98 2.711,-2.145 2.277,-2.227 1.781,-2.227 c -0.488,0 -0.92,0.082 -1.296,0.247 -0.376,0.164 -0.692,0.391 -0.948,0.683 -0.256,0.292 -0.447,0.635 -0.576,1.027 -0.127,0.391 -0.191,0.815 -0.191,1.272 0,0.455 0.064,0.881 0.191,1.277"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path340" /></g><g
id="g342"
transform="translate(330.2456,55.8867)"><path
d="m 0,0 v -1.309 h 0.023 c 0.248,0.504 0.553,0.877 0.913,1.118 0.359,0.239 0.816,0.351 1.368,0.336 V -0.936 C 1.896,-0.936 1.548,-0.992 1.26,-1.104 0.972,-1.217 0.739,-1.38 0.563,-1.596 0.388,-1.812 0.26,-2.074 0.18,-2.383 0.1,-2.689 0.06,-3.044 0.06,-3.444 v -2.76 H -0.961 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path344" /></g><g
id="g346"
transform="translate(339.1362,49.6826)"><path
d="m 0,0 v 6.097 h -2.207 v 0.815 c 0.287,0 0.567,0.023 0.84,0.065 0.271,0.045 0.517,0.128 0.738,0.247 0.219,0.121 0.405,0.284 0.558,0.492 C 0.08,7.924 0.185,8.189 0.24,8.508 H 1.02 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path348" /></g><g
id="g350"
transform="translate(343.2172,56.3789)"><path
d="M 0,0 C 0.112,0.367 0.286,0.686 0.522,0.953 0.758,1.222 1.052,1.432 1.403,1.584 1.756,1.735 2.155,1.811 2.604,1.811 2.972,1.811 3.317,1.758 3.642,1.65 3.966,1.541 4.248,1.386 4.487,1.182 4.728,0.977 4.918,0.724 5.058,0.42 5.198,0.115 5.269,-0.236 5.269,-0.637 5.269,-1.012 5.21,-1.344 5.094,-1.633 4.978,-1.92 4.823,-2.178 4.632,-2.406 4.44,-2.635 4.22,-2.84 3.972,-3.024 3.724,-3.209 3.468,-3.385 3.204,-3.553 2.94,-3.713 2.676,-3.87 2.411,-4.026 2.147,-4.182 1.905,-4.349 1.687,-4.524 1.466,-4.7 1.278,-4.891 1.122,-5.094 0.966,-5.299 0.864,-5.532 0.815,-5.797 h 4.37 v -0.899 h -5.557 c 0.04,0.504 0.13,0.934 0.269,1.29 0.141,0.355 0.319,0.666 0.535,0.929 0.215,0.264 0.46,0.497 0.732,0.697 0.272,0.2 0.556,0.387 0.852,0.563 0.36,0.225 0.676,0.431 0.948,0.619 0.271,0.188 0.498,0.377 0.678,0.57 0.179,0.192 0.316,0.399 0.408,0.624 0.092,0.224 0.139,0.484 0.139,0.779 0,0.232 -0.045,0.443 -0.133,0.631 C 3.968,0.193 3.85,0.355 3.702,0.492 3.554,0.627 3.38,0.732 3.18,0.804 2.979,0.875 2.768,0.912 2.544,0.912 2.247,0.912 1.993,0.85 1.782,0.726 1.569,0.602 1.396,0.439 1.26,0.24 1.124,0.039 1.026,-0.187 0.966,-0.439 0.905,-0.691 0.88,-0.944 0.888,-1.2 h -1.02 C -0.156,-0.768 -0.112,-0.368 0,0"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path352" /></g><g
id="g354"
transform="translate(350.8432,52.7968)"><path
d="m 0,0 c 0.02,-0.396 0.084,-0.768 0.191,-1.116 0.109,-0.349 0.283,-0.642 0.523,-0.882 0.239,-0.24 0.575,-0.36 1.008,-0.36 0.432,0 0.768,0.12 1.008,0.36 0.24,0.24 0.414,0.533 0.522,0.882 0.107,0.348 0.172,0.72 0.191,1.116 0.02,0.396 0.031,0.754 0.031,1.074 0,0.207 -0.002,0.438 -0.006,0.69 C 3.463,2.016 3.443,2.268 3.408,2.52 3.371,2.771 3.32,3.018 3.252,3.258 3.184,3.498 3.084,3.707 2.951,3.888 2.82,4.068 2.654,4.213 2.453,4.326 2.254,4.437 2.01,4.494 1.722,4.494 1.434,4.494 1.189,4.437 0.99,4.326 0.789,4.213 0.623,4.068 0.492,3.888 0.359,3.707 0.26,3.498 0.191,3.258 0.123,3.018 0.072,2.771 0.035,2.52 0,2.268 -0.021,2.016 -0.024,1.764 -0.028,1.512 -0.03,1.281 -0.03,1.074 -0.03,0.754 -0.021,0.396 0,0 m -1.086,2.033 c 0.016,0.336 0.056,0.664 0.119,0.985 0.065,0.32 0.156,0.624 0.277,0.912 0.12,0.288 0.284,0.54 0.492,0.756 C 0.01,4.902 0.271,5.074 0.588,5.201 0.904,5.33 1.281,5.394 1.722,5.394 2.162,5.394 2.539,5.33 2.855,5.201 3.172,5.074 3.434,4.902 3.642,4.686 3.85,4.47 4.014,4.218 4.134,3.93 4.254,3.642 4.346,3.338 4.41,3.018 4.474,2.697 4.514,2.369 4.529,2.033 4.546,1.697 4.554,1.373 4.554,1.062 4.554,0.75 4.546,0.426 4.529,0.09 4.514,-0.246 4.474,-0.574 4.41,-0.895 4.346,-1.215 4.254,-1.517 4.134,-1.801 4.014,-2.084 3.85,-2.334 3.642,-2.551 3.434,-2.766 3.174,-2.936 2.861,-3.061 2.55,-3.184 2.17,-3.246 1.722,-3.246 c -0.441,0 -0.818,0.062 -1.134,0.185 -0.317,0.125 -0.578,0.295 -0.786,0.51 -0.208,0.217 -0.372,0.467 -0.492,0.75 -0.121,0.284 -0.212,0.586 -0.277,0.906 -0.063,0.321 -0.103,0.649 -0.119,0.985 -0.017,0.336 -0.024,0.66 -0.024,0.972 0,0.311 0.007,0.635 0.024,0.971"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path356" /></g><g
id="g358"
transform="translate(361.3911,53.6845)"><path
d="m 0,0 c -0.076,0.276 -0.192,0.522 -0.349,0.738 -0.156,0.216 -0.355,0.388 -0.599,0.516 -0.244,0.128 -0.531,0.192 -0.858,0.192 -0.344,0 -0.636,-0.068 -0.877,-0.204 -0.24,-0.136 -0.435,-0.313 -0.588,-0.534 -0.152,-0.221 -0.261,-0.471 -0.33,-0.75 -0.068,-0.28 -0.101,-0.564 -0.101,-0.852 0,-0.304 0.036,-0.598 0.107,-0.882 0.073,-0.284 0.187,-0.534 0.342,-0.75 0.156,-0.216 0.358,-0.39 0.607,-0.522 0.248,-0.133 0.547,-0.198 0.9,-0.198 0.351,0 0.645,0.067 0.882,0.204 0.236,0.136 0.425,0.316 0.57,0.54 0.144,0.224 0.248,0.48 0.312,0.769 0.063,0.287 0.096,0.584 0.096,0.886 C 0.114,-0.558 0.075,-0.276 0,0 m -3.666,2.202 v -0.84 h 0.024 c 0.168,0.344 0.432,0.594 0.791,0.75 0.361,0.157 0.756,0.235 1.189,0.235 0.479,0 0.897,-0.089 1.254,-0.265 C -0.052,1.905 0.243,1.668 0.479,1.368 0.716,1.067 0.893,0.722 1.014,0.33 c 0.12,-0.392 0.18,-0.808 0.18,-1.248 0,-0.44 -0.058,-0.856 -0.174,-1.248 C 0.903,-2.558 0.728,-2.899 0.491,-3.192 0.256,-3.483 -0.04,-3.714 -0.396,-3.882 -0.753,-4.05 -1.167,-4.134 -1.638,-4.134 c -0.152,0 -0.322,0.016 -0.51,0.048 -0.189,0.032 -0.374,0.084 -0.558,0.155 -0.184,0.073 -0.358,0.17 -0.522,0.295 -0.164,0.123 -0.302,0.278 -0.414,0.462 h -0.024 v -3.192 h -1.021 v 8.568 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path360" /></g><g
id="g362"
transform="translate(363.2924,55.8867)"><path
d="M 0,0 H 1.309 L 2.796,-2.172 4.344,0 h 1.224 l -2.136,-2.855 2.4,-3.349 H 4.523 L 2.796,-3.637 1.068,-6.204 h -1.236 l 2.328,3.265 z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path364" /></g><g
id="g366"
transform="translate(379.1928,53.1269)"><path
d="m 0,0 v -0.816 h -2.616 v -2.628 h -0.816 v 2.628 H -6.048 V 0 h 2.616 v 2.627 h 0.816 V 0 Z"
style="fill:#176fc1;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path368" /></g></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1,13 +0,0 @@
<svg width="512" height="512" xmlns="http://www.w3.org/2000/svg">
<title/>
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<path fill="#ffffff" id="svg_1" d="m293.9,450l-60.37,0a15,15 0 0 1 -14.92,-13.42l-4.47,-42.09a152.77,152.77 0 0 1 -18.25,-7.56l-32.89,26.6a15,15 0 0 1 -20,-1.06l-42.69,-42.69a15,15 0 0 1 -1.06,-20l26.61,-32.93a152.15,152.15 0 0 1 -7.57,-18.25l-42.16,-4.5a15,15 0 0 1 -13.42,-14.91l0,-60.38a15,15 0 0 1 13.42,-14.91l42.09,-4.47a152.15,152.15 0 0 1 7.57,-18.25l-26.61,-32.93a15,15 0 0 1 1.06,-20l42.69,-42.69a15,15 0 0 1 20,-1.06l32.93,26.6a152.77,152.77 0 0 1 18.25,-7.56l4.47,-42.09a15,15 0 0 1 14.95,-13.45l60.37,0a15,15 0 0 1 14.92,13.42l4.46,42.09a152.91,152.91 0 0 1 18.26,7.56l32.92,-26.6a15,15 0 0 1 20,1.06l42.69,42.69a15,15 0 0 1 1.06,20l-26.61,32.93a153.8,153.8 0 0 1 7.57,18.25l42.09,4.47a15,15 0 0 1 13.41,14.91l0,60.38a15,15 0 0 1 -13.37,14.94l-42.09,4.47a153.8,153.8 0 0 1 -7.57,18.25l26.61,32.93a15,15 0 0 1 -1.06,20l-42.69,42.72a15,15 0 0 1 -20,1.06l-32.92,-26.6a152.91,152.91 0 0 1 -18.26,7.56l-4.46,42.09a15,15 0 0 1 -14.96,13.42zm-46.9,-30l33.39,0l4.09,-38.56a15,15 0 0 1 11.06,-12.91a123,123 0 0 0 30.16,-12.53a15,15 0 0 1 17,1.31l30.16,24.37l23.61,-23.61l-24.41,-30.07a15,15 0 0 1 -1.31,-17a122.63,122.63 0 0 0 12.49,-30.14a15,15 0 0 1 12.92,-11.06l38.55,-4.1l0,-33.39l-38.55,-4.1a15,15 0 0 1 -12.92,-11.06a122.63,122.63 0 0 0 -12.49,-30.15a15,15 0 0 1 1.31,-17l24.37,-30.16l-23.61,-23.61l-30.16,24.37a15,15 0 0 1 -17,1.31a123,123 0 0 0 -30.14,-12.49a15,15 0 0 1 -11.06,-12.91l-4.05,-38.51l-33.41,0l-4.09,38.56a15,15 0 0 1 -11.07,12.91a122.79,122.79 0 0 0 -30.11,12.53a15,15 0 0 1 -17,-1.31l-30.13,-24.41l-23.6,23.61l24.38,30.16a15,15 0 0 1 1.3,17a123.41,123.41 0 0 0 -12.49,30.14a15,15 0 0 1 -12.91,11.06l-38.56,4.1l0,33.38l38.56,4.1a15,15 0 0 1 12.91,11.06a123.41,123.41 0 0 0 12.48,30.11a15,15 0 0 1 -1.3,17l-24.37,30.11l23.61,23.61l30.17,-24.37a15,15 0 0 1 17,-1.31a122.79,122.79 0 0 0 30.13,12.49a15,15 0 0 1 11.07,12.91l4.02,38.56zm202.71,-140.81l0,0z"/>
<path fill="#ffffff" id="svg_2" d="m263.71,340.36a91.36,91.36 0 1 1 91.37,-91.36a91.46,91.46 0 0 1 -91.37,91.36zm0,-152.72a61.36,61.36 0 1 0 61.37,61.36a61.43,61.43 0 0 0 -61.37,-61.36z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

View File

@@ -1,12 +0,0 @@
<svg width="50" height="50" xmlns="http://www.w3.org/2000/svg">
<g>
<title>background</title>
<rect fill="none" id="canvas_background" height="402" width="582" y="-1" x="-1"/>
</g>
<g>
<title>Layer 1</title>
<circle id="svg_1" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke="#ffffff" r="24" fill="none" cy="25" cx="25"/>
<path id="svg_3" stroke-width="2" stroke-miterlimit="10" stroke-linecap="round" stroke="#ffffff" fill="none" d="m29.933,35.528c-0.146,-1.612 -0.09,-2.737 -0.09,-4.21c0.73,-0.383 2.038,-2.825 2.259,-4.888c0.574,-0.047 1.479,-0.607 1.744,-2.818c0.143,-1.187 -0.425,-1.855 -0.771,-2.065c0.934,-2.809 2.874,-11.499 -3.588,-12.397c-0.665,-1.168 -2.368,-1.759 -4.581,-1.759c-8.854,0.163 -9.922,6.686 -7.981,14.156c-0.345,0.21 -0.913,0.878 -0.771,2.065c0.266,2.211 1.17,2.771 1.744,2.818c0.22,2.062 1.58,4.505 2.312,4.888c0,1.473 0.055,2.598 -0.091,4.21c-1.261,3.39 -7.737,3.655 -11.473,6.924c3.906,3.933 10.236,6.746 16.916,6.746s14.532,-5.274 15.839,-6.713c-3.713,-3.299 -10.204,-3.555 -11.468,-6.957z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

View File

@@ -4,17 +4,30 @@ using System.Text;
using System.Windows; using System.Windows;
namespace Server_Dashboard { namespace Server_Dashboard {
public abstract class BaseAttachedProperty<Parent, Property>
where Parent : BaseAttachedProperty<Parent, Property>, new() { /// <summary>
/// Attached property base class
/// </summary>
/// <typeparam name="TParent"></typeparam>
/// <typeparam name="TProperty"></typeparam>
public abstract class BaseAttachedProperty<TParent, TProperty>
where TParent : BaseAttachedProperty<TParent, TProperty>, new() {
public event Action<DependencyObject, DependencyPropertyChangedEventArgs> ValueChanged = (sender, e) => { }; public event Action<DependencyObject, DependencyPropertyChangedEventArgs> ValueChanged = (sender, e) => { };
public static Parent Instance { get; private set; } = new Parent();
public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached("Value", typeof(Property), typeof(BaseAttachedProperty<Parent, Property>), new PropertyMetadata(new PropertyChangedCallback(OnValuePropertyChanged))); public static TParent Instance { get; private set; } = new TParent();
public static readonly DependencyProperty ValueProperty = DependencyProperty.RegisterAttached("Value", typeof(TProperty), typeof(BaseAttachedProperty<TParent, TProperty>), new PropertyMetadata(new PropertyChangedCallback(OnValuePropertyChanged)));
private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { private static void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
Instance.OnValueChanged(d, e); Instance.OnValueChanged(d, e);
Instance.ValueChanged(d, e); Instance.ValueChanged(d, e);
} }
public static Property GetValue(DependencyObject d) => (Property)d.GetValue(ValueProperty);
public static void SetValue(DependencyObject d, Property value) => d.SetValue(ValueProperty, value); public static TProperty GetValue(DependencyObject d) => (TProperty)d.GetValue(ValueProperty);
public virtual void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { }
public static void SetValue(DependencyObject d, TProperty value) => d.SetValue(ValueProperty, value);
public virtual void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
}
} }
} }

View File

@@ -5,9 +5,10 @@ using System.Text;
using System.Windows; using System.Windows;
using System.Windows.Documents; using System.Windows.Documents;
namespace Server_Dashboard namespace Server_Dashboard {
{
public static class HyperlinkExtensions { public static class HyperlinkExtensions {
public static bool GetIsExternal(DependencyObject obj) { public static bool GetIsExternal(DependencyObject obj) {
return (bool)obj.GetValue(IsExternalProperty); return (bool)obj.GetValue(IsExternalProperty);
} }
@@ -15,23 +16,25 @@ namespace Server_Dashboard
public static void SetIsExternal(DependencyObject obj, bool value) { public static void SetIsExternal(DependencyObject obj, bool value) {
obj.SetValue(IsExternalProperty, value); obj.SetValue(IsExternalProperty, value);
} }
public static readonly DependencyProperty IsExternalProperty = public static readonly DependencyProperty IsExternalProperty =
DependencyProperty.RegisterAttached("IsExternal", typeof(bool), typeof(HyperlinkExtensions), new UIPropertyMetadata(false, OnIsExternalChanged)); DependencyProperty.RegisterAttached("IsExternal", typeof(bool), typeof(HyperlinkExtensions), new UIPropertyMetadata(false, OnIsExternalChanged));
private static void OnIsExternalChanged(object sender, DependencyPropertyChangedEventArgs args) { private static void OnIsExternalChanged(object sender, DependencyPropertyChangedEventArgs args) {
var hyperlink = sender as Hyperlink; var hyperlink = sender as Hyperlink;
if ((bool)args.NewValue) if ((bool)args.NewValue) {
hyperlink.RequestNavigate += Hyperlink_RequestNavigate; if (hyperlink != null)
else hyperlink.RequestNavigate += Hyperlink_RequestNavigate;
} else if (hyperlink != null)
hyperlink.RequestNavigate -= Hyperlink_RequestNavigate; hyperlink.RequestNavigate -= Hyperlink_RequestNavigate;
} }
private static void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) { private static void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e) {
try { try {
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true }); Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri) { UseShellExecute = true });
} catch { } } catch (Exception) { }
e.Handled = true; e.Handled = true;
} }
} }
} }

View File

@@ -2,17 +2,18 @@
using System.Windows.Controls; using System.Windows.Controls;
namespace Server_Dashboard { namespace Server_Dashboard {
public class MonitorPasswordProperty : BaseAttachedProperty<MonitorPasswordProperty, bool> { public class MonitorPasswordProperty : BaseAttachedProperty<MonitorPasswordProperty, bool> {
public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
var passwordBox = sender as PasswordBox; if (!(sender is PasswordBox passwordBox))
if (passwordBox == null)
return; return;
passwordBox.PasswordChanged -= PasswordBox_PasswordChanged; passwordBox.PasswordChanged -= PasswordBox_PasswordChanged;
if ((bool)e.NewValue) { if (!(bool)e.NewValue)
HasTextProperty.SetValue(passwordBox); return;
passwordBox.PasswordChanged += PasswordBox_PasswordChanged; HasTextProperty.SetValue(passwordBox);
} passwordBox.PasswordChanged += PasswordBox_PasswordChanged;
} }
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) {
@@ -21,8 +22,9 @@ namespace Server_Dashboard {
} }
public class HasTextProperty : BaseAttachedProperty<HasTextProperty, bool> { public class HasTextProperty : BaseAttachedProperty<HasTextProperty, bool> {
public static void SetValue(DependencyObject sender) { public static void SetValue(DependencyObject sender) {
SetValue(sender, ((PasswordBox)sender).SecurePassword.Length < 1); SetValue(sender, ((PasswordBox)sender).SecurePassword.Length < 1);
} }
} }
} }

View File

@@ -1,7 +1,9 @@
using System.Windows; using System.Windows;
namespace Server_Dashboard { namespace Server_Dashboard {
public class CloseProperty : BaseAttachedProperty<CloseProperty, bool> { public class CloseProperty : BaseAttachedProperty<CloseProperty, bool> {
public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { public override void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
if (sender is Window window) { if (sender is Window window) {
window.Loaded += (s, e) => { window.Loaded += (s, e) => {
@@ -14,4 +16,4 @@ namespace Server_Dashboard {
} }
} }
} }
} }

View File

@@ -1,308 +0,0 @@
<Window x:Class="Server_Dashboard.Views.DashboardPages.ModuleCRUD.CreateModulePopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Server_Dashboard.Views.DashboardPages.ModuleCRUD"
xmlns:root="clr-namespace:Server_Dashboard" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
d:DataContext="{d:DesignInstance Type=root:DashboardModuleViewModel}"
mc:Ignorable="d"
ResizeMode="NoResize"
Height="700"
Width="500"
d:WindowStyle="None"
>
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0"/>
</WindowChrome.WindowChrome>
<Border
Width="500"
Height="700"
>
<Border.Background>
<SolidColorBrush Color="#2D2D2D" Opacity="1"/>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid
Background="{StaticResource BackgroundSurface_04dp}"
Grid.Row="0"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text="Create a new Server"
Margin="5 0 0 0"
Foreground="{StaticResource DeepPurple_A100}"
VerticalAlignment="Center"
/>
<Button
Style="{StaticResource CloseButton}"
Grid.Column="2"
Content="✕"
Cursor="Hand"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
<Grid
Background="{StaticResource BackgroundSurface_04dp}"
Grid.Row="1"
Margin="20"
>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel VerticalAlignment="Center" Grid.Row="0" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock
Text="Server Name"
FontSize="24"
Margin="0 0 0 5"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock
Text="*"
Foreground="{StaticResource ErrorRed}"
FontSize="20"
/>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<TextBox
Text="{Binding ServerName}"
Grid.Column="1"
Height="40"
FontSize="20"
x:Name="ServerName"
/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="My Awesome Server"
FontSize="20"
Visibility="{Binding ElementName=ServerName, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}"
Grid.Column="1"
IsHitTestVisible="False"
Margin="5 0 0 0"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel VerticalAlignment="Center" Grid.Row="1" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock
Text="Password"
FontSize="24"
Margin="0 0 0 5"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock
Text="*"
Foreground="{StaticResource ErrorRed}"
FontSize="20"
/>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<PasswordBox
Width="420"
VerticalAlignment="Center"
HorizontalAlignment="Left"
root:MonitorPasswordProperty.Value="True"
Grid.Column="1"
FontSize="20"
x:Name="Password"
Height="40"
>
</PasswordBox>
<TextBlock
Visibility="{Binding ElementName=Password, Path=(root:HasTextProperty.Value), Converter={StaticResource UserNameVisibillity}}" x:Name="PasswordHint"
Text="********"
Grid.Column="1"
IsHitTestVisible="False"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5 0 0 0"
FontSize="20"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel VerticalAlignment="Center" Grid.Row="2" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock
Text="Username"
FontSize="24"
Margin="0 0 0 5"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock
Text="*"
Foreground="{StaticResource ErrorRed}"
FontSize="16"
/>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<TextBox
Text="{Binding Username}"
Grid.Column="1"
Height="40"
FontSize="20"
x:Name="UserName"
/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="Name"
FontSize="20"
Visibility="{Binding ElementName=UserName, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}"
Grid.Column="1"
IsHitTestVisible="False"
Margin="5 0 0 0"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel VerticalAlignment="Center" Grid.Row="3" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock
Text="IP Adress"
FontSize="24"
Margin="0 0 0 5"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock
Text="*"
Foreground="{StaticResource ErrorRed}"
FontSize="16"
/>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<TextBox
Text="{Binding IPAdress}"
Grid.Column="1"
Height="40"
FontSize="20"
x:Name="IPAdress"
/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="sample.ssh.com"
FontSize="20"
Visibility="{Binding ElementName=IPAdress, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}"
Grid.Column="1"
IsHitTestVisible="False"
Margin="5 0 0 0"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<StackPanel VerticalAlignment="Center" Grid.Row="4" Margin="20 0 20 0">
<TextBlock
Text="Port"
FontSize="24"
Margin="0 0 0 5"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87"/>
</TextBlock.Foreground>
</TextBlock>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0"/>
</Grid.Effect>
<TextBox
Text="{Binding Port}"
Grid.Column="1"
Height="40"
FontSize="20"
x:Name="Port"
/>
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="22"
FontSize="20"
Visibility="{Binding ElementName=Port, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}"
Grid.Column="1"
IsHitTestVisible="False"
Margin="5 0 0 0"
>
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/>
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<Button
Height="60"
Width="350"
Command="{Binding CreateModuleCommand}"
CommandParameter="{Binding ElementName=CREATE_MODULE}"
Grid.Row="5"
Content="CREATE MODULE"
Grid.ColumnSpan="2"
/>
</Grid>
</Grid>
</Border>
</Window>

View File

@@ -1,94 +1,24 @@
<UserControl x:Class="Server_Dashboard.Controls.DoubleRoundProgressBar.DoubleRoundProgressBar" <UserControl x:Class="Server_Dashboard.Controls.DoubleRoundProgressBar.DoubleRoundProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Controls.DoubleRoundProgressBar" xmlns:local="clr-namespace:Server_Dashboard.Controls.DoubleRoundProgressBar"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:root="clr-namespace:Server_Dashboard" xmlns:root="clr-namespace:Server_Dashboard"
mc:Ignorable="d" mc:Ignorable="d"
x:Name="_this" x:Name="_this"
d:DesignHeight="50" d:DesignWidth="50"> d:DesignHeight="50" d:DesignWidth="50">
<UserControl.Resources> <UserControl.Resources>
<root:ValueToAngleConverter x:Key="valueToAngle"/> <root:ValueToAngleConverter x:Key="valueToAngle" />
</UserControl.Resources> </UserControl.Resources>
<!--Circular Progress bar-->
<Grid> <Grid>
<Ellipse <Ellipse x:Name="Background" Fill="{Binding ElementName=_this, Path=BackgroundBrush}" Margin="0" Stroke="{Binding ElementName=_this, Path=BackgroundBrush}" />
x:Name="Background" <ed:Arc ArcThickness="8" ArcThicknessUnit="Pixel" EndAngle="{Binding Converter={StaticResource valueToAngle}, ElementName=_this, Path=ValueRead}" Fill="{Binding ElementName=_this, Path=ReadIndicatorBrush}" Stretch="None" StartAngle="0" />
<Ellipse x:Name="Seperator" Fill="Transparent" Margin="7" Stroke="{Binding ElementName=_this, Path=ProgressBorderBrush}" Panel.ZIndex="1" />
Fill="{Binding <Ellipse x:Name="Seperator2" Fill="Transparent" Margin="8" Stroke="{Binding ElementName=_this, Path=ProgressBorderBrush}" Panel.ZIndex="1" />
ElementName=_this, <ed:Arc Margin="8" ArcThickness="8" ArcThicknessUnit="Pixel" EndAngle="{Binding Converter={StaticResource valueToAngle}, ElementName=_this, Path=ValueWrite}" Fill="{Binding ElementName=_this, Path=WriteIndicatorBrush}" Stretch="None" StartAngle="0" />
Path=BackgroundBrush <Ellipse x:Name="Border" Fill="{Binding ElementName=_this, Path=ProgressBorderBrush}" Margin="16" Stroke="{Binding ElementName=_this, Path=ProgressBorderBrush}" />
}"
Margin="0"
Stroke="{Binding
ElementName=_this,
Path=BackgroundBrush
}"
/>
<ed:Arc
ArcThickness="8"
ArcThicknessUnit="Pixel"
EndAngle="{Binding
Converter={StaticResource valueToAngle},
ElementName=_this,
Path=ValueRead
}"
Fill="{Binding
ElementName=_this,
Path=ReadIndicatorBrush
}"
Stretch="None"
StartAngle="0"
/>
<Ellipse
x:Name="Seperator"
Fill="Transparent"
Margin="7"
Stroke="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
Panel.ZIndex="1"
/>
<Ellipse
x:Name="Seperator2"
Fill="Transparent"
Margin="8"
Stroke="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
Panel.ZIndex="1"
/>
<ed:Arc
Margin="8"
ArcThickness="8"
ArcThicknessUnit="Pixel"
EndAngle="{Binding
Converter={StaticResource valueToAngle},
ElementName=_this,
Path=ValueWrite
}"
Fill="{Binding
ElementName=_this,
Path=WriteIndicatorBrush
}"
Stretch="None"
StartAngle="0"
/>
<Ellipse
x:Name="Border"
Fill="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
Margin="16"
Stroke="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -1,57 +1,64 @@
using System; using System.Windows;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Server_Dashboard.Controls.DoubleRoundProgressBar { namespace Server_Dashboard.Controls.DoubleRoundProgressBar {
/// <summary>
/// DependencyProperties
/// </summary>
public partial class DoubleRoundProgressBar : UserControl { public partial class DoubleRoundProgressBar : UserControl {
public static DependencyProperty ReadIndicatorBrushProperty = DependencyProperty.Register("ReadIndicatorBrush", typeof(Brush), typeof(DoubleRoundProgressBar)); //Property for the ReadIndicatorBrush
public static readonly DependencyProperty ReadIndicatorBrushProperty = DependencyProperty.Register("ReadIndicatorBrush", typeof(Brush), typeof(DoubleRoundProgressBar));
public Brush ReadIndicatorBrush { public Brush ReadIndicatorBrush {
get { return (Brush)GetValue(ReadIndicatorBrushProperty); } get => (Brush)GetValue(ReadIndicatorBrushProperty);
set { SetValue(ReadIndicatorBrushProperty, value); } set => SetValue(ReadIndicatorBrushProperty, value);
} }
public static DependencyProperty WriteIndicatorBrushProperty = DependencyProperty.Register("WriteIndicatorBrush", typeof(Brush), typeof(DoubleRoundProgressBar)); //Property for the WriteIndicatorBrush
public static readonly DependencyProperty WriteIndicatorBrushProperty = DependencyProperty.Register("WriteIndicatorBrush", typeof(Brush), typeof(DoubleRoundProgressBar));
public Brush WriteIndicatorBrush { public Brush WriteIndicatorBrush {
get { return (Brush)GetValue(WriteIndicatorBrushProperty); } get => (Brush)GetValue(WriteIndicatorBrushProperty);
set { SetValue(WriteIndicatorBrushProperty, value); } set => SetValue(WriteIndicatorBrushProperty, value);
} }
public static DependencyProperty BackgroundBrushProperty = DependencyProperty.Register("BackgroundBrush", typeof(Brush), typeof(DoubleRoundProgressBar)); //Property for the BackgroundBrush
public static readonly DependencyProperty BackgroundBrushProperty = DependencyProperty.Register("BackgroundBrush", typeof(Brush), typeof(DoubleRoundProgressBar));
public Brush BackgroundBrush { public Brush BackgroundBrush {
get { return (Brush)GetValue(BackgroundBrushProperty); } get => (Brush)GetValue(BackgroundBrushProperty);
set { SetValue(BackgroundBrushProperty, value); } set => SetValue(BackgroundBrushProperty, value);
} }
public static DependencyProperty ProgressBorderBrushProperty = DependencyProperty.Register("ProgressBorderBrush", typeof(Brush), typeof(DoubleRoundProgressBar)); //Property for the ProgressBorderBrush
public static readonly DependencyProperty ProgressBorderBrushProperty = DependencyProperty.Register("ProgressBorderBrush", typeof(Brush), typeof(DoubleRoundProgressBar));
public Brush ProgressBorderBrush { public Brush ProgressBorderBrush {
get { return (Brush)GetValue(ProgressBorderBrushProperty); } get => (Brush)GetValue(ProgressBorderBrushProperty);
set { SetValue(ProgressBorderBrushProperty, value); } set => SetValue(ProgressBorderBrushProperty, value);
} }
public static DependencyProperty ValueWriteProperty = DependencyProperty.Register("ValueWrite", typeof(int), typeof(DoubleRoundProgressBar)); //Property for the Value Write
public static readonly DependencyProperty ValueWriteProperty = DependencyProperty.Register("ValueWrite", typeof(int), typeof(DoubleRoundProgressBar));
public int ValueWrite { public int ValueWrite {
get { return (int)GetValue(ValueWriteProperty); } get => (int)GetValue(ValueWriteProperty);
set { SetValue(ValueWriteProperty, value); } set => SetValue(ValueWriteProperty, value);
} }
public static DependencyProperty ValueReadProperty = DependencyProperty.Register("ValueRead", typeof(int), typeof(DoubleRoundProgressBar));
//Property for the Value Read
public static readonly DependencyProperty ValueReadProperty = DependencyProperty.Register("ValueRead", typeof(int), typeof(DoubleRoundProgressBar));
public int ValueRead { public int ValueRead {
get { return (int)GetValue(ValueReadProperty); } get => (int)GetValue(ValueReadProperty);
set { SetValue(ValueReadProperty, value); } set => SetValue(ValueReadProperty, value);
} }
public DoubleRoundProgressBar() { public DoubleRoundProgressBar() {
InitializeComponent(); InitializeComponent();
} }
} }
} }

View File

@@ -1,57 +1,19 @@
<UserControl x:Class="Server_Dashboard.Controls.HalfRoundProgressBar.HalfRoundProgressBar" <UserControl x:Class="Server_Dashboard.Controls.HalfRoundProgressBar.HalfRoundProgressBar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Controls.HalfRoundProgressBar" xmlns:local="clr-namespace:Server_Dashboard.Controls.HalfRoundProgressBar"
xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing"
xmlns:root="clr-namespace:Server_Dashboard" xmlns:root="clr-namespace:Server_Dashboard"
mc:Ignorable="d" mc:Ignorable="d" x:Name="_this" d:DesignHeight="50" d:DesignWidth="50">
x:Name="_this"
d:DesignHeight="50" d:DesignWidth="50">
<UserControl.Resources> <UserControl.Resources>
<root:ValueToAngleConverter x:Key="valueToAngle"/> <root:ValueToAngleConverter x:Key="valueToAngle" />
</UserControl.Resources> </UserControl.Resources>
<!--Progress bar but just half round-->
<Grid> <Grid>
<Ellipse <Ellipse x:Name="Background" Fill="{Binding ElementName=_this, Path=BackgroundBrush}" Margin="0" Stroke="{Binding ElementName=_this, Path=BackgroundBrush}" />
x:Name="Background" <ed:Arc ArcThickness="8" ArcThicknessUnit="Pixel" EndAngle="{Binding Converter={StaticResource valueToAngle}, ElementName=_this, Path=Value}" Fill="{Binding ElementName=_this, Path=IndicatorBrush}" Stretch="None" StartAngle="0" />
Fill="{Binding <Ellipse x:Name="Border" Fill="{Binding ElementName=_this, Path=ProgressBorderBrush}" Margin="8" Stroke="{Binding ElementName=_this, Path=ProgressBorderBrush}" />
ElementName=_this,
Path=BackgroundBrush
}"
Margin="0"
Stroke="{Binding
ElementName=_this,
Path=BackgroundBrush
}"
/>
<ed:Arc
ArcThickness="8"
ArcThicknessUnit="Pixel"
EndAngle="{Binding
Converter={StaticResource valueToAngle},
ElementName=_this,
Path=Value
}"
Fill="{Binding
ElementName=_this,
Path=IndicatorBrush
}"
Stretch="None"
StartAngle="0"
/>
<Ellipse
x:Name="Border"
Fill="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
Margin="8"
Stroke="{Binding
ElementName=_this,
Path=ProgressBorderBrush
}"
/>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -1,46 +1,48 @@
using System; using System.Windows;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Server_Dashboard.Controls.HalfRoundProgressBar { namespace Server_Dashboard.Controls.HalfRoundProgressBar {
/// <summary>
/// Dependency Properties
/// </summary>
public partial class HalfRoundProgressBar : UserControl { public partial class HalfRoundProgressBar : UserControl {
public static DependencyProperty IndicatorBrushProperty = DependencyProperty.Register("IndicatorBrush", typeof(Brush), typeof(HalfRoundProgressBar)); //Indicator Brush Property
public static readonly DependencyProperty IndicatorBrushProperty = DependencyProperty.Register("IndicatorBrush", typeof(Brush), typeof(HalfRoundProgressBar));
public Brush IndicatorBrush { public Brush IndicatorBrush {
get { return (Brush)GetValue(IndicatorBrushProperty); } get => (Brush)GetValue(IndicatorBrushProperty);
set { SetValue(IndicatorBrushProperty, value); } set => SetValue(IndicatorBrushProperty, value);
} }
public static DependencyProperty BackgroundBrushProperty = DependencyProperty.Register("BackgroundBrush", typeof(Brush), typeof(HalfRoundProgressBar)); //Background Brush Property
public static readonly DependencyProperty BackgroundBrushProperty = DependencyProperty.Register("BackgroundBrush", typeof(Brush), typeof(HalfRoundProgressBar));
public Brush BackgroundBrush { public Brush BackgroundBrush {
get { return (Brush)GetValue(BackgroundBrushProperty); } get => (Brush)GetValue(BackgroundBrushProperty);
set { SetValue(BackgroundBrushProperty, value); } set => SetValue(BackgroundBrushProperty, value);
} }
public static DependencyProperty ProgressBorderBrushProperty = DependencyProperty.Register("ProgressBorderBrush", typeof(Brush), typeof(HalfRoundProgressBar)); //ProgressBorder Property
public static readonly DependencyProperty ProgressBorderBrushProperty = DependencyProperty.Register("ProgressBorderBrush", typeof(Brush), typeof(HalfRoundProgressBar));
public Brush ProgressBorderBrush { public Brush ProgressBorderBrush {
get { return (Brush)GetValue(ProgressBorderBrushProperty); } get => (Brush)GetValue(ProgressBorderBrushProperty);
set { SetValue(ProgressBorderBrushProperty, value); } set => SetValue(ProgressBorderBrushProperty, value);
} }
public static DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(HalfRoundProgressBar)); //Value
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(int), typeof(HalfRoundProgressBar));
public int Value { public int Value {
get { return (int)GetValue(ValueProperty); } get => (int)GetValue(ValueProperty);
set { SetValue(ValueProperty, value); } set => SetValue(ValueProperty, value);
} }
public HalfRoundProgressBar() { public HalfRoundProgressBar() {
InitializeComponent(); InitializeComponent();
} }
} }
} }

View File

@@ -2,75 +2,45 @@
x:Name="control" x:Name="control"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Controls" xmlns:local="clr-namespace:Server_Dashboard.Controls"
mc:Ignorable="d" mc:Ignorable="d">
> <!--The Loading indicator circle-->
<Grid DataContext="{Binding RelativeSource={RelativeSource Self}}"> <Grid DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Path <Path Stroke="Transparent" StrokeThickness=".5" RenderTransformOrigin=".5,.5" Width="60" Height="60">
Stroke="Transparent"
StrokeThickness=".5"
RenderTransformOrigin=".5,.5"
Width="60"
Height="60"
>
<Path.Effect> <Path.Effect>
<DropShadowEffect BlurRadius="5" ShadowDepth="0" Opacity="1" Color="#B388FF"/> <DropShadowEffect BlurRadius="5" ShadowDepth="0" Opacity="1" Color="#B388FF" />
</Path.Effect> </Path.Effect>
<Path.Data> <Path.Data>
<CombinedGeometry <CombinedGeometry GeometryCombineMode="Xor">
GeometryCombineMode="Xor"
>
<CombinedGeometry.Geometry1> <CombinedGeometry.Geometry1>
<EllipseGeometry <EllipseGeometry RadiusX="30" RadiusY="30" Center="30,30" />
RadiusX="30"
RadiusY="30"
Center="30,30"
/>
</CombinedGeometry.Geometry1> </CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2> <CombinedGeometry.Geometry2>
<EllipseGeometry <EllipseGeometry RadiusX="24" RadiusY="24" Center="30,30" />
RadiusX="24"
RadiusY="24"
Center="30,30"
/>
</CombinedGeometry.Geometry2> </CombinedGeometry.Geometry2>
</CombinedGeometry> </CombinedGeometry>
</Path.Data> </Path.Data>
<Path.Fill> <Path.Fill>
<LinearGradientBrush <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
StartPoint="0,0" <GradientStop Color="#B388FF" Offset="0" />
EndPoint="1,1" <GradientStop Color="#A7FFEB" Offset="1" />
>
<GradientStop
Color="#B388FF" Offset="0"
/>
<GradientStop
Color="#A7FFEB" Offset="1"
/>
</LinearGradientBrush> </LinearGradientBrush>
</Path.Fill> </Path.Fill>
<Path.RenderTransform> <Path.RenderTransform>
<RotateTransform/> <RotateTransform />
<!--This is necessary for the animation not to stop--> <!--This is necessary for the animation not to stop-->
</Path.RenderTransform> </Path.RenderTransform>
<Path.Triggers> <Path.Triggers>
<EventTrigger <EventTrigger RoutedEvent="Loaded">
RoutedEvent="Loaded"
>
<BeginStoryboard> <BeginStoryboard>
<Storyboard> <Storyboard>
<DoubleAnimation <DoubleAnimation Storyboard.TargetProperty="(Rectangle.RenderTransform).(RotateTransform.Angle)" To="360" Duration="0:0:.8" RepeatBehavior="Forever" />
Storyboard.TargetProperty="(Rectangle.RenderTransform).(RotateTransform.Angle)"
To="360"
Duration="0:0:.8"
RepeatBehavior="Forever"
/>
</Storyboard> </Storyboard>
</BeginStoryboard> </BeginStoryboard>
</EventTrigger> </EventTrigger>
</Path.Triggers> </Path.Triggers>
</Path> </Path>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -12,12 +12,14 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace Server_Dashboard.Controls { namespace Server_Dashboard.Controls {
/// <summary> /// <summary>
/// Interaction logic for LoadingIndicator.xaml /// Interaction logic for LoadingIndicator.xaml
/// </summary> /// </summary>
public partial class LoadingIndicator : UserControl { public partial class LoadingIndicator : UserControl {
public LoadingIndicator() { public LoadingIndicator() {
InitializeComponent(); InitializeComponent();
} }
} }
} }

View File

@@ -1,263 +1,270 @@
<UserControl x:Class="Server_Dashboard.Controls.ServerModules.ServerModule" <UserControl x:Class="Server_Dashboard.Controls.ServerModules.ServerModule"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Controls.ServerModules" xmlns:local="clr-namespace:Server_Dashboard.Controls.ServerModules"
xmlns:halfroundprogressbar="clr-namespace:Server_Dashboard.Controls.HalfRoundProgressBar" xmlns:halfroundprogressbar="clr-namespace:Server_Dashboard.Controls.HalfRoundProgressBar"
xmlns:doubleroundprogressbar="clr-namespace:Server_Dashboard.Controls.DoubleRoundProgressBar" xmlns:doubleroundprogressbar="clr-namespace:Server_Dashboard.Controls.DoubleRoundProgressBar" mc:Ignorable="d">
mc:Ignorable="d"> <!--Module-->
<Border Background="{StaticResource BackgroundSurface_02dp}" MinHeight="100" MinWidth="300" Width="Auto" Height="Auto" Margin="10" CornerRadius="5"> <Button Cursor="Hand">
<Border.Effect> <Button.Style>
<DropShadowEffect BlurRadius="5" ShadowDepth="0"/> <Style TargetType="Button">
</Border.Effect> <Setter Property="Template">
<Grid> <Setter.Value>
<Grid.RowDefinitions> <ControlTemplate TargetType="Button">
<RowDefinition Height="40"/> <Border x:Name="Border" Background="{StaticResource BackgroundSurface_02dp}" BorderThickness="2" MinHeight="300" MinWidth="400" Width="Auto" Height="Auto" Margin="10" CornerRadius="5">
<RowDefinition Height="*"/> <Border.Effect>
</Grid.RowDefinitions> <DropShadowEffect BlurRadius="5" ShadowDepth="0" />
<Border </Border.Effect>
CornerRadius="5 5 0 0" <Border x:Name="BorderBackground" Background="{StaticResource BackgroundSurface_02dp}" CornerRadius="5">
Grid.Row="0" <Grid>
Background="{StaticResource BackgroundSurface_08dp}" <Grid.RowDefinitions>
> <RowDefinition Height="40" />
<Grid> <RowDefinition Height="Auto" />
<Grid.ColumnDefinitions> <RowDefinition Height="*" />
<ColumnDefinition Width="Auto"/> </Grid.RowDefinitions>
<ColumnDefinition Width="Auto"/> <!--Top Bar-->
<ColumnDefinition Width="*"/> <Border CornerRadius="4 4 0 0" Grid.Row="0" Background="{StaticResource BackgroundSurface_08dp}">
<ColumnDefinition Width="Auto"/> <Grid>
</Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<Image Grid.Column="0" Margin="7.5 0 7.5 0" Height="25" Width="25" Source="{Binding ModuleIcon}"/> <ColumnDefinition Width="Auto" />
<TextBlock Foreground="{StaticResource DeepPurple_A100}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding ModulName}"/> <ColumnDefinition Width="Auto" />
<Border CornerRadius="0 5 0 0" Background="{Binding StatusIndicator}" Grid.Column="3"> <ColumnDefinition Width="*" />
<Grid> <ColumnDefinition Width="Auto" />
<Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ColumnDefinition/> <Image Grid.Column="0" Margin="7.5 0 7.5 0" Height="25" Width="25" Source="{Binding ModuleIcon}" />
<ColumnDefinition/> <TextBlock Foreground="{StaticResource DeepPurple_A100}" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="{Binding ModuleName}" />
</Grid.ColumnDefinitions> <Border CornerRadius="0 5 0 0" Background="{Binding StatusIndicator}" Grid.Column="3">
<TextBlock Margin="7 0 30 0" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Column="0" FontSize="24" Text="Status"> <Grid>
<TextBlock.Foreground> <Grid.ColumnDefinitions>
<SolidColorBrush Color="White" Opacity="0.87"/> <ColumnDefinition />
</TextBlock.Foreground> <ColumnDefinition />
</TextBlock> </Grid.ColumnDefinitions>
<Border CornerRadius="0 5 0 0" Grid.Column="1" HorizontalAlignment="Right" Background="{Binding StatusIndicatorBG}" Padding="6"> <TextBlock Margin="7 0 30 0" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Column="0" FontSize="24" Text="Status">
<Ellipse Fill="{Binding StatusIndicator}" StrokeThickness="0" Width="25" Height="25"/> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
<Border CornerRadius="0 4 0 0" Grid.Column="1" HorizontalAlignment="Right" Background="{Binding StatusIndicatorBG}" Padding="6">
<Ellipse Fill="{Binding StatusIndicator}" StrokeThickness="0" Width="25" Height="25" />
</Border>
</Grid>
</Border>
</Grid>
</Border>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Server" FontSize="20" Margin="10 5 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
<TextBlock Grid.Column="1" Text="{Binding ServerInformation.ServerName}" FontSize="20" Margin="10 5 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
<!--Main Content-->
<Grid Grid.Row="2" Margin="20" Width="Auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1.5*" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--Information panel, left-->
<Grid Margin="0 0 25 0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<Border BorderThickness="0 0 0 1" Padding="0 0 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="User" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="Public IP" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="Private IP" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="Uptime" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="Creation Date" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 0" Padding="0 5 0 0">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="Creator" FontSize="16">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
</StackPanel>
<StackPanel Grid.Column="1">
<Border BorderThickness="0 0 0 1" Padding="0 0 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding ServerInformation.OsUserName}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding ServerInformation.PublicIpAddress}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding ServerInformation.PrivateIpAddress}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding ServerInformation.Uptime}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 1" Padding="0 5 0 5">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding CreationDate}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
<Border BorderThickness="0 1 0 0" Padding="0 5 0 0">
<Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush>
<TextBlock Text="{Binding Creator}" FontSize="16" Padding="15 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60" />
</TextBlock.Foreground>
</TextBlock>
</Border>
</StackPanel>
</Grid>
<!--Graphical Indicators Right-->
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<halfroundprogressbar:HalfRoundProgressBar Margin="5" Grid.Row="0" ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}" BackgroundBrush="{StaticResource BackgroundSurface_08dp}" Height="100" Width="100" Value="{Binding ServerInfo.CpuUsage}" IndicatorBrush="{StaticResource Teal_A100}" />
<TextBlock Foreground="{StaticResource Teal_A100}" Grid.Row="0" Text="CPU" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" />
<halfroundprogressbar:HalfRoundProgressBar Margin="5" Grid.Row="1" ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}" BackgroundBrush="{StaticResource BackgroundSurface_08dp}" Height="100" Width="100" Value="{Binding ServerInfo.GpuUsage}" IndicatorBrush="{StaticResource Teal_A100}" />
<TextBlock Foreground="{StaticResource Teal_A100}" Grid.Row="1" Text="GPU" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" />
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<doubleroundprogressbar:DoubleRoundProgressBar ValueRead="70" ValueWrite="60" ReadIndicatorBrush="{StaticResource DeepPurple_A100}" WriteIndicatorBrush="{StaticResource Teal_A100}" Margin="5" Grid.Row="0" ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}" BackgroundBrush="{StaticResource BackgroundSurface_08dp}" Height="100" Width="100" />
<StackPanel Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" TextAlignment="Center" Text="Read" Foreground="{StaticResource DeepPurple_A100}" />
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" TextAlignment="Center" Text="Write" Foreground="{StaticResource Teal_A100}" />
</StackPanel>
<doubleroundprogressbar:DoubleRoundProgressBar ValueRead="70" ValueWrite="60" ReadIndicatorBrush="{StaticResource DeepPurple_A100}" WriteIndicatorBrush="{StaticResource Teal_A100}" Margin="5" Grid.Row="1" ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}" BackgroundBrush="{StaticResource BackgroundSurface_08dp}" Height="100" Width="100" />
<StackPanel Grid.Row="1" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" TextAlignment="Center" Text="UP" Foreground="{StaticResource DeepPurple_A100}" />
<TextBlock Grid.Row="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="18" TextAlignment="Center" Text="DOWN" Foreground="{StaticResource Teal_A100}" />
</StackPanel>
</Grid>
</Grid>
</Grid>
</Grid>
</Border>
</Border> </Border>
</Grid> <ControlTemplate.Triggers>
</Border> <Trigger Property="IsMouseOver" Value="True">
</Grid> <Setter TargetName="Border" Property="BorderBrush">
</Border> <Setter.Value>
<Grid Grid.Row="2" Margin="20" Width="Auto"> <SolidColorBrush Color="#B388FF" Opacity=".37" />
<Grid.ColumnDefinitions> </Setter.Value>
<ColumnDefinition Width="1.5*"/> </Setter>
<ColumnDefinition/> </Trigger>
</Grid.ColumnDefinitions> <Trigger Property="IsFocused" Value="True">
<Grid Grid.Row="1" Margin="0 0 25 0"> </Trigger>
<Grid.ColumnDefinitions> <Trigger Property="IsPressed" Value="True">
<ColumnDefinition Width="Auto"/> <Setter TargetName="Border" Property="BorderBrush">
<ColumnDefinition Width="Auto"/> <Setter.Value>
</Grid.ColumnDefinitions> <SolidColorBrush Color="#B388FF" Opacity=".87" />
<StackPanel Grid.Column="0"> </Setter.Value>
<TextBlock Text="Servername" FontSize="16" Margin="2 2 5 10"> </Setter>
<TextBlock.Foreground> </Trigger>
<SolidColorBrush Color="White" Opacity="0.60"/> </ControlTemplate.Triggers>
</TextBlock.Foreground> </ControlTemplate>
</TextBlock> </Setter.Value>
<TextBlock Text="User" FontSize="16" Margin="2 2 5 10"> </Setter>
<TextBlock.Foreground> </Style>
<SolidColorBrush Color="White" Opacity="0.60"/> </Button.Style>
</TextBlock.Foreground> </Button>
</TextBlock> </UserControl>
<TextBlock Text="Public IP" FontSize="16" Margin="2 2 5 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="Private IP" FontSize="16" Margin="2 2 5 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="Uptime" FontSize="16" Margin="2 2 5 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="Creation Date" FontSize="16" Margin="2 2 5 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="Creator" FontSize="16" Margin="2 2 5 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="{Binding ServerInfo.ServerName}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding ServerInfo.OSUserName}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding ServerInfo.PublicIpAdress}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding ServerInfo.PrivateIpAdress}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding ServerInfo.Uptime}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding CreationDate}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="{Binding Creator}" FontSize="16" Margin="5 2 2 10">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.60"/>
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</Grid>
<Grid Grid.Row="1" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<halfroundprogressbar:HalfRoundProgressBar
Margin="5"
Grid.Row="0"
ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}"
BackgroundBrush="{StaticResource BackgroundSurface_08dp}"
Height="100"
Width="100"
Value="{Binding ServerInfo.CpuUsage}"
IndicatorBrush="{StaticResource Teal_A100}"
/>
<TextBlock
Foreground="{StaticResource Teal_A100}"
Grid.Row="0"
Text="CPU"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
/>
<halfroundprogressbar:HalfRoundProgressBar
Margin="5"
Grid.Row="1"
ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}"
BackgroundBrush="{StaticResource BackgroundSurface_08dp}"
Height="100"
Width="100"
Value="{Binding ServerInfo.GpuUsage}"
IndicatorBrush="{StaticResource Teal_A100}"
/>
<TextBlock
Foreground="{StaticResource Teal_A100}"
Grid.Row="1"
Text="GPU"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
/>
</Grid>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<doubleroundprogressbar:DoubleRoundProgressBar
ValueRead="70"
ValueWrite="60"
ReadIndicatorBrush="{StaticResource DeepPurple_A100}"
WriteIndicatorBrush="{StaticResource Teal_A100}"
Margin="5"
Grid.Row="0"
ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}"
BackgroundBrush="{StaticResource BackgroundSurface_08dp}"
Height="100"
Width="100"
/>
<StackPanel
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
TextAlignment="Center"
Text="Read"
Foreground="{StaticResource DeepPurple_A100}"
/>
<TextBlock
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
TextAlignment="Center"
Text="Write"
Foreground="{StaticResource Teal_A100}"
/>
</StackPanel>
<doubleroundprogressbar:DoubleRoundProgressBar
ValueRead="70"
ValueWrite="60"
ReadIndicatorBrush="{StaticResource DeepPurple_A100}"
WriteIndicatorBrush="{StaticResource Teal_A100}"
Margin="5"
Grid.Row="1"
ProgressBorderBrush="{StaticResource BackgroundSurface_02dp}"
BackgroundBrush="{StaticResource BackgroundSurface_08dp}"
Height="100"
Width="100"
/>
<StackPanel
Grid.Row="1"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<TextBlock
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
TextAlignment="Center"
Text="UP"
Foreground="{StaticResource DeepPurple_A100}"
/>
<TextBlock
Grid.Row="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
FontSize="18"
TextAlignment="Center"
Text="DOWN"
Foreground="{StaticResource Teal_A100}"
/>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Grid>
</Border>
</UserControl>

View File

@@ -12,12 +12,14 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace Server_Dashboard.Controls.ServerModules { namespace Server_Dashboard.Controls.ServerModules {
/// <summary> /// <summary>
/// Interaktionslogik für ServerModule.xaml /// Interaktionslogik für ServerModule.xaml
/// </summary> /// </summary>
public partial class ServerModule : UserControl { public partial class ServerModule : UserControl {
public ServerModule() { public ServerModule() {
InitializeComponent(); InitializeComponent();
} }
} }
} }

View File

@@ -1,22 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
class DashboardModule {
public string ModuleName { get; set; }
public string Creator { get; set; }
public ServerInformation ServerInfo { get; set; }
public string StatusIndicator { get; set; }
public string StatusIndicatorBG { get; set; }
public bool ServerAvailable { get; set; }
public string ModuleIcon { get; set; }
public string CreationDate { get; set; }
public DashboardModule(bool serverAvailable) {
ServerAvailable = serverAvailable;
StatusIndicator = ServerAvailable ? "#20c657" : "#e53935";
StatusIndicatorBG = ServerAvailable ? "#94eeb0" : "#ef9a9a";
}
}
}

View File

@@ -1,12 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard.DashboardModules {
class NewModuleInformation {
public string ServerName { get; set; }
public string Username { get; set; }
public string IPAdress { get; set; }
public int Port { get; set; }
}
}

View File

@@ -1,19 +0,0 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Server_Dashboard {
class ServerInformation {
public string ServerName { get; set; }
public string OSUserName { get; set; }
public string CpuTemp { get; set; }
public string GpuTemp { get; set; }
public string Uptime { get; set; }
public string DeployDate { get; set; }
public string PublicIpAdress { get; set; }
public string PrivateIpAdress { get; set; }
public string GpuUsage { get; set; }
public string CpuUsage { get; set; }
}
}

View File

@@ -1,105 +1,303 @@
using Microsoft.Win32; using System;
using System;
using System.Collections.Generic;
using System.Configuration; using System.Configuration;
using System.Data; using System.Data;
using System.Data.SqlClient; using System.Data.SqlClient;
using System.Reflection;
namespace Server_Dashboard { namespace Server_Dashboard {
/// <summary>
/// Database class to access the database
/// </summary>
public static class DatabaseHandler { public static class DatabaseHandler {
public static DataTable GetServerInformation() { #region Public Methods
return null;
}
public static int CheckLogin(string uname, string passwd) {
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString)) {
try {
con.Open();
string query = "EXEC ValidateUserLogin @Username = @uname, @Password = @passwd, @Valid = @valid OUTPUT";
using (SqlCommand com = new SqlCommand(query, con)) {
com.Parameters.AddWithValue("@uname", uname);
com.Parameters.AddWithValue("@passwd", passwd);
com.Parameters.Add("@valid", SqlDbType.NVarChar, 250);
com.Parameters["@valid"].Direction = ParameterDirection.Output;
com.ExecuteNonQuery();
return Convert.ToInt32(com.Parameters["@Valid"].Value);
}
} catch (SqlException ex) {
return ex.Number;
} finally {
con.Close();
}
}
}
public static bool CheckCookie(string cookie, string username) {
string valid = "False";
ConnectToDatabase(con => {
string query = "EXEC CheckUserCookie @Cookie = @cookie, @UserName = @username, @Valid = @valid OUTPUT";
using (SqlCommand com = new SqlCommand(query, con)) {
com.Parameters.AddWithValue("@cookie", cookie);
com.Parameters.AddWithValue("@username", username);
com.Parameters.Add("@valid", SqlDbType.NVarChar, 250);
com.Parameters["@valid"].Direction = ParameterDirection.Output;
com.ExecuteNonQuery();
valid = Convert.ToString(com.Parameters["@Valid"].Value);
}
});
return Convert.ToBoolean(valid);
}
public static bool DeleteCookie(string username) {
string valid = "False";
ConnectToDatabase(con => {
string query = "EXEC DeleteUserCookie @Username = @username, @ResponseMessage = @response OUTPUT";
using (SqlCommand com = new SqlCommand(query, con)) {
com.Parameters.AddWithValue("@username", username);
com.Parameters.Add("@response", SqlDbType.NVarChar, 250);
com.Parameters["@response"].Direction = ParameterDirection.Output;
com.ExecuteNonQuery();
valid = Convert.ToString(com.Parameters["@ResponseMessage"].Value);
}
});
return Convert.ToBoolean(valid);
}
public static bool AddCookie(string cookie, string username) {
string valid = "False";
ConnectToDatabase(con => {
string query = "EXEC AddCookieToUser @Cookie = @cookie, @UserName = @username, @ResponseMessage = @response OUTPUT";
using (SqlCommand com = new SqlCommand(query, con)) {
com.Parameters.AddWithValue("@cookie", cookie);
com.Parameters.AddWithValue("@username", username);
com.Parameters.Add("@response", SqlDbType.NVarChar, 250);
com.Parameters["@response"].Direction = ParameterDirection.Output;
com.ExecuteNonQuery();
valid = Convert.ToString(com.Parameters["@ResponseMessage"].Value);
}
});
return Convert.ToBoolean(valid);
}
#region Private methods
/// <summary> /// <summary>
/// Opens a database connection /// Checks the user credentials
/// </summary> /// </summary>
/// <param name="callback">Callback type SqlConnection</param> /// <param name="uname">The username</param>
/// <returns></returns> /// <param name="passwd">The plain text password</param>
private static SqlConnection ConnectToDatabase(Action<SqlConnection> callback) { /// <returns>[0] is false, [1] is true, [2] connection error</returns>
using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString)) { public static int CheckLogin(string uname, string passwd) {
try { //Creates the database connection
con.Open(); using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
callback(con); try {
con.Close(); //Open the connection
} catch (SqlException ex) { con.Open();
return null; //SQL Query
} string query = "EXEC ValidateUserLogin @Username = @uname, @Password = @passwd, @Valid = @valid OUTPUT";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@uname", uname);
com.Parameters.AddWithValue("@passwd", passwd);
com.Parameters.Add("@valid", SqlDbType.NVarChar, 250);
com.Parameters["@valid"].Direction = ParameterDirection.Output;
//Execute query and return number of rows affected
com.ExecuteNonQuery();
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
return Convert.ToInt32(com.Parameters["@Valid"].Value) == 0 ? 1 : 0;
//Catch any error
} catch (SqlException ex) {
return ex.Number;
} finally {
//Always close the connection
con.Close();
} }
return null;
} }
#endregion
public static DataTable GetUserData(string username) {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "SELECT ID, Username, Email, RegistrationDate FROM UserData WHERE Username = @username";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@username", username);
//Execute query and return number of rows affected
DataTable resultTable = new DataTable() { TableName = "Userdata" };
using SqlDataAdapter sda = new SqlDataAdapter(com);
sda.Fill(resultTable);
return resultTable;
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
//Catch any error
} catch (SqlException) {
return null;
} finally {
//Always close the connection
con.Close();
}
}
public static DataTable GetUserModuleData(int uid) {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "SELECT Creator, CreationTime, ModuleName, MI.Image, ModuleData.ID FROM ModuleData LEFT JOIN ModuleIcon MI on ModuleData.ID = MI.Module WHERE UserID = @userID";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@userID", uid);
//Execute query and return number of rows affected
DataTable resultTable = new DataTable();
using SqlDataAdapter sda = new SqlDataAdapter(com);
sda.Fill(resultTable);
return resultTable;
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
//Catch any error
} catch (SqlException) {
return null;
} finally {
//Always close the connection
con.Close();
}
}
/// <summary>
/// This function will fetch every server data for each module
/// This will need some optimization, for now we just asynchronously
/// fetch the server data for each module
/// </summary>
/// <param name="mid">ModuleID to fetch the data from</param>
/// <returns></returns>
public static DataTable GetServerData(int mid) {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "SELECT * FROM ServerData WHERE ModuleID = @mid";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@mid", mid);
//Execute query and return number of rows affected
DataTable resultTable = new DataTable();
using SqlDataAdapter sda = new SqlDataAdapter(com);
sda.Fill(resultTable);
return resultTable;
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
//Catch any error
} catch (SqlException) {
return null;
} finally {
//Always close the connection
con.Close();
}
}
/// <summary>
/// Creates a new Module for the current user
/// </summary>
/// <param name="ipAddress">Server IP Address</param>
/// <param name="moduleName">Module name, default is Module</param>
/// <param name="serverName">Server name, default is Server</param>
/// <param name="username">Username of the current user</param>
/// <param name="moduleIcon">module icon as byte[]</param>
/// <param name="port">port, default ist 22</param>
/// <returns></returns>
public static int CreateNewModule(string ipAddress, string moduleName, string serverName, string username, byte[] moduleIcon, string port = "22") {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "EXEC AddNewModuleToUser @UserName = @username, @DateTime = @time, @ModuleName = @moduleName, @ServerName = @serverName, @ModuleIcon = @moduleIcon, @IPAddress = @ipAddress, @Port = @port";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);
//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@username", username);
com.Parameters.AddWithValue("@time", DateTime.Now);
com.Parameters.AddWithValue("@moduleName", moduleName);
com.Parameters.AddWithValue("@serverName", serverName);
com.Parameters.Add("@moduleIcon", SqlDbType.VarBinary, -1).Value = moduleIcon;
if (moduleIcon == null)
com.Parameters["@moduleIcon"].Value = DBNull.Value;
//com.Parameters.AddWithValue("@moduleIcon", moduleIcon);
com.Parameters.AddWithValue("@ipAddress", ipAddress);
com.Parameters.AddWithValue("@port", port);
//Execute query and return number of rows affected
int sqlResponse = com.ExecuteNonQuery();
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
return sqlResponse == 0 ? 1 : 0;
//Catch any error
} catch (SqlException ex) {
return ex.Number;
} finally {
//Always close the connection
con.Close();
}
}
/// <summary>
/// Currently obsolete, would check the Username and Cookie
/// </summary>
/// <param name="cookie">Locally stored user cookie</param>
/// <param name="username">Locally stored username</param>
/// <returns>[0] is false, [1] is true, [2] connection error</returns>
public static int CheckCookie(string cookie, string username) {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "((SELECT Cookie FROM UserData WHERE Username = @username) = @cookie)";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);
//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@cookie", cookie);
com.Parameters.AddWithValue("@username", username);
//Execute query and return number of rows affected
int sqlResponse = com.ExecuteNonQuery();
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successfull
return sqlResponse == 0 ? 1 : 0;
//Catch any error
} catch (SqlException ex) {
return ex.Number;
} finally {
//Always close the connection
con.Close();
}
}
/// <summary>
/// Deletes a the cookie from the given user
/// </summary>
/// <param name="username">User who doesnt deserve any delicious cookies :3</param>
public static int DeleteCookie(string username) {
//Creates the database connection
using SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "UPDATE UserData SET Cookie = null WHERE Username = @username";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);
//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.AddWithValue("@username", username);
//Execute query and return number of rows affected
int sqlResponse = com.ExecuteNonQuery();
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
return sqlResponse == 0 ? 1 : 0;
//Catch any error
} catch (SqlException ex) {
return ex.Number;
} finally {
//Always close the connection
con.Close();
}
}
/// <summary>
/// Adds a new Cookie to a user
/// </summary>
/// <param name="cookie">The delicious locally stored cookie</param>
/// <param name="username">The User who deserves a cookie :3</param>
/// <returns>[0] is false, [1] is true, [2] connection error</returns>
public static int AddCookie(string username, string cookie) {
//Creates the database connection
using SqlConnection con =
new SqlConnection(ConfigurationManager.ConnectionStrings["ServerDashboardDB"].ConnectionString);
try {
//Open the connection
con.Open();
//SQL Query
const string query = "UPDATE UserData SET Cookie = @cookie WHERE Username = @username";
//Creates a new command
using SqlCommand com = new SqlCommand(query, con);
//For security reasons the values are added with this function
//this will avoid SQL Injections
com.Parameters.Add("@cookie", SqlDbType.NVarChar, -1).Value = cookie;
com.Parameters.AddWithValue("@username", username);
//Execute query and return number of rows affected
int sqlResponse = com.ExecuteNonQuery();
//Checks if there are any rows successful
//If the query returns 0 the query wasn't successful
//if its any number above 0 it was successful
return sqlResponse == 0 ? 1 : 0;
//Catch any error
} catch (SqlException ex) {
return ex.Number;
} finally {
//Always close the connection
con.Close();
}
}
#endregion Public Methods
} }
} }

View File

@@ -4,7 +4,11 @@ using System.Security;
using System.Text; using System.Text;
namespace Server_Dashboard { namespace Server_Dashboard {
/// <summary>
/// Interface that makes a SecurePassword go one way
/// </summary>
public interface IHavePassword { public interface IHavePassword {
SecureString SecurePassword { get; } SecureString SecurePassword { get; }
} }
} }

View File

@@ -3,7 +3,11 @@ using System.Collections.Generic;
using System.Text; using System.Text;
namespace Server_Dashboard { namespace Server_Dashboard {
interface IWindowHelper {
/// <summary>
/// Interface to help close a window with a button
/// </summary>
internal interface IWindowHelper {
Action Close { get; set; } Action Close { get; set; }
} }
} }

View File

@@ -6,308 +6,184 @@
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:local="clr-namespace:Server_Dashboard" xmlns:local="clr-namespace:Server_Dashboard"
xmlns:loading="clr-namespace:Server_Dashboard.Controls" xmlns:loading="clr-namespace:Server_Dashboard.Controls"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
x:Name="Login" x:Name="Login"
mc:Ignorable="d" mc:Ignorable="d"
Title="Server Dashboard" Height="700" Width="500" WindowStyle="None" Background="Transparent" ResizeMode="CanResize" local:CloseProperty.Value="True"> Title="Server Dashboard"
Height="700" Width="500" WindowStyle="None" Background="Transparent" ResizeMode="CanResize" local:CloseProperty.Value="True">
<WindowChrome.WindowChrome> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0"/> <WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
</WindowChrome.WindowChrome> </WindowChrome.WindowChrome>
<Window.DataContext> <Window.DataContext>
<local:LoginViewModel/> <local:LoginViewModel />
</Window.DataContext> </Window.DataContext>
<!--#region Login forms main container--> <!--#region Login forms main container-->
<Border Background="{StaticResource BackgroundSurface_00dp}"> <Border Background="{StaticResource BackgroundSurface_00dp}">
<Grid Grid.Row="0"> <Grid Grid.Row="0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="30"/> <RowDefinition Height="30" />
<RowDefinition Height="*"/> <RowDefinition Height="*" />
<RowDefinition Height="70"/> <RowDefinition Height="70" />
<RowDefinition Height="80"/> <RowDefinition Height="80" />
<RowDefinition Height="80"/> <RowDefinition Height="80" />
<RowDefinition Height="80"/> <RowDefinition Height="80" />
<RowDefinition Height="30"/> <RowDefinition Height="30" />
<RowDefinition Height="30"/> <RowDefinition Height="30" />
<RowDefinition Height="80"/> <RowDefinition Height="80" />
<RowDefinition Height=".3*"/> <RowDefinition Height=".3*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<!--#region Custom title bar--> <!--#region Custom title bar-->
<Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="0" Grid.ColumnSpan="2"> <Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="0" Grid.ColumnSpan="2">
<Grid.Effect> <Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="270" ShadowDepth="0" BlurRadius="5" />
</Grid.Effect> </Grid.Effect>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*" />
<ColumnDefinition Width="40"/> <ColumnDefinition Width="40" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Label Grid.Column="0"/> <TextBlock Grid.Column="0" Text="Login" Margin="5 0 0 0" VerticalAlignment="Center">
<Button Style="{StaticResource CloseButton}" Grid.Column="2" Content="✕"> <i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<Button Style="{StaticResource CloseButton}" Grid.Column="1" Content="✕">
<i:Interaction.Triggers> <i:Interaction.Triggers>
<i:EventTrigger EventName="Click"> <i:EventTrigger EventName="Click">
<i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/> <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger> </i:EventTrigger>
</i:Interaction.Triggers> </i:Interaction.Triggers>
</Button> </Button>
</Grid> </Grid>
<!--#endregion--> <!--#endregion-->
<!--#region Greeting text--> <!--#region Greeting text-->
<Border <Border Height="100" BorderBrush="{StaticResource DeepPurple_A100}" BorderThickness="0 2 0 2" Background="{StaticResource BackgroundSurface_00dp}" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Bottom" Grid.ColumnSpan="2" Margin="0 0 0 10">
Height="100" <StackPanel VerticalAlignment="Center" Margin="0 0 0 5">
BorderBrush="{StaticResource DeepPurple_400}" <TextBlock Text="Server Dashboard" FontSize="30" HorizontalAlignment="Center">
BorderThickness="0 2 0 2"
Background="{StaticResource BackgroundSurface_00dp}"
Grid.Row="1"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
Grid.ColumnSpan="2"
Margin="0 0 0 10"
>
<StackPanel
VerticalAlignment="Center"
Margin="0 0 0 5"
>
<TextBlock
Text="Server Dashboard"
FontSize="30"
HorizontalAlignment="Center"
>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
<TextBlock <TextBlock Text="Login" FontSize="30" HorizontalAlignment="Center">
Text="Login"
FontSize="30"
HorizontalAlignment="Center"
>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
</StackPanel> </StackPanel>
</Border> </Border>
<UserControl Grid.Row="2" Visibility="{Binding Loading}"> <UserControl Grid.Row="2" Visibility="{Binding Loading}">
<loading:LoadingIndicator/> <loading:LoadingIndicator />
</UserControl> </UserControl>
<!--#endregion--> <!--#endregion-->
<!--#region Username form--> <!--#region Username form-->
<Border <Border CornerRadius="4" Margin="0 10 0 10" Width="350" Height="60" Background="{StaticResource BackgroundSurface_01dp}" Grid.Row="3" Grid.ColumnSpan="2">
CornerRadius="4"
Margin="0 10 0 10"
Width="350"
Height="60"
Background="{StaticResource BackgroundSurface_01dp}"
Grid.Row="3"
Grid.ColumnSpan="2"
>
<Border.Effect> <Border.Effect>
<DropShadowEffect <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
Direction="0"
ShadowDepth="0"
BlurRadius="5"
/>
</Border.Effect> </Border.Effect>
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/> <ColumnDefinition Width="60" />
<ColumnDefinition/> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image <Viewbox Grid.Column="0" Width="30" Height="30">
Grid.Column="0" <Canvas Width="24" Height="24">
Height="30" <Path Data="M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z">
Source="Assets/Images/userlogin.png" <Path.Fill>
/> <SolidColorBrush Color="White" Opacity="0.38" />
<TextBox </Path.Fill>
Text="{Binding Username}" </Path>
x:Name="UserName" </Canvas>
Grid.Column="1" </Viewbox>
Margin="0 0 5 0" <TextBox Text="{Binding Username}" x:Name="UserName" Grid.Column="1" Margin="0 0 5 0" />
/> <TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Username" Visibility="{Binding ElementName=UserName, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}" Grid.Column="1" IsHitTestVisible="False">
<TextBlock
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="Username"
Visibility="{Binding ElementName=UserName, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}"
Grid.Column="1"
IsHitTestVisible="False"
>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
</Grid> </Grid>
</Border> </Border>
<!--#endregion--> <!--#endregion-->
<!--#region Password form--> <!--#region Password form-->
<Border <Border Margin="0 10 0 10" Background="{StaticResource BackgroundSurface_01dp}" Grid.Row="4" Grid.ColumnSpan="2" Width="350" CornerRadius="4" Padding="0 0 5 0">
Margin="0 10 0 10"
Background="{StaticResource BackgroundSurface_01dp}"
Grid.Row="4"
Grid.ColumnSpan="2"
Width="350"
CornerRadius="4"
Padding="0 0 5 0"
>
<Border.Effect> <Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect> </Border.Effect>
<Grid Grid.Column="1"> <Grid Grid.Column="1">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/> <ColumnDefinition Width="60" />
<ColumnDefinition/> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image Grid.Column="0" Height="30" Source="Assets/Images/userpasswd.png"/> <Viewbox Grid.Column="0" Width="30" Height="30">
<PasswordBox <Canvas Width="24" Height="24">
Width="290" <Path Data="M12,17A2,2 0 0,0 14,15C14,13.89 13.1,13 12,13A2,2 0 0,0 10,15A2,2 0 0,0 12,17M18,8A2,2 0 0,1 20,10V20A2,2 0 0,1 18,22H6A2,2 0 0,1 4,20V10C4,8.89 4.9,8 6,8H7V6A5,5 0 0,1 12,1A5,5 0 0,1 17,6V8H18M12,3A3,3 0 0,0 9,6V8H15V6A3,3 0 0,0 12,3Z">
Height="60" <Path.Fill>
local:MonitorPasswordProperty.Value="True" <SolidColorBrush Color="White" Opacity="0.38" />
Grid.Column="1" </Path.Fill>
x:Name="Password" </Path>
> </Canvas>
</Viewbox>
<PasswordBox Width="290" Height="60" local:MonitorPasswordProperty.Value="True" Grid.Column="1" x:Name="Password">
<PasswordBox.InputBindings> <PasswordBox.InputBindings>
<KeyBinding <KeyBinding Key="Return" Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=Login}" />
Key="Return"
Command="{Binding LoginCommand}"
CommandParameter="{Binding ElementName=Login}"
/>
</PasswordBox.InputBindings> </PasswordBox.InputBindings>
</PasswordBox> </PasswordBox>
<TextBlock <TextBlock Visibility="{Binding ElementName=Password, Path=(local:HasTextProperty.Value), Converter={StaticResource UserNameVisibillity}}" x:Name="PasswordHint" Text="Password" Grid.Column="1" IsHitTestVisible="False" VerticalAlignment="Center" HorizontalAlignment="Left">
Visibility="{Binding ElementName=Password, Path=(local:HasTextProperty.Value), Converter={StaticResource UserNameVisibillity}}" x:Name="PasswordHint"
Text="Password"
Grid.Column="1"
IsHitTestVisible="False"
VerticalAlignment="Center"
HorizontalAlignment="Left"
>
<TextBlock.InputBindings> <TextBlock.InputBindings>
<KeyBinding <KeyBinding Key="Return" Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=Login}" />
Key="Return"
Command="{Binding LoginCommand}"
CommandParameter="{Binding ElementName=Login}"
/>
</TextBlock.InputBindings> </TextBlock.InputBindings>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
</Grid> </Grid>
</Border> </Border>
<!--#endregion--> <!--#endregion-->
<!--#region Login button--> <!--#region Login button-->
<Button <Button Height="60" Width="350" Command="{Binding LoginCommand}" CommandParameter="{Binding ElementName=Login}" Grid.Row="5" Content="LOGIN" Grid.ColumnSpan="2" />
Height="60"
Width="350"
Command="{Binding LoginCommand}"
CommandParameter="{Binding ElementName=Login}"
Grid.Row="5"
Content="LOGIN"
Grid.ColumnSpan="2"
/>
<!--#endregion--> <!--#endregion-->
<!--#region Error text--> <!--#region Error text-->
<TextBlock <TextBlock Text="{Binding ErrorText}" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="6" Grid.Column="1" Foreground="{StaticResource ErrorRed}" FontSize="14" />
Text="{Binding ErrorText}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Grid.Row="6"
Grid.Column="1"
Foreground="{StaticResource ErrorRed}"
FontSize="14"
/>
<!--#endregion--> <!--#endregion-->
<!--#region Remember me and Password forgotten link--> <!--#region Remember me and Password forgotten link-->
<Grid Grid.Row="7"> <Grid Grid.Row="7">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<CheckBox <CheckBox IsChecked="{Binding RememberUser}" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="75 0 0 0" />
IsChecked="{Binding RememberUser}" <TextBlock Grid.Column="1" Text="Remember me?" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10 0 0 0">
Grid.Column="0"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="75 0 0 0"
/>
<TextBlock
Grid.Column="1"
Text="Remember me?"
FontSize="14"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="10 0 0 0"
>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
<TextBlock <TextBlock Grid.Column="3" FontSize="14" Margin="0 0 75 0" VerticalAlignment="Center" HorizontalAlignment="Right">
Grid.Column="3"
FontSize="14"
Margin="0 0 75 0"
VerticalAlignment="Center"
HorizontalAlignment="Right"
>
<!--Send recovery Email to user, probably replace with a button--> <!--Send recovery Email to user, probably replace with a button-->
<Hyperlink <Hyperlink NavigateUri="https://example.com" local:HyperlinkExtensions.IsExternal="True">
NavigateUri="https://example.com"
local:HyperlinkExtensions.IsExternal="True"
>
Forgot password Forgot password
</Hyperlink> </Hyperlink>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
</Grid> </Grid>
<!--#endregion--> <!--#endregion-->
<!--#region Link to register form--> <!--#region Link to register form-->
<Grid Grid.Row="8"> <Grid Grid.Row="8">
<StackPanel <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
Orientation="Horizontal" <TextBlock Text="Don't have an account?" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Right">
HorizontalAlignment="Center"
>
<TextBlock
Text="Don't have an account?"
FontSize="16"
VerticalAlignment="Center"
HorizontalAlignment="Right"
>
<TextBlock.Foreground> <TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.64"/> <SolidColorBrush Color="White" Opacity="0.64" />
</TextBlock.Foreground> </TextBlock.Foreground>
</TextBlock> </TextBlock>
<Button <Button Command="{Binding RegisterCommand}" Content="REGISTER" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="12" Height="30" Width="80" Margin="10 0 0 0" />
Command="{Binding RegisterCommand}"
Content="REGISTER"
VerticalAlignment="Center"
HorizontalAlignment="Left"
FontSize="12"
Height="30"
Width="80"
Margin="10 0 0 0"
/>
</StackPanel> </StackPanel>
</Grid> </Grid>
<!--#endregion--> <!--#endregion-->
</Grid> </Grid>
</Border> </Border>
<!--#endregion--> <!--#endregion-->
</Window> </Window>

View File

@@ -0,0 +1,63 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Server_Dashboard.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Server_Dashboard.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
}
}

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 1.3
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">1.3</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1">this is my long string</data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
[base64 mime encoded serialized .NET Framework object]
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
[base64 mime encoded string representing a byte array form of the .NET Framework object]
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -58,5 +58,17 @@ namespace Server_Dashboard.Properties {
this["RememberMe"] = value; this["RememberMe"] = value;
} }
} }
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string Password {
get {
return ((string)(this["Password"]));
}
set {
this["Password"] = value;
}
}
} }
} }

View File

@@ -11,5 +11,8 @@
<Setting Name="RememberMe" Type="System.Boolean" Scope="User"> <Setting Name="RememberMe" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value> <Value Profile="(Default)">False</Value>
</Setting> </Setting>
<Setting Name="Password" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings> </Settings>
</SettingsFile> </SettingsFile>

View File

@@ -5,12 +5,21 @@ using System.Security;
using System.Text; using System.Text;
namespace Server_Dashboard { namespace Server_Dashboard {
/// <summary>
/// Secure string helper class to unsecure the Password b4 it goes to the database
/// </summary>
public static class SecureStringHelpers { public static class SecureStringHelpers {
//Unsecures a given password
public static string Unsecure(this SecureString secureString) { public static string Unsecure(this SecureString secureString) {
//If empty return nothing
if (secureString == null) if (secureString == null)
return string.Empty; return string.Empty;
//New zero pointer
var unmanagedString = IntPtr.Zero; var unmanagedString = IntPtr.Zero;
//Try to unsecure the string
try { try {
unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString); unmanagedString = Marshal.SecureStringToGlobalAllocUnicode(secureString);
return Marshal.PtrToStringUni(unmanagedString); return Marshal.PtrToStringUni(unmanagedString);
@@ -19,4 +28,4 @@ namespace Server_Dashboard {
} }
} }
} }
} }

View File

@@ -18,23 +18,6 @@
<None Remove="Assets\Fonts\OpenSans\OpenSans-Regular.ttf" /> <None Remove="Assets\Fonts\OpenSans\OpenSans-Regular.ttf" />
<None Remove="Assets\Fonts\OpenSans\OpenSans-SemiBold.ttf" /> <None Remove="Assets\Fonts\OpenSans\OpenSans-SemiBold.ttf" />
<None Remove="Assets\Fonts\OpenSans\OpenSans-SemiBoldItalic.ttf" /> <None Remove="Assets\Fonts\OpenSans\OpenSans-SemiBoldItalic.ttf" />
<None Remove="Assets\Images\Docs.png" />
<None Remove="Assets\Images\Docs.svg" />
<None Remove="Assets\Images\DocsLight.png" />
<None Remove="Assets\Images\GitHub-Mark.zip" />
<None Remove="Assets\Images\GitHub.png" />
<None Remove="Assets\Images\GitHubLight.png" />
<None Remove="Assets\Images\GreenSettings.png" />
<None Remove="Assets\Images\PlaceHolderModule.png" />
<None Remove="Assets\Images\PlaceHolderModuleLight.png" />
<None Remove="Assets\Images\Settings.png" />
<None Remove="Assets\Images\Settings.svg" />
<None Remove="Assets\Images\SettingsLight.png" />
<None Remove="Assets\Images\User.png" />
<None Remove="Assets\Images\User.svg" />
<None Remove="Assets\Images\UserLight.png" />
<None Remove="Assets\Images\userlogin.png" />
<None Remove="Assets\Images\userpasswd.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -65,23 +48,17 @@
<Resource Include="Assets\Fonts\OpenSans\OpenSans-Regular.ttf" /> <Resource Include="Assets\Fonts\OpenSans\OpenSans-Regular.ttf" />
<Resource Include="Assets\Fonts\OpenSans\OpenSans-SemiBold.ttf" /> <Resource Include="Assets\Fonts\OpenSans\OpenSans-SemiBold.ttf" />
<Resource Include="Assets\Fonts\OpenSans\OpenSans-SemiBoldItalic.ttf" /> <Resource Include="Assets\Fonts\OpenSans\OpenSans-SemiBoldItalic.ttf" />
<Resource Include="Assets\Images\Docs.png" />
<Resource Include="Assets\Images\Docs.svg" />
<Resource Include="Assets\Images\DocsLight.png" />
<Resource Include="Assets\Images\GitHub.png" />
<Resource Include="Assets\Images\GitHubLight.png" />
<Resource Include="Assets\Images\PlaceHolderModule.png" />
<Resource Include="Assets\Images\PlaceHolderModuleLight.png" />
<Resource Include="Assets\Images\Settings.svg" />
<Resource Include="Assets\Images\User.svg" />
<Resource Include="Assets\Images\userlogin.png" />
<Resource Include="Assets\Images\userpasswd.png" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Update="Controls\DoubleRoundProgressBar\DoubleRoundProgressBar.xaml.cs"> <Compile Update="Controls\DoubleRoundProgressBar\DoubleRoundProgressBar.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Update="Properties\Settings.Designer.cs"> <Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@@ -89,6 +66,13 @@
</Compile> </Compile>
</ItemGroup> </ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup> <ItemGroup>
<None Update="Properties\Settings.settings"> <None Update="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator> <Generator>SettingsSingleFileGenerator</Generator>

View File

@@ -0,0 +1,2 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/CodeInspection/Daemon/ConfigureAwaitAnalysisMode/@EntryValue">UI</s:String></wpf:ResourceDictionary>

View File

@@ -18,10 +18,16 @@
<Compile Update="Controls\ServerModules\ServerModule.xaml.cs"> <Compile Update="Controls\ServerModules\ServerModule.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Update="Views\DashboardPages\MainDashboardPage.xaml.cs"> <Compile Update="Views\Dashboard\AnalyticsPage.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Update="Controls\Dashboard\CRUD Popup\CreateModulePopup.xaml.cs"> <Compile Update="Views\Dashboard\SettingsPage.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Pages\MainDashboardPage.xaml.cs">
<SubType>Code</SubType>
</Compile>
<Compile Update="Views\Dashboard\CRUD Popup\CreateModulePopup.xaml.cs">
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Update="Views\DashboardWindow.xaml.cs"> <Compile Update="Views\DashboardWindow.xaml.cs">
@@ -44,10 +50,16 @@
<Page Update="LoginWindow.xaml"> <Page Update="LoginWindow.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Update="Views\DashboardPages\MainDashboardPage.xaml"> <Page Update="Views\Dashboard\AnalyticsPage.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Update="Controls\Dashboard\CRUD Popup\CreateModulePopup.xaml"> <Page Update="Views\Dashboard\SettingsPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Pages\MainDashboardPage.xaml">
<SubType>Designer</SubType>
</Page>
<Page Update="Views\Dashboard\CRUD Popup\CreateModulePopup.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
</Page> </Page>
<Page Update="Views\DashboardWindow.xaml"> <Page Update="Views\DashboardWindow.xaml">

View File

@@ -0,0 +1,44 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Media.Imaging;
namespace Server_Dashboard {
internal class ModuleData {
//The name the user gives the module
public string ModuleName { get; set; }
//The user who created it
public string Creator { get; set; }
//The status indicator
public string StatusIndicator { get; set; }
//The background color of the status indicator
public string StatusIndicatorBG { get; set; }
//If the server is avaibale or not
public bool ServerAvailable { get; set; }
//The Module icon the user give the server, defaults to a generic server symbol
public BitmapImage ModuleIcon { get; set; }
//Creation date with System.DateTime.Now
public DateTime CreationDate { get; set; }
//List that contains all the serverinformation over a period of time(lifespan of the module)
public ServerInformation ServerInformation { get; set; }
/// <summary>
/// This will set the Module status indicator red or green if the server is available or not
/// </summary>
/// <param name="serverAvailable"></param>
public ModuleData(bool serverAvailable) {
ServerAvailable = serverAvailable;
StatusIndicator = ServerAvailable ? "#20c657" : "#e53935";
StatusIndicatorBG = ServerAvailable ? "#94eeb0" : "#ef9a9a";
}
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// Server information class, this will probably scale pretty big later on
/// This will hold all the information the socket will gather
/// </summary>
internal class ServerInformation {
public string ServerName { get; set; }
public string OsUserName { get; set; }
public double CpuTemp { get; set; }
public double GpuTemp { get; set; }
public TimeSpan Uptime { get; set; }
public DateTime DeployDate { get; set; }
public string PublicIpAddress { get; set; }
public string PrivateIpAddress { get; set; }
public int GpuUsage { get; set; }
public int CpuUsage { get; set; }
public double NetworkUP { get; set; }
public double NetworkDown { get; set; }
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents a single CPU and will be added
/// to a list to account for a multi CPU system
/// </summary>
internal class CPU {
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents a single drive on a server, this will be added
/// to a list to account for multiple drives
/// </summary>
internal class Drives {
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents a single GPU and will be added to a list
/// to account for multiple GPU's
/// </summary>
internal class GPU {
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents the mainboard
/// It will hold information about the chipset, number of hardware etc...
/// </summary>
internal class Motherboard {
}
}

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents a single network interface and will be added
/// to a list to account for multiple networking interfaces
/// </summary>
internal class NetworkInterface {
}
}

View File

@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// This class represents RAM
/// TODO: figure out if it makes sense to create a class for the entire system memory
/// or for each and every stick
/// </summary>
internal class RAM {
}
}

View File

@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Data;
using System.Text;
namespace Server_Dashboard {
/// <summary>
/// User class to store user informations
/// </summary>
internal class User {
public int UID { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public DateTime RegistrationDate { get; set; }
public User(DataTable userData) {
foreach (DataRow row in userData.Rows) {
UID = (int)row[0];
UserName = (string)row[1];
Email = (string)row[2];
RegistrationDate = (DateTime)row[3];
}
}
}
}

View File

@@ -5,10 +5,15 @@ using System.Text;
using System.Windows.Data; using System.Windows.Data;
namespace Server_Dashboard { namespace Server_Dashboard {
/// <summary>
/// Value to angle converter
/// </summary>
[ValueConversion(typeof(int), typeof(double))] [ValueConversion(typeof(int), typeof(double))]
public class ValueToAngleConverter : IValueConverter { public class ValueToAngleConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => (int)value * 0.01 * 360; public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => (int)value * 0.01 * 360;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => (int)((double)value / 360); public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => (int)((double)value / 360);
} }
} }

View File

@@ -1,14 +1,17 @@
using System; using System.ComponentModel;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
namespace Server_Dashboard { namespace Server_Dashboard {
class BaseViewModel : INotifyPropertyChanged {
/// <summary>
/// Base View Model all the other view models inherit from
/// Makes me write the INotifyPropertyChanged only once
/// </summary>
public class BaseViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { }; public event PropertyChangedEventHandler PropertyChanged = (sender, e) => { };
protected void OnPropertyChanged(string prop) { protected void OnPropertyChanged(string prop) {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
} }
} }
} }

View File

@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
internal class AnalyticsViewModel : BaseViewModel {
}
}

View File

@@ -1,44 +1,65 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Data;
using System.IO;
using System.Text; using System.Text;
using System.Windows.Media.Imaging;
namespace Server_Dashboard { namespace Server_Dashboard {
class DashboardModuleViewModel : BaseViewModel {
public ObservableCollection<DashboardModule> Modules { get; set; }
private int gpuUsage;
public int GPUUsage { /// <summary>
get { return gpuUsage; } /// View Model for the modules
set { /// </summary>
if(value != gpuUsage) internal class DashboardModuleViewModel : BaseViewModel {
gpuUsage = value;
OnPropertyChanged(nameof(gpuUsage));
}
}
public DashboardModuleViewModel() { //List with all Modules inside
Modules = new ObservableCollection<DashboardModule>(); public ObservableCollection<ModuleData> Modules { get; set; }
for (int i = 0; i < 10; i++) {
Modules.Add(new DashboardModule(true) { //Creates Default Modules, remove before release and when implementing the actual data coming from the socket
ModuleName = "TestModule", public DashboardModuleViewModel(DataTable moduleData) {
Creator = "Username", Modules = new ObservableCollection<ModuleData>();
ModuleIcon = "../../Assets/Images/PlaceHolderModuleLight.png", foreach (DataRow row in moduleData.Rows) {
CreationDate = DateTime.Now.ToString(), if (row[0] == null)
ServerInfo = new ServerInformation() { return;
GpuUsage = "20", byte[] iconBytes = row[3] == DBNull.Value ? null : (byte[])row[3];
CpuUsage = "20", DataTable serverData = DatabaseHandler.GetServerData((int)row[4]);
CpuTemp = "88.88", ServerInformation serverInformation = null;
DeployDate = DateTime.Now.ToString(), if (serverData.Rows.Count != 0) {
GpuTemp = "69.69", DataRow serverRow = serverData.Rows[0];
ServerName = "Ubuntu", serverInformation = new ServerInformation {
OSUserName = "crylia " + i, ServerName = (string)serverRow[4] ?? "",
PrivateIpAdress = "192.168.1.1", PublicIpAddress = (string)serverRow[6] ?? "",
PublicIpAdress = "85.69.102.58", PrivateIpAddress = (string)serverRow[5] ?? "",
Uptime = DateTime.Now.ToString() Uptime = (TimeSpan)serverRow[7],
} OsUserName = (string)serverRow[3] ?? ""
};
}
Modules.Add(new ModuleData(false) {
ModuleName = (string)row[2] ?? "",
Creator = (string)row[0] ?? "",
ModuleIcon = ConvertByteToBitmapImage(iconBytes),
CreationDate = (DateTime)row[1],
ServerInformation = serverInformation
}); });
} }
} }
private static BitmapImage ConvertByteToBitmapImage(byte[] icon) {
if (icon == null)
return null;
try {
using MemoryStream ms = new MemoryStream(icon);
BitmapImage moduleIcon = new BitmapImage();
moduleIcon.BeginInit();
moduleIcon.StreamSource = ms;
moduleIcon.CreateOptions = BitmapCreateOptions.PreservePixelFormat;
moduleIcon.CacheOption = BitmapCacheOption.OnLoad;
moduleIcon.EndInit();
moduleIcon.Freeze();
return moduleIcon;
} catch { }
return null;
}
} }
} }

View File

@@ -1,60 +1,141 @@
using Server_Dashboard.Views.DashboardPages.ModuleCRUD; using Server_Dashboard.Views.DashboardPages.ModuleCRUD;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Data;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using Server_Dashboard_Socket;
namespace Server_Dashboard { namespace Server_Dashboard {
class DashboardViewModel : BaseViewModel {
private string userName = "Username";
private DashboardModuleViewModel dmvm = new DashboardModuleViewModel();
public string UserName { /// <summary>
get { return userName; } /// View Model for the Dashboard
set { /// </summary>
if(userName != value) internal class DashboardViewModel : BaseViewModel {
userName = value;
OnPropertyChanged(nameof(userName)); #region Private Values
private DashboardModuleViewModel dmvm;
#endregion Private Values
#region Public Values
public SettingsViewModel SettingsViewModel { get; set; }
public AnalyticsViewModel AnalyticsViewModel { get; set; }
#endregion Public Values
#region Properties
//The Username displayed defaults to Username
private User user;
public User User {
get { return user; }
set {
if (user != value)
user = value;
OnPropertyChanged(nameof(user));
} }
} }
private ObservableCollection<DashboardModule> modules; //List that contains every Module
private ObservableCollection<ModuleData> modules;
public ObservableCollection<DashboardModule> Modules { public ObservableCollection<ModuleData> Modules {
get { return modules; } get { return modules; }
set { set {
if(value != modules) if (value != modules)
modules = value; modules = value;
OnPropertyChanged(nameof(modules)); OnPropertyChanged(nameof(modules));
} }
} }
public DashboardViewModel() { private object currentView;
EchoServer echoServer = new EchoServer();
echoServer.Start(); public object CurrentView {
get => currentView;
set {
if (value != currentView)
currentView = value;
OnPropertyChanged(nameof(currentView));
}
}
#endregion Properties
#region Constructor
public DashboardViewModel(string username) {
//Command init
OpenLinkCommand = new RelayCommand(OpenLink); OpenLinkCommand = new RelayCommand(OpenLink);
OpenNewModuleWindowCommand = new RelayCommand(OpenNewModuleWindow); OpenNewModuleWindowCommand = new RelayCommand(OpenNewModuleWindow);
CreateModuleCommand = new RelayCommand(CreateModule); SwitchViewModelCommand = new RelayCommand(SwitchViewModel);
Modules = dmvm.Modules; AnalyticsViewModel = new AnalyticsViewModel();
SettingsViewModel = new SettingsViewModel();
CurrentView = this;
DataTable userData = DatabaseHandler.GetUserData(username);
User = new User(userData);
GetModules();
} }
#endregion Constructor
#region ICommands
public ICommand OpenLinkCommand { get; set; } public ICommand OpenLinkCommand { get; set; }
public ICommand OpenNewModuleWindowCommand { get; set; } public ICommand OpenNewModuleWindowCommand { get; set; }
public ICommand CreateModuleCommand { get; set; } public ICommand SwitchViewModelCommand { get; set; }
private void OpenLink(object param) {
Process.Start(new ProcessStartInfo((string)param) { UseShellExecute = true }); #endregion ICommands
#region Commands
private void SwitchViewModel(object param) {
switch (param) {
case "settingsviewmodel":
CurrentView = SettingsViewModel;
break;
case "analyticsviewmodel":
CurrentView = AnalyticsViewModel;
break;
case "dashboardviewmodel":
CurrentView = this;
break;
}
} }
/// <summary>
/// Opens a given link in the default browser
/// </summary>
/// <param name="param">The Link to be opened e.g. https://github.com/Crylia/Server-Dashboard </param>
private void OpenLink(object param) => Process.Start(new ProcessStartInfo((string)param) { UseShellExecute = true });
/// <summary>
/// Creates a new window to create a new Module
/// </summary>
/// <param name="param">Nothing</param>
private void OpenNewModuleWindow(object param) { private void OpenNewModuleWindow(object param) {
//Creates a new CreateModulePopup and sets this view model as data context
CreateModulePopup cmp = new CreateModulePopup { CreateModulePopup cmp = new CreateModulePopup {
DataContext = this DataContext = new CreateModuleViewModel(User.UserName)
}; };
//Opens it in the middle of the screen, setting the parent window as owner causes the
//application to crash when NOT in debug mode(???)
cmp.WindowStartupLocation = WindowStartupLocation.CenterScreen; cmp.WindowStartupLocation = WindowStartupLocation.CenterScreen;
cmp.ShowDialog(); cmp.ShowDialog();
GetModules();
} }
private void CreateModule(object param) {
private void GetModules() {
dmvm = new DashboardModuleViewModel(DatabaseHandler.GetUserModuleData(User.UID));
//Sets the local module to the dashboard view module modules
Modules = dmvm.Modules;
} }
#endregion Commands
} }
} }

View File

@@ -0,0 +1,178 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Input;
using System.Windows.Media.Imaging;
namespace Server_Dashboard {
internal class CreateModuleViewModel : BaseViewModel, IWindowHelper {
private readonly string username;
private string serverName;
public string ServerName {
get => serverName;
set {
if (serverName != value)
serverName = value;
OnPropertyChanged(nameof(serverName));
}
}
private string moduleName;
public string ModuleName {
get => moduleName;
set {
if (moduleName != value)
moduleName = value;
OnPropertyChanged(nameof(moduleName));
}
}
private string ipAddress;
public string IpAddress {
get => ipAddress;
set {
if (ipAddress != value)
ipAddress = value;
OnPropertyChanged(nameof(ipAddress));
}
}
private string port;
public string Port {
get => port;
set {
if (port != value)
port = value;
OnPropertyChanged(nameof(port));
}
}
private BitmapImage moduleIcon;
public BitmapImage ModuleIcon {
get => moduleIcon;
set {
if (moduleIcon != value)
moduleIcon = value;
OnPropertyChanged(nameof(moduleIcon));
}
}
private string userInformationMessage;
public string UserInformationMessage {
get => userInformationMessage;
set {
if (userInformationMessage != value)
userInformationMessage = value;
OnPropertyChanged(nameof(userInformationMessage));
}
}
public CreateModuleViewModel(string username) {
this.username = username;
CreateModuleCommand = new RelayCommand(CreateModuleAsync);
SelectIconCommand = new RelayCommand(SelectIcon);
RemoveIconCommand = new RelayCommand(RemoveIcon);
TestConnectionCommand = new RelayCommand(TestConnection);
}
public ICommand RemoveIconCommand { get; set; }
public ICommand SelectIconCommand { get; set; }
public ICommand CreateModuleCommand { get; set; }
public ICommand TestConnectionCommand { get; set; }
public Action Close { get; set; }
//private readonly Regex moduleNameFilter = new Regex(@"^[A-Z][a-z][0-9]{0-20}$");
//private readonly Regex serverNameFilter = new Regex(@"^[A-Z][a-z][0-9]{0-20}$");
private readonly Regex ipFilter = new Regex(@"^(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$");
/// <summary>
/// First checks if the IP address and the other credentials are valid
/// than asynchronously sends the data to the database where the module will be saved
/// this also triggers a reload of all modules to make sure the newly created module
/// will be shown without an application restart
/// </summary>
/// <param name="param">Nothing</param>
private async void CreateModuleAsync(object param) {
//Checks if the IP field is not empty and valid
if (!string.IsNullOrWhiteSpace(ipAddress) && ipFilter.IsMatch(ipAddress)) {
//Gives the Module a default name if the user doesn't name it
if (string.IsNullOrWhiteSpace(moduleName))
moduleName = "Module";
//Gives the Server a default name is the user doesn't name it
if (string.IsNullOrWhiteSpace(serverName))
serverName = "Server";
//Makes sure the name isn't any longer than characters
if (moduleName.Length >= 20) {
UserInformationMessage = "The Module Name is too long";
return;
}
//Makes sure the name isn't any longer than characters
if (serverName.Length >= 20) {
UserInformationMessage = "The Server Name is too long";
return;
}
//Clears the error message if there isn't any error
UserInformationMessage = "";
byte[] moduleIconStream = null;
if (moduleIcon != null) {
try {
JpegBitmapEncoder encoder = new JpegBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(moduleIcon));
await using MemoryStream ms = new MemoryStream();
encoder.Save(ms);
moduleIconStream = ms.ToArray();
} catch (Exception) { }
}
if (await Task.Run(() => DatabaseHandler.CreateNewModule(ipAddress, moduleName, serverName, username, moduleIconStream, port)) == 0) {
Close?.Invoke();
} else {
UserInformationMessage = "Unknown error occurred, please try again later";
}
} else {
UserInformationMessage = "The IP Address is invalid";
}
}
/// <summary>
/// Opens a file dialog and lets the user select a .jpg, .jpeg or .png file as icon
/// </summary>
/// <param name="param"></param>
private void SelectIcon(object param) {
OpenFileDialog ofd = new OpenFileDialog {
Title = "Choose an Image",
Filter = "Supported format|*.jpg;*.jpeg;*.png"
};
if (Convert.ToBoolean(ofd.ShowDialog())) {
ModuleIcon = new BitmapImage(new Uri(ofd.FileName));
}
}
/// <summary>
/// Removes the selected ModuleIcon
/// </summary>
/// <param name="param"></param>
private void RemoveIcon(object param) => ModuleIcon = null;
/// <summary>
/// Tests the socket connection
/// </summary>
/// <param name="param"></param>
private void TestConnection(object param) {
//TODO: Test connection to the socket server
}
}
}

View File

@@ -0,0 +1,9 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Server_Dashboard {
internal class SettingsViewModel : BaseViewModel {
}
}

View File

@@ -3,10 +3,18 @@ using Server_Dashboard.Properties;
using System; using System;
using System.Windows.Input; using System.Windows.Input;
using System.Threading.Tasks; using System.Threading.Tasks;
using Server_Dashboard_Socket;
namespace Server_Dashboard { namespace Server_Dashboard {
class LoginViewModel : BaseViewModel, IWindowHelper {
/// <summary>
/// View Model for the Login Window
/// </summary>
internal class LoginViewModel : BaseViewModel, IWindowHelper {
#region Properties
//Username Property
private string username; private string username;
public string Username { public string Username {
@@ -18,6 +26,7 @@ namespace Server_Dashboard {
} }
} }
//Error Text displays an error to help the user to fill the form
private string errorText; private string errorText;
public string ErrorText { public string ErrorText {
@@ -29,17 +38,19 @@ namespace Server_Dashboard {
} }
} }
//Remember me button
private bool rememberUser; private bool rememberUser;
public bool RememberUser { public bool RememberUser {
get { return rememberUser; } get { return rememberUser; }
set { set {
if(value != rememberUser) if (value != rememberUser)
rememberUser = value; rememberUser = value;
OnPropertyChanged(nameof(rememberUser)); OnPropertyChanged(nameof(rememberUser));
} }
} }
//Loading circle, gets hidden and shown when logging in
private string loading; private string loading;
public string Loading { public string Loading {
@@ -51,71 +62,157 @@ namespace Server_Dashboard {
} }
} }
public Action Close { get ; set; } #endregion Properties
#region Public Values
//Close action for the Window to close properly
public Action Close { get; set; }
#endregion Public Values
#region Constructor
public LoginViewModel() { public LoginViewModel() {
//SocketClient sc = new SocketClient();
//Loading circle is hidden on startup
Loading = "Hidden"; Loading = "Hidden";
//Command inits
LoginCommand = new RelayCommand(LoginAsync); LoginCommand = new RelayCommand(LoginAsync);
if (!String.IsNullOrEmpty(Settings.Default.Username)) { //Checks if the Username and Cookie is saved in the Settings.settings
if (!String.IsNullOrEmpty(Settings.Default.Username) && !String.IsNullOrEmpty(Settings.Default.Cookies)) {
//Takes the saved Username and Remember me button status and pre fills the username and checks the Remember me button
Username = Settings.Default.Username; Username = Settings.Default.Username;
RememberUser = Settings.Default.RememberMe; RememberUser = Settings.Default.RememberMe;
} }
//TODO: Auto login
//AutoLoginAsync();
} }
#endregion Constructor
#region ICommands
public ICommand LoginCommand { get; set; } public ICommand LoginCommand { get; set; }
#endregion ICommands
#region Commands
/// <summary>
/// Async login
/// </summary>
/// <param name="parameter">Secure password string</param>
private async void LoginAsync(object parameter) { private async void LoginAsync(object parameter) {
//Checks if the Username and Password field has content
if (!String.IsNullOrWhiteSpace(Username) && !String.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) { if (!String.IsNullOrWhiteSpace(Username) && !String.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) {
//Sets loading to true to show the loading icon
Loading = "Visible"; Loading = "Visible";
//Sends the Username and Password to the database and saved the result, 1 successful, 0 wrong username or password
int result = await Task.Run(() => DatabaseHandler.CheckLogin(Username, (parameter as IHavePassword).SecurePassword.Unsecure())); int result = await Task.Run(() => DatabaseHandler.CheckLogin(Username, (parameter as IHavePassword).SecurePassword.Unsecure()));
//hides the loading again
Loading = "Hidden"; Loading = "Hidden";
/*result can be:
0 for Wrong username or password
1 for true username or password
2 for network or database unreachable
default error for everything else
*/
switch (result) { switch (result) {
case 0: case 0:
//Sets the error text and exits function
ErrorText = "Username or password is wrong."; ErrorText = "Username or password is wrong.";
return; return;
case 1: case 1:
/*No idea why this is here, gonna let it be till the remember me and autologin is 100% done
if (RememberUser && !String.IsNullOrEmpty(Settings.Default.Cookies)) { if (RememberUser && !String.IsNullOrEmpty(Settings.Default.Cookies)) {
DatabaseHandler.CheckCookie(Settings.Default.Cookies, Username); DatabaseHandler.CheckCookie(Settings.Default.Cookies, Username);
} }*/
//If the remember me is not checked and a cookie exists the local storage gets cleared
if (!RememberUser && !String.IsNullOrEmpty(Settings.Default.Cookies)) { if (!RememberUser && !String.IsNullOrEmpty(Settings.Default.Cookies)) {
Settings.Default.Cookies = null; Settings.Default.Cookies = null;
Settings.Default.Username = ""; Settings.Default.Username = "";
Settings.Default.RememberMe = false; Settings.Default.RememberMe = false;
Settings.Default.Password = "";
Settings.Default.Save(); Settings.Default.Save();
//Also deletes the cookie from the database
DatabaseHandler.DeleteCookie(Username); DatabaseHandler.DeleteCookie(Username);
} }
if (RememberUser && String.IsNullOrEmpty(Settings.Default.Cookies)) { //If the remember user option is checked and the cookie is not set save everything locally
var guid = new Guid().ToString() + Username; if (RememberUser && Settings.Default.Username != Username) {
Settings.Default.Cookies = guid; //Creates a new GUID with the username at the end, this is the cookie
var cookie = $"{Guid.NewGuid()}+user:{Username}";
//Saves cookie, Username Remember me option to the local storage (Settings.settings)
Settings.Default.Cookies = cookie;
Settings.Default.Username = Username; Settings.Default.Username = Username;
Settings.Default.RememberMe = true; Settings.Default.RememberMe = true;
Settings.Default.Save(); Settings.Default.Save();
DatabaseHandler.AddCookie(Username, guid); //Saves the cookie in the database
DatabaseHandler.AddCookie(Username, cookie);
} }
DashboardWindow window = new DashboardWindow(); //Creates a new Dashboard window and shows it
DashboardWindow window = new DashboardWindow() {
DataContext = new DashboardViewModel(Username)
};
window.Show(); window.Show();
//Close window when dashboard is shown
Close?.Invoke(); Close?.Invoke();
return; return;
case 2: case 2:
//Sets the error text
ErrorText = "Server unreachable, connection timeout."; ErrorText = "Server unreachable, connection timeout.";
return; return;
default: default:
ErrorText = "An unknown error has occured"; //Sets the error text
ErrorText = "An unknown error has occurred";
return; return;
} }
} else if (String.IsNullOrWhiteSpace(Username) && String.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) { //If the Username and password is blank
//All these IF's could be one but i made multiple for the different errors so the user knows whats wrong
}
if (string.IsNullOrWhiteSpace(Username) && string.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) {
//Sets the error text
ErrorText = "Please provide a username and password"; ErrorText = "Please provide a username and password";
return; return;
} }
if (String.IsNullOrWhiteSpace(Username)) { //Only if the Username is empty
if (string.IsNullOrWhiteSpace(Username)) {
//Sets the error text
ErrorText = "Username cannot be empty."; ErrorText = "Username cannot be empty.";
return; return;
} }
if (String.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) { //Only if the password is empty
if (string.IsNullOrWhiteSpace((parameter as IHavePassword).SecurePassword.Unsecure())) {
//Sets the error text
ErrorText = "Password cannot be empty."; ErrorText = "Password cannot be empty.";
return; return;
} }
//If there is no error, clear the error text
ErrorText = ""; ErrorText = "";
} }
#endregion Commands
#region private functions
//TODO: Add auto login function that locks the UI until the user hits the abort button or the login completes
/*private async void AutoLoginAsync() {
if (Settings.Default.RememberMe && !String.IsNullOrEmpty(Settings.Default.Username) && !String.IsNullOrEmpty(Settings.Default.Cookies)) {
Loading = "Visible";
int result = await Task.Run(() => DatabaseHandler.CheckCookie(Settings.Default.Cookies, Username));
Loading = "Hidden";
if (result == 1) {
DashboardWindow window = new DashboardWindow();
window.Show();
Close?.Invoke();
return;
}
}
}*/
#endregion private functions
} }
} }

View File

@@ -7,7 +7,7 @@ namespace Server_Dashboard {
class RelayCommand : ICommand { class RelayCommand : ICommand {
//New Action //New Action
private Action<object> execAction; private readonly Action<object> execAction;
//Never gets fires, but needs to be implemented //Never gets fires, but needs to be implemented
public event EventHandler CanExecuteChanged = (sender, e) => { }; public event EventHandler CanExecuteChanged = (sender, e) => { };

View File

@@ -0,0 +1,12 @@
<UserControl x:Class="Server_Dashboard.Views.Dashboard.AnalyticsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Views.Dashboard"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Server_Dashboard.Views.Dashboard {
/// <summary>
/// Interaction logic for AnalyticsPage.xaml
/// </summary>
public partial class AnalyticsPage : UserControl {
public AnalyticsPage() {
InitializeComponent();
}
}
}

View File

@@ -0,0 +1,202 @@
<Window x:Class="Server_Dashboard.Views.DashboardPages.ModuleCRUD.CreateModulePopup"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Server_Dashboard.Views.DashboardPages.ModuleCRUD"
xmlns:ap="clr-namespace:Server_Dashboard"
xmlns:root="clr-namespace:Server_Dashboard" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
Height="700" Width="500" WindowStyle="None" Background="Transparent" ResizeMode="CanResize" ap:CloseProperty.Value="True">
<WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" ResizeBorderThickness="0" />
</WindowChrome.WindowChrome>
<!--Create new Server Form-->
<Border Width="500" Height="700">
<Border.Background>
<SolidColorBrush Color="#2D2D2D" Opacity="1" />
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--Title Bar-->
<Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="40" />
</Grid.ColumnDefinitions>
<TextBlock FontSize="18" Grid.Column="0" Text="Create a new Server" Margin="5 0 0 0" Foreground="White" VerticalAlignment="Center">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
<Button Style="{StaticResource CloseButton}" Grid.Column="1" Content="✕">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
<!--Main Content-->
<Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="1" Margin="20">
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0" />
</Grid.Effect>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition Height="30" />
<RowDefinition />
</Grid.RowDefinitions>
<!--Server Name-->
<StackPanel VerticalAlignment="Center" Grid.Row="0" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Module Name" FontSize="24" Margin="0 0 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0" />
</Grid.Effect>
<TextBox Text="{Binding ModuleName}" Height="40" FontSize="20" x:Name="ServerName" />
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="My Awesome Server" FontSize="20" Visibility="{Binding ElementName=ServerName, PresentationTraceSources.TraceLevel=High, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}" IsHitTestVisible="False" Margin="5 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<!--Username-->
<StackPanel VerticalAlignment="Center" Grid.Row="1" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="Server Name" FontSize="24" Margin="0 0 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0" />
</Grid.Effect>
<TextBox Text="{Binding ServerName}" Height="40" FontSize="20" x:Name="UserName" />
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="Name" FontSize="20" Visibility="{Binding ElementName=UserName, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}" IsHitTestVisible="False" Margin="5 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<!--IP Address-->
<StackPanel VerticalAlignment="Center" Grid.Row="2" Margin="20 0 20 0">
<StackPanel Orientation="Horizontal">
<TextBlock Text="IP Address" FontSize="24" Margin="0 0 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
<TextBlock Text="*" Foreground="{StaticResource ErrorRed}" FontSize="16" />
</StackPanel>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0" />
</Grid.Effect>
<TextBox Text="{Binding IpAddress}" Height="40" FontSize="20" x:Name="IpAddress" />
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="sample.ssh.com" FontSize="20" Visibility="{Binding ElementName=IpAddress, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}" IsHitTestVisible="False" Margin="5 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<!--Port-->
<StackPanel VerticalAlignment="Center" Grid.Row="3" Margin="20 0 20 0">
<TextBlock Text="Port" FontSize="24" Margin="0 0 0 5">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="0" BlurRadius="5" ShadowDepth="0" />
</Grid.Effect>
<TextBox Text="{Binding Port}" Height="40" FontSize="20" x:Name="Port" />
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Left" Text="22" FontSize="20" Visibility="{Binding ElementName=Port, Path=Text.IsEmpty, Converter={StaticResource UserNameVisibillity}}" Grid.Column="1" IsHitTestVisible="False" Margin="5 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.12" />
</TextBlock.Foreground>
</TextBlock>
</Grid>
</StackPanel>
<!--Module Icon-->
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="102" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Cursor="Hand" Command="{Binding SelectIconCommand}" HorizontalAlignment="Left" Margin="20 0 20 0" Height="62" Width="62">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border CornerRadius="4" x:Name="Border" Background="{StaticResource BackgroundSurface_04dp}" BorderBrush="Transparent" BorderThickness="{TemplateBinding BorderThickness}">
<Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect>
<Grid>
<Rectangle RadiusX="4" RadiusY="4">
<Rectangle.Fill>
<ImageBrush ImageSource="{Binding ModuleIcon}" />
</Rectangle.Fill>
</Rectangle>
<Viewbox Width="20" Height="20" VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="2">
<Canvas Width="24" Height="24">
<Path Data="M12,20C7.59,20 4,16.41 4,12C4,7.59 7.59,4 12,4C16.41,4 20,7.59 20,12C20,16.41 16.41,20 12,20M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2M13,7H11V11H7V13H11V17H13V13H17V11H13V7Z">
<Path.Fill>
<SolidColorBrush Color="White" Opacity="0.87" />
</Path.Fill>
</Path>
</Canvas>
</Viewbox>
</Grid>
</Border>
<ControlTemplate.Triggers>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<Button Command="{Binding RemoveIconCommand}" HorizontalAlignment="Left" Grid.Column="1" Content="Remove Icon" Height="40" Width="150" />
</Grid>
<!--Error Text / Test Connection Result-->
<TextBlock Text="{Binding UserInformationMessage}" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Row="5" FontSize="14">
<TextBlock.Foreground>
<SolidColorBrush Color="#64FFDA" Opacity="0.64" />
</TextBlock.Foreground>
</TextBlock>
<!--Create Module button-->
<Grid Grid.Row="6">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Margin="20 0 10 0" Height="60" Width="Auto" Command="{Binding CreateModuleCommand}" CommandParameter="{Binding ElementName=CREATE_MODULE}" Content="CREATE MODULE" Grid.Column="0" />
<Button Margin="10 0 20 0" Height="60" Width="Auto" Command="{Binding TestConnectionCommand}" Content="TEST CONNECTION" Grid.Column="1" />
</Grid>
</Grid>
</Grid>
</Border>
</Window>

View File

@@ -0,0 +1,13 @@
<UserControl
x:Class="Server_Dashboard.Views.Dashboard.SettingsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Server_Dashboard.Views.Dashboard"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

View File

@@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Server_Dashboard.Views.Dashboard {
/// <summary>
/// Interaction logic for SettingsPage.xaml
/// </summary>
public partial class SettingsPage : UserControl {
public SettingsPage() {
InitializeComponent();
}
}
}

View File

@@ -1,75 +0,0 @@
<UserControl x:Class="Server_Dashboard.Views.DashboardPages.MainDashboardPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:vm="clr-namespace:Server_Dashboard"
xmlns:local="clr-namespace:Server_Dashboard.Views.DashboardPages"
xmlns:modulescrud="clr-namespace:Server_Dashboard.Views.DashboardPages.ModuleCRUD"
xmlns:root="clr-namespace:Server_Dashboard"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:controls="clr-namespace:Server_Dashboard.Controls.ServerModules"
mc:Ignorable="d"
d:DesignHeight="920"
d:DesignWidth="1600"
>
<Grid Background="{StaticResource BackgroundSurface_00dp}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Dashboard and Options-->
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="{StaticResource BackgroundSurface_02dp}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button
Grid.Row="0"
Command="{Binding OpenNewModuleWindowCommand}"
Content="New Module"
Height="50"
Margin="5 10 5 0" Cursor="Hand"
x:Name="CreateModule"
/>
<Button
Grid.Row="1"
Command="{Binding OpenDeleteModuleWindowCommand}"
Content="Remove Module"
Height="50"
Margin="5 10 5 0"
/>
<Button
Grid.Row="2"
Command="{Binding OpenUpdateModuleWindowCommand}"
Content="Change Module"
Height="50"
Margin="5 10 5 0" Cursor="Hand"
/>
</Grid>
<Grid Grid.Column="1">
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Modules}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel HorizontalAlignment="Center"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:ServerModule/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
</Grid>
</UserControl>

View File

@@ -3,125 +3,74 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Server_Dashboard.Views"
xmlns:root="clr-namespace:Server_Dashboard"
xmlns:views="clr-namespace:Server_Dashboard.Views.DashboardPages" xmlns:views="clr-namespace:Server_Dashboard.Views.DashboardPages"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:svgc="http://sharpvectors.codeplex.com/svgc/" xmlns:svgc="http://sharpvectors.codeplex.com/svgc/"
Height="1000" Height="1000" Width="Auto" WindowStyle="None" Background="Transparent" ResizeMode="CanResize" mc:Ignorable="d" d:Height="1000" d:Width="1900">
Width="Auto"
WindowStyle="None"
Background="Transparent"
ResizeMode="CanResize"
mc:Ignorable="d"
d:Height="1000" d:Width="1900"
>
<WindowChrome.WindowChrome> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0"/> <WindowChrome CaptionHeight="0" />
</WindowChrome.WindowChrome> </WindowChrome.WindowChrome>
<Window.DataContext> <!--Dashboard Window and Container for the Dashboards-->
<root:DashboardViewModel/>
</Window.DataContext>
<Grid Background="{StaticResource BackgroundSurface_00dp}"> <Grid Background="{StaticResource BackgroundSurface_00dp}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="30"/> <RowDefinition Height="30" />
<RowDefinition Height="50"/> <RowDefinition Height="50" />
<RowDefinition Height="*"/> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!--Window Title--> <!--Window Title-->
<Grid Background="{StaticResource BackgroundSurface_06dp}" Grid.Row="0"> <Grid Background="{StaticResource BackgroundSurface_06dp}" Grid.Row="0">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*" />
<ColumnDefinition Width="40"/> <ColumnDefinition Width="40" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<i:Interaction.Triggers> <TextBlock FontSize="18" VerticalAlignment="Center" Grid.Column="0" Text="Server Dashboard" Margin="5 0 0 0">
<i:EventTrigger EventName="MouseDown"> <i:Interaction.Triggers>
<i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/> <i:EventTrigger EventName="MouseLeftButtonDown">
</i:EventTrigger> <i:CallMethodAction MethodName="DragMove" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:Interaction.Triggers> </i:EventTrigger>
<Label Grid.Column="0"/> </i:Interaction.Triggers>
<Button Style="{StaticResource CloseButton}" Grid.Column="2" Content="✕" Cursor="Hand"> </TextBlock>
<Button Style="{StaticResource CloseButton}" Grid.Column="1" Content="✕">
<i:Interaction.Triggers> <i:Interaction.Triggers>
<i:EventTrigger EventName="Click"> <i:EventTrigger EventName="Click">
<i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/> <i:CallMethodAction MethodName="Close" TargetObject="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" />
</i:EventTrigger> </i:EventTrigger>
</i:Interaction.Triggers> </i:Interaction.Triggers>
</Button> </Button>
</Grid> </Grid>
<!--Settings, Docs, User, links etc--> <!--Settings, Docs, User, links etc-->
<Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="1" x:Name="TopBarGrid"> <Grid Background="{StaticResource BackgroundSurface_04dp}" Grid.Row="1">
<Grid.Effect> <Grid.Effect>
<DropShadowEffect Direction="270" BlurRadius="5"/> <DropShadowEffect Direction="270" BlurRadius="5" />
</Grid.Effect> </Grid.Effect>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Button Grid.Column="0" > <Button Grid.Column="3" Command="{Binding OpenLinkCommand}" Content="{Binding User.UserName}" Margin="10 0 10 0" Height="40" Cursor="Hand">
<Button.Template>
<ControlTemplate TargetType="{x:Type Button}">
<Border
x:Name="Border"
CornerRadius="4"
Padding="2"
Background="Transparent"
BorderBrush="Transparent"
BorderThickness="0"
>
<svgc:SvgViewbox
Source="../Assets/Images/Settings.svg"
Margin="5"
IsHitTestVisible="False"
Opacity="0.87"
/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
</Trigger>
<Trigger Property="IsPressed" Value="True">
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
<Button
Grid.Column="4"
Command="{Binding OpenLinkCommand}"
Content="{Binding UserName}"
Margin="10 0 10 0"
Height="40" Cursor="Hand"
>
<Button.Template> <Button.Template>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> <Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
<Border.Effect> <Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect> </Border.Effect>
<Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}"> <Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}">
<Border.BorderBrush> <Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush> </Border.BorderBrush>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<svgc:SvgViewbox <Viewbox Width="Auto" Height="Auto" IsHitTestVisible="False" Margin="5">
Source="../Assets/Images/User.svg" <Canvas Width="24" Height="24">
Margin="5" <Path Data="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z">
IsHitTestVisible="False" <Path.Fill>
Opacity="0.87" <SolidColorBrush Color="White" Opacity="0.87" />
/> </Path.Fill>
<TextBlock </Path>
FontSize="{TemplateBinding FontSize}" </Canvas>
TextAlignment="Center" </Viewbox>
Padding="0" <TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5 0 10 0" />
TextWrapping="Wrap"
Text="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="5 0 10 0"
/>
</StackPanel> </StackPanel>
</Border> </Border>
</Border> </Border>
@@ -129,7 +78,7 @@
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04"/> <SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -138,12 +87,12 @@
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12"/> <SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter TargetName="BackgroundOverlay" Property="BorderBrush"> <Setter TargetName="BackgroundOverlay" Property="BorderBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87"/> <SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -151,42 +100,28 @@
</ControlTemplate> </ControlTemplate>
</Button.Template> </Button.Template>
</Button> </Button>
<Button <Button Grid.Column="2" Command="{Binding OpenLinkCommand}" CommandParameter="https://github.com/Crylia/Server-Dashboard/wiki" Content="Docs" Margin="10 0 10 0" Height="40">
Grid.Column="3"
Command="{Binding OpenLinkCommand}"
CommandParameter="https://github.com/Crylia/Server-Dashboard/wiki"
Content="Docs"
Margin="10 0 10 0"
Height="40"
>
<Button.Template> <Button.Template>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> <Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
<Border.Effect> <Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect> </Border.Effect>
<Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}"> <Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}">
<Border.BorderBrush> <Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush> </Border.BorderBrush>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<svgc:SvgViewbox <Viewbox IsHitTestVisible="False" Width="Auto" Height="Auto" Margin="5">
Source="../Assets/Images/Docs.svg" <Canvas Width="24" Height="24">
Margin="5" <Path Data="M6,2A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6M6,4H13V9H18V20H6V4M8,12V14H16V12H8M8,16V18H13V16H8Z">
IsHitTestVisible="False" <Path.Fill>
Opacity="0.87" <SolidColorBrush Color="White" Opacity="0.87" />
/> </Path.Fill>
<TextBlock </Path>
FontSize="{TemplateBinding FontSize}" </Canvas>
TextAlignment="Center" </Viewbox>
Padding="0" <TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5 0 10 0" />
TextWrapping="Wrap"
Text="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="5 0 10 0"
/>
</StackPanel> </StackPanel>
</Border> </Border>
</Border> </Border>
@@ -194,7 +129,7 @@
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04"/> <SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -203,12 +138,12 @@
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12"/> <SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter TargetName="BackgroundOverlay" Property="BorderBrush"> <Setter TargetName="BackgroundOverlay" Property="BorderBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87"/> <SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -216,41 +151,28 @@
</ControlTemplate> </ControlTemplate>
</Button.Template> </Button.Template>
</Button> </Button>
<Button <Button Grid.Column="1" Command="{Binding OpenLinkCommand}" CommandParameter="https://github.com/Crylia/Server-Dashboard" Content="GitHub" Margin="10 0 10 0" Height="40" Opacity="0.87" Cursor="Hand">
Grid.Column="2"
Command="{Binding OpenLinkCommand}"
CommandParameter="https://github.com/Crylia/Server-Dashboard"
Content="GitHub"
Margin="10 0 10 0"
Height="40"
Opacity="0.87" Cursor="Hand"
>
<Button.Template> <Button.Template>
<ControlTemplate TargetType="{x:Type Button}"> <ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0"> <Border x:Name="Border" CornerRadius="5" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0">
<Border.Effect> <Border.Effect>
<DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5"/> <DropShadowEffect Direction="0" ShadowDepth="0" BlurRadius="5" />
</Border.Effect> </Border.Effect>
<Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}"> <Border x:Name="BackgroundOverlay" CornerRadius="4" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}">
<Border.BorderBrush> <Border.BorderBrush>
<SolidColorBrush Color="White" Opacity="0.12"/> <SolidColorBrush Color="White" Opacity="0.12" />
</Border.BorderBrush> </Border.BorderBrush>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<Image <Viewbox IsHitTestVisible="False" Width="Auto" Height="Auto" Margin="5">
Source="../Assets/Images/GitHubLight.png" <Canvas Width="24" Height="24">
Margin="5" <Path Data="M12,2A10,10 0 0,0 2,12C2,16.42 4.87,20.17 8.84,21.5C9.34,21.58 9.5,21.27 9.5,21C9.5,20.77 9.5,20.14 9.5,19.31C6.73,19.91 6.14,17.97 6.14,17.97C5.68,16.81 5.03,16.5 5.03,16.5C4.12,15.88 5.1,15.9 5.1,15.9C6.1,15.97 6.63,16.93 6.63,16.93C7.5,18.45 8.97,18 9.54,17.76C9.63,17.11 9.89,16.67 10.17,16.42C7.95,16.17 5.62,15.31 5.62,11.5C5.62,10.39 6,9.5 6.65,8.79C6.55,8.54 6.2,7.5 6.75,6.15C6.75,6.15 7.59,5.88 9.5,7.17C10.29,6.95 11.15,6.84 12,6.84C12.85,6.84 13.71,6.95 14.5,7.17C16.41,5.88 17.25,6.15 17.25,6.15C17.8,7.5 17.45,8.54 17.35,8.79C18,9.5 18.38,10.39 18.38,11.5C18.38,15.32 16.04,16.16 13.81,16.41C14.17,16.72 14.5,17.33 14.5,18.26C14.5,19.6 14.5,20.68 14.5,21C14.5,21.27 14.66,21.59 15.17,21.5C19.14,20.16 22,16.42 22,12A10,10 0 0,0 12,2Z">
/> <Path.Fill>
<TextBlock <SolidColorBrush Color="White" Opacity="0.87" />
FontSize="{TemplateBinding FontSize}" </Path.Fill>
TextAlignment="Center" </Path>
Padding="0" </Canvas>
TextWrapping="Wrap" </Viewbox>
Text="{TemplateBinding Content}" <TextBlock FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5 0 10 0" />
Foreground="{TemplateBinding Foreground}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Margin="5 0 10 0"
/>
</StackPanel> </StackPanel>
</Border> </Border>
</Border> </Border>
@@ -258,7 +180,7 @@
<Trigger Property="IsMouseOver" Value="True"> <Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04"/> <SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -267,12 +189,12 @@
<Trigger Property="IsPressed" Value="True"> <Trigger Property="IsPressed" Value="True">
<Setter TargetName="BackgroundOverlay" Property="Background"> <Setter TargetName="BackgroundOverlay" Property="Background">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12"/> <SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
<Setter TargetName="BackgroundOverlay" Property="BorderBrush"> <Setter TargetName="BackgroundOverlay" Property="BorderBrush">
<Setter.Value> <Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87"/> <SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value> </Setter.Value>
</Setter> </Setter>
</Trigger> </Trigger>
@@ -281,8 +203,265 @@
</Button.Template> </Button.Template>
</Button> </Button>
</Grid> </Grid>
<UserControl Grid.Row="3"> <!--UserControl Container for the Dashboard pages-->
<views:MainDashboardPage/> <Grid Grid.Row="2">
</UserControl> <Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="{StaticResource BackgroundSurface_02dp}">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Navigation" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.67" />
</TextBlock.Foreground>
</TextBlock>
<RadioButton IsChecked="True" Command="{Binding SwitchViewModelCommand}" CommandParameter="dashboardviewmodel" Grid.Row="1" Content="Dashboard" Height="50">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Background" Value="{StaticResource BackgroundSurface_02dp}" />
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="3 0 0 0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<Viewbox IsHitTestVisible="False" Width="20" Height="20" Margin="15 0 5 0">
<Canvas Width="24" Height="24">
<Path x:Name="PathHome" Data="M10,20V14H14V20H19V12H22L12,3L2,12H5V20H10Z">
<Path.Fill>
<SolidColorBrush Color="White" Opacity="0.87" />
</Path.Fill>
</Path>
</Canvas>
</Viewbox>
<TextBlock x:Name="Text" FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter TargetName="PathHome" Property="Fill">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#181818" />
<Setter TargetName="Text" Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value>
</Setter>
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</RadioButton.Style>
</RadioButton>
<RadioButton Command="{Binding SwitchViewModelCommand}" CommandParameter="analyticsviewmodel" Grid.Row="2" Content="Analytics" Height="50">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Background" Value="{StaticResource BackgroundSurface_02dp}" />
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="3 0 0 0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<Viewbox Margin="15 0 5 0" IsHitTestVisible="False" Width="20" Height="20">
<Canvas Width="24" Height="24">
<Path x:Name="PathAnalysis" Data="M6,22A3,3 0 0,1 3,19C3,18.4 3.18,17.84 3.5,17.37L9,7.81V6A1,1 0 0,1 8,5V4A2,2 0 0,1 10,2H14A2,2 0 0,1 16,4V5A1,1 0 0,1 15,6V7.81L20.5,17.37C20.82,17.84 21,18.4 21,19A3,3 0 0,1 18,22H6M5,19A1,1 0 0,0 6,20H18A1,1 0 0,0 19,19C19,18.79 18.93,18.59 18.82,18.43L16.53,14.47L14,17L8.93,11.93L5.18,18.43C5.07,18.59 5,18.79 5,19M13,10A1,1 0 0,0 12,11A1,1 0 0,0 13,12A1,1 0 0,0 14,11A1,1 0 0,0 13,10Z">
<Path.Fill>
<SolidColorBrush Color="White" Opacity="0.87" />
</Path.Fill>
</Path>
</Canvas>
</Viewbox>
<TextBlock x:Name="Text" FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter TargetName="PathAnalysis" Property="Fill">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#181818" />
<Setter TargetName="Text" Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value>
</Setter>
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</RadioButton.Style>
</RadioButton>
<RadioButton Command="{Binding SwitchViewModelCommand}" CommandParameter="settingsviewmodel" Grid.Row="3" Content="Settings" Height="50">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}">
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Background" Value="{StaticResource BackgroundSurface_02dp}" />
<Setter Property="FontSize" Value="20" />
<Setter Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
<Setter Property="BorderThickness" Value="2" />
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border x:Name="Background" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="3 0 0 0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left">
<Viewbox Margin="15 0 5 0" IsHitTestVisible="False" Width="20" Height="20">
<Canvas Width="24" Height="24">
<Path x:Name="PathSettings" Data="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z">
<Path.Fill>
<SolidColorBrush Color="White" Opacity="0.87" />
</Path.Fill>
</Path>
</Canvas>
</Viewbox>
<TextBlock x:Name="Text" FontSize="{TemplateBinding FontSize}" TextAlignment="Center" Padding="0" TextWrapping="Wrap" Text="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.87" />
</TextBlock.Foreground>
</TextBlock>
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.04" />
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter TargetName="PathSettings" Property="Fill">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
<Setter Property="Background" Value="#181818" />
<Setter TargetName="Text" Property="Foreground" Value="{StaticResource DeepPurple_A100}" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity="0.12" />
</Setter.Value>
</Setter>
<Setter TargetName="Background" Property="BorderBrush">
<Setter.Value>
<SolidColorBrush Color="#B388FF" Opacity=".87" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</RadioButton.Style>
</RadioButton>
</Grid>
<Grid Grid.Row="2">
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Module" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10 0 0 0">
<TextBlock.Foreground>
<SolidColorBrush Color="White" Opacity="0.67" />
</TextBlock.Foreground>
</TextBlock>
<Button Grid.Row="1" Command="{Binding OpenNewModuleWindowCommand}" Content="New Module" Height="50" Margin="5 10 5 0" Cursor="Hand" />
<Button Grid.Row="2" Command="{Binding OpenDeleteModuleWindowCommand}" Content="Remove Module" Height="50" Margin="5 10 5 0" Cursor="Hand" />
<Button Grid.Row="3" Command="{Binding OpenUpdateModuleWindowCommand}" Content="Change Module" Height="50" Margin="5 10 5 0" Cursor="Hand" />
</Grid>
</Grid>
<ContentControl Grid.Column="1" Content="{Binding CurrentView}" />
</Grid>
</Grid> </Grid>
</Window> </Window>

View File

@@ -0,0 +1,30 @@
<UserControl x:Class="Server_Dashboard.Views.DashboardPages.MainDashboardPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:controls="clr-namespace:Server_Dashboard.Controls.ServerModules"
mc:Ignorable="d" d:DesignHeight="920" d:DesignWidth="1600">
<Grid Background="{StaticResource BackgroundSurface_00dp}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--ItemsControl list for the Dashboard modules-->
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Hidden">
<ItemsControl ItemsSource="{Binding Modules}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel VerticalAlignment="Top" HorizontalAlignment="Left" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:ServerModule />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</Grid>
</UserControl>

View File

@@ -12,12 +12,14 @@ using System.Windows.Navigation;
using System.Windows.Shapes; using System.Windows.Shapes;
namespace Server_Dashboard.Views.DashboardPages { namespace Server_Dashboard.Views.DashboardPages {
/// <summary> /// <summary>
/// Interaktionslogik für MainDashboardPage.xaml /// Interaktionslogik für MainDashboardPage.xaml
/// </summary> /// </summary>
public partial class MainDashboardPage : UserControl { public partial class MainDashboardPage : UserControl {
public MainDashboardPage() { public MainDashboardPage() {
InitializeComponent(); InitializeComponent();
} }
} }
} }

View File

@@ -33,6 +33,14 @@
} }
} }
}, },
"Newtonsoft.Json/13.0.1": {
"runtime": {
"lib/netstandard2.0/Newtonsoft.Json.dll": {
"assemblyVersion": "13.0.0.0",
"fileVersion": "13.0.1.25517"
}
}
},
"runtime.native.System.Data.SqlClient.sni/4.7.0": { "runtime.native.System.Data.SqlClient.sni/4.7.0": {
"dependencies": { "dependencies": {
"runtime.win-arm64.runtime.native.System.Data.SqlClient.sni": "4.4.0", "runtime.win-arm64.runtime.native.System.Data.SqlClient.sni": "4.4.0",
@@ -157,6 +165,9 @@
}, },
"System.Security.Principal.Windows/4.7.0": {}, "System.Security.Principal.Windows/4.7.0": {},
"Server Dashboard Socket/1.0.0": { "Server Dashboard Socket/1.0.0": {
"dependencies": {
"Newtonsoft.Json": "13.0.1"
},
"runtime": { "runtime": {
"Server Dashboard Socket.dll": {} "Server Dashboard Socket.dll": {}
} }
@@ -198,6 +209,13 @@
"path": "microsoft.xaml.behaviors.wpf/1.1.31", "path": "microsoft.xaml.behaviors.wpf/1.1.31",
"hashPath": "microsoft.xaml.behaviors.wpf.1.1.31.nupkg.sha512" "hashPath": "microsoft.xaml.behaviors.wpf.1.1.31.nupkg.sha512"
}, },
"Newtonsoft.Json/13.0.1": {
"type": "package",
"serviceable": true,
"sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==",
"path": "newtonsoft.json/13.0.1",
"hashPath": "newtonsoft.json.13.0.1.nupkg.sha512"
},
"runtime.native.System.Data.SqlClient.sni/4.7.0": { "runtime.native.System.Data.SqlClient.sni/4.7.0": {
"type": "package", "type": "package",
"serviceable": true, "serviceable": true,

View File

@@ -1,4 +1,4 @@
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8B13C63F73D8B03B1CC973E996B230B95776E3E8" #pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "BA652589A766CDFB2D42F74F8B0DDD26A50869F0"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
@@ -10,8 +10,10 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
using Server_Dashboard; using Server_Dashboard;
using Server_Dashboard.Views.Dashboard;
using Server_Dashboard.Views.DashboardPages; using Server_Dashboard.Views.DashboardPages;
using Server_Dashboard.Views.DashboardPages.ModuleCRUD; using Server_Dashboard.Views.DashboardPages.ModuleCRUD;
using SharpVectors.Converters;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
@@ -56,7 +58,7 @@ namespace Server_Dashboard {
} }
_contentLoaded = true; _contentLoaded = true;
#line 7 "..\..\..\App.xaml" #line 9 "..\..\..\App.xaml"
this.StartupUri = new System.Uri("LoginWindow.xaml", System.UriKind.Relative); this.StartupUri = new System.Uri("LoginWindow.xaml", System.UriKind.Relative);
#line default #line default

View File

@@ -1,4 +1,4 @@
#pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "8B13C63F73D8B03B1CC973E996B230B95776E3E8" #pragma checksum "..\..\..\App.xaml" "{ff1816ec-aa5e-4d10-87f7-6f4963833460}" "BA652589A766CDFB2D42F74F8B0DDD26A50869F0"
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// This code was generated by a tool. // This code was generated by a tool.
@@ -10,8 +10,10 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
using Server_Dashboard; using Server_Dashboard;
using Server_Dashboard.Views.Dashboard;
using Server_Dashboard.Views.DashboardPages; using Server_Dashboard.Views.DashboardPages;
using Server_Dashboard.Views.DashboardPages.ModuleCRUD; using Server_Dashboard.Views.DashboardPages.ModuleCRUD;
using SharpVectors.Converters;
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
@@ -56,7 +58,7 @@ namespace Server_Dashboard {
} }
_contentLoaded = true; _contentLoaded = true;
#line 7 "..\..\..\App.xaml" #line 9 "..\..\..\App.xaml"
this.StartupUri = new System.Uri("LoginWindow.xaml", System.UriKind.Relative); this.StartupUri = new System.Uri("LoginWindow.xaml", System.UriKind.Relative);
#line default #line default

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