709 lines
22 KiB
C#
709 lines
22 KiB
C#
using Step.Model.DatabaseModels;
|
|
using Step.Model.DTOModels.ToolModels;
|
|
using Step.Utils;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Data.Entity;
|
|
using System.Linq;
|
|
using static Step.Utils.SupportFunctions;
|
|
using static Step.Model.Constants;
|
|
|
|
namespace Step.Database.Controllers
|
|
{
|
|
public class NcToolManagerController : IDisposable
|
|
{
|
|
public DatabaseContext dbCtx;
|
|
|
|
public NcToolManagerController()
|
|
{
|
|
// Initialize database context
|
|
dbCtx = new DatabaseContext();
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
// Clear database context
|
|
dbCtx.Dispose();
|
|
}
|
|
|
|
public List<DbNcFamilyModel> FindFamilies()
|
|
{
|
|
List<DbNcFamilyModel> families = dbCtx
|
|
.Families
|
|
.Include("Tools")
|
|
.ToList();
|
|
|
|
return families;
|
|
}
|
|
|
|
public List<DTONcFamilyModel> GetFamilies()
|
|
{
|
|
List<DbNcFamilyModel> dbFamilies = FindFamilies();
|
|
|
|
return dbFamilies
|
|
.Select(x => (DTONcFamilyModel)x)
|
|
.ToList();
|
|
}
|
|
|
|
public List<DbNcFamilyModel> FindFamiliesByShankId(int shankId)
|
|
{
|
|
DbNcShankModel shank = FindShankWithTools(shankId);
|
|
// Get only families id
|
|
short[] ids = shank.Tools.Select(x => x.FamilyId).ToArray();
|
|
|
|
return FindFamilies() // Get Families
|
|
.Where(x => ids.Contains(x.FamilyId)) // Filter by ids
|
|
.ToList();
|
|
}
|
|
|
|
public DbNcToolModel FindTool(int toolId)
|
|
{
|
|
return dbCtx.Tools
|
|
.Where(x => x.ToolId == toolId)
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public DbNcToolModel FindToolWithDependencies(int toolId)
|
|
{
|
|
return dbCtx.Tools
|
|
.Where(x => x.ToolId == toolId)
|
|
.Include("Family")
|
|
.Include("Shank")
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public DbNcShankModel FindShankWithTools(int shankId)
|
|
{
|
|
return dbCtx.Shanks
|
|
.Include("Tools")
|
|
.Where(x => x.ShankId == shankId)
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public DbNcFamilyModel FindFamily(int familyId)
|
|
{
|
|
return dbCtx
|
|
.Families
|
|
.Where(x => x.FamilyId == familyId)
|
|
.Include("Tools")
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public List<DbNcToolModel> FindToolsWithDependencies()
|
|
{
|
|
List<DbNcToolModel> tools = dbCtx
|
|
.Tools
|
|
.Include("Family")
|
|
.Include("Shank")
|
|
.ToList();
|
|
|
|
return tools;
|
|
}
|
|
|
|
public List<DbNcToolModel> FindToolsByShankIdWithDependencies(int shankId)
|
|
{
|
|
List<DbNcToolModel> tools = FindToolsWithDependencies()
|
|
.Where(x => x.ShankId == shankId)
|
|
.ToList();
|
|
|
|
return tools;
|
|
}
|
|
|
|
public List<DbNcToolModel> FindTools()
|
|
{
|
|
List<DbNcToolModel> tools = dbCtx
|
|
.Tools
|
|
.ToList();
|
|
|
|
return tools;
|
|
}
|
|
|
|
public List<DTONcToolModel> GetTools()
|
|
{
|
|
List<DbNcToolModel> dbTools = FindToolsWithDependencies();
|
|
|
|
return dbTools
|
|
.Select(x => (DTONcToolModel)x)
|
|
.ToList();
|
|
}
|
|
|
|
public List<DbNcShankModel> FindShanks()
|
|
{
|
|
List<DbNcShankModel> shanks = dbCtx
|
|
.Shanks
|
|
.Include("MagazinePosition")
|
|
.ToList();
|
|
|
|
return shanks;
|
|
}
|
|
|
|
public DbNcShankModel FindShank(int shankId)
|
|
{
|
|
return dbCtx.Shanks
|
|
.Where(x => x.ShankId == shankId)
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public DbNcShankModel FindShanksByPositions(int magazineId, int positionId)
|
|
{
|
|
DbNcShankModel shank = FindShanks()
|
|
.Where(x => x.MagazineId == magazineId && x.PositionId == positionId)
|
|
.FirstOrDefault();
|
|
|
|
return shank;
|
|
}
|
|
|
|
public List<DbNcShankModel> FindShanksByFamilyId(int familyId)
|
|
{
|
|
return dbCtx
|
|
.Tools
|
|
.Include("Shank")
|
|
.Where(x => x.FamilyId == familyId && x.ShankId != null)
|
|
.Select(x => x.Shank)
|
|
.ToList();
|
|
}
|
|
|
|
public DbNcShankModel FindShankByToolId(int toolId)
|
|
{
|
|
return dbCtx
|
|
.Tools
|
|
.Include("Shank")
|
|
.Where(x => x.ToolId == toolId && x.ShankId != null)
|
|
.Select(x => x.Shank)
|
|
.FirstOrDefault();
|
|
}
|
|
|
|
public List<DTONcShankModel> GetShanks()
|
|
{
|
|
// Get shank from database
|
|
List<DbNcShankModel> dbShanks = dbCtx
|
|
.Shanks
|
|
.Include("Tools")
|
|
.ToList();
|
|
|
|
// Populate dto shanks
|
|
List<DTONcShankModel> dtoShanks = dbShanks
|
|
.Select(x => (DTONcShankModel)x)
|
|
.ToList();
|
|
|
|
return dtoShanks;
|
|
}
|
|
|
|
public List<DTONcShankModel> GetShanksWithSpace()
|
|
{
|
|
// Populate nks
|
|
List<DTONcShankModel> dtoShanks = GetShanks();
|
|
|
|
List<DTONcFamilyModel> dtoFamilies = GetFamilies();
|
|
|
|
// Calculate & set space occupied for each shank
|
|
foreach(var shank in dtoShanks)
|
|
{
|
|
// Get only families id
|
|
short[] ids = shank.ChildsTools.Select(x => x.FamilyId).ToArray();
|
|
|
|
// Get Families data
|
|
List<DTONcFamilyModel> families = dtoFamilies
|
|
.Where(x => ids.Contains(x.Id))
|
|
.ToList();
|
|
|
|
if (families.Count() > 0)
|
|
{
|
|
// Find max between families
|
|
shank.MaxRight = families.Max(x => x.RightSize);
|
|
shank.MaxLeft = families.Max(x => x.LeftSize);
|
|
}
|
|
}
|
|
|
|
return dtoShanks;
|
|
}
|
|
|
|
public DTONcShankModel GetShank(int shankId)
|
|
{
|
|
// Get shank from database
|
|
DTONcShankModel dtoShanks = GetShanksWithSpace()
|
|
.Where(x => x.Id == shankId)
|
|
.FirstOrDefault();
|
|
|
|
return dtoShanks;
|
|
}
|
|
|
|
public List<DbNcMagazinePositionModel> FindMagazinesPositions()
|
|
{
|
|
List<DbNcMagazinePositionModel> positions = dbCtx
|
|
.MagazinePositions
|
|
.ToList();
|
|
|
|
return positions;
|
|
}
|
|
|
|
public List<DbNcMagazinePositionModel> FindMagazinePositions(byte magId)
|
|
{
|
|
return dbCtx
|
|
.MagazinePositions
|
|
.Where(x => x.MagazineId == magId)
|
|
.ToList();
|
|
}
|
|
|
|
public void GetShankMaxSpaceOccupied(int shankId, out int maxRight, out int maxLeft)
|
|
{
|
|
// Get families
|
|
List<DbNcFamilyModel> families = FindFamiliesByShankId(shankId);
|
|
// Find max
|
|
maxRight = families.Max(x => x.RightSize);
|
|
maxLeft = families.Max(x => x.LeftSize);
|
|
}
|
|
|
|
public List<DTONcMagazinePositionModel> GetMagazinePositions(byte magId)
|
|
{
|
|
// Get only magazine positions that match with magazineId
|
|
List<DTONcMagazinePositionModel> magPos = FindMagazinePositions(magId).Select(x => (DTONcMagazinePositionModel)x).ToList();
|
|
// Get&filter shanks by magazineId in order to get only mounted shanks in the current magazineId
|
|
List<DbNcShankModel> shanks = dbCtx.Shanks.Where(x => x.MagazineId == magId || x.OriginMagazineId == magId).ToList();
|
|
|
|
foreach(DbNcShankModel shank in shanks)
|
|
{
|
|
DTONcMagazinePositionModel pos = null;
|
|
|
|
// Populate magazinePosition shank Id, check actual position and origin position
|
|
if(shank.MagazineId == magId)
|
|
pos = magPos // Actual case
|
|
.FirstOrDefault(x => x.PositionId == shank.PositionId);
|
|
else
|
|
pos = magPos // Origin case
|
|
.FirstOrDefault(x => x.PositionId == shank.OriginPositionId);
|
|
|
|
if (pos != null)
|
|
pos.ShankId = shank.ShankId;
|
|
}
|
|
// Convert in DTOModel and return
|
|
return magPos;
|
|
}
|
|
|
|
public DbNcMagazinePositionModel FindMagazinePosition(byte magId, ushort posId)
|
|
{
|
|
DbNcMagazinePositionModel positions = dbCtx
|
|
.MagazinePositions
|
|
.FirstOrDefault(x => x.MagazineId == magId && x.PositionId == posId);
|
|
|
|
return positions;
|
|
}
|
|
|
|
public List<DTONcShankModel> GetMountedShanks(int magazineId)
|
|
{
|
|
List<DTONcShankModel> dtoShanks = GetShanksWithSpace()
|
|
.Where(x =>
|
|
(x.MagazineId != null && x.MagazineId == magazineId) ||
|
|
(x.OriginMagazineId != null && x.OriginMagazineId == magazineId))
|
|
.ToList();
|
|
|
|
return dtoShanks;
|
|
}
|
|
|
|
public List<DbNcToolModel> GetMountedTools()
|
|
{
|
|
List<DbNcToolModel> tools = FindToolsWithDependencies()
|
|
.Where(x => x.Shank != null && x.Shank.MagazineId != null)
|
|
.ToList();
|
|
|
|
return tools;
|
|
}
|
|
|
|
public List<DTONcShankModel> GetAvailableShanksWithChilds()
|
|
{
|
|
List<DTONcShankModel> dtoShanks = GetShanksWithSpace()
|
|
.Where(x => x.MagazineId == null && x.ChildsTools.Count > 0)
|
|
.ToList();
|
|
|
|
return dtoShanks;
|
|
}
|
|
|
|
public List<DTONcToolModel> GetAvailableTools()
|
|
{
|
|
List<DTONcToolModel> dtoTools = GetTools()
|
|
.Where(x => x.ShankId == null || x.ShankId == 0)
|
|
.ToList();
|
|
|
|
return dtoTools;
|
|
}
|
|
|
|
public DbNcToolModel AddTool(DTONewNcToolModel dtoTool, short toolId)
|
|
{
|
|
// Copy data
|
|
DbNcToolModel dbTool = (DbNcToolModel)dtoTool;
|
|
|
|
if (toolId == 0)
|
|
// Get next id
|
|
dbTool.ToolId = GetFirstFreeId(dbCtx.Tools.Select(x => x.ToolId).ToList());
|
|
else
|
|
dbTool.ToolId = toolId;
|
|
|
|
dbCtx.Tools.Add(dbTool);
|
|
|
|
dbCtx.SaveChanges();
|
|
// Get foreign key data
|
|
dbCtx.Entry(dbTool).Reference(x => x.Family).Load();
|
|
dbCtx.Entry(dbTool).Reference(x => x.Shank).Load();
|
|
|
|
return dbTool;
|
|
}
|
|
|
|
public DbNcToolModel UpdateTool(int toolId, DTONewNcToolModel dtoTool)
|
|
{
|
|
DbNcToolModel tool = FindTool(toolId);
|
|
|
|
tool.Status = ((DbNcToolModel)dtoTool).Status;
|
|
var shankId = tool.ShankId;
|
|
|
|
// Update db model
|
|
SupportFunctions.CopyProperties(dtoTool, tool);
|
|
tool.ShankId = shankId;
|
|
|
|
// Save
|
|
dbCtx.SaveChanges();
|
|
|
|
return tool;
|
|
}
|
|
|
|
public DbNcToolModel UpdateToolOffset(int toolId, int position, short offsetId)
|
|
{
|
|
DbNcToolModel tool = FindTool(toolId);
|
|
|
|
switch (position)
|
|
{
|
|
case 1:
|
|
tool.OffsetId1 = offsetId;
|
|
break;
|
|
case 2:
|
|
tool.OffsetId2 = offsetId;
|
|
break;
|
|
case 3:
|
|
tool.OffsetId3 = offsetId;
|
|
break;
|
|
}
|
|
|
|
// Save
|
|
dbCtx.SaveChanges();
|
|
|
|
return tool;
|
|
}
|
|
|
|
public void DeleteTool(int toolId)
|
|
{
|
|
DbNcToolModel tool = FindTool(toolId);
|
|
if(tool != null)
|
|
DeleteTool(tool);
|
|
}
|
|
|
|
public void DeleteTool(DbNcToolModel tool)
|
|
{
|
|
dbCtx.Tools.Remove(tool);
|
|
|
|
dbCtx.SaveChanges();
|
|
}
|
|
|
|
public DbNcFamilyModel AddFamily(DTONcFamilyModel family)
|
|
{
|
|
DbNcFamilyModel dbFamily = (DbNcFamilyModel)family;
|
|
|
|
// Get next free id if id is 0
|
|
if (dbFamily.FamilyId == 0)
|
|
dbFamily.FamilyId = GetFirstFreeId(dbCtx.Families.Select(x => x.FamilyId).ToList());
|
|
|
|
dbFamily.Name = DEFAULT_FAM_NAME + dbFamily.FamilyId;
|
|
dbCtx.Families.Add(dbFamily);
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return dbFamily;
|
|
}
|
|
|
|
public DbNcFamilyModel UpdateFamily(int familyId, DTONewNcFamilyModel family)
|
|
{
|
|
DbNcFamilyModel dbFamily = FindFamily(familyId);
|
|
// Copy data from NewModel to DbModel
|
|
SupportFunctions.CopyProperties(family, dbFamily);
|
|
// Set cooling byte
|
|
dbFamily.CoolingByte = ((DbNcFamilyModel)family).CoolingByte;
|
|
|
|
dbCtx.SaveChanges();
|
|
// Connect tools data
|
|
dbCtx.Entry(dbFamily).Collection(x => x.Tools).Load();
|
|
|
|
return dbFamily;
|
|
}
|
|
|
|
public void DeleteFamily(int famId)
|
|
{
|
|
var family = FindFamily(famId);
|
|
|
|
dbCtx.Families.Remove(family);
|
|
|
|
dbCtx.SaveChanges();
|
|
}
|
|
|
|
public DbNcShankModel AddShank(DTONewNcShankModel shank, short shankId = 0)
|
|
{
|
|
DbNcShankModel dbShank = (DbNcShankModel)shank;
|
|
|
|
if (shankId == 0)
|
|
// Get next id
|
|
dbShank.ShankId = GetFirstFreeId(dbCtx.Shanks.Select(x => x.ShankId).ToList());
|
|
else
|
|
dbShank.ShankId = shankId;
|
|
|
|
dbCtx.Shanks.Add(dbShank);
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
|
|
return dbShank;
|
|
}
|
|
|
|
public DbNcShankModel UpdateShank(int shankId, DTONewNcShankModel dtoShank)
|
|
{
|
|
DbNcShankModel ncShank = FindShankWithTools(shankId);
|
|
|
|
return UpdateShank(ncShank, dtoShank);
|
|
}
|
|
|
|
public DbNcShankModel UpdateShank(DbNcShankModel dbShank, DTONewNcShankModel dtoShank)
|
|
{
|
|
dbShank.Balluf = dtoShank.Balluf;
|
|
dbShank.MagazinePositionType = dtoShank.MagazinePositionType;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
dbCtx.Entry(dbShank).Collection(x => x.Tools).Load();
|
|
|
|
return dbShank;
|
|
}
|
|
|
|
public DbNcShankModel DeleteNcShank(int shankId)
|
|
{
|
|
DbNcShankModel shank = FindShankWithTools(shankId);
|
|
DeleteNcShank(shank);
|
|
|
|
return shank;
|
|
}
|
|
|
|
public void DeleteNcShank(DbNcShankModel shank)
|
|
{
|
|
dbCtx.Shanks.Remove(shank);
|
|
|
|
dbCtx.SaveChanges();
|
|
}
|
|
|
|
public DbNcMagazinePositionModel UpdatePosition(DbNcMagazinePositionModel dbPos, DTONcMagazinePositionModel dtoPos)
|
|
{
|
|
dbCtx.MagazinePositions.Attach(dbPos);
|
|
dbPos.Type = dtoPos.Type;
|
|
dbPos.Disabled = dtoPos.Disabled;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return dbPos;
|
|
}
|
|
|
|
public DbNcMagazinePositionModel LoadShankInMagazine(byte magazineId, ushort positionId, DbNcShankModel shank)
|
|
{
|
|
dbCtx.Shanks.Attach(shank);
|
|
// Set ids with new positions
|
|
shank.MagazineId = magazineId;
|
|
shank.PositionId = positionId;
|
|
|
|
// Set original Ids
|
|
shank.OriginMagazineId = magazineId;
|
|
shank.OriginPositionId = positionId;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return FindMagazinePosition(magazineId, positionId);
|
|
}
|
|
|
|
public DbNcMagazinePositionModel LoadShankInMagazineWithoutOrigin(byte magazineId, ushort positionId, DbNcShankModel shank)
|
|
{
|
|
dbCtx.Shanks.Attach(shank);
|
|
// Set ids with new positions
|
|
shank.MagazineId = magazineId;
|
|
shank.PositionId = positionId;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return FindMagazinePosition(magazineId, positionId);
|
|
}
|
|
|
|
public DbNcMagazinePositionModel UnloadShankInMagazine(byte magazineId, ushort positionId, DbNcShankModel shank)
|
|
{
|
|
dbCtx.Shanks.Attach(shank);
|
|
// set id to null
|
|
shank.MagazineId = null;
|
|
shank.PositionId = null;
|
|
|
|
shank.OriginMagazineId = null;
|
|
shank.OriginPositionId = null;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return FindMagazinePosition(magazineId, positionId);
|
|
}
|
|
|
|
public DTONcShankModel LoadToolIntoShank(DbNcToolModel tool, short shankId)
|
|
{
|
|
dbCtx.Tools.Attach(tool);
|
|
// Set tool shankId
|
|
tool.ShankId = shankId;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return GetShank(shankId);
|
|
}
|
|
|
|
public DTONcShankModel UnloadToolFromShank(DbNcToolModel tool)
|
|
{
|
|
dbCtx.Tools.Attach(tool);
|
|
int? shankId = tool.ShankId;
|
|
// Set to null shankId
|
|
tool.ShankId = null;
|
|
|
|
dbCtx.SaveChanges();
|
|
|
|
return GetShank(shankId.Value);
|
|
}
|
|
|
|
public void SetupMagazinePositions(List<DbNcMagazinePositionModel> config)
|
|
{
|
|
dbCtx.MagazinePositions.AddRange(config);
|
|
dbCtx.SaveChanges();
|
|
}
|
|
|
|
public void UpdateToolsData(List<DbNcToolModel> tools)
|
|
{
|
|
foreach (var tool in tools)
|
|
{
|
|
DbNcToolModel tmpTool = dbCtx.Tools.Where(x => x.ToolId == tool.ToolId).FirstOrDefault();
|
|
tmpTool = tool;
|
|
}
|
|
|
|
dbCtx.SaveChanges();
|
|
}
|
|
|
|
public DTOExportToolTableModel GetExportData()
|
|
{
|
|
return new DTOExportToolTableModel
|
|
{
|
|
Tools = FindTools(),
|
|
Families = FindFamilies(),
|
|
Shanks = FindShanks()
|
|
.Select(x => {
|
|
// Reset positional Data
|
|
x.MagazineId = null;
|
|
x.PositionId = null;
|
|
x.OriginMagazineId = null;
|
|
x.OriginPositionId = null;
|
|
|
|
return x; })
|
|
.ToList()
|
|
};
|
|
}
|
|
|
|
public List<DTOImportStatusModel> ImportData(DTOExportToolTableModel data)
|
|
{
|
|
List<DTOImportStatusModel> importStatus = new List<DTOImportStatusModel>();
|
|
|
|
List<DbNcToolModel> tools = FindTools();
|
|
List<DbNcFamilyModel> families = FindFamilies();
|
|
List<DbNcShankModel> shanks = FindShanks();
|
|
|
|
var positions = FindMagazinesPositions();
|
|
if (positions.Count() == 0)
|
|
return new List<DTOImportStatusModel>();
|
|
|
|
if(data.Families != null)
|
|
// loop thought new families
|
|
foreach (var family in data.Families)
|
|
{
|
|
// Check if not exist
|
|
if (families.FirstOrDefault(x => x.FamilyId == family.FamilyId) == null)
|
|
{
|
|
dbCtx.Families.Add(family);
|
|
// Set status
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = family.FamilyId,
|
|
Status = IMPORT_STATUS.OK.ToString(),
|
|
Type = "FAMILY"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
// Set duplicated status
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = family.FamilyId,
|
|
Status = IMPORT_STATUS.EXIST.ToString(),
|
|
Type = "FAMILY"
|
|
});
|
|
}
|
|
}
|
|
|
|
if(data.Shanks != null)
|
|
// loop thought new shanks
|
|
foreach (var shank in data.Shanks)
|
|
{
|
|
// Check if not exist
|
|
if (shanks.FirstOrDefault(x => x.ShankId == shank.ShankId) == null)
|
|
{
|
|
dbCtx.Shanks.Add(shank);
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = shank.ShankId,
|
|
Status = IMPORT_STATUS.OK.ToString(),
|
|
Type = "SHANK"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = shank.ShankId,
|
|
Status = IMPORT_STATUS.EXIST.ToString(),
|
|
Type = "SHANK"
|
|
});
|
|
}
|
|
}
|
|
|
|
if(data.Tools != null)
|
|
// loop thought new tools
|
|
foreach (var tool in data.Tools)
|
|
{
|
|
// Check if not exist
|
|
if (tools.FirstOrDefault(x => x.ToolId == tool.ToolId) == null)
|
|
{
|
|
dbCtx.Tools.Add(tool);
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = tool.ToolId,
|
|
Status = IMPORT_STATUS.EXIST.ToString(),
|
|
Type = "TOOL"
|
|
});
|
|
}
|
|
else
|
|
{
|
|
importStatus.Add(new DTOImportStatusModel()
|
|
{
|
|
Id = tool.ToolId,
|
|
Status = IMPORT_STATUS.EXIST.ToString(),
|
|
Type = "TOOL"
|
|
});
|
|
}
|
|
}
|
|
|
|
// Save
|
|
dbCtx.SaveChanges();
|
|
|
|
return importStatus;
|
|
}
|
|
|
|
}
|
|
} |