Commit 487c0cea by qianmo

update:雏形完成

parent 9c46c67b
VITE_REQUEST_BASE_URL=http://192.168.110.200:10000/hy-web #VITE_REQUEST_BASE_URL=http://192.168.110.200:10000/hy-web
...@@ -50,6 +50,8 @@ function _next(to, next) { ...@@ -50,6 +50,8 @@ function _next(to, next) {
// 基础的路由前拦截 // 基础的路由前拦截
export async function routeBaseBefore(to, from, next) { export async function routeBaseBefore(to, from, next) {
if (to.name !== from.name) { if (to.name !== from.name) {
NProgress.start() NProgress.start()
} }
......
<template>
<div class="chat-box">
<div class="message" ref="messageContainer">
<div v-for="(message, index) in messages" :key="index">
{{ message }}
<br /> <!-- 换行 -->
</div>
</div>
</div>
</template>
<script setup>
import { toRefs, defineProps, ref, watchEffect } from 'vue'
const props = defineProps({
//子组件接收父组件传递过来的值
messages: String,
})
//使用父组件传递过来的值
console.log(props)
const {messages} =toRefs(props)
const messageContainer = ref(null);
function scrollToBottom() {
if (messageContainer.value) {
messageContainer.value.scrollTop = messageContainer.value.scrollHeight;
}
}
watchEffect(() => {
// 在 messages 更新后滚动到底部
scrollToBottom();
});
</script>
<style scoped>
.chat-box {
width: 300px;
height: 400px;
border: 1px solid #ccc;
overflow-y: auto;
}
.message {
padding: 8px;
margin: 4px;
border-radius: 4px;
background-color: #f0f0f0;
}
</style>
<template>
<div class="demo-collapse">
<div class="container">
<div class="left">
<div class="mr-4">协议版本</div>
<el-select>
<el-option :value="option"></el-option>
</el-select>
</div>
<div class="right">
<el-button @click="addCmd = true">新增指令</el-button>
<el-button>导出协议</el-button>
</div>
</div>
<div class="mb-4 mt-4">协议指令</div>
<el-collapse class="mt-4">
<el-collapse-item title="HY_ACU7M5_PositionSet&nbsp;&nbsp;&nbsp;XY置位指令&nbsp;&nbsp;&nbsp;Tx" name="1">
<protpcol-table></protpcol-table>
</el-collapse-item>
<el-collapse-item title="HY_ACU7M5_MoveStop&nbsp;&nbsp;&nbsp;停止运动指令&nbsp;&nbsp;&nbsp;Tx" name="2">
<protpcol-table></protpcol-table>
</el-collapse-item>
</el-collapse>
<el-dialog v-model="addCmd" title="新增指令">
<el-form >
<el-form-item label="协议名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="指令名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="指令类型" :label-width="formLabelWidth">
<el-select>
<el-option label="TX"></el-option>
<el-option label="RX"></el-option>
</el-select>
</el-form-item>
<el-form-item label="协议类型" :label-width="formLabelWidth">
<el-select>
<el-option label="ASCII"></el-option>
<el-option label="HEX"></el-option>
</el-select>
</el-form-item>
<el-form-item label="定时发送" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="说明" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addCmd = false">取消</el-button>
<el-button type="primary" @click="open">
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</template>
<script setup>
import {ref} from 'vue'
import {ElMessage, ElMessageBox} from "element-plus";
import ProtpcolTable from "./protpcol-table.vue";
const addCmd = ref(false)
const option = ref('option')
const formLabelWidth = '140px'
const open = () => {
ElMessageBox.confirm(
'是否确认增加?',
'Warning',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '增加成功',
})
addCmd.value = false
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消',
})
})
}
</script>
<style>
.container {
/*width: 100%;*/
/*border: 1px solid;*/
display: flex;
justify-content: space-between; /* 使内部元素平均分布 */
align-items: center; /* 垂直居中 */
margin: auto;
}
.left {
align-items: center;
display: flex;
}
.right {
display: flex;
align-items: center; /* 垂直居中 */
}
</style>
<template>
<div class="demo-collapse">
<el-collapse>
<el-collapse-item title="HY_ACU7M5_Antenna_PROTOCOL" name="1">
<div style="margin: auto; width: 90%">
<collapse-table class="mt-4"></collapse-table>
</div>
</el-collapse-item>
<el-collapse-item title=" HY_HWF0355-0357FC_PROTOCOL" name="2">
<div style="margin: auto; width: 90%">
<collapse-table class="mt-4"></collapse-table>
</div>
</el-collapse-item>
<el-collapse-item title="HY_DualChannelLBandOpticalTransceiver_PROTOCOL" name="3">
<div style="margin: auto; width: 90%">
<collapse-table class="mt-4"></collapse-table>
</div>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script setup>
import {ref} from 'vue'
import CollapseTable from "./collapse-table.vue";
</script>
<style>
.el-collapse-item__header {
padding-left: 40px; /* 调整合适的左边距值 */
}
</style>
<template>
<div class="mt-10" v-for="item in deviceData">
<span>{{item.name}}</span>
<div id="flex-container" class="mt-4">
<div class="flex-item">端口号:</div>
<div class="flex-item">
<el-input v-model="item.portNumber" ></el-input>
</div>
<div class="flex-item">开关:</div>
<div class="flex-item">
<el-switch v-model="item.switchValue"></el-switch>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const deviceData = ref([
{ name: '7M5ACU', portNumber: '1111', switchValue: true},
{ name: '变频器', portNumber: '0000', switchValue: false}
])
</script>
<style>
#flex-container {
display: flex;
align-items: center;
}
.flex-item {
margin-right: 20px;
}
</style>
<template>
<el-row >
<el-col >
<el-menu @select="handleMenuItemSelect">
<el-sub-menu index="1">
<template #title>
<span>设备列表</span>
</template>
<el-sub-menu index="1-1">
<template #title>
<span>ACU</span>
</template>
<el-menu-item index="/acu">
<span>7.5米ACU(23所)</span>
</el-menu-item>
<el-menu-item index="1-1-2">
<span>5米ACU(2=39所)</span>
</el-menu-item>
</el-sub-menu>
<el-menu-item index="1-2">
<span>变频器</span>
</el-menu-item>
<el-menu-item index="1-3">
<span>信号源</span>
</el-menu-item>
<el-menu-item index="1-4">
<span>跟踪接收机</span>
</el-menu-item>
<el-menu-item index="1-5">
<span>矩阵</span>
</el-menu-item>
<el-menu-item index="1-6">
<span>气象站</span>
</el-menu-item>
</el-sub-menu>
</el-menu>
</el-col>
</el-row>
</template>
<script setup>
const emit = defineEmits(['handleMenuItemSelect'])
function handleMenuItemSelect(index){
emit('handleMenuItemSelect', index)
}
</script>
<template>
<el-table :data="tableData" style="width: 100%">
<el-table-column fixed prop="FieldName" label="字段名" style="width: 25%" />
<el-table-column prop="FieldLength" label="字段长度" style="width: 25%" />
<el-table-column prop="Value" label="值" style="width: 25%" />
<el-table-column fixed="right" style="width: 25%">
<template #default="{row}">
<div style="display: flex; justify-content: space-between;">
<el-button type="primary" @click="open('delete')">删除字段</el-button>
<el-button type="primary" @click="editField(row)">修改字段</el-button>
</div>
</template>
</el-table-column>
</el-table>
<el-button
style="width: 100%; border: 1px dashed"
class="mt-4"
@click="addField"
>+</el-button>
<el-dialog v-model="dialogVisible" >
<template #title>{{flag ? '新增' : '编辑'}}字段</template>
<el-form label-position="right" label-width="150px" :model="fields">
<el-row>
<el-col :span="12">
<el-form-item label="命令名">
<el-input v-model="fields.cmdName"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="指令类型">
<el-input v-model="fields.cmdType"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="序号">
<el-input v-model="fields.index"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="名称">
<el-input v-model="fields.name"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="长度">
<el-input v-model="fields.length"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="值">
<el-input v-model="fields.value"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="指令最大值">
<el-input v-model="fields.cmdMax"></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="指令最小值">
<el-input v-model="fields.cmdMin"></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="字段类型">
<el-select v-model="fields.fieldType">
<el-option v-for="item in fieldTypes" :label="item.label" :value="item.value" :key="item.value"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="输入数据操作">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="输入数据操作参数">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="输出数据操作">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="输出数据操作参数">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="输入数据字节操作">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="输出数据字节操作">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="12">
<el-form-item label="Lua对输入数据的操作">
<el-input></el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="Lua对输出数据的操作">
<el-input></el-input>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="open">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {ref} from 'vue'
import {ElMessage, ElMessageBox} from "element-plus";
const flag = ref(false)
const dialogVisible = ref(false)
const tableData = [
{
FieldName: 'Cmds',
FieldLength: 3,
Value: '$XY',
},
{
FieldName: 'Comma',
FieldLength: 1,
Value: ',',
},
]
const fields = ref({
cmdName: '',
cmdType: '',
index: '',
name: '',
length: '',
value: '',
cmdMax: '',
cmdMin: '',
fieldType: '',
inputDataAction: '',
inputDataActionParam: '',
outputDataAction: '',
outputDataActionParam: '',
inputDataByteAction: '',
outputDataByteAction: '',
LuaInput: '',
LuaOutput: ''
})
const fieldTypes = [
{ value: 0, label: 'DATATYPE_DEFAULT'},
{ value: 1, label: 'DATATYPE_STR '},
{ value: 2, label: 'DATATYPE_UINT_STR '},
{ value: 3, label: 'DATATYPE_INT_STR '},
{ value: 4, label: 'DATATYPE_FLOAT_STR '},
{ value: 5, label: 'DATATYPE_DOUBLE_STR '},
{ value: 6, label: 'DATATYPE_HEX '},
{ value: 7, label: 'DATATYPE_STR_HEX '},
{ value: 8, label: 'DATATYPE_UINT_HEX '},
{ value: 9, label: 'DATATYPE_INT_HEX '},
{ value: 10, label: 'DATATYPE_FLOAT_HEX '},
{ value: 11, label: 'DATATYPE_DOUBLE_HEX '},
{ value: 12, label: 'DATATYPE_DOUBLE '},
{ value: 13, label: 'DATATYPE_PAYLOAD '},
{ value: 14, label: 'DATATYPE_INT8 '},
{ value: 15, label: 'DATATYPE_TIMESTR '},
{ value: 16, label: 'DATATYPE_MAX'},
]
let operation = ''
const addField = () => {
dialogVisible.value = true;
flag.value = true;
for(const key in fields.value){
fields.value[key] = '';
}
}
function editField(data){
dialogVisible.value = true
flag.value = false
fields.value['cmdName'] = data.FieldName
fields.value['length'] = data.FieldLength
fields.value['value'] = data.Value
}
function open(data){
console.log(data)
if (data === 'delete'){
operation = '删除'
} else if(flag.value){
operation = '增加'
}else if (!flag.value){
operation = '修改'
}
ElMessageBox.confirm(
'是否确认' + operation + '?',
'Warning',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
ElMessage({
type: 'success',
message: operation + '成功',
})
dialogVisible.value = false
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消',
})
})
}
</script>
<style>
.el-row:not(:last-child) {
margin-bottom: 10px; /* 添加间距 */
}
</style>
\ No newline at end of file
...@@ -21,14 +21,33 @@ export const routes = [ ...@@ -21,14 +21,33 @@ export const routes = [
}, },
children: [ children: [
{ {
path: "/receive-statistics", path: "/index",
name: "receive-statistics", name: "receive-stats",
component: () => import("../views/index/index.vue"), component: () => import("../views/index/home-page.vue"),
meta: { meta: {
menuTitle: "首页", menuTitle: "首页",
menuIcon: "fee", menuIcon: "fee",
}, },
}, },
{
path: "/protocol",
name: "protocol",
component: () => import("../views/protocol/protocol.vue"),
meta: {
menuTitle: "协议",
menuIcon: "fee",
},
},
{
path: "/device",
name: "device",
component: () => import("../views/device/device.vue"),
meta: {
menuTitle: "模拟设备",
menuIcon: "fee",
}
},
], ],
}, },
] ]
<template>
<div class="common-layout">
<el-container>
<el-aside width="200px">
<kit-menu @handleMenuItemSelect="MenuItem"></kit-menu>
</el-aside>
<el-main>
<el-button @click="addDevice = true">新增模拟设备</el-button>
<component :is="currentComponent"></component>
</el-main>
</el-container>
</div>
<el-dialog v-model="addDevice" title="新增指令">
<el-form >
<el-form-item label="设备名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="设备英文名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
<el-form-item label="协议" :label-width="formLabelWidth">
<el-select>
<el-option label="TX"></el-option>
<el-option label="RX"></el-option>
</el-select>
</el-form-item>
<el-form-item label="通信方式" :label-width="formLabelWidth">
<el-select>
<el-option label="ASCII"></el-option>
<el-option label="HEX"></el-option>
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addDevice = false">取消</el-button>
<el-button type="primary" @click="open">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {ref, shallowRef} from "vue";
import {ElMessage, ElMessageBox} from "element-plus";
import KitMenu from "../../components/kit-menu.vue";
import KitDevice from "../../components/kit-device.vue";
const currentComponent = shallowRef(KitDevice)
const addDevice = ref(false)
const formLabelWidth = '140px'
function MenuItem(index){
console.log(index)
currentComponent.value = KitDevice
}
function open(){
ElMessageBox.confirm(
'是否确认增加?',
'Warning',
{
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
ElMessage({
type: 'success',
message: '增加成功',
})
addDevice.value = false
})
.catch(() => {
ElMessage({
type: 'info',
message: '已取消',
})
})
}
</script>
<style>
body,html{
height: 100%;
}
html,body,.common-layout,.el-container{
margin: 0px;
padding: 0px;
height: 100%;
}
.el-aside {
background-color: #ffffff;
color: #333;
text-align: center;
line-height: 200px;
}
.el-main {
border: 1px solid;
/*background-color: #f3f4f6;*/
color: #333;
/*text-align: center;*/
}
</style>
<template>
<div class="flex items-center w-1/2">
<div style="width: 10%" >订阅主题</div>
<el-input style="width: 30%" class="ml-4"></el-input>
<el-button style="width: 15%" class="ml-4">连接mqtt</el-button>
</div>
<div class="flex mt-4">
<el-input
style="width: 40%"
:rows="24"
type="textarea"
disabled
/>
</div>
<div class="mt-4">
<el-input
style="width: 80%"
:rows="4"
type="textarea"
disabled
/>
<el-button class="ml-4">导出</el-button>
</div>
</template>
<script setup>
</script>
<template>
<div class="demo-collapse">
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item :title="title" name="1">
<kit-form/>
</el-collapse-item>
<el-collapse-item title="Feedback" name="2">
<template slot="title">
<div @click.stop="" class="collapse-title">
<span>随便起个名字</span>
</div>
</template>
</el-collapse-item>
<el-collapse-item title="Efficiency" name="3">
<div>
Simplify the process: keep operating process simple and intuitive;
</div>
<div>
Definite and clear: enunciate your intentions clearly so that the
users can quickly understand and make decisions;
</div>
<div>
Easy to identify: the interface should be straightforward, which helps
the users to identify and frees them from memorizing and recalling.
</div>
</el-collapse-item>
<el-collapse-item title="Controllability" name="4">
<div>
Decision making: giving advices about operations is acceptable, but do
not make decisions for the users;
</div>
<div>
Controlled consequences: users should be granted the freedom to
operate, including canceling, aborting or terminating current
operation.
</div>
</el-collapse-item>
</el-collapse>
<el-button type="primary" @click="confirm">确定</el-button>
</div>
</template>
<script setup>
import { ref } from 'vue'
import KitForm from "../../components/kit-form.vue";
import axios from "axios"
const title = ref('')
const activeNames = ref(['1'])
title.value = "title"
function confirm(){
axios.get('http://192.168.0.214:8000/api/test').then(function (response){
title.value = response.data.test
})
}
// const handleChange = (val: string[]) => {
// console.log(val)
// }
</script>
<template>
<div class="button-container">
<el-button class="left-button" @click="addProtocol = true">新增协议</el-button>
<div class="right-buttons">
<el-button>导入</el-button>
<el-button>导出所有协议</el-button>
</div>
</div>
<kit-collapse class="mt-4"></kit-collapse>
<el-dialog title="新增协议" v-model="addProtocol">
<el-form >
<el-form-item label="协议名称" :label-width="formLabelWidth">
<el-input autocomplete="off" />
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="addProtocol = false">取消</el-button>
<el-button type="primary" @click="addProtocol = false">
确定
</el-button>
</span>
</template>
</el-dialog>
</template>
<script setup>
import {ref} from 'vue';
import KitCollapse from "../../components/kit-collapse.vue";
const addProtocol = ref(false)
const formLabelWidth = '140px'
</script>
<style scoped>
.button-container {
display: flex;
justify-content: space-between; /* 使内部元素平均分布 */
align-items: center; /* 垂直居中 */
}
.left-button {
margin-right: auto; /* 将按钮1靠左 */
}
.right-buttons {
display: flex;
align-items: center; /* 垂直居中 */
}
</style>
...@@ -25,8 +25,7 @@ SECRET_KEY = 'django-insecure-68xzqkau2%ulw2t^tpfo0d8$+_8$5z2jixypnxv$#81l&0=)s0 ...@@ -25,8 +25,7 @@ SECRET_KEY = 'django-insecure-68xzqkau2%ulw2t^tpfo0d8$+_8$5z2jixypnxv$#81l&0=)s0
# SECURITY WARNING: don't run with debug turned on in production! # SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True DEBUG = True
ALLOWED_HOSTS = [] ALLOWED_HOSTS = ['*']
# Application definition # Application definition
...@@ -40,11 +39,13 @@ INSTALLED_APPS = [ ...@@ -40,11 +39,13 @@ INSTALLED_APPS = [
'rest_framework', 'rest_framework',
'frontend', 'frontend',
'corsheaders',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
...@@ -74,7 +75,6 @@ TEMPLATES = [ ...@@ -74,7 +75,6 @@ TEMPLATES = [
WSGI_APPLICATION = 'vue_django.wsgi.application' WSGI_APPLICATION = 'vue_django.wsgi.application'
# Database # Database
# https://docs.djangoproject.com/en/3.2/ref/settings/#databases # https://docs.djangoproject.com/en/3.2/ref/settings/#databases
...@@ -85,7 +85,6 @@ DATABASES = { ...@@ -85,7 +85,6 @@ DATABASES = {
} }
} }
# Password validation # Password validation
# https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators # https://docs.djangoproject.com/en/3.2/ref/settings/#auth-password-validators
...@@ -104,7 +103,6 @@ AUTH_PASSWORD_VALIDATORS = [ ...@@ -104,7 +103,6 @@ AUTH_PASSWORD_VALIDATORS = [
}, },
] ]
# Internationalization # Internationalization
# https://docs.djangoproject.com/en/3.2/topics/i18n/ # https://docs.djangoproject.com/en/3.2/topics/i18n/
...@@ -118,7 +116,6 @@ USE_L10N = True ...@@ -118,7 +116,6 @@ USE_L10N = True
USE_TZ = True USE_TZ = True
# Static files (CSS, JavaScript, Images) # Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.2/howto/static-files/ # https://docs.djangoproject.com/en/3.2/howto/static-files/
...@@ -128,8 +125,19 @@ STATICFILES_DIRS = [ ...@@ -128,8 +125,19 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'frontend', 'dist', 'assets') os.path.join(BASE_DIR, 'frontend', 'dist', 'assets')
] ]
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_HEADERS = [
'x-requested-with',
'content-type',
'accept',
'origin',
'authorization',
'x-csrftoken',
'token'
]
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment