560 lines
19 KiB
C#
560 lines
19 KiB
C#
![]() |
|
|||
|
using Bricscad.ApplicationServices;
|
|||
|
using Bricscad.EditorInput;
|
|||
|
using Prism.Events;
|
|||
|
using Prism.Ioc;
|
|||
|
using Prism.Services.Dialogs;
|
|||
|
using SWS.CAD.Base;
|
|||
|
using SWS.CAD.Event;
|
|||
|
using SWS.CAD.ViewModels.myViewModelBase;
|
|||
|
using SWS.CAD.Views;
|
|||
|
using SWS.CAD.Views.CustomControl;
|
|||
|
using SWS.Commons;
|
|||
|
using SWS.Model;
|
|||
|
using SWS.Service;
|
|||
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.Collections.ObjectModel;
|
|||
|
using System.Linq;
|
|||
|
using System.Threading.Tasks;
|
|||
|
using System.Windows;
|
|||
|
using System.Windows.Controls;
|
|||
|
using System.Windows.Documents;
|
|||
|
using System.Windows.Input;
|
|||
|
using Teigha.DatabaseServices;
|
|||
|
using Telerik.Windows.Controls;
|
|||
|
using Unity;
|
|||
|
|
|||
|
namespace SWS.CAD.ViewModels
|
|||
|
{
|
|||
|
/// <summary>
|
|||
|
/// 信号预分配页面的模型类
|
|||
|
/// </summary>
|
|||
|
public class DialogSectionBoxViewModel : DialogBase, IDialogAware
|
|||
|
{
|
|||
|
#region 字段
|
|||
|
private ObservableCollection<CircuitBreakerInfo> _CircuitBreakerInfos = new ObservableCollection<CircuitBreakerInfo>();
|
|||
|
/// <summary>
|
|||
|
/// 表格数据
|
|||
|
/// </summary>
|
|||
|
public ObservableCollection<CircuitBreakerInfo> CircuitBreakerInfos
|
|||
|
{
|
|||
|
get { return _CircuitBreakerInfos; }
|
|||
|
set
|
|||
|
{
|
|||
|
_CircuitBreakerInfos = value;
|
|||
|
RaisePropertyChanged(nameof(CircuitBreakerInfos));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private CircuitBreakerInfo _SelectCircuitBreaker;
|
|||
|
/// <summary>
|
|||
|
/// 表格选中行
|
|||
|
/// </summary>
|
|||
|
public CircuitBreakerInfo SelectCircuitBreaker
|
|||
|
{
|
|||
|
get { return _SelectCircuitBreaker; }
|
|||
|
set { _SelectCircuitBreaker = value; }
|
|||
|
}
|
|||
|
|
|||
|
private string _DefaultBreakerType;
|
|||
|
/// <summary>
|
|||
|
/// 开关类型
|
|||
|
/// </summary>
|
|||
|
public string DefaultBreakerType
|
|||
|
{
|
|||
|
get { return _DefaultBreakerType; }
|
|||
|
set
|
|||
|
{
|
|||
|
_DefaultBreakerType = value;
|
|||
|
RaisePropertyChanged(nameof(DefaultBreakerType));
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
private List<string> _BreakerTypels = new List<string>() { "MCCB", "ACB" };
|
|||
|
/// <summary>
|
|||
|
/// 开关类型的下拉列表
|
|||
|
/// </summary>
|
|||
|
public List<string> BreakerTypels
|
|||
|
{
|
|||
|
get { return _BreakerTypels; }
|
|||
|
set { _BreakerTypels = value; }
|
|||
|
}
|
|||
|
|
|||
|
private List<string> _CB_Typels = new List<string>() { "输入", "输出" };
|
|||
|
/// <summary>
|
|||
|
/// 分电箱类型列的下拉列表
|
|||
|
/// </summary>
|
|||
|
public List<string> CB_Typels
|
|||
|
{
|
|||
|
get { return _CB_Typels; }
|
|||
|
set
|
|||
|
{
|
|||
|
_CB_Typels = value;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// 表示要删除的开关id集合
|
|||
|
/// </summary>
|
|||
|
public List<string> DeleBreakerIds = new List<string>();
|
|||
|
#endregion
|
|||
|
|
|||
|
IOModuleService _iOModuleService;
|
|||
|
ObjectTypeService _objectTypeService;
|
|||
|
RelService _relService;
|
|||
|
PDBService _pDBService;
|
|||
|
IEventAggregator _eventAggregator;
|
|||
|
|
|||
|
public DialogSectionBoxViewModel()
|
|||
|
{
|
|||
|
_iOModuleService = GlobalObject.container.Resolve<IOModuleService>();
|
|||
|
_pDBService = GlobalObject.container.Resolve<PDBService>();
|
|||
|
_relService = GlobalObject.container.Resolve<RelService>();
|
|||
|
_objectTypeService = GlobalObject.container.Resolve<ObjectTypeService>();
|
|||
|
_eventAggregator = GlobalObject.container.Resolve<IEventAggregator>();
|
|||
|
|
|||
|
}
|
|||
|
public string Title => "";
|
|||
|
|
|||
|
public event Action<IDialogResult> RequestClose;
|
|||
|
|
|||
|
public bool CanCloseDialog()
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
public void OnDialogClosed()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
private ec_Panel resBreakers;
|
|||
|
public async void OnDialogOpened(IDialogParameters parameters)
|
|||
|
{
|
|||
|
//title = $"电缆信号({parameters.GetValue<string>(GlobalObject.dialogPar.para2.ToString())})预分配";
|
|||
|
var resTagInfos = await _objectTypeService.GetTagInfosByPixels("857e8ae5-d9b4-4dc7-8ebc-d7e752a4b31c", "2C01C");
|
|||
|
|
|||
|
//var resRel = await _relService.GetRelDefByName("主配电板");
|
|||
|
//获取分电箱的开关信息
|
|||
|
IsBusy = true;
|
|||
|
resBreakers = await _pDBService.GetBreakers(resTagInfos.FirstOrDefault().tags.FirstOrDefault().EngineDataID);
|
|||
|
if (resBreakers != null)
|
|||
|
{
|
|||
|
int i = 0;
|
|||
|
foreach (var Breaker in resBreakers.Breakers)
|
|||
|
{
|
|||
|
i++;
|
|||
|
CircuitBreakerInfo breakerInfo = new CircuitBreakerInfo(Breaker);
|
|||
|
breakerInfo.Index = i;
|
|||
|
CircuitBreakerInfos.Add(breakerInfo);
|
|||
|
}
|
|||
|
DefaultBreakerType = resBreakers.DefaultBreakerType;
|
|||
|
}
|
|||
|
|
|||
|
title = $"{resTagInfos.FirstOrDefault().tags.FirstOrDefault().ObjectTypeName + resTagInfos.FirstOrDefault().tags.FirstOrDefault().TagNumber}开关管理";
|
|||
|
IsBusy = false;
|
|||
|
|
|||
|
|
|||
|
}
|
|||
|
public override async void ExecuteOKCommandAsync(object para)
|
|||
|
{
|
|||
|
await SavePanelAndBreaker();
|
|||
|
|
|||
|
IDialogParameters res = new Prism.Services.Dialogs.DialogParameters();
|
|||
|
//res.Add(GlobalObject.dialogPar.info.ToString(), TagNumber);
|
|||
|
RequestClose.Invoke(new DialogResult(ButtonResult.Yes, res));
|
|||
|
}
|
|||
|
public override void ExecuteCloseCommand(object parameter)
|
|||
|
{
|
|||
|
if (parameter as string == "ClickNo")
|
|||
|
{
|
|||
|
DialogResult res = new DialogResult(ButtonResult.No);
|
|||
|
RequestClose.Invoke(res);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
RequestClose.Invoke(new DialogResult(ButtonResult.Cancel));
|
|||
|
}
|
|||
|
this.Dispose();
|
|||
|
}
|
|||
|
#region 方法
|
|||
|
|
|||
|
#region 按钮点击事件
|
|||
|
public ICommand ButtonCmd => new DelegateCommand(Button_Click);
|
|||
|
/// <summary>
|
|||
|
/// 页面左侧按钮
|
|||
|
/// </summary>
|
|||
|
/// <param name="parameter"></param>
|
|||
|
public virtual async void Button_Click(object parameter)
|
|||
|
{
|
|||
|
#region 新增
|
|||
|
if (parameter.ToString().Equals("新增"))
|
|||
|
{
|
|||
|
CircuitBreakerInfo breakerInfo = new CircuitBreakerInfo();
|
|||
|
breakerInfo.Index = CircuitBreakerInfos.Count() + 1;
|
|||
|
breakerInfo.Name = "开关" + (CircuitBreakerInfos.Count() + 1);
|
|||
|
breakerInfo.Phase = 1;
|
|||
|
breakerInfo.OrderId = CircuitBreakerInfos.Count();
|
|||
|
breakerInfo.CB_Type = "输出";
|
|||
|
breakerInfo.IsModified = true;
|
|||
|
CircuitBreakerInfos.Add(breakerInfo);
|
|||
|
return;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 删除
|
|||
|
if (parameter.ToString().Equals("删除"))
|
|||
|
{
|
|||
|
//当前选择不为空
|
|||
|
if (SelectCircuitBreaker != null)
|
|||
|
{
|
|||
|
if (!string.IsNullOrEmpty(SelectCircuitBreaker.EngineerDataID))
|
|||
|
{
|
|||
|
DeleBreakerIds.Add(SelectCircuitBreaker.EngineerDataID);
|
|||
|
}
|
|||
|
CircuitBreakerInfos.Remove(SelectCircuitBreaker);
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
System.Windows.MessageBox.Show("请先选择删除行", "KunHengCAD", MessageBoxButton.OK, MessageBoxImage.Warning); return;
|
|||
|
}
|
|||
|
//删除之后重新排序
|
|||
|
int i = 0;
|
|||
|
foreach (var CircuitBreakerInfo in CircuitBreakerInfos)
|
|||
|
{
|
|||
|
i++;
|
|||
|
CircuitBreakerInfo.Index = i;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 关联电缆
|
|||
|
if (parameter.ToString().Equals("关联电缆"))
|
|||
|
{
|
|||
|
//当前选择不为空
|
|||
|
if (SelectCircuitBreaker != null)
|
|||
|
{
|
|||
|
//在SWS系统内打开且不是只读的图纸才可
|
|||
|
var dwgName = General.GetDwgName();
|
|||
|
var dwgFile = GlobalObject.ListDwgOpened.FirstOrDefault(a => a.Path == dwgName && a.IsReadOnly == false);
|
|||
|
if (dwgFile == null)
|
|||
|
{ return; }
|
|||
|
Document doc = Bricscad.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
|
|||
|
Database db = doc.Database;
|
|||
|
Editor ed = doc.Editor;
|
|||
|
//选择的元素返回的属性信息
|
|||
|
var ResTagInfosByPixels = new Model.ec_objecttype();
|
|||
|
var listPropertys = new List<propertyModel>();
|
|||
|
// 持续选择直到获取有效电缆
|
|||
|
bool isValidCable = false;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
|
|||
|
// 创建选择选项(禁用回车确认)
|
|||
|
PromptEntityOptions options = new PromptEntityOptions("\n请单击选择电缆: ");
|
|||
|
options.AllowNone = false; // 禁止空选
|
|||
|
|
|||
|
// 执行选择(直接单击生效)
|
|||
|
PromptEntityResult resultEntity = ed.GetEntity(options);
|
|||
|
|
|||
|
while (resultEntity.Status == PromptStatus.OK)
|
|||
|
{
|
|||
|
using (Transaction tr = db.TransactionManager.StartTransaction())
|
|||
|
{
|
|||
|
// 获取选中的电缆实体
|
|||
|
Entity cable = tr.GetObject(resultEntity.ObjectId, OpenMode.ForRead) as Entity;
|
|||
|
//if (cable != null&&cable.XData != null)
|
|||
|
if (cable != null)
|
|||
|
{
|
|||
|
// 获取句柄(Handle 是字符串类型)
|
|||
|
var handId = (cable.Handle.ToString());
|
|||
|
_objectTypeService = GlobalObject.container.Resolve<ObjectTypeService>();
|
|||
|
var res = await _objectTypeService.GetTagInfosByPixels(dwgFile.Id, handId);
|
|||
|
if (res != null)
|
|||
|
{
|
|||
|
if (res.Count == 1)
|
|||
|
{
|
|||
|
var item = res[0];
|
|||
|
var objTypeName = item.ObjectTypeName;
|
|||
|
if (objTypeName.Contains("电缆"))
|
|||
|
{
|
|||
|
ResTagInfosByPixels = item;
|
|||
|
isValidCable = true; // 校验通过
|
|||
|
ed.WriteMessage($"\n已选择电缆:{ResTagInfosByPixels.tags.FirstOrDefault().TagNumber}");
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
tr.Commit();
|
|||
|
}
|
|||
|
if (isValidCable)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
ed.WriteMessage($"\n已选择电缆:");
|
|||
|
resultEntity = ed.GetEntity(options);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
catch (Exception ex)
|
|||
|
{
|
|||
|
ed.WriteMessage($"\n错误: {ex.Message}");
|
|||
|
}
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
System.Windows.MessageBox.Show("请先选择行", "KunHengCAD", MessageBoxButton.OK, MessageBoxImage.Warning); return;
|
|||
|
}
|
|||
|
|
|||
|
return;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 放置开关
|
|||
|
if (parameter.ToString().Equals("放置开关"))
|
|||
|
{
|
|||
|
|
|||
|
//当前选择不为空
|
|||
|
if (SelectCircuitBreaker != null)
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
System.Windows.MessageBox.Show("请先选择行", "KunHengCAD", MessageBoxButton.OK, MessageBoxImage.Warning); return;
|
|||
|
}
|
|||
|
return;
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 表格编辑结束事件
|
|||
|
public ICommand EditEndCmd => new DelegateCommand(EditEnd);
|
|||
|
/// <summary>
|
|||
|
/// 编辑结束事件
|
|||
|
/// </summary>
|
|||
|
/// <param name="parameter"></param>
|
|||
|
public virtual void EditEnd(object parameter)
|
|||
|
{
|
|||
|
//做个标记表示该项修改过
|
|||
|
SelectCircuitBreaker.IsModified = true;
|
|||
|
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 保存
|
|||
|
/// <summary>
|
|||
|
/// 保存
|
|||
|
/// </summary>
|
|||
|
public async Task SavePanelAndBreaker()
|
|||
|
{
|
|||
|
//SavePanel
|
|||
|
ec_Panel panel = new ec_Panel();
|
|||
|
panel.CreateTime = resBreakers.CreateTime;
|
|||
|
panel.CreateUserID = resBreakers.CreateUserID;
|
|||
|
panel.DefaultBreakerType = DefaultBreakerType;
|
|||
|
panel.EngineerDataID = resBreakers.EngineerDataID;
|
|||
|
panel.MaxStripNumber = resBreakers.MaxStripNumber;
|
|||
|
panel.ObjectTypeName = resBreakers.ObjectTypeName;
|
|||
|
panel.PanelID = resBreakers.PanelID;
|
|||
|
panel.Panel_Loc_ID = resBreakers.Panel_Loc_ID;
|
|||
|
panel.TagNumber = resBreakers.TagNumber;
|
|||
|
panel.UpdateTime = resBreakers.UpdateTime;
|
|||
|
panel.UpdateUserID = resBreakers.UpdateUserID;
|
|||
|
panel.allowedIOTypes = resBreakers.allowedIOTypes;
|
|||
|
panel.strips = resBreakers.strips;
|
|||
|
panel.systempanel = resBreakers.systempanel;
|
|||
|
var resSavePanel = await _iOModuleService.SavePanel(panel);
|
|||
|
|
|||
|
//SaveBreakers
|
|||
|
List<ec_CircuitBreaker> circuitBreakerls = new List<ec_CircuitBreaker>();
|
|||
|
foreach (var CircuitBreakerInfo in CircuitBreakerInfos)
|
|||
|
{
|
|||
|
if (CircuitBreakerInfo.IsModified)
|
|||
|
{
|
|||
|
ec_CircuitBreaker circuitBreaker = new ec_CircuitBreaker();
|
|||
|
circuitBreaker.Name = CircuitBreakerInfo.Name;
|
|||
|
circuitBreaker.Phase = CircuitBreakerInfo.Phase;
|
|||
|
circuitBreaker.CB_Type = CircuitBreakerInfo.CB_Type;
|
|||
|
circuitBreaker.Capacity_Act = CircuitBreakerInfo.Capacity_Act;
|
|||
|
circuitBreaker.Capacity_Max = CircuitBreakerInfo.Capacity_Max;
|
|||
|
circuitBreaker.Capacity_Set = CircuitBreakerInfo.Capacity_Set;
|
|||
|
circuitBreaker.EngineerDataID = CircuitBreakerInfo.EngineerDataID;
|
|||
|
circuitBreaker.OrderId = CircuitBreakerInfo.OrderId;
|
|||
|
circuitBreakerls.Add(circuitBreaker);
|
|||
|
}
|
|||
|
}
|
|||
|
var resSaveBreaker = await _pDBService.SaveBreakers(resBreakers.EngineerDataID, circuitBreakerls);
|
|||
|
|
|||
|
//DeleteBreaker
|
|||
|
if (DeleBreakerIds.Count > 0)
|
|||
|
{
|
|||
|
var BreakerIds = string.Join(",", DeleBreakerIds);
|
|||
|
var resDele = await _pDBService.Delete(BreakerIds);
|
|||
|
}
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
public class CircuitBreakerInfo : ViewBase
|
|||
|
{
|
|||
|
#region 页面显示字段
|
|||
|
private int _Index;
|
|||
|
/// <summary>
|
|||
|
/// 序号
|
|||
|
/// </summary>
|
|||
|
public int Index
|
|||
|
{
|
|||
|
get { return _Index; }
|
|||
|
set { _Index = value; }
|
|||
|
}
|
|||
|
|
|||
|
private string _Name;
|
|||
|
/// <summary>
|
|||
|
/// 开关名字
|
|||
|
/// </summary>
|
|||
|
public string Name
|
|||
|
{
|
|||
|
get { return _Name; }
|
|||
|
set { _Name = value; }
|
|||
|
}
|
|||
|
|
|||
|
private int _Phase;
|
|||
|
/// <summary>
|
|||
|
/// 相数
|
|||
|
/// </summary>
|
|||
|
public int Phase
|
|||
|
{
|
|||
|
get { return _Phase; }
|
|||
|
set { _Phase = value; }
|
|||
|
}
|
|||
|
|
|||
|
private string _CB_Type;
|
|||
|
/// <summary>
|
|||
|
/// 分电箱类型
|
|||
|
/// 输出或输入
|
|||
|
/// </summary>
|
|||
|
public string CB_Type
|
|||
|
{
|
|||
|
get { return _CB_Type; }
|
|||
|
set { _CB_Type = value; }
|
|||
|
}
|
|||
|
private string _Capacity_Max;
|
|||
|
/// <summary>
|
|||
|
/// 额定电流
|
|||
|
/// </summary>
|
|||
|
public string Capacity_Max
|
|||
|
{
|
|||
|
get { return _Capacity_Max; }
|
|||
|
set { _Capacity_Max = value; }
|
|||
|
}
|
|||
|
private string _Capacity_Set;
|
|||
|
/// <summary>
|
|||
|
/// 整定电流
|
|||
|
/// </summary>
|
|||
|
public string Capacity_Set
|
|||
|
{
|
|||
|
get { return _Capacity_Set; }
|
|||
|
set { _Capacity_Set = value; }
|
|||
|
}
|
|||
|
private string _Capacity_Act;
|
|||
|
/// <summary>
|
|||
|
/// 实际电流
|
|||
|
/// </summary>
|
|||
|
public string Capacity_Act
|
|||
|
{
|
|||
|
get { return _Capacity_Act; }
|
|||
|
set { _Capacity_Act = value; }
|
|||
|
}
|
|||
|
private string _CableTagNumber;
|
|||
|
/// <summary>
|
|||
|
/// 电缆位号
|
|||
|
/// </summary>
|
|||
|
public string CableTagNumber
|
|||
|
{
|
|||
|
get { return _CableTagNumber; }
|
|||
|
set { _CableTagNumber = value; }
|
|||
|
}
|
|||
|
|
|||
|
private string _RemoteDeviceId;
|
|||
|
/// <summary>
|
|||
|
/// 对面的设备信息
|
|||
|
/// </summary>
|
|||
|
public string RemoteDeviceId
|
|||
|
{
|
|||
|
get { return _RemoteDeviceId; }
|
|||
|
set { _RemoteDeviceId = value; }
|
|||
|
}
|
|||
|
#endregion
|
|||
|
|
|||
|
#region 扩展字段
|
|||
|
private string _EngineerDataID;
|
|||
|
/// <summary>
|
|||
|
/// 开关工程ID
|
|||
|
/// </summary>
|
|||
|
public string EngineerDataID
|
|||
|
{
|
|||
|
get { return _EngineerDataID; }
|
|||
|
set { _EngineerDataID = value; }
|
|||
|
}
|
|||
|
|
|||
|
private int _OrderId;
|
|||
|
|
|||
|
public int OrderId
|
|||
|
{
|
|||
|
get { return _OrderId; }
|
|||
|
set { _OrderId = value; }
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
private bool _IsModified;
|
|||
|
/// <summary>
|
|||
|
/// 标记行数据是否修改
|
|||
|
/// </summary>
|
|||
|
public bool IsModified
|
|||
|
{
|
|||
|
get { return _IsModified; }
|
|||
|
set { _IsModified = value; }
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
public CircuitBreakerInfo()
|
|||
|
{
|
|||
|
|
|||
|
}
|
|||
|
public CircuitBreakerInfo(ec_CircuitBreaker ec_CircuitBreaker)
|
|||
|
{
|
|||
|
Name = ec_CircuitBreaker.Name;
|
|||
|
CB_Type = ec_CircuitBreaker.CB_Type;
|
|||
|
Phase = ec_CircuitBreaker.Phase;
|
|||
|
Capacity_Max = ec_CircuitBreaker.Capacity_Max;
|
|||
|
Capacity_Set = ec_CircuitBreaker.Capacity_Set;
|
|||
|
Capacity_Act = ec_CircuitBreaker.Capacity_Act;
|
|||
|
CableTagNumber = ec_CircuitBreaker.CableTagNumbers.FirstOrDefault();
|
|||
|
|
|||
|
EngineerDataID = ec_CircuitBreaker.EngineerDataID;
|
|||
|
OrderId = ec_CircuitBreaker.OrderId;
|
|||
|
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
}
|