Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
web-ui
Project
Overview
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
WEBGDE-Components
web-ui
Commits
3f94e7dd
Commit
3f94e7dd
authored
Oct 09, 2023
by
Owen Ryan Ang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'development-mobile' into 'feature-WG-399'
# Conflicts: # WebGde/WebContent/WebGde-Widgets/config.js # WebGde/WebContent/script.js # WebGde/WebContent/style.css
parents
1a65bd81
89892ed8
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
548 additions
and
66 deletions
+548
-66
.classpath
WebGde/.classpath
+5
-5
org.eclipse.ltk.core.refactoring.prefs
WebGde/.settings/org.eclipse.ltk.core.refactoring.prefs
+2
-0
org.eclipse.wst.common.project.facet.core.xml
...e/.settings/org.eclipse.wst.common.project.facet.core.xml
+1
-1
rejectElement.js
WebGde/WebContent/WebGde-Widgets/BPO/rejectElement.js
+9
-8
returnElement.js
WebGde/WebContent/WebGde-Widgets/BPO/returnElement.js
+9
-9
androidInterface.js
...gets/DataInputWidget/AndroidInterface/androidInterface.js
+4
-0
captureVideo.js
...bGde-Widgets/DataInputWidget/VideoCapture/captureVideo.js
+52
-0
generateFields.js
...bContent/WebGde-Widgets/DataInputWidget/generateFields.js
+438
-29
XML_Saver.js
...e/WebContent/WebGde-Widgets/Submit/XMLWriter/XML_Saver.js
+3
-3
submit.js
WebGde/WebContent/WebGde-Widgets/Submit/submit.js
+5
-7
config.js
WebGde/WebContent/WebGde-Widgets/config.js
+2
-2
schema_sqa.json
...e/WebContent/WebGde-Widgets/sample_schema/schema_sqa.json
+1
-1
script.js
WebGde/WebContent/script.js
+17
-1
No files found.
WebGde/.classpath
View file @
3f94e7dd
...
...
@@ -24,11 +24,6 @@
<attribute
name=
"maven.pomderived"
value=
"true"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"con"
path=
"fish.payara.eclipse.tools.server.lib.system"
>
<attributes>
<attribute
name=
"owner.project.facets"
value=
"jst.web"
/>
</attributes>
</classpathentry>
<classpathentry
excluding=
"**"
kind=
"src"
output=
"target/classes"
path=
"src/main/resources"
>
<attributes>
<attribute
name=
"maven.pomderived"
value=
"true"
/>
...
...
@@ -42,5 +37,10 @@
<attribute
name=
"optional"
value=
"true"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"con"
path=
"org.eclipse.payara.tools.lib.system"
>
<attributes>
<attribute
name=
"owner.project.facets"
value=
"jst.web"
/>
</attributes>
</classpathentry>
<classpathentry
kind=
"output"
path=
"target/classes"
/>
</classpath>
WebGde/.settings/org.eclipse.ltk.core.refactoring.prefs
0 → 100644
View file @
3f94e7dd
eclipse.preferences.version=1
org.eclipse.ltk.core.refactoring.enable.project.refactoring.history=false
WebGde/.settings/org.eclipse.wst.common.project.facet.core.xml
View file @
3f94e7dd
<?xml version="1.0" encoding="UTF-8"?>
<faceted-project>
<runtime
name=
"Payara"
/>
<runtime
name=
"Payara
Server 5 (5.2022.5)
"
/>
<fixed
facet=
"jst.web"
/>
<fixed
facet=
"java"
/>
<fixed
facet=
"wst.jsdt.web"
/>
...
...
WebGde/WebContent/WebGde-Widgets/BPO/rejectElement.js
View file @
3f94e7dd
import
{
createLoadingScreen
,
resetGDE
}
from
"../../script.js"
;
import
{
SCHEMA_FILE_PATH
}
from
"../DataInputWidget/config.js"
;
import
{
validateInput
}
from
"../DataInputWidget/validateInput.js"
;
import
{
PROJECT_CODE
}
from
"../Submit/config.js"
;
import
{
ENCODING_PASS
,
REASON_LIST
,
SCHEMA_FILE
}
from
"../config.js"
;
import
{
ENCODING_PASS
,
REASON_LIST
}
from
"../config.js"
;
import
{
createInfoModal
,
createModal
}
from
"../genericPopup/genericPopup.js"
;
import
{
BPO_OBJECT
,
IMAGE_VIEWER_OBJECT
,
INDEXED_DB_STORAGE
}
from
"../globalVariable.js"
;
import
{
getRejectElement
}
from
"./bpoService.js"
;
...
...
@@ -331,20 +332,20 @@ function saveExceptionToXml(){
"projCode"
:
PROJECT_CODE
,
"userId"
:
sessionStorage
.
getItem
(
"user_id"
),
"elementId"
:
elementId
,
"schema"
:
SCHEMA_FILE
,
"totalRec"
:
urls
.
length
,
"schema"
:
SCHEMA_FILE
_PATH
,
"totalRec"
:
"0"
,
"maxRec"
:
"1"
,
"totalKeystroke"
:
0
,
"totalKeystroke"
:
""
,
"procTime"
:
""
,
"procDuration"
:
0
,
"procDuration"
:
""
,
"eob"
:
""
,
"exceptionRemark"
:
selected
,
"recordNo"
:
"
1
"
,
"recordNo"
:
"
0
"
,
"totalSubRec"
:
"1"
,
"maxSubRec"
:
"1"
,
"imageName"
:
urls
[
parseInt
(
sessionStorage
.
getItem
(
"display_counter"
))]
,
"imageName"
:
""
,
"subRecordNo"
:
"1"
,
"eor"
:
""
,
"eor"
:
"
N
"
,
"fields"
:
{},
"outputDir"
:
sessionStorage
.
getItem
(
"element_file_loc"
)
+
"/"
+
(
ENCODING_PASS
==
"PASS1"
?
elementId
+
".DTA"
:
elementId
+
".DTB"
),
"doctype"
:
doctype
,
...
...
WebGde/WebContent/WebGde-Widgets/BPO/returnElement.js
View file @
3f94e7dd
import
{
createLoadingScreen
,
removeLoadingScreen
,
resetGDE
}
from
"../../script.js"
;
import
{
SCHEMA_FILE_PATH
}
from
"../DataInputWidget/config.js"
;
import
{
validateInput
}
from
"../DataInputWidget/validateInput.js"
;
import
{
PROJECT_CODE
}
from
"../Submit/config.js"
;
import
{
interval
}
from
"../captureMetrics/captureMetrics.js"
;
import
{
SCHEMA_FILE
}
from
"../config.js"
;
import
{
createInfoModal
,
createModal
}
from
"../genericPopup/genericPopup.js"
;
import
{
BPO_OBJECT
,
IMAGE_VIEWER_OBJECT
,
INDEXED_DB_STORAGE
}
from
"../globalVariable.js"
;
import
{
getUrlReturnElement
}
from
"./bpoService.js"
;
...
...
@@ -59,21 +59,21 @@ function returnSaveXML(){
"projCode"
:
PROJECT_CODE
,
"userId"
:
sessionStorage
.
getItem
(
"user_id"
),
"elementId"
:
elementId
,
"schema"
:
SCHEMA_FILE
,
"totalRec"
:
filePaths
.
length
,
"schema"
:
SCHEMA_FILE
_PATH
,
"totalRec"
:
"0"
,
"maxRec"
:
"1"
,
"totalKeystroke"
:
0
,
"totalKeystroke"
:
""
,
"procTime"
:
""
,
"procDuration"
:
0
,
"procDuration"
:
""
,
"eob"
:
""
,
"exceptionRemark"
:
""
,
"recordNo"
:
parseInt
(
sessionStorage
.
getItem
(
"display_counter"
))
+
1
,
"recordNo"
:
"0"
,
"totalSubRec"
:
"1"
,
"maxSubRec"
:
"1"
,
"imageName"
:
filePaths
[
parseInt
(
sessionStorage
.
getItem
(
"display_counter"
))]
,
"imageName"
:
""
,
"subRecordNo"
:
"1"
,
"eor"
:
""
,
"fields"
:
{}
,
"eor"
:
"
N
"
,
"fields"
:
fields
,
"outputDir"
:
sessionStorage
.
getItem
(
"element_file_loc"
)
+
"/"
+
(
ENCODING_PASS
==
"PASS1"
?
elementId
+
".DTA"
:
elementId
+
".DTB"
),
"doctype"
:
doctype
,
"section"
:
section
...
...
WebGde/WebContent/WebGde-Widgets/DataInputWidget/AndroidInterface/androidInterface.js
View file @
3f94e7dd
...
...
@@ -3,6 +3,10 @@ export function imageCapture(key) {
window
.
ImageCaptureInterface
.
captureImage
(
key
);
}
export
function
videoCapture
(
key
){
window
.
VideoCaptureInterface
.
captureVideo
(
key
);
}
export
function
selfieCapture
(
key
)
{
// Call Android function via javaScript interface
window
.
ImageCaptureInterface
.
captureSelfie
(
key
);
...
...
WebGde/WebContent/WebGde-Widgets/DataInputWidget/VideoCapture/captureVideo.js
0 → 100644
View file @
3f94e7dd
export
function
processVideoCapture
(
key
,
videoFilename
){
const
form
=
document
.
getElementById
(
'fields'
);
const
thumb
=
document
.
getElementById
(
`
${
key
}
_thumbnail`
);
const
filename
=
document
.
getElementById
(
`
${
key
}
_fname`
);
const
x
=
document
.
getElementById
(
`
${
key
}
_x`
);
// const filenameString = generateMediaFileName(sessionStorage.getItem('user_id'));
const
filenameString
=
videoFilename
;
// Create hidden inputs for fname and file content
const
hiddenFnameInput
=
document
.
createElement
(
'input'
);
hiddenFnameInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFnameInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFnameInput
.
setAttribute
(
'name'
,
'hidden_fname'
);
form
.
appendChild
(
hiddenFnameInput
);
const
hiddenFileContentInput
=
document
.
createElement
(
'input'
);
hiddenFileContentInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFileContentInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFileContentInput
.
setAttribute
(
'name'
,
'hidden_file_content'
);
form
.
appendChild
(
hiddenFileContentInput
);
thumb
.
style
.
display
=
'inline'
;
thumb
.
style
.
width
=
'100%'
;
thumb
.
style
.
height
=
'100%'
;
filename
.
textContent
=
filenameString
;
filename
.
style
.
display
=
'inline'
;
// Set the hidden inputs when a file is selected
hiddenFnameInput
.
value
=
filenameString
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
thumb
.
src
;
// This will store the base64-encoded content of the file
hiddenFileContentInput
.
display
=
''
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
thumb
.
style
.
display
=
'none'
;
x
.
style
.
display
=
'none'
;
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
// Clear the hidden fields
hiddenFnameInput
.
display
=
'none'
;
hiddenFnameInput
.
value
=
''
;
hiddenFileContentInput
.
display
=
'none'
;
hiddenFileContentInput
.
value
=
''
;
});
}
\ No newline at end of file
WebGde/WebContent/WebGde-Widgets/DataInputWidget/generateFields.js
View file @
3f94e7dd
...
...
@@ -6,9 +6,10 @@ import { showError } from "./showError.js";
import
{
submitForm
}
from
"../Submit/submit.js"
;
import
{
BPO_OBJECT
}
from
"../globalVariable.js"
;
import
{
fetchOptionsDB
}
from
"./DBLookup/DBLookup.js"
;
import
{
fingerprintCapture
,
getLocation
,
imageCapture
}
from
"./AndroidInterface/androidInterface.js"
;
import
{
fingerprintCapture
,
getLocation
,
imageCapture
,
videoCapture
}
from
"./AndroidInterface/androidInterface.js"
;
import
{
processCapture
}
from
"./ImageCapture/captureImage.js"
;
import
{
processFingerprint
}
from
"./FingerprintCapture/captureFingerprint.js"
;
import
{
processVideoCapture
}
from
"./VideoCapture/captureVideo.js"
;
let
newOption
;
export
let
schema
;
...
...
@@ -53,7 +54,7 @@ export async function generateFields(inputSchema, containerId) {
let
doctype
=
sessionStorage
.
getItem
(
'doctype'
);
let
section
=
sessionStorage
.
getItem
(
'section'
);
if
((
doctype
===
null
||
doctype
===
"undefined"
)
&&
(
section
===
null
||
section
===
"undefined"
))
{
Object
.
keys
(
schema
).
every
(
function
(
key
)
{
Object
.
keys
(
schema
).
every
(
function
(
key
)
{
let
doctypes
=
schema
[
key
];
let
underscoredKey
=
key
.
replaceAll
(
" "
,
"_"
);
sessionStorage
.
setItem
(
"currentDoctype"
,
underscoredKey
);
...
...
@@ -122,7 +123,7 @@ export async function generateFields(inputSchema, containerId) {
}
}
$
(
document
.
body
).
on
(
"change"
,
"#DocType"
,
async
function
()
{
$
(
document
.
body
).
on
(
"change"
,
"#DocType"
,
async
function
()
{
const
elements
=
document
.
getElementsByClassName
(
sessionStorage
.
getItem
(
"currentSection"
));
while
(
elements
.
length
>
0
)
{
elements
[
0
].
parentNode
.
removeChild
(
elements
[
0
]);
...
...
@@ -156,7 +157,7 @@ export async function generateFields(inputSchema, containerId) {
}
});
$
(
document
.
body
).
on
(
"change"
,
"#Section"
,
async
function
()
{
$
(
document
.
body
).
on
(
"change"
,
"#Section"
,
async
function
()
{
const
elements
=
document
.
getElementsByClassName
(
sessionStorage
.
getItem
(
"currentSection"
));
while
(
elements
.
length
>
0
)
{
elements
[
0
].
parentNode
.
removeChild
(
elements
[
0
]);
...
...
@@ -177,7 +178,7 @@ export async function generateFields(inputSchema, containerId) {
// add handler event handler for dropdown
// separate handler is used to fit with the library used 'select2'
$
(
document
.
body
).
ready
(
function
()
{
$
(
document
.
body
).
ready
(
function
()
{
const
dropdowns
=
$
(
'.dropdown-input'
).
select2
();
dropdowns
.
splice
(
0
,
2
);
$
(
'.dropdown-input'
).
select2
().
on
(
'select2:open'
,
()
=>
{
...
...
@@ -193,7 +194,7 @@ export async function generateFields(inputSchema, containerId) {
dropdowns
.
on
(
'select2:close'
,
handleDropdown
)
});
$
(
document
).
ready
(
function
()
{
$
(
document
).
ready
(
function
()
{
$
(
'form:first *:input[type!=hidden]:first'
).
focus
();
// Run code
});
}
...
...
@@ -515,7 +516,7 @@ const inputImageCapture = (key, validation) => {
if
(
file
.
type
.
startsWith
(
'image/'
))
{
// If it's an image file, display it directly
const
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
reader
.
onload
=
function
(
e
)
{
img
.
src
=
e
.
target
.
result
;
img
.
style
.
display
=
'inline'
;
thumb
.
style
.
display
=
'none'
;
...
...
@@ -590,7 +591,7 @@ const inputImageCapture = (key, validation) => {
const
x
=
document
.
createElement
(
'span'
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'class'
,
'x'
);
x
.
setAttribute
(
'style'
,
'display: none'
)
x
.
textContent
=
'x'
;
...
...
@@ -664,6 +665,204 @@ const inputImageCapture = (key, validation) => {
* @returns
* created input field element
*/
const
inputVideoCapture
=
(
key
,
validation
)
=>
{
try
{
const
{
mandatory
,
fieldLength
}
=
validation
const
container
=
document
.
createElement
(
'div'
);
const
container2
=
document
.
createElement
(
'div'
);
container
.
appendChild
(
container2
);
container2
.
classList
.
add
(
'image-capture'
);
const
input
=
document
.
createElement
(
'input'
);
input
.
setAttribute
(
'id'
,
`
${
key
}
_attachedMedia`
);
input
.
setAttribute
(
'name'
,
`
${
key
}
`
);
input
.
setAttribute
(
'type'
,
'file'
);
input
.
setAttribute
(
'style'
,
'display: none'
);
input
.
setAttribute
(
'accept'
,
'image/*, video/*'
);
// Accept both image and video files
const
capturedImage
=
document
.
createElement
(
'input'
);
capturedImage
.
setAttribute
(
'id'
,
`
${
key
}
_capturedImageData`
);
capturedImage
.
setAttribute
(
'name'
,
`
${
key
}
`
);
capturedImage
.
setAttribute
(
'type'
,
'hidden'
);
capturedImage
.
setAttribute
(
'style'
,
'display: none'
);
// Add an event listener to handle when a file is selected
input
.
addEventListener
(
'change'
,
(
event
)
=>
{
const
file
=
event
.
target
.
files
[
0
];
if
(
file
)
{
// Create hidden inputs for fname and file content
const
hiddenFnameInput
=
document
.
createElement
(
'input'
);
hiddenFnameInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFnameInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFnameInput
.
setAttribute
(
'name'
,
'hidden_fname'
);
container2
.
appendChild
(
hiddenFnameInput
);
const
hiddenFileContentInput
=
document
.
createElement
(
'input'
);
hiddenFileContentInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFileContentInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFileContentInput
.
setAttribute
(
'name'
,
'hidden_file_content'
);
container2
.
appendChild
(
hiddenFileContentInput
);
const
img
=
document
.
getElementById
(
`
${
key
}
_zz`
);
const
thumb
=
document
.
getElementById
(
`
${
key
}
_thumbnail`
);
const
x
=
document
.
getElementById
(
`
${
key
}
_x`
);
if
(
file
.
type
.
startsWith
(
'image/'
))
{
// If it's an image file, display it directly
const
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
img
.
src
=
e
.
target
.
result
;
img
.
style
.
display
=
'inline'
;
thumb
.
style
.
display
=
'none'
;
filename
.
textContent
=
file
.
name
;
filename
.
style
.
display
=
'inline'
;
// Set the hidden inputs when a file is selected
hiddenFnameInput
.
value
=
file
.
name
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
e
.
target
.
result
;
// This will store the base64-encoded content of the file
hiddenFileContentInput
.
display
=
''
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
img
.
style
.
display
=
'none'
;
img
.
src
=
''
;
thumb
.
style
.
display
=
'none'
;
x
.
style
.
display
=
'none'
;
input
.
value
=
''
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
// Clear the hidden fields
container2
.
removeChild
(
hiddenFnameInput
);
container2
.
removeChild
(
hiddenFileContentInput
);
});
};
reader
.
readAsDataURL
(
file
);
}
else
if
(
file
.
type
.
startsWith
(
'video/'
))
{
const
reader
=
new
FileReader
();
reader
.
readAsDataURL
(
file
);
reader
.
onload
=
(
e
)
=>
{
thumbnail
.
src
=
e
.
target
.
result
;
thumbnail
.
style
.
display
=
'inline'
;
filename
.
textContent
=
file
.
name
;
filename
.
style
.
display
=
'inline'
;
// Set the hidden inputs when a file is selected
hiddenFnameInput
.
value
=
file
.
name
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
e
.
target
.
result
;
// This will store the base64-encoded content of the file
hiddenFileContentInput
.
display
=
''
;
// Hide the img tag since we're showing the video thumbnail
document
.
getElementById
(
`
${
key
}
_zz`
).
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
img
.
style
.
display
=
'none'
;
img
.
src
=
''
;
thumb
.
style
.
display
=
'none'
;
x
.
style
.
display
=
'none'
;
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
input
.
value
=
''
// Clear the hidden fields
container2
.
removeChild
(
hiddenFnameInput
);
container2
.
removeChild
(
hiddenFileContentInput
);
});
}
}
else
{
console
.
log
(
'Unsupported file type'
);
}
}
});
const
x
=
document
.
createElement
(
'span'
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'class'
,
'x'
);
x
.
setAttribute
(
'style'
,
'display: none'
)
x
.
textContent
=
'x'
;
const
dash
=
document
.
createElement
(
'label'
);
dash
.
setAttribute
(
'class'
,
'dash'
);
dash
.
innerHTML
=
' or '
;
const
input1
=
document
.
createElement
(
'input'
);
input1
.
setAttribute
(
'id'
,
`
${
key
}
`
);
input1
.
setAttribute
(
'name'
,
`
${
key
}
`
);
input1
.
setAttribute
(
'type'
,
'button'
);
input1
.
addEventListener
(
'click'
,
()
=>
{
document
.
getElementById
(
`
${
key
}
_attachedMedia`
).
click
();
// Trigger click on hidden input
});
input1
.
setAttribute
(
'value'
,
'Upload File'
);
const
input2
=
document
.
createElement
(
'input'
);
input2
.
setAttribute
(
'id'
,
`
${
key
}
`
);
input2
.
setAttribute
(
'name'
,
`
${
key
}
`
);
input2
.
setAttribute
(
'type'
,
'button'
);
input2
.
setAttribute
(
'value'
,
'Capture Video'
);
input2
.
addEventListener
(
'click'
,
()
=>
{
videoCapture
(
key
);
});
window
.
processVideoCapture
=
processVideoCapture
;
const
img
=
document
.
createElement
(
'img'
);
const
thumbnail
=
document
.
createElement
(
'video'
);
thumbnail
.
setAttribute
(
'style'
,
'display: none'
);
thumbnail
.
setAttribute
(
'id'
,
`
${
key
}
_thumbnail`
);
img
.
setAttribute
(
'id'
,
`
${
key
}
_zz`
);
img
.
setAttribute
(
'style'
,
'display: none'
);
const
filename
=
document
.
createElement
(
'span'
);
filename
.
setAttribute
(
'id'
,
`
${
key
}
_fname`
);
filename
.
setAttribute
(
'name'
,
`
${
key
}
`
);
filename
.
setAttribute
(
'type'
,
'text'
);
filename
.
setAttribute
(
'style'
,
'display: none; font-size: inherit;'
);
// Append all elements to the container
const
container3
=
document
.
createElement
(
'div'
);
container2
.
appendChild
(
x
);
container3
.
setAttribute
(
'id'
,
`
${
key
}
_buttonsContainer-video`
)
container3
.
setAttribute
(
'class'
,
'buttonsContainer'
);
container3
.
appendChild
(
input
);
// container3.appendChild(input1);
// container3.appendChild(dash);
container3
.
appendChild
(
input2
);
container2
.
appendChild
(
container3
)
container2
.
appendChild
(
img
);
container2
.
appendChild
(
thumbnail
);
container2
.
appendChild
(
filename
);
mandatory
?
input
.
setAttribute
(
'required'
,
'true'
)
:
null
return
container
}
catch
(
err
)
{
throw
err
}
}
/**
*
* @param {*} key
* will serve as id of input field
* @param {*} validation
* validation of field from schema
* @returns
* created input field element
*/
const
inputFingerprintCapture
=
(
key
,
validation
)
=>
{
try
{
const
{
...
...
@@ -709,11 +908,11 @@ const inputFingerprintCapture = (key, validation) => {
const
img
=
document
.
getElementById
(
`
${
key
}
_zz`
);
const
thumb
=
document
.
getElementById
(
`
${
key
}
_thumbnail`
);
const
x
=
document
.
getElement
sByClassName
(
'x'
)[
0
]
;
const
x
=
document
.
getElement
ById
(
`
${
key
}
_x`
)
;
if
(
file
.
type
.
startsWith
(
'image/'
))
{
// If it's an image file, display it directly
const
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
reader
.
onload
=
function
(
e
)
{
img
.
src
=
e
.
target
.
result
;
img
.
style
.
display
=
'inline'
;
thumb
.
style
.
display
=
'none'
;
...
...
@@ -788,7 +987,7 @@ const inputFingerprintCapture = (key, validation) => {
const
x
=
document
.
createElement
(
'span'
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'class'
,
'x'
);
x
.
setAttribute
(
'style'
,
'display: none'
)
x
.
textContent
=
'x'
;
...
...
@@ -927,6 +1126,214 @@ const inputAudioUpload = (key, validation) => {
}
/**
*
* @param {*} key
* will serve as id of input field
* @param {*} validation
* validation of field from schema
* @returns
* created input field element
*/
const
inputFileUpload
=
(
key
,
validation
)
=>
{
try
{
const
{
mandatory
,
fieldLength
}
=
validation
const
container
=
document
.
createElement
(
'div'
);
const
container2
=
document
.
createElement
(
'div'
);
container
.
appendChild
(
container2
);
container2
.
classList
.
add
(
'file-upload'
);
const
input
=
document
.
createElement
(
'input'
);
input
.
setAttribute
(
'id'
,
`
${
key
}
_attachedMedia`
);
input
.
setAttribute
(
'name'
,
`
${
key
}
`
);
input
.
setAttribute
(
'type'
,
'file'
);
input
.
setAttribute
(
'style'
,
'display: none'
);
input
.
setAttribute
(
'accept'
,
'*/*'
);
// Accept any files
const
capturedImage
=
document
.
createElement
(
'input'
);
capturedImage
.
setAttribute
(
'id'
,
`
${
key
}
_capturedImageData`
);
capturedImage
.
setAttribute
(
'name'
,
`
${
key
}
`
);
capturedImage
.
setAttribute
(
'type'
,
'hidden'
);
capturedImage
.
setAttribute
(
'style'
,
'display: none'
);
// Add an event listener to handle when a file is selected
input
.
addEventListener
(
'change'
,
(
event
)
=>
{
const
file
=
event
.
target
.
files
[
0
];
if
(
file
)
{
// Create hidden inputs for fname and file content
const
hiddenFnameInput
=
document
.
createElement
(
'input'
);
hiddenFnameInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFnameInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFnameInput
.
setAttribute
(
'name'
,
'hidden_fname'
);
container2
.
appendChild
(
hiddenFnameInput
);
const
hiddenFileContentInput
=
document
.
createElement
(
'input'
);
hiddenFileContentInput
.
setAttribute
(
'id'
,
`
${
key
}
`
);
hiddenFileContentInput
.
setAttribute
(
'type'
,
'hidden'
);
hiddenFileContentInput
.
setAttribute
(
'name'
,
'hidden_file_content'
);
container2
.
appendChild
(
hiddenFileContentInput
);
const
img
=
document
.
getElementById
(
`
${
key
}
_zz`
);
const
thumb
=
document
.
getElementById
(
`
${
key
}
_thumbnail`
);
const
x
=
document
.
getElementById
(
`
${
key
}
_x`
);
if
(
file
.
type
.
startsWith
(
'image/'
))
{
// If it's an image file, display it directly
const
reader
=
new
FileReader
();
reader
.
onload
=
function
(
e
)
{
img
.
src
=
e
.
target
.
result
;
img
.
style
.
display
=
'inline'
;
img
.
style
.
width
=
'100%'
;
// Set maximum width to 100% of the container
img
.
style
.
height
=
'100%'
;
// Set maximum height to a specific value (adjust as needed)
thumb
.
style
.
display
=
'none'
;
filename
.
textContent
=
file
.
name
;
filename
.
style
.
display
=
'inline'
;
// Set the hidden inputs when a file is selected
hiddenFnameInput
.
value
=
file
.
name
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
e
.
target
.
result
;
// This will store the base64-encoded content of the file
hiddenFileContentInput
.
display
=
''
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
img
.
style
.
display
=
'none'
;
img
.
src
=
''
;
thumb
.
style
.
display
=
'none'
;
x
.
style
.
display
=
'none'
;
input
.
value
=
''
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
// Clear the hidden fields
container2
.
removeChild
(
hiddenFnameInput
);
container2
.
removeChild
(
hiddenFileContentInput
);
});
};
reader
.
readAsDataURL
(
file
);
}
else
if
(
file
.
type
.
startsWith
(
'video/'
))
{
const
reader
=
new
FileReader
();
reader
.
readAsDataURL
(
file
);
reader
.
onload
=
(
e
)
=>
{
thumbnail
.
src
=
e
.
target
.
result
;
thumbnail
.
style
.
display
=
'inline'
;
thumbnail
.
style
.
width
=
'100%'
;
thumbnail
.
style
.
height
=
'100%'
;
filename
.
textContent
=
file
.
name
;
filename
.
style
.
display
=
'inline'
;
// Set the hidden inputs when a file is selected
hiddenFnameInput
.
value
=
file
.
name
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
e
.
target
.
result
;
// This will store the base64-encoded content of the file
hiddenFileContentInput
.
display
=
''
;
// Hide the img tag since we're showing the video thumbnail
document
.
getElementById
(
`
${
key
}
_zz`
).
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
img
.
style
.
display
=
'none'
;
img
.
src
=
''
;
thumb
.
style
.
display
=
'none'
;
x
.
style
.
display
=
'none'
;
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
input
.
value
=
''
// Clear the hidden fields
container2
.
removeChild
(
hiddenFnameInput
);
container2
.
removeChild
(
hiddenFileContentInput
);
});
}
}
else
{
// Display the filename only for unsupported file types
filename
.
textContent
=
file
.
name
;
filename
.
style
.
display
=
'inline'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'none'
;
x
.
style
.
display
=
'block'
;
x
.
style
.
position
=
'absolute'
;
// Set the hidden inputs for filename and empty file content
hiddenFnameInput
.
value
=
file
.
name
;
hiddenFnameInput
.
display
=
''
;
hiddenFileContentInput
.
value
=
''
;
// Empty content for unsupported file types
hiddenFileContentInput
.
display
=
''
;
// Remove the file on 'x' click
document
.
getElementById
(
`
${
key
}
_x`
).
addEventListener
(
'click'
,
()
=>
{
filename
.
style
.
display
=
'none'
;
document
.
getElementById
(
`
${
key
}
_buttonsContainer-video`
).
style
.
display
=
'flex'
;
input
.
value
=
''
;
x
.
style
.
display
=
'none'
;
// Clear the hidden fields
container2
.
removeChild
(
hiddenFnameInput
);
container2
.
removeChild
(
hiddenFileContentInput
);
});
}
}
});
const
x
=
document
.
createElement
(
'span'
)
x
.
setAttribute
(
'id'
,
`
${
key
}
_x`
)
x
.
setAttribute
(
'class'
,
'x'
);
x
.
setAttribute
(
'style'
,
'display: none'
)
x
.
textContent
=
'x'
;
const
input1
=
document
.
createElement
(
'input'
);
input1
.
setAttribute
(
'id'
,
`
${
key
}
`
);
input1
.
setAttribute
(
'name'
,
`
${
key
}
`
);
input1
.
setAttribute
(
'type'
,
'button'
);
input1
.
addEventListener
(
'click'
,
()
=>
{
document
.
getElementById
(
`
${
key
}
_attachedMedia`
).
click
();
// Trigger click on hidden input
});
input1
.
setAttribute
(
'value'
,
'Upload File'
);
const
img
=
document
.
createElement
(
'img'
);
const
thumbnail
=
document
.
createElement
(
'video'
);
thumbnail
.
setAttribute
(
'style'
,
'display: none'
);
thumbnail
.
setAttribute
(
'id'
,
`
${
key
}
_thumbnail`
);
img
.
setAttribute
(
'id'
,
`
${
key
}
_zz`
);
img
.
setAttribute
(
'style'
,
'display: none'
);
const
filename
=
document
.
createElement
(
'span'
);
filename
.
setAttribute
(
'id'
,
`
${
key
}
_fname`
);
filename
.
setAttribute
(
'name'
,
`
${
key
}
`
);
filename
.
setAttribute
(
'type'
,
'text'
);
filename
.
setAttribute
(
'style'
,
'display: none; font-size: inherit;'
);
// Append all elements to the container
const
container3
=
document
.
createElement
(
'div'
);
container2
.
appendChild
(
x
);
container3
.
setAttribute
(
'id'
,
`
${
key
}
_buttonsContainer-video`
)
container3
.
setAttribute
(
'class'
,
'buttonsContainer'
);
container3
.
appendChild
(
input
);
container3
.
appendChild
(
input1
);
container2
.
appendChild
(
container3
)
container2
.
appendChild
(
img
);
container2
.
appendChild
(
thumbnail
);
container2
.
appendChild
(
filename
);
mandatory
?
input
.
setAttribute
(
'required'
,
'true'
)
:
null
return
container
}
catch
(
err
)
{
throw
err
}
}
/**
*
...
...
@@ -949,10 +1356,10 @@ const inputChecklist = (key, validation) => {
var
isOther
=
false
;
// Create the checkboxes for each item
items
.
forEach
(
function
(
item
,
index
)
{
if
(
item
.
toLowerCase
()
===
"other"
||
item
.
toLowerCase
()
===
"others"
){
items
.
forEach
(
function
(
item
,
index
)
{
if
(
item
.
toLowerCase
()
===
"other"
||
item
.
toLowerCase
()
===
"others"
)
{
isOther
=
true
;
}
else
{
}
else
{
var
div
=
document
.
createElement
(
'div'
);
div
.
classList
.
add
(
'checkbox'
);
...
...
@@ -969,8 +1376,8 @@ const inputChecklist = (key, validation) => {
dropdownContent
.
appendChild
(
div
)
}
})
if
(
isOther
)
{
if
(
isOther
)
{
// Create the checkbox dependent on an input text value
var
dependentDiv
=
document
.
createElement
(
'div'
);
dependentDiv
.
classList
.
add
(
'checkbox'
);
...
...
@@ -985,7 +1392,7 @@ const inputChecklist = (key, validation) => {
var
dependentLabel
=
document
.
createTextNode
(
'other'
);
dependentDiv
.
appendChild
(
dependentLabel
);
dropdownContent
.
appendChild
(
dependentDiv
);
// Initially hide the input text box
var
inputTextBox
=
document
.
createElement
(
'input'
);
inputTextBox
.
type
=
'text'
;
...
...
@@ -996,7 +1403,7 @@ const inputChecklist = (key, validation) => {
dropdownContent
.
appendChild
(
inputTextBox
);
// Add event listener to the "other" checkbox
dependentCheckbox
.
addEventListener
(
'change'
,
function
()
{
dependentCheckbox
.
addEventListener
(
'change'
,
function
()
{
if
(
dependentCheckbox
.
checked
)
{
inputTextBox
.
style
.
display
=
'inline-block'
;
}
else
{
...
...
@@ -1040,9 +1447,9 @@ const inputRadiolist = (key, validation) => {
// Create radio buttons for each item
items
.
forEach
((
item
,
index
)
=>
{
if
(
item
.
toLowerCase
()
===
"other"
||
item
.
toLowerCase
()
===
"others"
){
if
(
item
.
toLowerCase
()
===
"other"
||
item
.
toLowerCase
()
===
"others"
)
{
isOther
=
true
;
}
else
{
}
else
{
var
radioDiv
=
document
.
createElement
(
'div'
);
radioDiv
.
classList
.
add
(
'radio-like-checkbox'
);
...
...
@@ -1059,7 +1466,7 @@ const inputRadiolist = (key, validation) => {
dropdownContent
.
appendChild
(
radioDiv
);
}
});
if
(
isOther
){
if
(
isOther
)
{
// Create the radio button dependent on an input text value
var
dependentDiv
=
document
.
createElement
(
'div'
);
dependentDiv
.
classList
.
add
(
'radio-like-checkbox'
);
...
...
@@ -1083,7 +1490,7 @@ const inputRadiolist = (key, validation) => {
dropdownContent
.
appendChild
(
inputTextBox
);
// Add event listener to the "other" radio button
dependentRadio
.
addEventListener
(
'change'
,
function
()
{
dependentRadio
.
addEventListener
(
'change'
,
function
()
{
if
(
dependentRadio
.
checked
)
{
inputTextBox
.
style
.
display
=
'inline-block'
;
}
else
{
...
...
@@ -1127,7 +1534,7 @@ const inputGeoTag = (key, validation) => {
input1
.
setAttribute
(
'class'
,
`
${
collection
}
`
)
input1
.
setAttribute
(
'type'
,
'text'
)
input1
.
setAttribute
(
'readonly'
,
'true'
)
if
(
collection
===
'geotag'
)
{
if
(
collection
===
'geotag'
)
{
getLocation
();
}
...
...
@@ -1163,7 +1570,7 @@ const inputDropdown = (key, validation) => {
input
.
classList
.
add
(
'dropdown-input'
)
input
.
addEventListener
(
'focusout'
,
handleInput
)
input
.
addEventListener
(
'keydown'
,
function
(
event
)
{
input
.
addEventListener
(
'keydown'
,
function
(
event
)
{
if
(
event
.
keyCode
==
9
)
{
event
.
preventDefault
();
var
elem
=
document
.
getElementsByClassName
(
'select2-search__field'
);
...
...
@@ -1207,7 +1614,7 @@ const inputDbLookup = async (key, validation) => {
input
.
classList
.
add
(
'dropdown-input'
);
input
.
addEventListener
(
'focusout'
,
handleInput
);
input
.
addEventListener
(
'keydown'
,
function
(
event
)
{
input
.
addEventListener
(
'keydown'
,
function
(
event
)
{
if
(
event
.
keyCode
==
9
)
{
event
.
preventDefault
();
var
elem
=
document
.
getElementsByClassName
(
'select2-search__field'
);
...
...
@@ -1379,14 +1786,16 @@ const deconstruct = async (section, container, classAttribute) => {
input
=
await
inputDbLookup
(
key
,
validation
)
break
case
'image-capture'
:
case
'video-capture'
:
input
=
inputImageCapture
(
key
,
validation
)
break
case
'video-capture'
:
input
=
inputVideoCapture
(
key
,
validation
)
break
case
'fingerprint'
:
input
=
inputFingerprintCapture
(
key
,
validation
)
break
case
'
selfie-capture
'
:
input
=
input
SelfieCapture
(
key
,
validation
)
case
'
file-upload
'
:
input
=
input
FileUpload
(
key
,
validation
)
break
case
'audio-upload'
:
input
=
inputAudioUpload
(
key
,
validation
)
...
...
@@ -1458,7 +1867,7 @@ const deconstruct = async (section, container, classAttribute) => {
showHideElements
(
section
);
// Replace "SECTION1" with the desired section key
//logic for show hide
if
(
selectElement
)
{
selectElement
.
addEventListener
(
"change"
,
function
()
{
selectElement
.
addEventListener
(
"change"
,
function
()
{
showHideElements
(
section
);
});
}
...
...
WebGde/WebContent/WebGde-Widgets/Submit/XMLWriter/XML_Saver.js
View file @
3f94e7dd
...
...
@@ -158,17 +158,17 @@ async function createBPOXML(fields, metrics, doctype, section){
"userId"
:
sessionStorage
.
getItem
(
"user_id"
),
"elementId"
:
elementId
,
"schema"
:
SCHEMA_FILE_PATH
,
"totalRec"
:
filePaths
.
length
,
"totalRec"
:
"0"
,
"maxRec"
:
"1"
,
"totalKeystroke"
:
metrics
[
0
],
"procTime"
:
""
,
"procDuration"
:
metrics
[
1
],
"eob"
:
""
,
"exceptionRemark"
:
""
,
"recordNo"
:
parseInt
(
sessionStorage
.
getItem
(
"display_counter"
))
+
1
,
"recordNo"
:
"0"
,
"totalSubRec"
:
"1"
,
"maxSubRec"
:
"1"
,
"imageName"
:
filePaths
[
parseInt
(
sessionStorage
.
getItem
(
"display_counter"
))]
,
"imageName"
:
""
,
"subRecordNo"
:
"1"
,
"eor"
:
"N"
,
"fields"
:
fields
,
...
...
WebGde/WebContent/WebGde-Widgets/Submit/submit.js
View file @
3f94e7dd
...
...
@@ -111,7 +111,11 @@ export const submitForm = async (e) => {
});
console
.
log
(
await
getFile
.
text
());
// await uploadTOGFS(await getFile.text(), sessionStorage.getItem("recentlySavedFileName"));
}
else
if
(
IS_RETRIEVE_FROM_BPO
===
"Y"
){
}
else
{
createInfoModal
(
null
,
'OK'
,
'Error while uploading'
);
return
false
}
}
else
{
let
response
=
await
WriteForm
(
e
,
[],
doctype
,
section
);
await
batchUpload
(
Form
);
if
(
response
!==
false
)
{
...
...
@@ -128,12 +132,6 @@ export const submitForm = async (e) => {
});
}
}
}
else
{
createInfoModal
(
null
,
'OK'
,
'Error while uploading'
);
return
false
}
// saveForm(sessionStorage.getItem("display_counter"));
}
return
true
...
...
WebGde/WebContent/WebGde-Widgets/config.js
View file @
3f94e7dd
...
...
@@ -12,7 +12,7 @@ export const ROOT_FOLDER = "/WebGde-Widgets";
//this determines if the images will be retrieved from the gfs
export
const
DOMAIN
=
"http://52.207.220.74:8080"
export
const
CONTEXTROOT
=
"gfs-explorer-ws"
export
const
GDE_URL
=
DOMAIN
+
"/MobileGde/svc/gfs-rest"
export
const
GDE_URL
=
DOMAIN
+
"/MobileGde
Dev
/svc/gfs-rest"
export
const
FOLDER_URL
=
DOMAIN
+
"/"
+
CONTEXTROOT
+
"/svc/gfs-rest/get-folder?parentPath=/Users/"
export
const
DOWNLOAD_URL
=
DOMAIN
+
"/"
+
CONTEXTROOT
+
"/svc/gfs-rest/get-download-link"
export
const
IS_RETRIEVE_FROM_GFS
=
"N"
...
...
@@ -20,7 +20,7 @@ export const IS_RETRIEVE_FROM_GFS = "N"
export
const
INVALID_KEYS
=
"F1,F2,F3,F4,F5,F6,F7,F8,F9,F10,F11,F12,PrintScreen,ScrollLock,Pause,PageUp,PageDown,Insert,Delete,Control"
//BPO CONFIG
export
const
IS_RETRIEVE_FROM_BPO
=
"
Y
"
export
const
IS_RETRIEVE_FROM_BPO
=
"
N
"
// export const BPO_URL = "http://35.171.20.94:8080/bpo-sqa/"
// export const CURRENT_NODE = "Web GDE"
export
const
BPO_URL
=
DOMAIN
+
"/bpo/"
;
...
...
WebGde/WebContent/WebGde-Widgets/sample_schema/schema_sqa.json
View file @
3f94e7dd
...
...
@@ -13,7 +13,7 @@
"fieldLabel"
:
"Patient Image"
,
"aka"
:
"field1"
,
"validation"
:
{
"collection"
:
"
image
-capture"
,
"collection"
:
"
video
-capture"
,
"mandatory"
:
true
}
},
...
...
WebGde/WebContent/script.js
View file @
3f94e7dd
...
...
@@ -44,16 +44,23 @@ async function initializeWebGDE() {
// UNCOMMENTED BY ADAM 9/25/2023
sessionStorage
.
setItem
(
"element_id"
,
"element1"
);
<<<<<<<
WebGde
/
WebContent
/
script
.
js
/* await createWebGdeInterface(null);*/
setDocumentControlObject
(
new
DocumentControlWidget
());
/* document.getElementById("input-field-container").appendChild(DOCUMENT_CONTROL_OBJECT.getWidget());*/
=======
await
createWebGdeInterface
(
null
);
setDocumentControlObject
(
new
DocumentControlWidget
());
document
.
getElementById
(
"input-field-container"
).
appendChild
(
DOCUMENT_CONTROL_OBJECT
.
getWidget
());
>>>>>>>
WebGde
/
WebContent
/
script
.
js
var
mainLogInScreenContainer
=
document
.
getElementById
(
"logInMainContainer"
);
mainLogInScreenContainer
.
remove
();
removeLoadingScreen
();
new
ElementListWidget
(
'Web_GDE_DEV'
,
'containerId'
);
//
new ElementListWidget('Web_GDE_DEV', 'containerId');
}
...
...
@@ -135,12 +142,21 @@ export function removeLoadingScreen() {
}
<<<<<<<
WebGde
/
WebContent
/
script
.
js
export
async
function
resetGDE
()
{
// TO-DO
}
function
init
()
{
console
.
log
(
"Application Started"
);
=======
export
async
function
resetGDE
(){
// TO-DO
}
function
init
(){
console
.
log
(
"Application Started"
);
>>>>>>>
WebGde
/
WebContent
/
script
.
js
}
...
...
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