Former-commit-id: 7b8d9415a4ddceae7af6929de453347b7db7136e
Former-commit-id: 32b33fa1f6f344042f53b10c31f6428c72195424
1.0
wanggang 5 years ago
parent f46df727d2
commit 0ebe815dcf

@ -13,15 +13,14 @@ namespace Infrastructure.Extensions
{
throw new ArgumentNullException(nameof(ex));
}
Debug.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff", CultureInfo.CurrentCulture));
if (rawMessage != null)
{
Debug.WriteLine(rawMessage);
}
Debug.WriteLine(memberName);
Debug.WriteLine(ex.Message);
Debug.WriteLine(ex.StackTrace);
Debug.WriteLine(ex?.Message);
Debug.WriteLine(ex?.StackTrace);
ex.InnerException?.PrintStack();
}

@ -0,0 +1,30 @@
using Microsoft.Extensions.Hosting;
using System;
namespace Infrastructure.Extensions
{
public static class HostEnvironmentEnvExtensions
{
public static void Debug(this IHostEnvironment hostEnvironment,string message)
{
if(hostEnvironment.IsDevelopment())
{
Console.WriteLine(message);
}
}
public static void Debug(this IHostEnvironment hostEnvironment, Exception ex)
{
if (hostEnvironment.IsDevelopment())
{
ex.PrintStack();
}
}
public static void Debug(this IHostEnvironment hostEnvironment, Func<string> getMessage)
{
if (hostEnvironment.IsDevelopment())
{
Console.WriteLine(getMessage());
}
}
}
}

@ -11,16 +11,19 @@ using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
namespace IoTNode.DeviceServices
{
public class BaseDeviceService : IHostedService
{
internal readonly IServiceProvider _applicationServices;
protected readonly IWebHostEnvironment _env;
public BaseDeviceService(IServiceProvider applicationServices)
public BaseDeviceService(IServiceProvider applicationServices, IWebHostEnvironment env)
{
this._applicationServices = applicationServices;
this._env = env;
}
protected string GetSetting(string name)

@ -19,6 +19,7 @@ using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
namespace IoTNode.DeviceServices.FBee
{
@ -27,8 +28,8 @@ namespace IoTNode.DeviceServices.FBee
private readonly ConcurrentDictionary<string, TcpClientWrapper> Clients = new ConcurrentDictionary<string, TcpClientWrapper>();
private readonly ILogger<FBeeService> _logger;
public FBeeService(IServiceProvider applicationServices, ILogger<FBeeService> logger)
: base(applicationServices)
public FBeeService(IServiceProvider applicationServices, IWebHostEnvironment env,ILogger<FBeeService> logger)
: base(applicationServices,env)
{
this._logger = logger;
}

@ -2,11 +2,11 @@
using Infrastructure.Extensions;
using IoT.Shared.Application.Domain.Entities;
using IoT.Shared.Services;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
@ -94,21 +94,21 @@ namespace IoTNode.DeviceServices.LiChuang
private CancellationToken _cancellationToken;
private string _mac;
public LCDAUE800DService(IServiceProvider applicationServices)
: base(applicationServices)
public LCDAUE800DService(IServiceProvider applicationServices, IWebHostEnvironment env)
: base(applicationServices,env)
{
}
public override Task StartAsync(CancellationToken cancellationToken)
{
Debug.WriteLine("~~start");
this._env.Debug("~~start");
this._cancellationToken = cancellationToken;
return base.StartAsync(cancellationToken);
}
public override void Execute()
{
Console.WriteLine("lc exec");
this._env.Debug("lc exec");
try
{
if (this._listener == null)
@ -143,7 +143,7 @@ namespace IoTNode.DeviceServices.LiChuang
public override Task StopAsync(CancellationToken cancellationToken)
{
Debug.WriteLine("~~end");
this._env.Debug("lc end");
return base.StopAsync(cancellationToken);
}
@ -160,12 +160,12 @@ namespace IoTNode.DeviceServices.LiChuang
{
bufferLength = stream.Read(buffer);
var rawData = buffer.Take(bufferLength).ToArray();
Console.WriteLine($"from {_client.Client.RemoteEndPoint}:{rawData.Length}");
this._env.Debug($"from {_client.Client.RemoteEndPoint}:{rawData.Length}");
UnitHandle(stream, rawData);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
this._env.Debug(ex);
}
}
else
@ -174,9 +174,8 @@ namespace IoTNode.DeviceServices.LiChuang
{
stream.Write(buffer, 0, 0);
}
catch (Exception ex)
catch
{
Console.WriteLine(ex.ToString());
break;
}
}
@ -192,18 +191,18 @@ namespace IoTNode.DeviceServices.LiChuang
var unitLength = 4 + 4 + BitConverter.ToInt32(data.Skip(4).Take(4).ToArray()) + 2 + 4;
if (length == unitLength)
{
Console.WriteLine("单个包");
this._env.Debug("单个包");
Handle(stream, data);
}
else if (length > unitLength)
{
Console.WriteLine("多个包");
this._env.Debug("多个包");
Handle(stream, data.Take(unitLength).ToArray());
UnitHandle(stream, data.Skip(unitLength).ToArray());
}
else if (length < unitLength)
{
Console.WriteLine("长包开头");
this._env.Debug("长包开头");
_frame.Clear();
_frame.AddRange(data);
_frameLength = unitLength;
@ -213,21 +212,21 @@ namespace IoTNode.DeviceServices.LiChuang
{
if (_frame.Count + length == _frameLength)
{
Console.WriteLine("长包结尾");
this._env.Debug("长包结尾");
_frame.AddRange(data);
Handle(stream, _frame.ToArray());
_frame.Clear();
}
else if (_frame.Count + length > _frameLength)
{
Console.WriteLine("长包结尾+后续包");
this._env.Debug("长包结尾+后续包");
_frame.AddRange(data.Take(length - _frame.Count));
Handle(stream, _frame.ToArray());
Handle(stream, data.Skip(length - _frame.Count).ToArray());
}
else if (_frame.Count + length < _frameLength)
{
Console.WriteLine("长包中间");
this._env.Debug("长包中间");
_frame.AddRange(data);
}
}
@ -236,10 +235,10 @@ namespace IoTNode.DeviceServices.LiChuang
private void Handle(NetworkStream stream, byte[] rawData)
{
var xml = GetXml(rawData);
Console.WriteLine("收到客户端的消息:");
Console.WriteLine(FormatXml(xml));
this._env.Debug("收到客户端的消息");
this._env.Debug(()=>FormatXml(xml));
var type = GetTypeFromXml(xml);
Console.WriteLine($"type:{type}");
this._env.Debug($"type:{type}");
if (type == "request")
{
HandleRequest(stream, xml);
@ -321,7 +320,7 @@ namespace IoTNode.DeviceServices.LiChuang
var factory = doc.SelectSingleNode("//factory").InnerText.Trim();
var hardware = doc.SelectSingleNode("//hardware").InnerText.Trim();
var software = doc.SelectSingleNode("//software").InnerText.Trim();
Console.WriteLine($"factory:{factory},hardware{hardware},software:{software},mac{mac}");
this._env.Debug($"factory:{factory},hardware{hardware},software:{software},mac{mac}");
//Console.WriteLine($"楼宇建筑编码:{building_id},行政区域:{buildArea},建筑类型:{buildType},建筑名称:{buildName}");
//add for iotnode start
@ -329,7 +328,7 @@ namespace IoTNode.DeviceServices.LiChuang
{
this._mac = mac;
var timestamp = DateTimeOffset.Now.ToUnixTimeMilliseconds();
var product = this.UpdateProduct("LC集抄器", hardware, "", "gateway");
var product = this.UpdateProduct("LC集抄器", hardware, "", "collector");
using var scope = _applicationServices.CreateScope();
var iotNodeClient = scope.ServiceProvider.GetService<IoTNodeClient>();
var deviceNodeRepo = scope.ServiceProvider.GetService<IRepository<IoTGateway>>();
@ -342,7 +341,7 @@ namespace IoTNode.DeviceServices.LiChuang
Name= "LC集抄器",
Number= mac,
DisplayName="LC集抄器",
Icon="gateway",
Icon= "collector",
Ip = ip,
NodeId = iotNode.Id,
ProductId=product.Id,
@ -479,7 +478,7 @@ namespace IoTNode.DeviceServices.LiChuang
var key = function.Attributes["id"].Value.Trim();
var name = Keys[key];
var value = function.InnerText.Trim();
Console.WriteLine($"type:{type},time:{time},equipidex:{equipidex},item:{name},value:{value}");
this._env.Debug($"type:{type},time:{time},equipidex:{equipidex},item:{name},value:{value}");
//add for iotnode start
if (!string.IsNullOrEmpty(this._mac))
{
@ -546,9 +545,9 @@ namespace IoTNode.DeviceServices.LiChuang
private void Reply(NetworkStream stream, string xml)
{
Console.WriteLine("服务端响应:");
Console.WriteLine(FormatXml(xml));
Console.WriteLine();
this._env.Debug("服务端响应:");
this._env.Debug(()=>FormatXml(xml));
this._env.Debug("服务端响应:");
using var ms = new MemoryStream();
ms.Write(new byte[] { 0xaa, 0x55, 0xaa, 0x55 });//header
var data = new byte[] { 0x00, 0x00, 0x00, 0x00 }.Concat(AesEncrypt(Encoding.UTF8.GetBytes(xml))).ToArray();
@ -568,7 +567,7 @@ namespace IoTNode.DeviceServices.LiChuang
return doc.SelectSingleNode("/root/common/type").InnerText;
}
private static string GetXml(byte[] rawData)
private string GetXml(byte[] rawData)
{
var dataLength = BitConverter.ToUInt32(rawData.Skip(4).Take(4).ToArray());
var data = rawData.Skip(8).Take((int)dataLength).ToArray();
@ -581,7 +580,7 @@ namespace IoTNode.DeviceServices.LiChuang
result = result.Trim();
if (!result.EndsWith(">"))
{
Console.WriteLine("xml format error");
this._env.Debug("xml format error");
result += "></root>";
}
return result;
@ -636,7 +635,7 @@ namespace IoTNode.DeviceServices.LiChuang
return aesAlg;
}
private static string FormatXml(string xml)
private string FormatXml(string xml)
{
try
{
@ -647,7 +646,7 @@ namespace IoTNode.DeviceServices.LiChuang
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
this._env.Debug(ex);
return xml;
}
}

@ -27,15 +27,13 @@ namespace IoTNode.DeviceServices.Onvif
private bool isDisposed;
private readonly ConcurrentDictionary<string, Process> _list = new ConcurrentDictionary<string, Process>();
private readonly ILogger<OnvifService> _logger;
private readonly IWebHostEnvironment _env;
private readonly IHttpClientFactory _httpClientFactory;
private readonly IOnvifDeviceManagement _onvifDeviceManagement;
public OnvifService(IServiceProvider applicationServices, ILogger<OnvifService> logger, IWebHostEnvironment env, IHttpClientFactory httpClientFactory, IOnvifDeviceManagement onvifDeviceManagement)
: base(applicationServices)
: base(applicationServices,env)
{
this._logger = logger;
this._env = env;
this._httpClientFactory = httpClientFactory;
this._onvifDeviceManagement = onvifDeviceManagement;
}

@ -2,6 +2,7 @@
using Infrastructure.Extensions;
using IoT.Shared.Application.Domain.Entities;
using IoT.Shared.Application.Models;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using System;
@ -16,8 +17,8 @@ namespace IoTNode.DeviceServices.SerialPortManager
private const string _productNumber = "serialport";
private static readonly object lockObject = new object();
public SerialPortService(IServiceProvider applicationServices)
: base(applicationServices)
public SerialPortService(IServiceProvider applicationServices,IWebHostEnvironment env)
: base(applicationServices,env)
{
}

@ -16,6 +16,7 @@ using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
@ -45,12 +46,19 @@ namespace IoTNode
services.AddSingleton<OnvifService>();
services.AddSingleton<FBeeService>();
services.AddSingleton<LCDAUE800DService>();
//services.AddHostedService(o => o.GetService<IoTNodeClient>());
//services.AddHostedService(o => o.GetService<SerialPortService>());
//services.AddHostedService(o => o.GetService<OnvifService>());
//services.AddHostedService(o => o.GetService<FBeeService>());
services.AddHostedService(o => o.GetService<LCDAUE800DService>());
services.AddHostedService(o => o.GetService<IoTNodeClient>());
services.AddTransient<IEmailSender, EmptyEmailSender>();
if (Env.IsDevelopment())
{
services.AddHostedService(o => o.GetService<LCDAUE800DService>());
}
else
{
services.AddHostedService(o => o.GetService<SerialPortService>());
services.AddHostedService(o => o.GetService<OnvifService>());
services.AddHostedService(o => o.GetService<FBeeService>());
services.AddHostedService(o => o.GetService<LCDAUE800DService>());
}
base.ConfigureServices(services);
}

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1608020614205" class="icon" viewBox="0 0 1029 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5087" width="128.625" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M 647.529 276.078 H 371.451 c -55.2157 0 -95.3726 45.1765 -95.3726 95.3726 v 271.059 c 0 55.2157 45.1765 95.3726 95.3726 95.3726 h 271.059 c 55.2157 0 95.3726 -45.1765 95.3726 -95.3726 V 371.451 c 5.01961 -50.1961 -40.1569 -95.3726 -90.3529 -95.3726 Z M 818.196 381.49 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 Z M 993.882 436.706 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 993.882 537.098 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 993.882 637.49 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 637.49 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 537.098 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 436.706 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 336.314 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 361.412 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 C 381.49 10.0392 371.451 0 361.412 0 c -15.0588 0 -25.098 10.0392 -25.098 25.098 V 200.784 c 0 15.0588 10.0392 25.098 25.098 25.098 Z M 461.804 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 C 481.882 10.0392 471.843 0 461.804 0 c -15.0588 0 -25.098 10.0392 -25.098 25.098 V 200.784 c 0 15.0588 10.0392 25.098 25.098 25.098 Z M 557.176 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 s -25.098 10.0392 -25.098 25.098 V 200.784 c 5.01961 15.0588 15.0588 25.098 25.098 25.098 Z M 657.569 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 s -25.098 10.0392 -25.098 25.098 V 200.784 c 5.01961 15.0588 15.0588 25.098 25.098 25.098 Z M 657.569 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 Z M 557.176 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 Z M 461.804 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c -5.01961 -15.0588 -15.0588 -25.098 -25.098 -25.098 Z M 361.412 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c -5.01961 -15.0588 -15.0588 -25.098 -25.098 -25.098 Z" fill="#1afa29" p-id="5088"></path></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1608020614205" class="icon" viewBox="0 0 1029 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5087" width="128.625" height="128" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"></style></defs><path d="M 647.529 276.078 H 371.451 c -55.2157 0 -95.3726 45.1765 -95.3726 95.3726 v 271.059 c 0 55.2157 45.1765 95.3726 95.3726 95.3726 h 271.059 c 55.2157 0 95.3726 -45.1765 95.3726 -95.3726 V 371.451 c 5.01961 -50.1961 -40.1569 -95.3726 -90.3529 -95.3726 Z M 818.196 381.49 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 Z M 993.882 436.706 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 993.882 537.098 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 993.882 637.49 h -180.706 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 h 180.706 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 637.49 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 537.098 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 436.706 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 200.784 336.314 H 25.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 s 10.0392 25.098 25.098 25.098 H 200.784 c 15.0588 0 25.098 -10.0392 25.098 -25.098 s -10.0392 -25.098 -25.098 -25.098 Z M 361.412 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 C 381.49 10.0392 371.451 0 361.412 0 c -15.0588 0 -25.098 10.0392 -25.098 25.098 V 200.784 c 0 15.0588 10.0392 25.098 25.098 25.098 Z M 461.804 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 C 481.882 10.0392 471.843 0 461.804 0 c -15.0588 0 -25.098 10.0392 -25.098 25.098 V 200.784 c 0 15.0588 10.0392 25.098 25.098 25.098 Z M 557.176 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 s -25.098 10.0392 -25.098 25.098 V 200.784 c 5.01961 15.0588 15.0588 25.098 25.098 25.098 Z M 657.569 225.882 c 15.0588 0 25.098 -10.0392 25.098 -25.098 V 25.098 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 s -25.098 10.0392 -25.098 25.098 V 200.784 c 5.01961 15.0588 15.0588 25.098 25.098 25.098 Z M 657.569 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 Z M 557.176 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c 0 -15.0588 -10.0392 -25.098 -25.098 -25.098 Z M 461.804 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c -5.01961 -15.0588 -15.0588 -25.098 -25.098 -25.098 Z M 361.412 793.098 c -15.0588 0 -25.098 10.0392 -25.098 25.098 v 180.706 c 0 15.0588 10.0392 25.098 25.098 25.098 s 25.098 -10.0392 25.098 -25.098 v -180.706 c -5.01961 -15.0588 -15.0588 -25.098 -25.098 -25.098 Z" fill="#1afa29" p-id="5088"></path></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Loading…
Cancel
Save