feat: 통합 세력 장수/암행부 페이지 (#213)
- ag-grid 기반 - 컬럼 사용자 정의 기능 제공 - 컬럼 재정렬, 고정, 정렬 기능 - 컬럼 상태 저장, 불러오기 - 마지막 컬럼 재 사용 - 아이콘, 장수명 클릭 시 특수 기능 제공 - 기본 세력 장수/암행부에서는 '감찰부' - 추가 컬럼 - 최근 전투 - 전투 수 - 승리 수 - 살상률 - API/Nation/GeneralList 추가 Co-authored-by: hide_d <hided62@gmail.com> Reviewed-on: https://storage.hided.net/gitea/devsam/core/pulls/213
This commit is contained in:
+115
-3
@@ -1,5 +1,117 @@
|
||||
import type { ValidResponse } from "@/defs";
|
||||
import type { ValuesOf, TurnObj } from "@/defs";
|
||||
import type { GameObjClassKey } from "@/defs/GameObj";
|
||||
import type { ValidResponse } from "@/SammoAPI";
|
||||
|
||||
export type SetBlockWarResponse = ValidResponse & {
|
||||
availableCnt: number;
|
||||
};
|
||||
availableCnt: number;
|
||||
};
|
||||
|
||||
export type GeneralListItemP0 = {
|
||||
no: number,
|
||||
name: string,
|
||||
nation: number,
|
||||
npc: number,
|
||||
injury: number,
|
||||
leadership: number,
|
||||
strength: number,
|
||||
intel: number,
|
||||
explevel: number,
|
||||
dedlevel: number,
|
||||
gold: number,
|
||||
rice: number,
|
||||
killturn: number,
|
||||
picture: string,
|
||||
imgsvr: 0 | 1,
|
||||
age: number,
|
||||
specialDomestic: GameObjClassKey,
|
||||
specialWar: GameObjClassKey,
|
||||
personal: GameObjClassKey,
|
||||
belong: number,
|
||||
connect: number,
|
||||
|
||||
officerLevel: number, //권한에따라 태수,군사,시종 노출 여부가 다름
|
||||
officerLevelText: string,
|
||||
lbonus: number,
|
||||
ownerName: string | null, //NPC 출력용에 따라 결과가 다름
|
||||
honorText: string,
|
||||
dedLevelText: string,
|
||||
bill: number,
|
||||
reservedCommand: TurnObj[] | null,
|
||||
|
||||
autorun_limit: number,
|
||||
}
|
||||
|
||||
export type GeneralListItemP1 = {
|
||||
city: number,
|
||||
experience: number,
|
||||
dedication: number,
|
||||
} & GeneralListItemP0;
|
||||
|
||||
export type GeneralListItemP2 = GeneralListItemP1 & {
|
||||
officer_level: number,
|
||||
officer_city: number,
|
||||
defence_train: number,
|
||||
troop: number,
|
||||
crewtype: GameObjClassKey,
|
||||
crew: number,
|
||||
train: number,
|
||||
atmos: number,
|
||||
turntime: string,
|
||||
recent_war: string,
|
||||
horse: GameObjClassKey,
|
||||
weapon: GameObjClassKey,
|
||||
book: GameObjClassKey,
|
||||
item: GameObjClassKey,
|
||||
|
||||
warnum: number,
|
||||
killnum: number,
|
||||
deathnum: number,
|
||||
killcrew: number,
|
||||
deathcrew: number,
|
||||
firenum: number,
|
||||
}
|
||||
|
||||
export type RawGeneralListItem = GeneralListItemP0 | GeneralListItemP1 | GeneralListItemP2;
|
||||
|
||||
export type GeneralListItem =
|
||||
(GeneralListItemP0 & { st0: true, st1: false, st2: false, permission: 0 }) |
|
||||
(GeneralListItemP1 & { st0: true, st1: true, st2: false, permission: 1 }) |
|
||||
(GeneralListItemP2 & { st0: true, st1: true, st2: true, permission: 2 | 3 | 4 });
|
||||
|
||||
type ResponseEnv = {
|
||||
year: number,
|
||||
month: number,
|
||||
turntime: string,
|
||||
turnterm: number,
|
||||
killturn: number,
|
||||
autorun_user?: {
|
||||
limit_minutes: number,
|
||||
options: Record<string, number>,
|
||||
}
|
||||
}
|
||||
|
||||
export type RawGeneralListP0 = ValidResponse & {
|
||||
permission: 0,
|
||||
column: (keyof GeneralListItemP0)[],
|
||||
list: ValuesOf<GeneralListItemP0>[][],
|
||||
troops?: null,
|
||||
env: ResponseEnv,
|
||||
}
|
||||
|
||||
export type RawGeneralListP1 = ValidResponse & {
|
||||
permission: 1,
|
||||
column: (keyof GeneralListItemP1)[],
|
||||
list: ValuesOf<GeneralListItemP1>[][],
|
||||
troops?: null,
|
||||
env: ResponseEnv,
|
||||
}
|
||||
|
||||
export type RawGeneralListP2 = ValidResponse & {
|
||||
permission: 2 | 3 | 4,
|
||||
column: (keyof GeneralListItemP2)[],
|
||||
list: ValuesOf<GeneralListItemP2>[][],
|
||||
troops: [number, string][],
|
||||
env: ResponseEnv,
|
||||
}
|
||||
|
||||
export type GeneralListResponse = RawGeneralListP0 | RawGeneralListP1 | RawGeneralListP2;
|
||||
|
||||
@@ -203,7 +203,7 @@ export type GameCityDefault = {
|
||||
path: Record<CityID, string>;
|
||||
};
|
||||
|
||||
export type GameIActionCategory = "nationType" | "specialDomestic" | "specialWar" | "personality" | "item";
|
||||
export type GameIActionCategory = "nationType" | "specialDomestic" | "specialWar" | "personality" | "item" | "crewtype";
|
||||
|
||||
export type GameIActionInfo = {
|
||||
value: string;
|
||||
|
||||
@@ -0,0 +1,635 @@
|
||||
import type { ColumnState } from "ag-grid-community";
|
||||
|
||||
export type GridDisplaySetting = {
|
||||
column: ColumnState[];
|
||||
columnGroup: {
|
||||
groupId: string;
|
||||
open: boolean;
|
||||
}[];
|
||||
};
|
||||
export const defaultDisplaySetting: Record<"war" | "normal", GridDisplaySetting> = {
|
||||
war: {
|
||||
column: [
|
||||
{
|
||||
colId: "icon",
|
||||
width: 80,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "name",
|
||||
width: 126,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "stat_1",
|
||||
width: 88,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "troop",
|
||||
width: 90,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "leadership",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "strength",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "intel",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "officerLevel",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "expDedLv_1",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "explevel",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "dedlevel",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "goldRice_1",
|
||||
width: 80,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "gold",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "rice",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "city",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crewtypeAndCrew_1",
|
||||
width: 80,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crewtype",
|
||||
width: 80,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crew",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "trainAtmos_1",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "train",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "atmos",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "defence_train",
|
||||
width: 50,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specials_1",
|
||||
width: 80,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "personal",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specialDomestic",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specialWar",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "reservedCommandShort_1",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "reservedCommand",
|
||||
width: 120,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "turntime",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: "asc",
|
||||
sortIndex: 0,
|
||||
},
|
||||
{
|
||||
colId: "recent_war",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "years_1",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "age",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "belong",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killturnAndConnect_1",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killturn",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "connect",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "warResults_1",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "warnum",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killnum",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killcrew",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
],
|
||||
columnGroup: [
|
||||
{
|
||||
groupId: "0",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "1",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "stat",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "2",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "expDedLv",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "goldRice",
|
||||
open: true,
|
||||
},
|
||||
{
|
||||
groupId: "3",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "4",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "crewtypeAndCrew",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "trainAtmos",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "specials",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "reservedCommandShort",
|
||||
open: true,
|
||||
},
|
||||
{
|
||||
groupId: "5",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "6",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "years",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "killturnAndConnect",
|
||||
open: true,
|
||||
},
|
||||
{
|
||||
groupId: "warResults",
|
||||
open: false
|
||||
},
|
||||
],
|
||||
},
|
||||
normal: {
|
||||
column: [
|
||||
{
|
||||
colId: "icon",
|
||||
width: 80,
|
||||
hide: false,
|
||||
pinned: "left",
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "name",
|
||||
width: 126,
|
||||
hide: false,
|
||||
pinned: "left",
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "officerLevel",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "expDedLv_1",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "dedlevel",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "explevel",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "stat_1",
|
||||
width: 88,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "leadership",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "strength",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "intel",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "troop",
|
||||
width: 90,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "goldRice_1",
|
||||
width: 80,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "gold",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "rice",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "city",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crewtypeAndCrew_1",
|
||||
width: 80,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crewtype",
|
||||
width: 80,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "crew",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "trainAtmos_1",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "train",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "atmos",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "defence_train",
|
||||
width: 50,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specials_1",
|
||||
width: 80,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "personal",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specialDomestic",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "specialWar",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "reservedCommandShort_1",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "reservedCommand",
|
||||
width: 120,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "turntime",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "recent_war",
|
||||
width: 60,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "years_1",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "age",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "belong",
|
||||
width: 60,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killturnAndConnect_1",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killturn",
|
||||
width: 70,
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "connect",
|
||||
width: 70,
|
||||
hide: false,
|
||||
sort: "desc",
|
||||
sortIndex: 0,
|
||||
},
|
||||
{
|
||||
colId: "warResults_1",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "warnum",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killnum",
|
||||
hide: true,
|
||||
sort: null,
|
||||
},
|
||||
{
|
||||
colId: "killcrew",
|
||||
hide: true,
|
||||
sort: null,
|
||||
}
|
||||
],
|
||||
columnGroup: [
|
||||
{
|
||||
groupId: "0",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "1",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "stat",
|
||||
open: true
|
||||
},
|
||||
{
|
||||
groupId: "2",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "expDedLv",
|
||||
open: true
|
||||
},
|
||||
{
|
||||
groupId: "goldRice",
|
||||
open: true
|
||||
},
|
||||
{
|
||||
groupId: "3",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "4",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "crewtypeAndCrew",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "trainAtmos",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "specials",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "reservedCommandShort",
|
||||
open: true
|
||||
},
|
||||
{
|
||||
groupId: "5",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "6",
|
||||
open: false,
|
||||
},
|
||||
{
|
||||
groupId: "years",
|
||||
open: false
|
||||
},
|
||||
{
|
||||
groupId: "killturnAndConnect",
|
||||
open: true
|
||||
},
|
||||
{
|
||||
groupId: "warResults",
|
||||
open: false
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
+40
-12
@@ -1,5 +1,6 @@
|
||||
import type { Args } from "@/processing/args";
|
||||
import type { ValidResponse, InvalidResponse } from "@/util/callSammoAPI";
|
||||
import type { GameObjClassKey } from "./GameObj";
|
||||
|
||||
export type { ValidResponse, InvalidResponse };
|
||||
export type BasicGeneralListResponse = {
|
||||
@@ -15,21 +16,48 @@ export type BasicGeneralListResponse = {
|
||||
}>
|
||||
}
|
||||
|
||||
|
||||
export type PublicGeneralItem = {
|
||||
no: number,
|
||||
picture: string,
|
||||
imgsvr: 0 | 1,
|
||||
npc: number,
|
||||
age: number,
|
||||
nation: string,
|
||||
specialDomestic: GameObjClassKey,
|
||||
specialWar: GameObjClassKey,
|
||||
personal: GameObjClassKey,
|
||||
name: string,
|
||||
ownerName: string | null,
|
||||
injury: number,
|
||||
leadership: number,
|
||||
lbonus: number,
|
||||
strength: number,
|
||||
intel: number,
|
||||
explevel: number,
|
||||
experienceStr: string,
|
||||
dedicationStr: string,
|
||||
officerLevelStr: string,
|
||||
killturn: number,
|
||||
connect: number,
|
||||
}
|
||||
|
||||
|
||||
export type GeneralListResponse = {
|
||||
result: true,
|
||||
list: [
|
||||
number,
|
||||
string, 0 | 1,
|
||||
number, number, string,
|
||||
string, string, string,
|
||||
string, string | null,
|
||||
number,
|
||||
number, number, number, number,
|
||||
number,
|
||||
string, string, string,
|
||||
number, number
|
||||
PublicGeneralItem['no'],
|
||||
PublicGeneralItem['picture'], PublicGeneralItem['imgsvr'],
|
||||
PublicGeneralItem['npc'], PublicGeneralItem['age'], PublicGeneralItem['nation'],
|
||||
PublicGeneralItem['specialDomestic'], PublicGeneralItem['specialWar'], PublicGeneralItem['personal'],
|
||||
PublicGeneralItem['name'], PublicGeneralItem['ownerName'],
|
||||
PublicGeneralItem['injury'],
|
||||
PublicGeneralItem['leadership'], PublicGeneralItem['lbonus'], PublicGeneralItem['strength'], PublicGeneralItem['intel'],
|
||||
PublicGeneralItem['explevel'],
|
||||
PublicGeneralItem['experienceStr'], PublicGeneralItem['dedicationStr'], PublicGeneralItem['officerLevelStr'],
|
||||
PublicGeneralItem['killturn'], PublicGeneralItem['connect']
|
||||
][],
|
||||
token: Record<number, number>,
|
||||
token?: Record<number, number>,
|
||||
}
|
||||
|
||||
export type NationLevel = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
||||
@@ -200,4 +228,4 @@ export const diplomacyStateInfo: Record<diplomacyState, diplomacyInfo> = {
|
||||
1: { name: '선포중', color: 'magenta' },
|
||||
2: { name: '통상' },
|
||||
7: { name: '불가침', color: 'green' },
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user