function reordering
This commit is contained in:
parent
4b3542edad
commit
442288141d
|
@ -52,130 +52,8 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
// *************buttons*************
|
||||||
Widget build(BuildContext context) {
|
ElevatedButton createButton(String txt, void Function() onPressing) {
|
||||||
screenSize = MediaQuery.of(context).size.width;
|
|
||||||
_textGrNmController.text = graphData.getName();
|
|
||||||
return MaterialApp(
|
|
||||||
home: Scaffold(
|
|
||||||
appBar: AppBar(
|
|
||||||
title: const Align(
|
|
||||||
alignment: Alignment.topLeft,
|
|
||||||
child: Text("Graph name:\n",
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 18,
|
|
||||||
color: Colors.white,
|
|
||||||
))),
|
|
||||||
toolbarHeight: 110,
|
|
||||||
flexibleSpace: Container(
|
|
||||||
color: Colors.green.shade900,
|
|
||||||
child: Column(children: <Widget>[
|
|
||||||
const SizedBox(height: 5),
|
|
||||||
Row(children: [
|
|
||||||
addSpaceW(screenSize / 8 + 19),
|
|
||||||
createButton("\nAdd dot\n", addDotPushed),
|
|
||||||
createInputBox("Dot name", screenSize / 4 - 25, Icons.label,
|
|
||||||
_textNameController),
|
|
||||||
addSpaceW(8),
|
|
||||||
createButton("\nAdd path\n", addPathPushed),
|
|
||||||
createInputBox("Input length", screenSize / 4 - 25,
|
|
||||||
Icons.arrow_right_alt_outlined, _textLnthController),
|
|
||||||
]),
|
|
||||||
addSpaceH(3),
|
|
||||||
Row(children: [
|
|
||||||
addSpaceW(6),
|
|
||||||
createInputBox(
|
|
||||||
"Name", screenSize / 8 - 25, null, _textGrNmController),
|
|
||||||
//addSpaceW(screenSize / 8 - 4),
|
|
||||||
createButton("\nDel dot \n", delDotPushed),
|
|
||||||
//createInputBox("Dot number", screenSize / 4 - 25, Icons.fiber_manual_record, _textNumbController),
|
|
||||||
addSpaceW(54),
|
|
||||||
dropList1(screenSize / 4 - 80),
|
|
||||||
addSpaceW(54),
|
|
||||||
createButton("\nDel path\n", delPathPushed),
|
|
||||||
addSpaceW(54),
|
|
||||||
dropList2(screenSize / 4 - 80),
|
|
||||||
//createInputBox("Destination number", screenSize / 4 - 25, Icons.fiber_manual_record, _textDestController),
|
|
||||||
]),
|
|
||||||
]),
|
|
||||||
),
|
|
||||||
actions: [
|
|
||||||
IconButton(
|
|
||||||
onPressed: () {
|
|
||||||
setState(() {
|
|
||||||
startDot = null;
|
|
||||||
endDot = null;
|
|
||||||
bfsPath = null;
|
|
||||||
dfsAccessTable = null;
|
|
||||||
graphData.flushData();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
icon: const Icon(Icons.delete_sweep),
|
|
||||||
iconSize: 60,
|
|
||||||
),
|
|
||||||
]),
|
|
||||||
body: CustomPaint(
|
|
||||||
painter: CurvePainter(
|
|
||||||
graphData: graphData,
|
|
||||||
bfsPath: bfsPath,
|
|
||||||
dfsAccessTable: dfsAccessTable,
|
|
||||||
start: startDot,
|
|
||||||
end: endDot),
|
|
||||||
child: Align(
|
|
||||||
alignment: Alignment.topRight,
|
|
||||||
child: ButtonBar(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: <Widget>[
|
|
||||||
createButton("Bfs", bfsPushed),
|
|
||||||
createButton("Dfs", dfsPushed),
|
|
||||||
createButton("Clear dfs or bfs", () {
|
|
||||||
setState(() {
|
|
||||||
bfsPath = null;
|
|
||||||
dfsAccessTable = null;
|
|
||||||
startDot = null;
|
|
||||||
endDot = null;
|
|
||||||
clearInputData();
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
createButton(graphData.getUseLengthStr(), changeLength),
|
|
||||||
createButton(graphData.getDoubleSidedStr(), changeOriented),
|
|
||||||
/*Text(_textGrNmController.text,
|
|
||||||
style:
|
|
||||||
TextStyle(fontSize: 15, color: Colors.blueGrey.shade900)),*/
|
|
||||||
createButton("Save to file", fileSaver),
|
|
||||||
createButton("Load from file", fileOpener),
|
|
||||||
createButton("Help", () {
|
|
||||||
String out =
|
|
||||||
" В поле \"Graph name\" можно сменить имя графу.\n";
|
|
||||||
out +=
|
|
||||||
" Для добавления точки необходимо ввести имя в \"Dot name\" и нажать на \"Add dot\".\n";
|
|
||||||
out +=
|
|
||||||
" Для удаления точки необходимо ввести номер в \"Dot number\" и нажать на \"Del dot\".\n";
|
|
||||||
out +=
|
|
||||||
" Для добавления пути необходимо ввести: номер выходной вершины в \"Dot number\", номер входной вершины в \"Destination number\" ";
|
|
||||||
out +=
|
|
||||||
"и, если граф взвешенный, то ввести длину пути в \"Input length\". Затем нажать \"Add path\".\n";
|
|
||||||
out +=
|
|
||||||
" Для удаления пути необходимо ввести номер выходной вершины в \"Dot number\" и номер входной вершины в \"Destination number\". Затем нажать \"Del path\".\n\n";
|
|
||||||
out +=
|
|
||||||
" Кнопки \"Bfs\" и \"Dfs\" нумеруют точки в зависимости от послежовательности, в которой они будут пройдены.\n";
|
|
||||||
out +=
|
|
||||||
" Кнопки \"Взвешенный\" и \"Ориентированный\" позволяют сменить эти значения перед построением графа (т.е. для их работы граф должен быть пустым).\n";
|
|
||||||
out +=
|
|
||||||
" Кнопки \"Save to file\" и \"Load from file\" позволяют вывести информацию в файл и загрузить информацию из файла соответственно.\n";
|
|
||||||
out +=
|
|
||||||
" Кнопка \"Help\" описывает работу с интерфейсом программы.";
|
|
||||||
showPopUp("Help:", out);
|
|
||||||
})
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// ignore: avoid_types_as_parameter_names, non_constant_identifier_names, use_function_type_syntax_for_parameters
|
|
||||||
ElevatedButton createButton(String txt, void onPressing()) {
|
|
||||||
return ElevatedButton(
|
return ElevatedButton(
|
||||||
onPressed: onPressing,
|
onPressed: onPressing,
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
|
@ -190,6 +68,32 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void showPopUp(String alertTitle, String err) => showDialog<String>(
|
||||||
|
context: context,
|
||||||
|
builder: (BuildContext context) => AlertDialog(
|
||||||
|
title: Text(alertTitle),
|
||||||
|
content: Text(err),
|
||||||
|
actions: <Widget>[
|
||||||
|
TextButton(
|
||||||
|
onPressed: () => Navigator.pop(context, 'OK'),
|
||||||
|
child: const Text('OK'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
);
|
||||||
|
// *************buttons*************
|
||||||
|
|
||||||
|
// ***addSpace***
|
||||||
|
SizedBox addSpaceH(double h) {
|
||||||
|
return SizedBox(height: h);
|
||||||
|
}
|
||||||
|
|
||||||
|
SizedBox addSpaceW(double w) {
|
||||||
|
return SizedBox(width: w);
|
||||||
|
}
|
||||||
|
// ***addSpace***
|
||||||
|
|
||||||
|
// *************inputs*************
|
||||||
Container createInputBox(String text, double wid, IconData? icon,
|
Container createInputBox(String text, double wid, IconData? icon,
|
||||||
TextEditingController? controller) {
|
TextEditingController? controller) {
|
||||||
if (icon == null) {
|
if (icon == null) {
|
||||||
|
@ -233,32 +137,78 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
SizedBox addSpaceH(double h) {
|
SizedBox dropList1(double width) {
|
||||||
return SizedBox(height: h);
|
var button = DropdownButton(
|
||||||
}
|
hint: const Text(
|
||||||
|
'Select Dot',
|
||||||
SizedBox addSpaceW(double w) {
|
style: TextStyle(color: Colors.white, fontSize: 13),
|
||||||
return SizedBox(width: w);
|
|
||||||
}
|
|
||||||
|
|
||||||
void showPopUp(String alertTitle, String err) => showDialog<String>(
|
|
||||||
context: context,
|
|
||||||
builder: (BuildContext context) => AlertDialog(
|
|
||||||
title: Text(alertTitle),
|
|
||||||
content: Text(err),
|
|
||||||
actions: <Widget>[
|
|
||||||
TextButton(
|
|
||||||
onPressed: () => Navigator.pop(context, 'OK'),
|
|
||||||
child: const Text('OK'),
|
|
||||||
),
|
),
|
||||||
],
|
//icon: const Icon(Icons.fiber_manual_record, color: Colors.white),
|
||||||
|
alignment: AlignmentDirectional.bottomEnd,
|
||||||
|
value: dropdownValue1,
|
||||||
|
isDense: true,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
|
dropdownColor: Colors.green.shade800,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
),
|
),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
dropdownValue1 = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
items: graphData.getDots().map((location) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
child: Text(location.getName()),
|
||||||
|
value: location.num.toString(),
|
||||||
);
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
child: button,
|
||||||
|
width: width,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
SizedBox dropList2(double width) {
|
||||||
|
var button = DropdownButton(
|
||||||
|
hint: const Text(
|
||||||
|
'Select Dot',
|
||||||
|
style: TextStyle(color: Colors.white, fontSize: 13),
|
||||||
|
),
|
||||||
|
alignment: AlignmentDirectional.centerEnd,
|
||||||
|
value: dropdownValue2,
|
||||||
|
isDense: true,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
||||||
|
dropdownColor: Colors.green.shade800,
|
||||||
|
style: const TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 18,
|
||||||
|
),
|
||||||
|
onChanged: (String? newValue) {
|
||||||
|
setState(() {
|
||||||
|
dropdownValue2 = newValue;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
items: graphData.getDots().map((location) {
|
||||||
|
return DropdownMenuItem(
|
||||||
|
child: Text(location.getName()),
|
||||||
|
value: location.num.toString(),
|
||||||
|
);
|
||||||
|
}).toList(),
|
||||||
|
);
|
||||||
|
|
||||||
|
return SizedBox(
|
||||||
|
child: button,
|
||||||
|
width: width,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// *************inputs*************
|
||||||
|
|
||||||
//*********ButtonsFunctions*********
|
//*********ButtonsFunctions*********
|
||||||
void addDotPushed() {
|
void addDotPushed() {
|
||||||
//showPopUp("Test", "Test message");
|
|
||||||
//var inp = int.tryParse(_textNameController.text);
|
|
||||||
setState(() {
|
setState(() {
|
||||||
if (_textNameController.text == "") {
|
if (_textNameController.text == "") {
|
||||||
showPopUp("Error", "No name in \"Dot name\" box");
|
showPopUp("Error", "No name in \"Dot name\" box");
|
||||||
|
@ -339,19 +289,6 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
|
|
||||||
void delDotPushed() {
|
void delDotPushed() {
|
||||||
setState(() {
|
setState(() {
|
||||||
/*if (_textNumbController.text == "") {
|
|
||||||
showPopUp("Error", "No number in \"Dot number\" box");
|
|
||||||
} else {
|
|
||||||
int? dot = int.tryParse(_textNumbController.text);
|
|
||||||
if (dot == null) {
|
|
||||||
showPopUp("Error", "Can't parse input.\nInts only allowed");
|
|
||||||
} else {
|
|
||||||
String? res = graphData.delDot(dot);
|
|
||||||
if (res != null) {
|
|
||||||
showPopUp("Error", res);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
if (dropdownValue1 != null) {
|
if (dropdownValue1 != null) {
|
||||||
graphData.delDot(int.parse(dropdownValue1!));
|
graphData.delDot(int.parse(dropdownValue1!));
|
||||||
} else {
|
} else {
|
||||||
|
@ -369,14 +306,12 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
if (!result.files.single.path!.endsWith(".txt")) {
|
if (!result.files.single.path!.endsWith(".txt")) {
|
||||||
showPopUp("Error", "Can open only \".txt\" files");
|
showPopUp("Error", "Can open only \".txt\" files");
|
||||||
} else {
|
} else {
|
||||||
//print(result.files.single.path!);
|
|
||||||
String? res =
|
String? res =
|
||||||
graphData.replaceDataFromFile(result.files.single.path!);
|
graphData.replaceDataFromFile(result.files.single.path!);
|
||||||
if (res != null) showPopUp("Error", res);
|
if (res != null) showPopUp("Error", res);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
showPopUp("Error", "No file selected");
|
showPopUp("Error", "No file selected");
|
||||||
// User canceled the picker
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -388,7 +323,6 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
allowedExtensions: ["txt"]);
|
allowedExtensions: ["txt"]);
|
||||||
if (outputFile == null) {
|
if (outputFile == null) {
|
||||||
showPopUp("Error", "Save cancelled");
|
showPopUp("Error", "Save cancelled");
|
||||||
// User canceled the picker
|
|
||||||
} else {
|
} else {
|
||||||
if (!outputFile.endsWith(".txt")) {
|
if (!outputFile.endsWith(".txt")) {
|
||||||
outputFile += ".txt";
|
outputFile += ".txt";
|
||||||
|
@ -442,75 +376,124 @@ class _DrawingPageState extends State<DrawingPage> {
|
||||||
}
|
}
|
||||||
//*********ButtonsFunctions*********
|
//*********ButtonsFunctions*********
|
||||||
|
|
||||||
SizedBox dropList1(double width) {
|
// build
|
||||||
var button = DropdownButton(
|
@override
|
||||||
hint: const Text(
|
Widget build(BuildContext context) {
|
||||||
'Select Dot',
|
screenSize = MediaQuery.of(context).size.width;
|
||||||
style: TextStyle(color: Colors.white, fontSize: 13),
|
_textGrNmController.text = graphData.getName();
|
||||||
), // Not necessary for Option 1
|
return MaterialApp(
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
home: Scaffold(
|
||||||
value: dropdownValue1,
|
appBar: AppBar(
|
||||||
|
title: const Align(
|
||||||
isDense: true,
|
alignment: Alignment.topLeft,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
child: Text("Graph name:\n",
|
||||||
dropdownColor: Colors.green.shade800,
|
style: TextStyle(
|
||||||
style: const TextStyle(
|
|
||||||
//background: Paint()..color = Colors.white,
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
|
color: Colors.white,
|
||||||
|
))),
|
||||||
|
toolbarHeight: 110,
|
||||||
|
flexibleSpace: Container(
|
||||||
|
color: Colors.green.shade900,
|
||||||
|
child: Column(children: <Widget>[
|
||||||
|
const SizedBox(height: 5),
|
||||||
|
Row(children: [
|
||||||
|
addSpaceW(screenSize / 8 + 19),
|
||||||
|
createButton("\nAdd dot\n", addDotPushed),
|
||||||
|
createInputBox("Dot name", screenSize / 4 - 25, Icons.label,
|
||||||
|
_textNameController),
|
||||||
|
addSpaceW(8),
|
||||||
|
createButton("\nAdd path\n", addPathPushed),
|
||||||
|
createInputBox("Input length", screenSize / 4 - 25,
|
||||||
|
Icons.arrow_right_alt_outlined, _textLnthController),
|
||||||
|
]),
|
||||||
|
addSpaceH(3),
|
||||||
|
Row(children: [
|
||||||
|
addSpaceW(6),
|
||||||
|
createInputBox(
|
||||||
|
"Name", screenSize / 8 - 25, null, _textGrNmController),
|
||||||
|
//addSpaceW(screenSize / 8 - 4),
|
||||||
|
createButton("\nDel dot \n", delDotPushed),
|
||||||
|
//createInputBox("Dot number", screenSize / 4 - 25, Icons.fiber_manual_record, _textNumbController),
|
||||||
|
addSpaceW(54),
|
||||||
|
dropList1(screenSize / 4 - 80),
|
||||||
|
addSpaceW(54),
|
||||||
|
createButton("\nDel path\n", delPathPushed),
|
||||||
|
addSpaceW(54),
|
||||||
|
dropList2(screenSize / 4 - 80),
|
||||||
|
//createInputBox("Destination number", screenSize / 4 - 25, Icons.fiber_manual_record, _textDestController),
|
||||||
|
]),
|
||||||
|
]),
|
||||||
),
|
),
|
||||||
onChanged: (String? newValue) {
|
actions: [
|
||||||
|
IconButton(
|
||||||
|
onPressed: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
dropdownValue1 = newValue;
|
startDot = null;
|
||||||
|
endDot = null;
|
||||||
|
bfsPath = null;
|
||||||
|
dfsAccessTable = null;
|
||||||
|
graphData.flushData();
|
||||||
|
clearInputData();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
items: graphData.getDots().map((location) {
|
icon: const Icon(Icons.delete_sweep),
|
||||||
return DropdownMenuItem(
|
iconSize: 60,
|
||||||
child: Text(location.getName()),
|
|
||||||
value: location.num.toString(),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
);
|
|
||||||
|
|
||||||
return SizedBox(
|
|
||||||
child: button,
|
|
||||||
width: width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
SizedBox dropList2(double width) {
|
|
||||||
var button = DropdownButton(
|
|
||||||
hint: const Text(
|
|
||||||
'Select Dot',
|
|
||||||
style: TextStyle(color: Colors.white, fontSize: 13),
|
|
||||||
), // Not necessary for Option 1
|
|
||||||
alignment: AlignmentDirectional.centerEnd,
|
|
||||||
value: dropdownValue2,
|
|
||||||
|
|
||||||
isDense: true,
|
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(20)),
|
|
||||||
dropdownColor: Colors.green.shade800,
|
|
||||||
style: const TextStyle(
|
|
||||||
//background: Paint()..color = Colors.white,
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 18,
|
|
||||||
),
|
),
|
||||||
onChanged: (String? newValue) {
|
]),
|
||||||
|
body: CustomPaint(
|
||||||
|
painter: CurvePainter(
|
||||||
|
graphData: graphData,
|
||||||
|
bfsPath: bfsPath,
|
||||||
|
dfsAccessTable: dfsAccessTable,
|
||||||
|
start: startDot,
|
||||||
|
end: endDot),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.topRight,
|
||||||
|
child: ButtonBar(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: <Widget>[
|
||||||
|
createButton("Bfs", bfsPushed),
|
||||||
|
createButton("Dfs", dfsPushed),
|
||||||
|
createButton("Clear dfs or bfs", () {
|
||||||
setState(() {
|
setState(() {
|
||||||
dropdownValue2 = newValue;
|
bfsPath = null;
|
||||||
|
dfsAccessTable = null;
|
||||||
|
startDot = null;
|
||||||
|
endDot = null;
|
||||||
|
clearInputData();
|
||||||
});
|
});
|
||||||
},
|
}),
|
||||||
items: graphData.getDots().map((location) {
|
createButton(graphData.getUseLengthStr(), changeLength),
|
||||||
return DropdownMenuItem(
|
createButton(graphData.getDoubleSidedStr(), changeOriented),
|
||||||
child: Text(location.getName()),
|
createButton("Save to file", fileSaver),
|
||||||
value: location.num.toString(),
|
createButton("Load from file", fileOpener),
|
||||||
);
|
createButton("Help", () {
|
||||||
}).toList(),
|
String out =
|
||||||
);
|
" В поле \"Graph name\" можно сменить имя графу.\n";
|
||||||
|
out +=
|
||||||
return SizedBox(
|
" Для добавления точки необходимо ввести имя в \"Dot name\" и нажать на \"Add dot\".\n";
|
||||||
child: button,
|
out +=
|
||||||
width: width,
|
" Для удаления точки необходимо ввести номер в \"Dot number\" и нажать на \"Del dot\".\n";
|
||||||
);
|
out +=
|
||||||
|
" Для добавления пути необходимо ввести: номер выходной вершины в \"Dot number\", номер входной вершины в \"Destination number\" ";
|
||||||
|
out +=
|
||||||
|
"и, если граф взвешенный, то ввести длину пути в \"Input length\". Затем нажать \"Add path\".\n";
|
||||||
|
out +=
|
||||||
|
" Для удаления пути необходимо ввести номер выходной вершины в \"Dot number\" и номер входной вершины в \"Destination number\". Затем нажать \"Del path\".\n\n";
|
||||||
|
out +=
|
||||||
|
" Кнопки \"Bfs\" и \"Dfs\" нумеруют точки в зависимости от послежовательности, в которой они будут пройдены.\n";
|
||||||
|
out +=
|
||||||
|
" Кнопки \"Взвешенный\" и \"Ориентированный\" позволяют сменить эти значения перед построением графа (т.е. для их работы граф должен быть пустым).\n";
|
||||||
|
out +=
|
||||||
|
" Кнопки \"Save to file\" и \"Load from file\" позволяют вывести информацию в файл и загрузить информацию из файла соответственно.\n";
|
||||||
|
out +=
|
||||||
|
" Кнопка \"Help\" описывает работу с интерфейсом программы.";
|
||||||
|
showPopUp("Help:", out);
|
||||||
|
})
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue