Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
D
dlink
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhaowei
dlink
Commits
0d5e7e57
Commit
0d5e7e57
authored
Mar 19, 2022
by
wenmo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
common format
parent
f6d81b81
Changes
12
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
96 additions
and
108 deletions
+96
-108
Asserts.java
dlink-common/src/main/java/com/dlink/assertion/Asserts.java
+25
-25
JobLifeCycle.java
dlink-common/src/main/java/com/dlink/model/JobLifeCycle.java
+11
-13
SystemConfiguration.java
...on/src/main/java/com/dlink/model/SystemConfiguration.java
+15
-13
Table.java
dlink-common/src/main/java/com/dlink/model/Table.java
+16
-16
ClassEntity.java
dlink-common/src/main/java/com/dlink/pool/ClassEntity.java
+4
-4
ClassPool.java
dlink-common/src/main/java/com/dlink/pool/ClassPool.java
+2
-2
AbstractResult.java
...common/src/main/java/com/dlink/result/AbstractResult.java
+2
-2
SqlExplainResult.java
...mmon/src/main/java/com/dlink/result/SqlExplainResult.java
+6
-7
JSONUtil.java
dlink-common/src/main/java/com/dlink/utils/JSONUtil.java
+5
-16
LogUtil.java
dlink-common/src/main/java/com/dlink/utils/LogUtil.java
+8
-8
RunTimeUtil.java
dlink-common/src/main/java/com/dlink/utils/RunTimeUtil.java
+1
-1
SqlUtil.java
dlink-common/src/main/java/com/dlink/utils/SqlUtil.java
+1
-1
No files found.
dlink-common/src/main/java/com/dlink/assertion/Asserts.java
View file @
0d5e7e57
...
...
@@ -13,44 +13,44 @@ import java.util.Map;
*/
public
class
Asserts
{
public
static
boolean
isNotNull
(
Object
object
){
return
object
!=
null
;
public
static
boolean
isNotNull
(
Object
object
)
{
return
object
!=
null
;
}
public
static
boolean
isNull
(
Object
object
){
return
object
==
null
;
public
static
boolean
isNull
(
Object
object
)
{
return
object
==
null
;
}
public
static
boolean
isNullString
(
String
str
){
return
isNull
(
str
)
||
""
.
equals
(
str
);
public
static
boolean
isNullString
(
String
str
)
{
return
isNull
(
str
)
||
""
.
equals
(
str
);
}
public
static
boolean
isNotNullString
(
String
str
){
public
static
boolean
isNotNullString
(
String
str
)
{
return
!
isNullString
(
str
);
}
public
static
boolean
isEquals
(
String
str1
,
String
str2
)
{
if
(
isNull
(
str1
)&&
isNull
(
str2
))
{
public
static
boolean
isEquals
(
String
str1
,
String
str2
)
{
if
(
isNull
(
str1
)
&&
isNull
(
str2
))
{
return
true
;
}
else
if
(
isNull
(
str1
)||
isNull
(
str2
))
{
}
else
if
(
isNull
(
str1
)
||
isNull
(
str2
))
{
return
false
;
}
else
{
}
else
{
return
str1
.
equals
(
str2
);
}
}
public
static
boolean
isEqualsIgnoreCase
(
String
str1
,
String
str2
)
{
if
(
isNull
(
str1
)&&
isNull
(
str2
))
{
public
static
boolean
isEqualsIgnoreCase
(
String
str1
,
String
str2
)
{
if
(
isNull
(
str1
)
&&
isNull
(
str2
))
{
return
true
;
}
else
if
(
isNull
(
str1
)||
isNull
(
str2
))
{
}
else
if
(
isNull
(
str1
)
||
isNull
(
str2
))
{
return
false
;
}
else
{
}
else
{
return
str1
.
equalsIgnoreCase
(
str2
);
}
}
public
static
boolean
isNullCollection
(
Collection
collection
)
{
if
(
isNull
(
collection
)
||
collection
.
size
()==
0
)
{
if
(
isNull
(
collection
)
||
collection
.
size
()
==
0
)
{
return
true
;
}
return
false
;
...
...
@@ -61,7 +61,7 @@ public class Asserts {
}
public
static
boolean
isNullMap
(
Map
map
)
{
if
(
isNull
(
map
)
||
map
.
size
()==
0
)
{
if
(
isNull
(
map
)
||
map
.
size
()
==
0
)
{
return
true
;
}
return
false
;
...
...
@@ -71,32 +71,32 @@ public class Asserts {
return
!
isNullMap
(
map
);
}
public
static
void
checkNull
(
Object
key
,
String
msg
)
{
public
static
void
checkNull
(
Object
key
,
String
msg
)
{
if
(
key
==
null
)
{
throw
new
RunTimeException
(
msg
);
}
}
public
static
void
checkNotNull
(
Object
object
,
String
msg
)
{
public
static
void
checkNotNull
(
Object
object
,
String
msg
)
{
if
(
isNull
(
object
))
{
throw
new
RunTimeException
(
msg
);
}
}
public
static
void
checkNullString
(
String
key
,
String
msg
)
{
if
(
isNull
(
key
)
||
isEquals
(
""
,
key
))
{
public
static
void
checkNullString
(
String
key
,
String
msg
)
{
if
(
isNull
(
key
)
||
isEquals
(
""
,
key
))
{
throw
new
RunTimeException
(
msg
);
}
}
public
static
void
checkNullCollection
(
Collection
collection
,
String
msg
)
{
if
(
isNullCollection
(
collection
))
{
public
static
void
checkNullCollection
(
Collection
collection
,
String
msg
)
{
if
(
isNullCollection
(
collection
))
{
throw
new
RunTimeException
(
msg
);
}
}
public
static
void
checkNullMap
(
Map
map
,
String
msg
)
{
if
(
isNullMap
(
map
))
{
public
static
void
checkNullMap
(
Map
map
,
String
msg
)
{
if
(
isNullMap
(
map
))
{
throw
new
RunTimeException
(
msg
);
}
}
...
...
dlink-common/src/main/java/com/dlink/model/JobLifeCycle.java
View file @
0d5e7e57
package
com
.
dlink
.
model
;
import
com.dlink.assertion.Asserts
;
/**
* JobLifeCycle
*
...
...
@@ -9,13 +7,13 @@ import com.dlink.assertion.Asserts;
* @since 2022/2/1 16:37
*/
public
enum
JobLifeCycle
{
UNKNOWN
(
0
,
"未知"
),
CREATE
(
1
,
"创建"
),
DEVELOP
(
2
,
"开发"
),
DEBUG
(
3
,
"调试"
),
RELEASE
(
4
,
"发布"
),
ONLINE
(
5
,
"上线"
),
CANCEL
(
6
,
"注销"
);
UNKNOWN
(
0
,
"未知"
),
CREATE
(
1
,
"创建"
),
DEVELOP
(
2
,
"开发"
),
DEBUG
(
3
,
"调试"
),
RELEASE
(
4
,
"发布"
),
ONLINE
(
5
,
"上线"
),
CANCEL
(
6
,
"注销"
);
private
Integer
value
;
private
String
label
;
...
...
@@ -34,17 +32,17 @@ public enum JobLifeCycle {
}
public
static
JobLifeCycle
get
(
Integer
value
){
public
static
JobLifeCycle
get
(
Integer
value
)
{
for
(
JobLifeCycle
item
:
JobLifeCycle
.
values
())
{
if
(
item
.
getValue
()
==
value
)
{
if
(
item
.
getValue
()
==
value
)
{
return
item
;
}
}
return
JobLifeCycle
.
UNKNOWN
;
}
public
boolean
equalsValue
(
Integer
step
){
if
(
value
==
step
)
{
public
boolean
equalsValue
(
Integer
step
)
{
if
(
value
==
step
)
{
return
true
;
}
return
false
;
...
...
dlink-common/src/main/java/com/dlink/model/SystemConfiguration.java
View file @
0d5e7e57
...
...
@@ -16,10 +16,12 @@ import java.util.Map;
public
class
SystemConfiguration
{
private
static
volatile
SystemConfiguration
systemConfiguration
=
new
SystemConfiguration
();
public
static
SystemConfiguration
getInstances
()
{
return
systemConfiguration
;
}
private
static
final
List
<
Configuration
>
CONFIGURATION_LIST
=
new
ArrayList
<
Configuration
>(){{
private
static
final
List
<
Configuration
>
CONFIGURATION_LIST
=
new
ArrayList
<
Configuration
>()
{{
add
(
systemConfiguration
.
sqlSubmitJarPath
);
add
(
systemConfiguration
.
sqlSubmitJarParas
);
add
(
systemConfiguration
.
sqlSubmitJarMainAppClass
);
...
...
@@ -63,12 +65,12 @@ public class SystemConfiguration {
"Flink SQL 的语句分割符"
);
public
void
setConfiguration
(
JsonNode
jsonNode
){
for
(
Configuration
item
:
CONFIGURATION_LIST
)
{
if
(!
jsonNode
.
has
(
item
.
getName
()))
{
public
void
setConfiguration
(
JsonNode
jsonNode
)
{
for
(
Configuration
item
:
CONFIGURATION_LIST
)
{
if
(!
jsonNode
.
has
(
item
.
getName
()))
{
continue
;
}
switch
(
item
.
getType
()){
switch
(
item
.
getType
())
{
case
BOOLEAN:
item
.
setValue
(
jsonNode
.
get
(
item
.
getName
()).
asBoolean
());
break
;
...
...
@@ -81,12 +83,12 @@ public class SystemConfiguration {
}
}
public
void
addConfiguration
(
Map
<
String
,
Object
>
map
)
{
for
(
Configuration
item
:
CONFIGURATION_LIST
)
{
if
(
map
.
containsKey
(
item
.
getName
())&&
item
.
getType
().
equals
(
ValueType
.
BOOLEAN
))
{
map
.
put
(
item
.
getName
(),
Asserts
.
isEqualsIgnoreCase
(
"true"
,
map
.
get
(
item
.
getName
()).
toString
()));
public
void
addConfiguration
(
Map
<
String
,
Object
>
map
)
{
for
(
Configuration
item
:
CONFIGURATION_LIST
)
{
if
(
map
.
containsKey
(
item
.
getName
())
&&
item
.
getType
().
equals
(
ValueType
.
BOOLEAN
))
{
map
.
put
(
item
.
getName
(),
Asserts
.
isEqualsIgnoreCase
(
"true"
,
map
.
get
(
item
.
getName
()).
toString
()));
}
if
(!
map
.
containsKey
(
item
.
getName
()))
{
if
(!
map
.
containsKey
(
item
.
getName
()))
{
map
.
put
(
item
.
getName
(),
item
.
getValue
());
}
}
...
...
@@ -132,11 +134,11 @@ public class SystemConfiguration {
this
.
sqlSeparator
.
setValue
(
sqlSeparator
);
}
enum
ValueType
{
STRING
,
INT
,
DOUBLE
,
FLOAT
,
BOOLEAN
,
DATE
enum
ValueType
{
STRING
,
INT
,
DOUBLE
,
FLOAT
,
BOOLEAN
,
DATE
}
public
class
Configuration
{
public
class
Configuration
{
private
String
name
;
private
String
label
;
private
ValueType
type
;
...
...
dlink-common/src/main/java/com/dlink/model/Table.java
View file @
0d5e7e57
...
...
@@ -83,9 +83,9 @@ public class Table implements Serializable, Comparable<Table> {
}
sb
.
append
(
"`"
+
columns
.
get
(
i
).
getName
()
+
"` "
+
type
);
if
(
Asserts
.
isNotNullString
(
columns
.
get
(
i
).
getComment
()))
{
if
(
columns
.
get
(
i
).
getComment
().
contains
(
"\'"
)
|
columns
.
get
(
i
).
getComment
().
contains
(
"\""
))
{
sb
.
append
(
" COMMENT '"
+
columns
.
get
(
i
).
getComment
().
replaceAll
(
"\"|'"
,
""
)
+
"'"
);
}
else
{
if
(
columns
.
get
(
i
).
getComment
().
contains
(
"\'"
)
|
columns
.
get
(
i
).
getComment
().
contains
(
"\""
))
{
sb
.
append
(
" COMMENT '"
+
columns
.
get
(
i
).
getComment
().
replaceAll
(
"\"|'"
,
""
)
+
"'"
);
}
else
{
sb
.
append
(
" COMMENT '"
+
columns
.
get
(
i
).
getComment
()
+
"'"
);
}
}
...
...
@@ -99,7 +99,7 @@ public class Table implements Serializable, Comparable<Table> {
if
(
i
>
0
)
{
pksb
.
append
(
","
);
}
pksb
.
append
(
"`"
+
pks
.
get
(
i
)+
"`"
);
pksb
.
append
(
"`"
+
pks
.
get
(
i
)
+
"`"
);
}
pksb
.
append
(
" ) NOT ENFORCED\n"
);
if
(
pks
.
size
()
>
0
)
{
...
...
@@ -107,10 +107,10 @@ public class Table implements Serializable, Comparable<Table> {
sb
.
append
(
pksb
);
}
sb
.
append
(
")"
);
if
(
Asserts
.
isNotNullString
(
comment
))
{
if
(
comment
.
contains
(
"\'"
)
|
comment
.
contains
(
"\""
))
{
sb
.
append
(
" COMMENT '"
+
comment
.
replaceAll
(
"\"|'"
,
""
)
+
"'\n"
);
}
else
{
if
(
Asserts
.
isNotNullString
(
comment
))
{
if
(
comment
.
contains
(
"\'"
)
|
comment
.
contains
(
"\""
))
{
sb
.
append
(
" COMMENT '"
+
comment
.
replaceAll
(
"\"|'"
,
""
)
+
"'\n"
);
}
else
{
sb
.
append
(
" COMMENT '"
+
comment
+
"'\n"
);
}
}
...
...
@@ -128,21 +128,21 @@ public class Table implements Serializable, Comparable<Table> {
if
(
i
>
0
)
{
sb
.
append
(
","
);
}
String
columnComment
=
columns
.
get
(
i
).
getComment
();
if
(
Asserts
.
isNotNullString
(
columnComment
))
{
String
columnComment
=
columns
.
get
(
i
).
getComment
();
if
(
Asserts
.
isNotNullString
(
columnComment
))
{
if
(
columnComment
.
contains
(
"\'"
)
|
columnComment
.
contains
(
"\""
))
{
columnComment
=
columnComment
.
replaceAll
(
"\"|'"
,
""
);
}
sb
.
append
(
"`"
+
columns
.
get
(
i
).
getName
()
+
"` -- "
+
columnComment
+
" \n"
);
}
else
{
sb
.
append
(
"`"
+
columns
.
get
(
i
).
getName
()
+
"` \n"
);
sb
.
append
(
"`"
+
columns
.
get
(
i
).
getName
()
+
"` -- "
+
columnComment
+
" \n"
);
}
else
{
sb
.
append
(
"`"
+
columns
.
get
(
i
).
getName
()
+
"` \n"
);
}
}
if
(
Asserts
.
isNotNullString
(
comment
))
{
if
(
Asserts
.
isNotNullString
(
comment
))
{
sb
.
append
(
" FROM "
+
schema
+
"."
+
name
+
";"
+
" -- "
+
comment
+
"\n"
);
}
else
{
sb
.
append
(
" FROM "
+
schema
+
"."
+
name
+
";\n"
);
}
else
{
sb
.
append
(
" FROM "
+
schema
+
"."
+
name
+
";\n"
);
}
return
sb
.
toString
();
}
...
...
dlink-common/src/main/java/com/dlink/pool/ClassEntity.java
View file @
0d5e7e57
...
...
@@ -28,14 +28,14 @@ public class ClassEntity {
this
.
classByte
=
classByte
;
}
public
static
ClassEntity
build
(
String
name
,
String
code
){
return
new
ClassEntity
(
name
,
code
);
public
static
ClassEntity
build
(
String
name
,
String
code
)
{
return
new
ClassEntity
(
name
,
code
);
}
public
boolean
equals
(
ClassEntity
entity
)
{
if
(
Asserts
.
isEquals
(
name
,
entity
.
getName
())
&&
Asserts
.
isEquals
(
code
,
entity
.
getCode
())){
if
(
Asserts
.
isEquals
(
name
,
entity
.
getName
())
&&
Asserts
.
isEquals
(
code
,
entity
.
getCode
()))
{
return
true
;
}
else
{
}
else
{
return
false
;
}
}
...
...
dlink-common/src/main/java/com/dlink/pool/ClassPool.java
View file @
0d5e7e57
...
...
@@ -31,8 +31,8 @@ public class ClassPool {
return
false
;
}
public
static
Integer
push
(
ClassEntity
executorEntity
){
if
(
exist
(
executorEntity
.
getName
()))
{
public
static
Integer
push
(
ClassEntity
executorEntity
)
{
if
(
exist
(
executorEntity
.
getName
()))
{
remove
(
executorEntity
.
getName
());
}
classList
.
add
(
executorEntity
);
...
...
dlink-common/src/main/java/com/dlink/result/AbstractResult.java
View file @
0d5e7e57
...
...
@@ -17,12 +17,12 @@ public class AbstractResult {
protected
long
time
;
protected
String
error
;
public
void
success
(){
public
void
success
()
{
this
.
setEndTime
(
LocalDateTime
.
now
());
this
.
setSuccess
(
true
);
}
public
void
error
(
String
error
){
public
void
error
(
String
error
)
{
this
.
setEndTime
(
LocalDateTime
.
now
());
this
.
setSuccess
(
false
);
this
.
setError
(
error
);
...
...
dlink-common/src/main/java/com/dlink/result/SqlExplainResult.java
View file @
0d5e7e57
package
com
.
dlink
.
result
;
import
java.time.LocalDateTime
;
import
java.util.Date
;
/**
* 解释结果
*
* @author
wenmo
* @since
2021/6/7 22:06
* @author wenmo
* @since 2021/6/7 22:06
**/
public
class
SqlExplainResult
{
private
Integer
index
;
...
...
@@ -35,12 +34,12 @@ public class SqlExplainResult {
this
.
explainTime
=
explainTime
;
}
public
static
SqlExplainResult
success
(
String
type
,
String
sql
,
String
explain
)
{
return
new
SqlExplainResult
(
1
,
type
,
sql
,
null
,
explain
,
null
,
true
,
true
,
LocalDateTime
.
now
());
public
static
SqlExplainResult
success
(
String
type
,
String
sql
,
String
explain
)
{
return
new
SqlExplainResult
(
1
,
type
,
sql
,
null
,
explain
,
null
,
true
,
true
,
LocalDateTime
.
now
());
}
public
static
SqlExplainResult
fail
(
String
sql
,
String
error
)
{
return
new
SqlExplainResult
(
1
,
null
,
sql
,
null
,
null
,
error
,
false
,
false
,
LocalDateTime
.
now
());
public
static
SqlExplainResult
fail
(
String
sql
,
String
error
)
{
return
new
SqlExplainResult
(
1
,
null
,
sql
,
null
,
null
,
error
,
false
,
false
,
LocalDateTime
.
now
());
}
public
Integer
getIndex
()
{
...
...
dlink-common/src/main/java/com/dlink/utils/JSONUtil.java
View file @
0d5e7e57
...
...
@@ -3,12 +3,7 @@ package com.dlink.utils;
import
com.dlink.assertion.Asserts
;
import
com.fasterxml.jackson.core.JsonParser
;
import
com.fasterxml.jackson.core.type.TypeReference
;
import
com.fasterxml.jackson.databind.DeserializationContext
;
import
com.fasterxml.jackson.databind.JsonDeserializer
;
import
com.fasterxml.jackson.databind.JsonNode
;
import
com.fasterxml.jackson.databind.ObjectMapper
;
import
com.fasterxml.jackson.databind.ObjectWriter
;
import
com.fasterxml.jackson.databind.SerializationFeature
;
import
com.fasterxml.jackson.databind.*
;
import
com.fasterxml.jackson.databind.node.ArrayNode
;
import
com.fasterxml.jackson.databind.node.ObjectNode
;
import
com.fasterxml.jackson.databind.node.TextNode
;
...
...
@@ -17,15 +12,9 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.TimeZone
;
import
static
com
.
fasterxml
.
jackson
.
databind
.
DeserializationFeature
.
ACCEPT_EMPTY_ARRAY_AS_NULL_OBJECT
;
import
static
com
.
fasterxml
.
jackson
.
databind
.
DeserializationFeature
.
FAIL_ON_UNKNOWN_PROPERTIES
;
import
static
com
.
fasterxml
.
jackson
.
databind
.
DeserializationFeature
.
READ_UNKNOWN_ENUM_VALUES_AS_NULL
;
import
java.util.*
;
import
static
com
.
fasterxml
.
jackson
.
databind
.
DeserializationFeature
.*;
import
static
com
.
fasterxml
.
jackson
.
databind
.
MapperFeature
.
REQUIRE_SETTERS_FOR_GETTERS
;
import
static
java
.
nio
.
charset
.
StandardCharsets
.
UTF_8
;
...
...
@@ -124,7 +113,7 @@ public class JSONUtil {
}
public
static
String
toJsonString
(
Object
object
)
{
if
(
Asserts
.
isNull
(
object
))
{
if
(
Asserts
.
isNull
(
object
))
{
return
null
;
}
try
{
...
...
dlink-common/src/main/java/com/dlink/utils/LogUtil.java
View file @
0d5e7e57
...
...
@@ -18,33 +18,33 @@ public class LogUtil {
private
static
final
Logger
logger
=
LoggerFactory
.
getLogger
(
LogUtil
.
class
);
public
static
String
getError
(
Exception
e
){
public
static
String
getError
(
Exception
e
)
{
// e.printStackTrace();
String
error
=
null
;
try
(
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
))
{
try
(
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
))
{
e
.
printStackTrace
(
pw
);
error
=
sw
.
toString
();
logger
.
error
(
error
);
}
catch
(
IOException
ioe
)
{
ioe
.
printStackTrace
();
}
finally
{
}
finally
{
return
error
;
}
}
public
static
String
getError
(
String
msg
,
Exception
e
)
{
public
static
String
getError
(
String
msg
,
Exception
e
)
{
// e.printStackTrace();
String
error
=
null
;
try
(
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
))
{
try
(
StringWriter
sw
=
new
StringWriter
();
PrintWriter
pw
=
new
PrintWriter
(
sw
))
{
e
.
printStackTrace
(
pw
);
LocalDateTime
now
=
LocalDateTime
.
now
();
error
=
now
.
toString
()
+
": "
+
msg
+
" \nError message:\n "
+
sw
.
toString
();
logger
.
error
(
error
);
}
catch
(
IOException
ioe
)
{
ioe
.
printStackTrace
();
}
finally
{
}
finally
{
return
error
;
}
}
...
...
dlink-common/src/main/java/com/dlink/utils/RunTimeUtil.java
View file @
0d5e7e57
...
...
@@ -8,7 +8,7 @@ package com.dlink.utils;
**/
public
class
RunTimeUtil
{
public
static
void
recovery
(
Object
obj
){
public
static
void
recovery
(
Object
obj
)
{
obj
=
null
;
System
.
gc
();
}
...
...
dlink-common/src/main/java/com/dlink/utils/SqlUtil.java
View file @
0d5e7e57
...
...
@@ -25,6 +25,6 @@ public class SqlUtil {
}
public
static
String
replaceAllParam
(
String
sql
,
String
name
,
String
value
)
{
return
sql
.
replaceAll
(
"\\$\\{"
+
name
+
"\\}"
,
value
);
return
sql
.
replaceAll
(
"\\$\\{"
+
name
+
"\\}"
,
value
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment