ComplianceServer/oldcode/WeChatServerServices/WxDbJob/Wx_DbRead.cs

791 lines
36 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using DAL.Redis;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SQLite;
using System.Linq;
using WX.CRM.BLL.Base;
using WX.CRM.BLL.weapp;
using WX.CRM.BLL.Wx;
using WX.CRM.Common;
using WX.CRM.DAL.Redis;
using WX.CRM.IBLL.Wx;
//using WX.CRM.DataSynFactory;
using WX.CRM.Model.DTO;
using WX.CRM.Model.Entity;
namespace WeChatServerServices.WxDbJob
{
public class Wx_DbRead
{
private const string WxFix = "wxid:";
private const string WxMsgFix = "wxmsgid:";
private readonly PubSub _sub = new PubSub();
private RedisSet<string> _redisSet = new RedisSet<string>();
private RedisString<string> _redisMsg = new RedisString<string>();
public WX_RCONTACT_BL _rcontact = new WX_RCONTACT_BL();
public BAS_PARAMETER_BL _parameter = new BAS_PARAMETER_BL();
Wx_DbRead_BL bll = new Wx_DbRead_BL();
private IWx_MsgKey msgkey = new Wx_MsgKey_BL();
private static string _shareName;
private static string _isShare;
private static string _deviceName;
static Wx_DbRead()
{
//用户名勿比指定共享服务器的IP或名称否则会引起1312错误
_isShare = Utility.GetSettingByKey("IsShare");
if (!string.IsNullOrEmpty(_isShare))
{
_shareName = Utility.GetSettingByKey("NetUseShareName") ?? @"\\192.168.1.171\weixin";
_deviceName = Utility.GetSettingByKey("NetUseDeviceName") ?? "z:";
string user = Utility.GetSettingByKey("NetUseUser") ?? @"192.168.1.171\admin";
string pwd = Utility.GetSettingByKey("NetUsePwd") ?? "read,./1";
NetUseHelper.Build(_shareName, user, pwd, string.Empty);//不指定盘符,避免引起盘符被占用的错误
}
}
public void StartRead()
{
DataTable ta = bll.WxDbUploadLogRead();
if (ta == null)
{
return;
}
string username = string.Empty;
string dbfile = string.Empty;
decimal pkid = 0;
foreach (DataRow item in ta.Rows)
{
try
{
username = item["username"].ToString();
dbfile = item["dbfile"].ToString();
pkid = Convert.ToDecimal(item["pkid"]);
if (System.IO.File.Exists(dbfile))
{
ReadSQLiteDb(username, dbfile, pkid);
}
else
{
bll.UpdataStatus(pkid, 404, "找不到文件!");
}
}
catch (Exception ex)
{
LogHelper.Error("db调度出现错误:" + ex.ToString());
}
}
}
public void ReadSQLiteDb(string username, string dbfile, decimal pkid)
{
string content = "";
int status = 200;
try
{
WX_HONGBAO_BL wx_hongbao = new WX_HONGBAO_BL();
SQLiteConnection cnn = new SQLiteConnection();
cnn.ConnectionString = "Data Source=" + dbfile;
cnn.Open();
string isShowGroup = "false";
string isShowHongBao = "false";
BAS_PARAMETER parameter = _parameter.GetModel_Patameter("WeiXin_IsShowGroupMessage");
if (parameter != null && parameter.PARAVALUE == "true")
{
isShowGroup = "true";
}
parameter = _parameter.GetModel_Patameter("WeiXin_IsShowHongBao");
if (parameter != null && parameter.PARAVALUE == "true")
{
isShowHongBao = "true";
}
#region rcontact
try
{
string sql = @" select username,alias,chatroomFlag ,conRemark ,domainList ,nickname ,pyInitial ,quanPin ,showHead ,type ,weiboFlag ,
weiboNickname ,conRemarkPYFull ,conRemarkPYShort ,verifyFlag ,encryptUsername ,deleteFlag ,
contactLabelIds,ifnull((select min(createtime)/1000 from message x where x.talker=a.username),strftime('%s','now'))ctime from rcontact a
where a.type!=33
and a.username not like 'gh\_%'escape '\'
and a.username not like'%chatroom'
and a.username not like'%@stranger'
and a.username !='filehelper'
and a.username is not null
"; //用SQLite Expert管理器看表或者CMD看
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = sql;
SQLiteDataReader reader = cmd.ExecuteReader();
List<rcontact> rcontactList = new List<rcontact>();
try
{
while (reader.Read())
{
rcontact model = new rcontact();
model.username = reader.GetString(0);
model.alias = reader.GetString(1);
model.chatroomFlag = reader.GetInt64(2);
model.conRemark = reader.GetString(3);
model.domainList = reader.GetString(4);
model.nickname = reader.GetString(5);
model.pyInitial = reader.GetString(6);
model.quanPin = reader.GetString(7);
model.showHead = reader.GetInt64(8);
model.type = reader.GetInt64(9);
model.weiboFlag = reader.GetInt64(10);
model.weiboNickname = reader.GetString(11);
model.conRemarkPYFull = reader.GetString(12);
model.conRemarkPYShort = reader.GetString(13);
model.verifyFlag = reader.GetInt64(14);
model.encryptUsername = reader.GetString(15);
model.deleteFlag = reader.GetInt64(16);
model.contactLabelIds = reader.GetString(17);
model.ctime = Convert.ToInt64(reader.GetValue(18));
model.jobwxusername = username;
rcontactList.Add(model);
}
}
catch (Exception xs)
{
content += "[读取rcontact出错]";
status = 100;
LogHelper.Error("rcontact数据读取错误:" + xs.ToString());
}
finally
{
reader.Close();
}
content += "[读取rcontact成功" + rcontactList.Count() + "条]";
RContactPut(rcontactList);//rcontact
}
catch (Exception xx)
{
status = 100;
content += "[读取rcontact出错]";
LogHelper.Error(xx.ToString());
}
#endregion
#region message分析
try
{
string sql = @" select ifnull(msgSvrId,-a.msgId) msgSvrId,a.type,ifnull(a.isSend,1),a.createTime,a.talker,a.content,b.nickname,a.msgId from message a
join rcontact b on a.talker=b.username
and a.talker!='weixin'" +
(isShowGroup == "true" ? "" : @"and a.talker not like'%chatroom'") +
@"and a.talker not like'%@stranger'
and a.talker not like 'gh\_%'escape '\' " +
(isShowHongBao == "true" ? "and a.type in(10000,10002,1,3,47,43,34,49,436207665)" : "and a.type in(10000,10002,1,3,47,43,34,49)");
//用SQLite Expert管理器看表或者CMD看
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = sql;
SQLiteDataReader reader = cmd.ExecuteReader();
long msgId = 0;
try
{
List<friend> friendList = new List<friend>();
int i = 0;
int x = 0;
int zj = 0;
int addMsgCount = 0;
while (reader.Read())
{
message model = new message();
model.msgId = reader.GetInt32(7);
msgId = model.msgId;
model.msgSvrId = reader.GetInt64(0);
model.type = reader.GetInt32(1);
model.isSend = reader.GetInt32(2);
model.createTime = reader.GetInt64(3);
model.talker = reader.GetString(4);
model.content = reader.GetValue(5).ToString();
model.nickname = reader.GetString(6);
model.username = username;
model.msgType = "1";
#region
if (model.type == 3 || model.type == 47 || model.type == 43 || model.type == 34 || model.type == 49)
{
model.content = "";
}
int ntype = 0;
if (model.msgSvrId < 0 && model.isSend == 0 && model.type == 1)
{//有验证被加
ntype = 2;
}
if (model.type == 10000 && (model.content.EndsWith("刚刚把你添加到通讯录,现在可以开始聊天了。") || model.content.EndsWith("剛剛把你新增到通訊錄,現在可以開始聊天了。")))
{//无验证被加
ntype = 1;
}
if (model.type == 1 && model.isSend == 0 && (model.content == "我通过了你的朋友验证请求,现在我们可以开始聊天了" || model.content == "我通過了你的朋友驗證請求,現在我們可以開始聊天了"))
{//加别人 有验证\
ntype = 4;
}
if (model.type == 10000 && model.isSend == 0 && ((model.content.StartsWith("你已添加了") && model.content.EndsWith(",现在可以开始聊天了。")) || (model.content.StartsWith("你已加") && model.content.EndsWith("現在可以聊天了。"))))
{//可能加别人
ntype = 3;
}
if (ntype != 0)
{
friend friend = new friend();
friend.createtime = model.createTime.Value;
friend.jobusername = model.username;
friend.talker = model.talker;
friend.type = ntype;
friendList.Add(friend);
x++;
if (ntype == 1 || ntype == 2)
{
zj++;
}
}
#endregion
#region
//region ====================3.红包识别 ==============================================================================
//System.out.println("3.红包识别");
try
{
if (model.type == 436207665)
{//识别到红包
//System.out.println("===有红包===");
string sendUserName = string.Empty;
string title = string.Empty;
string sendid = string.Empty;
GetHongBaoMsg(model, ref sendUserName, ref title, ref sendid);
decimal type1 = model.talker.Contains("chatroom") ? 2 : 1;
DateTime time1 = DateTimeTool.GetTimeFromLinuxTime(model.createTime.Value);
bool isSucced = wx_hongbao.WxHongBao(sendid, model.msgSvrId.Value.ToString(), model.talker, sendUserName, type1, time1, title, type1 == 2 ? model.talker : "", username);
}
}
catch (Exception e)
{
LogHelper.Error(e.ToString());
}
//endregion===========================================================================================================
//region ====================4.红包领取识别 =========================================================================
//System.out.println("4.红包领取识别");
try
{
if (model.type == 10000)
{
int wtype = 0;//1:群领取别人的红吧2群别人领取你的红包 3普通领取别人的红包 4普通比人领取你的红包
if (model.talker.Contains("chatroom") && model.content.Contains("你领取了") && model.content.Contains("红包"))
{
wtype = 1;
}
else if (model.talker.Contains("chatroom") && model.content.Contains("领取了你的") && model.content.Contains("红包"))
{
wtype = 2;
}
else if (model.content.Contains("你领取了") && model.content.Contains("红包"))
{
wtype = 3;
}
else if (model.content.Contains("领取了你的") && model.content.Contains("红包"))
{
wtype = 4;
}
if (wtype != 0)
{
string sendid = string.Empty;
string lusername = string.Empty;
GetReceiveHongBao(cmd, model, wtype, ref sendid, ref lusername);
DateTime time = DateTimeTool.GetTimeFromLinuxTime(model.createTime.Value);
wx_hongbao.WxHongBaoReceuve(sendid, model.msgSvrId.ToString(), model.talker, time, lusername);
}
}
}
catch (Exception e)
{
LogHelper.Error(e.ToString());
}
//endregion===========================================================================================================
#endregion
if (MessagePut(model))
{
addMsgCount++;
}
i++;
}
int friendAddCount = FriendPut(friendList);
content += "[message分析成功" + i + "条补充" + addMsgCount + "条,加人" + x + "条被加" + zj + "条被加补充" + friendAddCount + "条]";
friendList = null;
}
catch (Exception xs)
{
status = 100;
content += "[message分析出错]";
LogHelper.Error("message数据读取MsID:" + msgId + ",pkid:" + pkid + "错误信息:" + xs.ToString());
}
finally
{
reader.Close();
}
}
catch (Exception xx)
{
status = 100;
LogHelper.Error(xx.ToString());
}
#endregion
#region massendinfo读取
try
{
string sql = @" select clientid,msgtype,createtime,tolist,filename from massendinfo"; //用SQLite Expert管理器看表或者CMD看
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = sql;
SQLiteDataReader reader = cmd.ExecuteReader();
try
{
int oi = 0;
int massendinfoAddCount = 0;
while (reader.Read())
{
message model = new message();
model.msgSvrId = Convert.ToInt64(reader.GetValue(0));
model.type = reader.GetInt32(1);
model.isSend = 1;
model.createTime = reader.GetInt64(2);
model.talker = reader.GetString(3);
model.content = reader.GetString(4);
model.nickname = "";
model.msgId = 0;
model.username = username;
model.msgType = "2";
if (MessagePut(model))
{
massendinfoAddCount++;
}
oi++;
}
content += "[massendinfo成功" + oi + "条,补充" + massendinfoAddCount + "条]";
}
catch (Exception xs)
{
status = 100;
content += "[massendinfo分析出错]";
LogHelper.Error("massendinfo数据读取错误:" + xs.ToString());
}
finally
{
reader.Close();
}
}
catch (Exception xx)
{
status = 100;
LogHelper.Error(xx.ToString());
}
#endregion
BAS_PARAMETER paramter = new BAS_PARAMETER_BL().GetModel_Patameter("WeiXin_IsShowGroupMessage");//是否显示群信息
string isShowGroupMessage = "false";
if (paramter != null)
isShowGroupMessage = paramter.PARAVALUE;
#region chatroom读取并维护
if (isShowGroupMessage == "true")
{
try
{
string sql = @"select chatroomname,memberlist,displayname,roomowner,ifnull(selfdisplayname,'')selfdisplayname,modifytime,ifnull(b.nickname,'')nickname from chatroom a left join rcontact b on a.chatroomname=b.username"; //用SQLite Expert管理器看表或者CMD看
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = sql;
SQLiteDataReader reader = cmd.ExecuteReader();
List<chatroom> chatroomList = new List<chatroom>();
try
{
while (reader.Read())
{
chatroom model = new chatroom();
model.chatroomname = reader.GetString(0);
model.memberlist = reader.GetString(1);
model.displayname = reader.GetString(2);
model.roomowner = reader.GetString(3);
LogHelper.Error("roomowner:" + model.roomowner);
model.selfdisplayname = reader.GetString(4);
//LogHelper.Error("selfdisplayname:" + model.selfdisplayname);
model.modifytime = DateTimeTool.GetTimeFromLinuxTime(reader.GetInt64(5));
//LogHelper.Error("modifytime:" + model.modifytime);
model.roomName = reader.GetString(6);
chatroomList.Add(model);
}
}
catch (Exception xs)
{
content += "[读取chatroom出错]";
status = 100;
LogHelper.Error("chatroom数据读取错误:" + xs.ToString());
}
finally
{
reader.Close();
}
content += "[读取chatroom成功" + chatroomList.Count() + "条]";
ChatRoom(chatroomList, username);//rcontact
}
catch (Exception xx)
{
status = 100;
content += "[读取chatroom出错]";
LogHelper.Error("[读取chatroom出错]" + xx.ToString());
}
}
#endregion
#region img_flag
string isHasFlag = "true";
BAS_PARAMETER WeiXin_IsHasFlag = new BAS_PARAMETER_BL().GetModel_Patameter("WeiXin_IsHasFlag");//
if (WeiXin_IsHasFlag != null)
isHasFlag = WeiXin_IsHasFlag.PARAVALUE;
if (isHasFlag == "true")
{
try
{
string sql = @"select username,imgflag,lastupdatetime,reserved1,reserved2,reserved3,reserved4 from img_flag where username not like'%@%' and username not in('filehelper' ,'mphelper','weixin') "; //用SQLite Expert管理器看表或者CMD看
SQLiteCommand cmd = cnn.CreateCommand();
cmd.CommandText = sql;
WX_UserInfo_BL wx_userinfo_bl = new WX_UserInfo_BL();
SQLiteDataReader reader = cmd.ExecuteReader();
//List<img_flag> img_flagList = new List<img_flag>();
int count = 0;
try
{
while (reader.Read())
{
count++;
img_flag model = new img_flag();
model.username = reader.GetString(0);
model.imgflag = reader.GetInt32(1);
model.lastupdatetime = reader.GetInt64(2);
model.reserved1 = reader.GetString(3);
model.reserved2 = reader.GetString(4);
model.reserved3 = reader.GetInt32(5).ToString();
model.reserved4 = reader.GetInt32(6).ToString();
//img_flagList.Add(model);
wx_userinfo_bl.Img_flat_Storage(model.username, model.imgflag, model.lastupdatetime, model.reserved1, model.reserved2, model.reserved3, model.reserved4);
}
}
catch (Exception xs)
{
content += "[读取img_flag出错]";
status = 100;
LogHelper.Error("img_flag数据读取错误:" + xs.ToString());
}
finally
{
reader.Close();
}
content += "[读取img_flag成功" + count + "条]";
}
catch (Exception xx)
{
status = 100;
content += "[读取img_flag出错]";
LogHelper.Error("[读取img_flag出错]" + xx.ToString());
}
}
#endregion
cnn.Close();
cnn.Dispose();
GC.Collect();
GC.WaitForPendingFinalizers();
//try
//{
// if (!string.IsNullOrEmpty(_isShare))
// {
// var yearMonth = DateTime.Now.Year.ToString() + DateTime.Now.Month.ToString();
// var uploadFolder = _shareName + @"\dbuploadfile\" + yearMonth;
// var fileName = Path.GetFileName(dbfile);
// File.Move(dbfile, Path.Combine(uploadFolder, fileName));
// }
//}
//catch (Exception ex)
//{
// LogHelper.Error("Move出错" + ex.ToString());
//}
//File.Delete(dbfile);
}
catch (Exception xs)
{
status = 100;
content += "[直接报错]";
LogHelper.Error(xs.ToString());
}
bll.UpdataStatus(pkid, status, content);
}
/// <summary>
/// 领取红包
/// </summary>
/// <param name="db"></param>
/// <param name="mn"></param>
/// <param name="ntype"></param>
/// <returns></returns>
private void GetReceiveHongBao(SQLiteCommand cmd, message mn, int ntype, ref string sendid, ref string username)
{
int nindex = mn.content.IndexOf("sendid=");
if (nindex > -1)
{
String content = mn.content.Substring(nindex, nindex + 50);
int index1 = content.IndexOf("&");
int index2 = content.IndexOf("\">");
if (index2 == -1 || (index1 != -1 && index1 < index2))
sendid = content.Substring(7, index1);
else
sendid = content.Substring(7, index2);
if (ntype == 2)
{//群别人领取了你的红包
int nindex1 = mn.content.IndexOf("/> ");
int nindex2 = mn.content.IndexOf("领取了你的<");
String nickname = mn.content.Substring(nindex1 + 4, nindex2);
SQLiteDataReader reader = cmd.ExecuteReader();
//System.out.println("ntype==2 nickname:"+nickname);
try
{
cmd.CommandText = "select username from rcontact t where t.nickname='" + nickname + "'or conremark='" + nickname + "'";
while (reader.Read())
{
username = reader.GetString(0);
}
}
catch (Exception xx) { LogHelper.Error(xx.ToString()); }
finally
{
reader.Close();
}
}
}
}
/// <summary>
/// 红包识别
/// </summary>
/// <param name="mn"></param>
/// <param name="sendUserName"></param>
/// <param name="title"></param>
/// <param name="sendid"></param>
private void GetHongBaoMsg(message mn, ref string sendUserName, ref string title, ref string sendid)
{
//System.out.println(mn.getContent());//===
int nindex = mn.content.IndexOf("sendid=");
if (nindex > -1)
{
string content = mn.content.Substring(nindex, nindex + 50);
int index1 = content.IndexOf("&");
int index2 = content.IndexOf("]]");
if (index2 == -1 || (index1 != -1 && index1 < index2))
{
sendid = content.Substring(7, index1);
}
else
sendid = content.Substring(7, index2);
}
nindex = mn.content.IndexOf("<receivertitle><![CDATA[");
int xn = mn.content.IndexOf("]]></receivertitle>");
sendUserName = mn.content.Substring(nindex + 24, xn);//--发送人
nindex = mn.content.IndexOf("<fromusername><![CDATA[");
xn = mn.content.IndexOf("]]></fromusername>");
title = mn.content.Substring(nindex + 23, xn);//发送人#标题
}
public void ChatRoom(List<chatroom> chatroom, string username)
{
WX_GROUP_BL wx_group = new WX_GROUP_BL();
foreach (chatroom content in chatroom)
{
string name = content.roomName;
string shortName = content.displayname.Substring(0, 20) + "...";
wx_group.WxGroupMaintain(content.chatroomname, name, content.roomowner, content.modifytime, shortName);//===维护群信息
string[] memberlist = content.memberlist.Split(';');//==群成员列表
string[] displayname = content.displayname.Split('、');//===群成员昵称列表
string nickname = string.Empty;
//LogHelper.Info(content.nickname);
for (int i = 0; i < memberlist.Count(); i++)
{
nickname = string.Empty;
if (username == memberlist[i])
{
nickname = content.selfdisplayname;
}
wx_group.WxGroupMemberMaintain(content.chatroomname, memberlist[i], displayname[i], nickname, username);
}
}
}
#region Rcontact
public void RContactPut(IList<rcontact> content)
{
//var userNames = new List<string>();
Rcontact_RK rk = new Rcontact_RK();
foreach (var item in content)
{
if (string.IsNullOrEmpty(item.username))
continue;
#region
#endregion
//var key = item.username == item.jobwxusername ? "rcontact1" : "rcontact0";
//var username = PushRcontactAsync<rcontact>(item, key, item.jobwxusername, item.username, item.alias, item.conRemark);
if (item.username == item.jobwxusername)
{
rk.WxWorkAccount(item);
//if (rk.WxWorkAccount(item) == false)
// userNames.Add(item.username);
}
else
{
rk.WxRcontact(item);
//if (rk.WxRcontact(item))
//{
// userNames.Add(item.username);
//}
}
}
}
private string PushRcontactAsync<T>(T model, string key, string jobWxUserName, string userName, string alias, string conRemark)
{
try
{
//如果是工作微信直接写入队列更新工作微信的信息不是的话写入联系人队列根据jobwxusername,username,alias,conRemark判断是否存在存在了不更新不存在写入队列
if (key == "rcontact1")
{
PushRedisAndPublish<T>(model, key);//写入队列
}
else
{
var isExists = _redisSet.ContainsTB(WxFix + jobWxUserName, userName + ":" + alias + ":" + conRemark);
if (!isExists)
{
var ret = PushRedisAndPublish<T>(model, key);//写入队列
if (ret)
_redisSet.Add(WxFix + jobWxUserName, userName + ":" + alias + ":" + conRemark); //写入微信好友关系
}
}
return string.Empty;
}
catch
{
return userName;
}
}
private bool PushRedisAndPublish<T>(T model, string key)
{
try
{
//写入队列
var result = new RedisList<T>().LeftPush(key, model);
if (result > 0)
{
//发送订阅通知
_sub.Publish("sub:" + key, "");
return true;
}
return false;
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
return false;
}
}
#endregion
#region Message
public bool MessagePut(message content)
{
bool isAdd = false;
try
{
#region
#endregion
bool ret = true;
var isExists = true;
string keyname = "";
if (content.talker.Contains("chatroom"))
{
keyname = WxMsgFix + content.msgSvrId + "|" + content.talker;
}
else
{
keyname = WxMsgFix + content.msgSvrId + "|" + content.username;
}
isExists = _redisMsg.Exists(keyname);
if (!isExists)
{
isExists = msgkey.HasMsgKey(keyname);
}
if (!isExists)
{
TimeSpan span = new TimeSpan(60, 0, 0, 0, 0);//保留60天
_redisMsg.Set(keyname, string.Empty, span);
ret = PushRedisAndPublish<message>(content, "message");
msgkey.CheckAndSetKey(keyname);
isAdd = true;
}
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
}
return isAdd;
}
#endregion
#region friend资源
public int FriendPut(IList<friend> friends)
{
int addCount = 0;
try
{
//LogHelper.Info("接收到参数:" + JsonConvert.SerializeObject(friends));
var userNames = new List<string>();
foreach (var item in friends)
{
var ret = true;
decimal pici = _rcontact.extractToBeFriendsDataFromMsg(item.type, item.talker, item.jobusername, DateTimeTool.GetTimeFromLinuxTime(item.createtime), ref ret);
if (pici > 0)
{
//MsgHelper msg = new MsgHelper(EnumMsgs.SendMsg);
//var messageDto = new MessageQueueDTO() { MsgType = pici, MsgData = "web_push_updateUser" };
//msg.SendMsg(messageDto);//触发推送通知
addCount++;
}
if (!ret)
{
userNames.Add(item.talker);
}
}
}
catch (Exception ex)
{
LogHelper.Error(ex.ToString());
}
return addCount;
}
#endregion
}
}