|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.ComponentModel;
|
|
|
|
|
using System.Data;
|
|
|
|
|
using System.Drawing;
|
|
|
|
|
using System.Linq;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using System.Windows.Forms;
|
|
|
|
|
using System.Net;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Threading;
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
|
|
|
|
namespace Diaoyong
|
|
|
|
|
{
|
|
|
|
|
public partial class ConnectionTest : Form
|
|
|
|
|
{
|
|
|
|
|
const int NumberOfSupportedCameras = 8;
|
|
|
|
|
public Thread recvThread = null;
|
|
|
|
|
public bool m_Done = false;
|
|
|
|
|
static byte[] clientIP = new byte[] { 192, 168, 31, 243 };
|
|
|
|
|
static byte[] localIP = new byte[] { 192, 168, 31, 226 };
|
|
|
|
|
static int clientport = 3333;
|
|
|
|
|
|
|
|
|
|
public ConnectionTest()
|
|
|
|
|
{
|
|
|
|
|
InitializeComponent();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void SendMsg(string obj, byte[] ip, int port)
|
|
|
|
|
{
|
|
|
|
|
byte[] IP = ip;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
UdpClient udpcSend = new UdpClient(0);
|
|
|
|
|
byte[] sendbytes = Encoding.UTF8.GetBytes(obj);
|
|
|
|
|
// IPEndPoint remoteIpep = new IPEndPoint(IPAddress.Parse("192.168.31.243"), 3333);
|
|
|
|
|
IPEndPoint remoteIpep = new IPEndPoint(new IPAddress(IP), port);
|
|
|
|
|
udpcSend.Send(sendbytes, sendbytes.Length, remoteIpep);
|
|
|
|
|
udpcSend.Close();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void RecMsg(byte[] ip, int port)
|
|
|
|
|
{
|
|
|
|
|
// UdpClient udpcSend = new UdpClient(0);
|
|
|
|
|
// byte[] sendbytes = Encoding.UTF8.GetBytes(obj);
|
|
|
|
|
// IPEndPoint remoteIpep = new IPEndPoint(new IPAddress(IP), dataPort);
|
|
|
|
|
// byte[] sendbytes = udpcSend.Receive(ref remoteIpep);
|
|
|
|
|
// udpcSend.Close();
|
|
|
|
|
byte[] IP = ip;
|
|
|
|
|
UdpClient u = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
if (u == null)
|
|
|
|
|
{
|
|
|
|
|
u = new UdpClient(new IPEndPoint(new IPAddress(IP), port));
|
|
|
|
|
// recvThread = new Thread(new ThreadStart(Received));
|
|
|
|
|
// recvThread.Priority = ThreadPriority.Normal;
|
|
|
|
|
// recvThread.Start();
|
|
|
|
|
u.Client.ReceiveTimeout = 100;
|
|
|
|
|
}
|
|
|
|
|
Received(u);
|
|
|
|
|
}
|
|
|
|
|
catch(Exception ex)
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show(ex.ToString(), "连接失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Received(UdpClient u)
|
|
|
|
|
{
|
|
|
|
|
//ASCII 编码
|
|
|
|
|
Encoding ASCII = Encoding.ASCII;
|
|
|
|
|
int tryLoop = 0;
|
|
|
|
|
while (!m_Done)
|
|
|
|
|
{
|
|
|
|
|
IPEndPoint endpoint = null;
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
Byte[] data = u.Receive(ref endpoint);
|
|
|
|
|
//得到数据的ACSII的字符串形式
|
|
|
|
|
String receiveString = ASCII.GetString(data);
|
|
|
|
|
if (receiveString != null)
|
|
|
|
|
{
|
|
|
|
|
String[] str = receiveString.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
if (str[0].CompareTo("HandShake") == 0) //connect success
|
|
|
|
|
{
|
|
|
|
|
if(str.Length > 1)
|
|
|
|
|
{
|
|
|
|
|
if(str[1].CompareTo("UnlockOk") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[0] = 1;
|
|
|
|
|
}
|
|
|
|
|
else if(str[1].CompareTo("LockOk") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[0] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (str.Length > 2)
|
|
|
|
|
{
|
|
|
|
|
if (str[2].CompareTo("DebugEn") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[1] = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (str[2].CompareTo("DebugDis") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[1] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (str.Length > 3)
|
|
|
|
|
{
|
|
|
|
|
if (str[3].CompareTo("UnKickOk") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[2] = 1;
|
|
|
|
|
}
|
|
|
|
|
else if (str[3].CompareTo("KickOk") == 0)
|
|
|
|
|
{
|
|
|
|
|
WindowsFormsApp2.UserControl1.status[2] = 0;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//DialogResult dr = MessageBox.Show("连接成功!", "连接成功", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
u.Close();
|
|
|
|
|
//u.Dispose();
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
System.Diagnostics.Debug.WriteLine(ex.Message);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
tryLoop++;//1 loop = 100ms
|
|
|
|
|
if(tryLoop == 50)
|
|
|
|
|
m_Done = true;
|
|
|
|
|
}
|
|
|
|
|
u.Close();
|
|
|
|
|
//u.Dispose();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void label1_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP1_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if ((int.Parse(this.clientIP1.Text) > 255) && (this.clientIP1.Text.Length > 0))
|
|
|
|
|
this.clientIP1.Text = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP2_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if ((int.Parse(this.clientIP2.Text) > 255) && (this.clientIP1.Text.Length > 0))
|
|
|
|
|
this.clientIP1.Text = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP3_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if ((int.Parse(this.clientIP3.Text) > 255) && (this.clientIP1.Text.Length > 0))
|
|
|
|
|
this.clientIP1.Text = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP4_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if ((int.Parse(this.clientIP4.Text) > 255) && (this.clientIP1.Text.Length > 0))
|
|
|
|
|
this.clientIP1.Text = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClientPort_TextChanged(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (this.ClientPort.Text.Length > 4)
|
|
|
|
|
this.clientIP1.Text = null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP1_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if(!(char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP2_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!(char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP3_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!(char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void clientIP4_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!(char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ClientPort_KeyPress(object sender, KeyPressEventArgs e)
|
|
|
|
|
{
|
|
|
|
|
if (!(char.IsNumber(e.KeyChar)) && e.KeyChar != (char)8)
|
|
|
|
|
e.Handled = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void ok_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//获取主机名
|
|
|
|
|
string HostName = Dns.GetHostName();
|
|
|
|
|
IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
|
|
|
|
|
for (int i = 0; i < IpEntry.AddressList.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
//从IP地址列表中筛选出IPv4类型的IP地址
|
|
|
|
|
//AddressFamily.InterNetwork表示此IP为IPv4,
|
|
|
|
|
//AddressFamily.InterNetworkV6表示此地址为IPv6类型
|
|
|
|
|
if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
|
|
|
|
|
{
|
|
|
|
|
localIP = IpEntry.AddressList[i].GetAddressBytes();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show("获取本机IP失败!", "获取本机IP失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((this.clientIP1.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP2.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP3.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP4.Text.Length != 0) &&
|
|
|
|
|
(this.ClientPort.ToString().Length != 0)
|
|
|
|
|
) {
|
|
|
|
|
|
|
|
|
|
clientIP[0] = (byte)(int.Parse(this.clientIP1.Text));
|
|
|
|
|
clientIP[1] = (byte)(int.Parse(this.clientIP2.Text));
|
|
|
|
|
clientIP[2] = (byte)(int.Parse(this.clientIP3.Text));
|
|
|
|
|
clientIP[3] = (byte)(int.Parse(this.clientIP4.Text));
|
|
|
|
|
|
|
|
|
|
clientport = int.Parse(this.ClientPort.Text.ToString());
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show("输入有误,请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.DialogLogin.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.ordPort = clientport+NumberOfSupportedCameras*2+1;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.feedPort = clientport+NumberOfSupportedCameras*2;
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.UserControl1.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.UserControl1.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.UserControl1.ordPort = clientport+NumberOfSupportedCameras*2+1;
|
|
|
|
|
WindowsFormsApp2.UserControl1.feedPort = clientport+NumberOfSupportedCameras*2;
|
|
|
|
|
WindowsFormsApp2.UserControl1.filePort = clientport+NumberOfSupportedCameras*2+2;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.Client.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.Client.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.Client.dataPort = clientport;
|
|
|
|
|
WindowsFormsApp2.Client.imagePort = clientport+NumberOfSupportedCameras;
|
|
|
|
|
this.Close();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void connection_Test(byte[] clientIP, int clientport, byte[] localIP)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
String data = "CONNECTIONTEST:";
|
|
|
|
|
data += clientIP.ToString();
|
|
|
|
|
|
|
|
|
|
data += (clientport + NumberOfSupportedCameras * 2 + 1).ToString();
|
|
|
|
|
data += ":";
|
|
|
|
|
data += (clientport + NumberOfSupportedCameras * 2).ToString();
|
|
|
|
|
|
|
|
|
|
SendMsg(data, clientIP, clientport + NumberOfSupportedCameras * 2 + 1);
|
|
|
|
|
RecMsg(localIP, clientport + NumberOfSupportedCameras * 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void test_Click(object sender, EventArgs e)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//获取主机名
|
|
|
|
|
string HostName = Dns.GetHostName();
|
|
|
|
|
IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
|
|
|
|
|
for (int i = 0; i < IpEntry.AddressList.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
//从IP地址列表中筛选出IPv4类型的IP地址
|
|
|
|
|
//AddressFamily.InterNetwork表示此IP为IPv4,
|
|
|
|
|
//AddressFamily.InterNetworkV6表示此地址为IPv6类型
|
|
|
|
|
if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
|
|
|
|
|
{
|
|
|
|
|
localIP = IpEntry.AddressList[i].GetAddressBytes();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show("获取本机IP失败!", "获取本机IP失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ((this.clientIP1.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP2.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP3.Text.Length != 0) &&
|
|
|
|
|
(this.clientIP4.Text.Length != 0) &&
|
|
|
|
|
(this.ClientPort.ToString().Length != 0)
|
|
|
|
|
)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
clientport = int.Parse(this.ClientPort.Text.ToString());
|
|
|
|
|
|
|
|
|
|
clientIP[0] = (byte)(int.Parse(this.clientIP1.Text));
|
|
|
|
|
clientIP[1] = (byte)(int.Parse(this.clientIP2.Text));
|
|
|
|
|
clientIP[2] = (byte)(int.Parse(this.clientIP3.Text));
|
|
|
|
|
clientIP[3] = (byte)(int.Parse(this.clientIP4.Text));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show("输入有误,请重新输入!", "错误", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connection_Test(clientIP, clientport, localIP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void ConnectionTesting()
|
|
|
|
|
{
|
|
|
|
|
connection_Test(clientIP, clientport, localIP);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void UpdateLableStatus(string str)
|
|
|
|
|
{
|
|
|
|
|
label5.Text = str;
|
|
|
|
|
}
|
|
|
|
|
public void conf_Load()
|
|
|
|
|
{
|
|
|
|
|
string ReadLine;
|
|
|
|
|
string Path = "IPconf.txt";
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
StreamReader reader = new StreamReader(Path);
|
|
|
|
|
while (reader.Peek() >= 0)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
ReadLine = reader.ReadLine();
|
|
|
|
|
if (ReadLine != "")
|
|
|
|
|
{
|
|
|
|
|
int index = ReadLine.IndexOf('=');
|
|
|
|
|
if(index!= -1)
|
|
|
|
|
{
|
|
|
|
|
string firststr = ReadLine.Substring(0, index);
|
|
|
|
|
|
|
|
|
|
if (firststr == "MonitorIP")
|
|
|
|
|
{
|
|
|
|
|
string secendstr = ReadLine.Substring(index + 1);
|
|
|
|
|
string[] ipstr = secendstr.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
|
|
|
|
|
clientIP[0] = (byte)(int.Parse(ipstr[0]));
|
|
|
|
|
clientIP[1] = (byte)(int.Parse(ipstr[1]));
|
|
|
|
|
clientIP[2] = (byte)(int.Parse(ipstr[2]));
|
|
|
|
|
clientIP[3] = (byte)(int.Parse(ipstr[3]));
|
|
|
|
|
}
|
|
|
|
|
else if (firststr == "MonitorPort")
|
|
|
|
|
{
|
|
|
|
|
clientport = Convert.ToInt32(ReadLine.Substring(index + 1));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
reader.Close();
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
MessageBox.Show(ex.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try
|
|
|
|
|
{
|
|
|
|
|
//获取主机名
|
|
|
|
|
string HostName = Dns.GetHostName();
|
|
|
|
|
IPHostEntry IpEntry = Dns.GetHostEntry(HostName);
|
|
|
|
|
for (int i = 0; i < IpEntry.AddressList.Length; i++)
|
|
|
|
|
{
|
|
|
|
|
//从IP地址列表中筛选出IPv4类型的IP地址
|
|
|
|
|
//AddressFamily.InterNetwork表示此IP为IPv4,
|
|
|
|
|
//AddressFamily.InterNetworkV6表示此地址为IPv6类型
|
|
|
|
|
if (IpEntry.AddressList[i].AddressFamily == AddressFamily.InterNetwork)
|
|
|
|
|
{
|
|
|
|
|
localIP = IpEntry.AddressList[i].GetAddressBytes();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch (Exception ex)
|
|
|
|
|
{
|
|
|
|
|
DialogResult dr = MessageBox.Show("获取本机IP失败!", "获取本机IP失败", MessageBoxButtons.OK, MessageBoxIcon.Warning);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.DialogLogin.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.ordPort = clientport + NumberOfSupportedCameras * 2 + 1;
|
|
|
|
|
WindowsFormsApp2.DialogLogin.feedPort = clientport + NumberOfSupportedCameras * 2;
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.UserControl1.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.UserControl1.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.UserControl1.ordPort = clientport + NumberOfSupportedCameras * 2 + 1;
|
|
|
|
|
WindowsFormsApp2.UserControl1.feedPort = clientport + NumberOfSupportedCameras * 2;
|
|
|
|
|
WindowsFormsApp2.UserControl1.filePort = clientport+NumberOfSupportedCameras*2+2;
|
|
|
|
|
|
|
|
|
|
WindowsFormsApp2.Client.localIP = localIP;
|
|
|
|
|
WindowsFormsApp2.Client.clientIP = clientIP;
|
|
|
|
|
WindowsFormsApp2.Client.dataPort = clientport;
|
|
|
|
|
WindowsFormsApp2.Client.imagePort = clientport + NumberOfSupportedCameras;
|
|
|
|
|
|
|
|
|
|
this.clientIP1.Text = clientIP[0].ToString();
|
|
|
|
|
this.clientIP2.Text = clientIP[1].ToString();
|
|
|
|
|
this.clientIP3.Text = clientIP[2].ToString();
|
|
|
|
|
this.clientIP4.Text = clientIP[3].ToString();
|
|
|
|
|
this.ClientPort.Text = clientport.ToString();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|