修改PSL和IBP构建模型的逻辑
This commit is contained in:
parent
7a679b716c
commit
420b18fccd
@ -1 +1 @@
|
|||||||
Subproject commit 6e8fecb59b22e10c00398820076edb1a84d825ba
|
Subproject commit 63774c3fa82b3831a06d7b2b68675677d6fd5e1e
|
@ -32,7 +32,7 @@ func NewPSLMs(vs *memory.VerifySimulation, mapId int32) ms_api.MsgTask {
|
|||||||
func collectGateBoxPSLState(world ecs.World, mapId int32, box *data_proto.GatedBox) (*state_proto.PushedDevicesStatus, error) {
|
func collectGateBoxPSLState(world ecs.World, mapId int32, box *data_proto.GatedBox) (*state_proto.PushedDevicesStatus, error) {
|
||||||
did := memory.GetMapElementId(box.Common)
|
did := memory.GetMapElementId(box.Common)
|
||||||
uidStructure := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
|
uidStructure := memory.QueryUidStructure[*memory.StationUidStructure](mapId)
|
||||||
boxUid := uidStructure.GateBoxIds[did].Uid
|
boxUid := uidStructure.PslIds[did].Uid
|
||||||
mkxEntry, ok := entity.GetEntityByUid(world, boxUid)
|
mkxEntry, ok := entity.GetEntityByUid(world, boxUid)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("[id:%s]的门控箱实体找不到", boxUid)
|
return nil, fmt.Errorf("[id:%s]的门控箱实体找不到", boxUid)
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 7ec4eb44e42ff61ba906f914ffc882b210391883
|
Subproject commit 7694e092231530cbfa1d838902d802ca8c1de336
|
@ -34,8 +34,9 @@ type StationUidStructure struct {
|
|||||||
StationIds map[uint32]*elementIdStructure
|
StationIds map[uint32]*elementIdStructure
|
||||||
PlatformIds map[uint32]*elementIdStructure
|
PlatformIds map[uint32]*elementIdStructure
|
||||||
PsdIds map[uint32]*elementIdStructure
|
PsdIds map[uint32]*elementIdStructure
|
||||||
GateBoxIds map[uint32]*elementIdStructure
|
PslIds map[uint32]*elementIdStructure
|
||||||
SpksSwitchIds map[uint32]*elementIdStructure
|
SpksSwitchIds map[uint32]*elementIdStructure
|
||||||
|
IbpIds map[uint32]*elementIdStructure
|
||||||
}
|
}
|
||||||
|
|
||||||
type RelayUidStructure struct {
|
type RelayUidStructure struct {
|
||||||
@ -245,8 +246,9 @@ func initStationUid(data *data_proto.RtssGraphicStorage) *StationUidStructure {
|
|||||||
StationIds: make(map[uint32]*elementIdStructure, len(data.Stations)),
|
StationIds: make(map[uint32]*elementIdStructure, len(data.Stations)),
|
||||||
PlatformIds: make(map[uint32]*elementIdStructure, len(data.Platforms)),
|
PlatformIds: make(map[uint32]*elementIdStructure, len(data.Platforms)),
|
||||||
PsdIds: make(map[uint32]*elementIdStructure, len(data.ScreenDoors)),
|
PsdIds: make(map[uint32]*elementIdStructure, len(data.ScreenDoors)),
|
||||||
GateBoxIds: make(map[uint32]*elementIdStructure, len(data.GateBoxs)),
|
PslIds: make(map[uint32]*elementIdStructure, len(data.GateBoxs)),
|
||||||
SpksSwitchIds: make(map[uint32]*elementIdStructure, len(data.SpksSwitchs)),
|
//SpksSwitchIds: make(map[uint32]*elementIdStructure, len(data.SpksSwitchs)),
|
||||||
|
IbpIds: make(map[uint32]*elementIdStructure, len(data.IbpBoxs)),
|
||||||
}
|
}
|
||||||
city, lineId, _ := getUIdPrefix(data.UniqueIdPrefix)
|
city, lineId, _ := getUIdPrefix(data.UniqueIdPrefix)
|
||||||
// 处理车站信息
|
// 处理车站信息
|
||||||
@ -368,50 +370,58 @@ func initStationUid(data *data_proto.RtssGraphicStorage) *StationUidStructure {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 屏蔽门
|
// 屏蔽门
|
||||||
psd_station_map := make(map[uint32]string)
|
|
||||||
for _, door := range data.ScreenDoors {
|
for _, door := range data.ScreenDoors {
|
||||||
station := stationMap[platformMap[door.RefPlatformId].GetRefStationId()]
|
station := stationMap[platformMap[door.RefPlatformId].GetRefStationId()]
|
||||||
if station == nil { //线路数据有问题
|
if station == nil { //线路数据有问题
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
eid := GetMapElementId(door.Common)
|
eid := GetMapElementId(door.Common)
|
||||||
psd_station_map[eid] = station.StationName
|
|
||||||
gus.PsdIds[eid] = &elementIdStructure{
|
gus.PsdIds[eid] = &elementIdStructure{
|
||||||
CommonId: eid,
|
CommonId: eid,
|
||||||
Code: door.Code,
|
Code: door.Code,
|
||||||
Uid: GenerateElementUid(city, lineId, []string{station.StationName}, door.Code),
|
Uid: GenerateElementUid(city, lineId, []string{station.StationName}, door.Code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 门控箱
|
// PSL
|
||||||
for _, box := range data.GateBoxs {
|
for _, box := range data.PslBoxs {
|
||||||
stationName := psd_station_map[box.RefScreenDoor]
|
stationName := stationMap[platformMap[box.RefPlatformId].RefStationId].StationName
|
||||||
eid := GetMapElementId(box.Common)
|
eid := GetMapElementId(box.Common)
|
||||||
gus.GateBoxIds[eid] = &elementIdStructure{
|
gus.PslIds[eid] = &elementIdStructure{
|
||||||
CommonId: eid,
|
CommonId: eid,
|
||||||
Code: box.Code,
|
Code: box.Code,
|
||||||
Uid: GenerateElementUid(city, lineId, []string{stationName}, box.Code),
|
Uid: GenerateElementUid(city, lineId, []string{stationName}, box.Code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// SPKS人员防护
|
// IBP
|
||||||
for _, spk := range data.SpksSwitchs {
|
for _, box := range data.IbpBoxs {
|
||||||
if spk.RefStand == 0 {
|
stationName := stationMap[box.RefStationId].StationName
|
||||||
continue
|
eid := GetMapElementId(box.Common)
|
||||||
}
|
gus.IbpIds[eid] = &elementIdStructure{
|
||||||
platform := platformMap[spk.RefStand]
|
|
||||||
if platform == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
station := gus.StationIds[platform.RefStationId]
|
|
||||||
if station == nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
eid := GetMapElementId(spk.Common)
|
|
||||||
gus.SpksSwitchIds[eid] = &elementIdStructure{
|
|
||||||
CommonId: eid,
|
CommonId: eid,
|
||||||
Code: spk.Code,
|
Code: box.Code,
|
||||||
Uid: station.Uid + "_key_SPKS_" + spk.Code,
|
Uid: GenerateElementUid(city, lineId, []string{stationName}, box.Code),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//// SPKS人员防护
|
||||||
|
//for _, spk := range data.SpksSwitchs {
|
||||||
|
// if spk.RefStand == 0 {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// platform := platformMap[spk.RefStand]
|
||||||
|
// if platform == nil {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// station := gus.StationIds[platform.RefStationId]
|
||||||
|
// if station == nil {
|
||||||
|
// continue
|
||||||
|
// }
|
||||||
|
// eid := GetMapElementId(spk.Common)
|
||||||
|
// gus.SpksSwitchIds[eid] = &elementIdStructure{
|
||||||
|
// CommonId: eid,
|
||||||
|
// Code: spk.Code,
|
||||||
|
// Uid: station.Uid + "_key_SPKS_" + spk.Code,
|
||||||
|
// }
|
||||||
|
//}
|
||||||
return gus
|
return gus
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import (
|
|||||||
// 操作PSL按钮
|
// 操作PSL按钮
|
||||||
func ChangePSLButtonState(sim *VerifySimulation, mapId int32, gateBoxId uint32, btnCode string, pressDown bool) {
|
func ChangePSLButtonState(sim *VerifySimulation, mapId int32, gateBoxId uint32, btnCode string, pressDown bool) {
|
||||||
uid := QueryUidStructure[*StationUidStructure](mapId)
|
uid := QueryUidStructure[*StationUidStructure](mapId)
|
||||||
gateBoxUid := uid.GateBoxIds[gateBoxId].Uid
|
gateBoxUid := uid.PslIds[gateBoxId].Uid
|
||||||
if pressDown {
|
if pressDown {
|
||||||
fi.PressDownButton(sim.World, gateBoxUid+"_"+btnCode)
|
fi.PressDownButton(sim.World, gateBoxUid+"_"+btnCode)
|
||||||
} else {
|
} else {
|
||||||
|
@ -1002,6 +1002,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
repo.MainCoordinateSystem = storage.UniqueIdPrefix.MainCoordinateSystem
|
repo.MainCoordinateSystem = storage.UniqueIdPrefix.MainCoordinateSystem
|
||||||
axleCountingMap := make(map[uint32]*data_proto.AxleCounting)
|
axleCountingMap := make(map[uint32]*data_proto.AxleCounting)
|
||||||
uidsMap := QueryUidStructure[*StationUidStructure](mapId)
|
uidsMap := QueryUidStructure[*StationUidStructure](mapId)
|
||||||
|
//计轴
|
||||||
for _, data := range storage.AxleCountings {
|
for _, data := range storage.AxleCountings {
|
||||||
id := GetMapElementId(data.Common)
|
id := GetMapElementId(data.Common)
|
||||||
axleCountingMap[id] = data
|
axleCountingMap[id] = data
|
||||||
@ -1019,6 +1020,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
repo.CheckPoints = append(repo.CheckPoints, cp)
|
repo.CheckPoints = append(repo.CheckPoints, cp)
|
||||||
}
|
}
|
||||||
|
//区段
|
||||||
for _, data := range storage.Section {
|
for _, data := range storage.Section {
|
||||||
var turnoutUids []string
|
var turnoutUids []string
|
||||||
if data.SectionType == data_proto.Section_TurnoutPhysical {
|
if data.SectionType == data_proto.Section_TurnoutPhysical {
|
||||||
@ -1043,6 +1045,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
repo.PhysicalSections = append(repo.PhysicalSections, physicalSection)
|
repo.PhysicalSections = append(repo.PhysicalSections, physicalSection)
|
||||||
}
|
}
|
||||||
|
//道岔
|
||||||
for _, data := range storage.Turnouts {
|
for _, data := range storage.Turnouts {
|
||||||
var km *proto.Kilometer
|
var km *proto.Kilometer
|
||||||
for _, ks := range data.KilometerSystem {
|
for _, ks := range data.KilometerSystem {
|
||||||
@ -1066,6 +1069,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
repo.Turnouts = append(repo.Turnouts, turnout)
|
repo.Turnouts = append(repo.Turnouts, turnout)
|
||||||
}
|
}
|
||||||
|
//信号机
|
||||||
for _, data := range storage.Signals {
|
for _, data := range storage.Signals {
|
||||||
signal := &proto.Signal{
|
signal := &proto.Signal{
|
||||||
Id: uidsMap.SignalIds[GetMapElementId(data.Common)].Uid,
|
Id: uidsMap.SignalIds[GetMapElementId(data.Common)].Uid,
|
||||||
@ -1081,6 +1085,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
repo.Signals = append(repo.Signals, signal)
|
repo.Signals = append(repo.Signals, signal)
|
||||||
}
|
}
|
||||||
stm := make(map[string][]string)
|
stm := make(map[string][]string)
|
||||||
|
//应答器
|
||||||
for _, data := range storage.Transponders {
|
for _, data := range storage.Transponders {
|
||||||
fixedTelegram, err := hex.DecodeString(data.FixedTelegram)
|
fixedTelegram, err := hex.DecodeString(data.FixedTelegram)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -1113,9 +1118,11 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
repo.Transponders = append(repo.Transponders, responder)
|
repo.Transponders = append(repo.Transponders, responder)
|
||||||
}
|
}
|
||||||
slopeKsMap := make(map[uint32]*data_proto.SlopeKiloMarker)
|
slopeKsMap := make(map[uint32]*data_proto.SlopeKiloMarker)
|
||||||
|
//坡度公里标
|
||||||
for _, data := range storage.SlopeKiloMarker {
|
for _, data := range storage.SlopeKiloMarker {
|
||||||
slopeKsMap[GetMapElementId(data.Common)] = data
|
slopeKsMap[GetMapElementId(data.Common)] = data
|
||||||
}
|
}
|
||||||
|
//坡度
|
||||||
for _, data := range storage.Slopes {
|
for _, data := range storage.Slopes {
|
||||||
var kms []*proto.Kilometer
|
var kms []*proto.Kilometer
|
||||||
for _, id := range data.RefDeviceId {
|
for _, id := range data.RefDeviceId {
|
||||||
@ -1129,9 +1136,11 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
repo.Slopes = append(repo.Slopes, slope)
|
repo.Slopes = append(repo.Slopes, slope)
|
||||||
}
|
}
|
||||||
curveKsMap := make(map[uint32]*data_proto.CurvatureKiloMarker)
|
curveKsMap := make(map[uint32]*data_proto.CurvatureKiloMarker)
|
||||||
|
//曲度公里标
|
||||||
for _, data := range storage.CurvatureKiloMarker {
|
for _, data := range storage.CurvatureKiloMarker {
|
||||||
curveKsMap[GetMapElementId(data.Common)] = data
|
curveKsMap[GetMapElementId(data.Common)] = data
|
||||||
}
|
}
|
||||||
|
//曲度
|
||||||
for _, data := range storage.Curvatures {
|
for _, data := range storage.Curvatures {
|
||||||
var kms []*proto.Kilometer
|
var kms []*proto.Kilometer
|
||||||
for _, id := range data.RefDeviceId {
|
for _, id := range data.RefDeviceId {
|
||||||
@ -1144,6 +1153,7 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope)
|
repo.SectionalCurvatures = append(repo.SectionalCurvatures, slope)
|
||||||
}
|
}
|
||||||
|
//公里标转换
|
||||||
for _, data := range storage.KilometerConvertList {
|
for _, data := range storage.KilometerConvertList {
|
||||||
repo.KilometerConverts = append(repo.KilometerConverts, &proto.KilometerConvert{
|
repo.KilometerConverts = append(repo.KilometerConverts, &proto.KilometerConvert{
|
||||||
KmA: convertKm(data.KmA),
|
KmA: convertKm(data.KmA),
|
||||||
@ -1165,11 +1175,13 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
relateMap[data.Code] = data
|
relateMap[data.Code] = data
|
||||||
}
|
}
|
||||||
// 处理车站信息
|
// 处理车站信息
|
||||||
|
repoStationMap := make(map[uint32]*proto.Station)
|
||||||
for _, data := range storage.Stations {
|
for _, data := range storage.Stations {
|
||||||
station := &proto.Station{
|
station := &proto.Station{
|
||||||
Id: uidsMap.StationIds[GetMapElementId(data.Common)].Uid,
|
Id: uidsMap.StationIds[GetMapElementId(data.Common)].Uid,
|
||||||
Code: data.StationName,
|
Code: data.StationName,
|
||||||
}
|
}
|
||||||
|
repoStationMap[GetMapElementId(data.Common)] = station
|
||||||
// 关联车站的设备
|
// 关联车站的设备
|
||||||
refs, ok := relateMap[station.Code]
|
refs, ok := relateMap[station.Code]
|
||||||
if ok {
|
if ok {
|
||||||
@ -1190,8 +1202,8 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
station.ElectronicGroup = append(station.ElectronicGroup, group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 处理车站关联IBP的设备
|
//// 处理车站关联IBP的设备
|
||||||
handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
|
//handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
|
||||||
repo.Stations = append(repo.Stations, station)
|
repo.Stations = append(repo.Stations, station)
|
||||||
// 处理集中站的信息
|
// 处理集中站的信息
|
||||||
if stm[station.Code] != nil {
|
if stm[station.Code] != nil {
|
||||||
@ -1199,15 +1211,48 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
ref.TransponderId = append(ref.TransponderId, stm[station.Code]...)
|
ref.TransponderId = append(ref.TransponderId, stm[station.Code]...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//门控箱
|
//站台
|
||||||
for _, data := range storage.GateBoxs {
|
platformMap := make(map[uint32]*data_proto.Platform)
|
||||||
boxUidInfo := uidsMap.GateBoxIds[GetMapElementId(data.Common)]
|
for _, data := range storage.Platforms {
|
||||||
|
platformId := GetMapElementId(data.Common)
|
||||||
|
platformMap[platformId] = data
|
||||||
|
platform := &proto.Platform{
|
||||||
|
Id: uidsMap.PlatformIds[platformId].Uid,
|
||||||
|
Code: data.Code,
|
||||||
|
}
|
||||||
|
repo.Platforms = append(repo.Platforms, platform)
|
||||||
|
platform.StationId = uidsMap.StationIds[data.RefStationId].Uid
|
||||||
|
platform.PhysicalSectionId = uidsMap.PhysicalSectionIds[data.RefSectionId].Uid
|
||||||
|
}
|
||||||
|
//屏蔽门
|
||||||
|
platformId_psdUid_map := make(map[uint32]string)
|
||||||
|
for _, data := range storage.ScreenDoors {
|
||||||
|
var asdGroups []*proto.AsdGroup
|
||||||
|
for _, group := range storage.ScreenDoorConfig.ScreenDoorGroupList {
|
||||||
|
asdGroups = append(asdGroups, &proto.AsdGroup{
|
||||||
|
Group: group.TrainGroupAmount,
|
||||||
|
Start: group.StartSmallDoor,
|
||||||
|
End: group.EndSmallDoor,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
psd := &proto.Psd{
|
||||||
|
Id: uidsMap.PsdIds[GetMapElementId(data.Common)].Uid,
|
||||||
|
AsdAmount: storage.ScreenDoorConfig.SonDoorAmount,
|
||||||
|
AsdGroups: asdGroups,
|
||||||
|
PlatformId: uidsMap.PlatformIds[data.RefPlatformId].Uid,
|
||||||
|
}
|
||||||
|
platformId_psdUid_map[data.GetRefPlatformId()] = psd.Id
|
||||||
|
repo.Psds = append(repo.Psds, psd)
|
||||||
|
}
|
||||||
|
//PSL
|
||||||
|
for _, data := range storage.PslBoxs {
|
||||||
|
boxUidInfo := uidsMap.PslIds[GetMapElementId(data.Common)]
|
||||||
mkx := &proto.Mkx{
|
mkx := &proto.Mkx{
|
||||||
Id: boxUidInfo.Uid,
|
Id: boxUidInfo.Uid,
|
||||||
PsdId: uidsMap.PsdIds[data.RefScreenDoor].Uid,
|
PsdId: platformId_psdUid_map[data.RefPlatformId],
|
||||||
}
|
}
|
||||||
repo.Mkxs = append(repo.Mkxs, mkx)
|
repo.Mkxs = append(repo.Mkxs, mkx)
|
||||||
_, pslStorage := QueryGiDataByName[*data_proto.PslGraphicStorage](data.RefGatedBoxMapCode)
|
_, pslStorage := QueryGiDataByName[*data_proto.PslGraphicStorage](data.RefPslMapCode)
|
||||||
for _, button := range pslStorage.PslButtons {
|
for _, button := range pslStorage.PslButtons {
|
||||||
repoButton := &proto.Button{
|
repoButton := &proto.Button{
|
||||||
Id: boxUidInfo.Uid + "_" + button.Code,
|
Id: boxUidInfo.Uid + "_" + button.Code,
|
||||||
@ -1244,36 +1289,10 @@ func fillProtoRepository(repo *proto.Repository, storage *data_proto.RtssGraphic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//站台
|
//IBP
|
||||||
platformMap := make(map[uint32]*data_proto.Platform)
|
for _, data := range storage.IbpBoxs {
|
||||||
for _, data := range storage.Platforms {
|
station := repoStationMap[data.RefStationId]
|
||||||
platformId := GetMapElementId(data.Common)
|
handlerIBPDeviceToStation(station, repo, data.RefIbpMapCode)
|
||||||
platformMap[platformId] = data
|
|
||||||
platform := &proto.Platform{
|
|
||||||
Id: uidsMap.PlatformIds[platformId].Uid,
|
|
||||||
Code: data.Code,
|
|
||||||
}
|
|
||||||
repo.Platforms = append(repo.Platforms, platform)
|
|
||||||
platform.StationId = uidsMap.StationIds[data.RefStationId].Uid
|
|
||||||
platform.PhysicalSectionId = uidsMap.PhysicalSectionIds[data.RefSectionId].Uid
|
|
||||||
}
|
|
||||||
//屏蔽门
|
|
||||||
for _, data := range storage.ScreenDoors {
|
|
||||||
var asdGroups []*proto.AsdGroup
|
|
||||||
for _, group := range storage.ScreenDoorConfig.ScreenDoorGroupList {
|
|
||||||
asdGroups = append(asdGroups, &proto.AsdGroup{
|
|
||||||
Group: group.TrainGroupAmount,
|
|
||||||
Start: group.StartSmallDoor,
|
|
||||||
End: group.EndSmallDoor,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
psd := &proto.Psd{
|
|
||||||
Id: uidsMap.PsdIds[GetMapElementId(data.Common)].Uid,
|
|
||||||
AsdAmount: storage.ScreenDoorConfig.SonDoorAmount,
|
|
||||||
AsdGroups: asdGroups,
|
|
||||||
PlatformId: uidsMap.PlatformIds[data.RefPlatformId].Uid,
|
|
||||||
}
|
|
||||||
repo.Psds = append(repo.Psds, psd)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user