Initial Commit
This commit is contained in:
commit
62d68374e1
|
|
@ -0,0 +1,2 @@
|
||||||
|
node_modules/
|
||||||
|
uploads/
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
const multer = require('multer');
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
var storage = multer.diskStorage({
|
||||||
|
destination: (req, file, cb) => {
|
||||||
|
var dir = __basedir + '/uploads/' + file.originalname.split('.').slice(0, -1).join('.');
|
||||||
|
if (!fs.existsSync(dir)){
|
||||||
|
fs.mkdirSync(dir);
|
||||||
|
}
|
||||||
|
cb(null, __basedir + '/uploads/' + file.originalname.split('.').slice(0, -1).join('.'))
|
||||||
|
},
|
||||||
|
filename: (req, file, cb) => {
|
||||||
|
cb(null, 'my_model.py');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
var upload = multer({storage: storage});
|
||||||
|
|
||||||
|
module.exports = upload;
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
const uploadFolder = __basedir + '/uploads/';
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
exports.uploadFile = (req, res) => {
|
||||||
|
res.send('File uploaded successfully! -> filename = ' + req.file.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.listAllFiles = (req, res) => {
|
||||||
|
fs.readdir(uploadFolder, (err, files) => {
|
||||||
|
res.send(files);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.downloadFile = (req, res) => {
|
||||||
|
var filename = req.params.filename;
|
||||||
|
res.download(uploadFolder + filename);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = (app, router, upload) => {
|
||||||
|
const fileWorker = require('../controllers/file.controller.js');
|
||||||
|
|
||||||
|
var path = __basedir + '/views/';
|
||||||
|
|
||||||
|
router.use((req,res,next) => {
|
||||||
|
console.log("/" + req.method);
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
app.get('/', (req,res) => {
|
||||||
|
res.sendFile(path + "index.html");
|
||||||
|
});
|
||||||
|
|
||||||
|
app.post('/api/files/upload', upload.single("uploadfile"), fileWorker.uploadFile);
|
||||||
|
|
||||||
|
app.get('/api/files/getall', fileWorker.listAllFiles);
|
||||||
|
|
||||||
|
app.get('/api/files/:filename', fileWorker.downloadFile);
|
||||||
|
|
||||||
|
app.use('/',router);
|
||||||
|
|
||||||
|
app.use('*', (req,res) => {
|
||||||
|
res.sendFile(path + "404.html");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,746 @@
|
||||||
|
{
|
||||||
|
"name": "nodejs-express-multer-multipartfile-ajax-jquery-bootstrap",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@types/component-emitter": {
|
||||||
|
"version": "1.2.10",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.10.tgz",
|
||||||
|
"integrity": "sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg=="
|
||||||
|
},
|
||||||
|
"@types/cookie": {
|
||||||
|
"version": "0.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.0.tgz",
|
||||||
|
"integrity": "sha512-y7mImlc/rNkvCRmg8gC3/lj87S7pTUIJ6QGjwHR9WQJcFs+ZMTOaoPrkdFA/YdbuqVEmEbb5RdhVxMkAcgOnpg=="
|
||||||
|
},
|
||||||
|
"@types/cors": {
|
||||||
|
"version": "2.8.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.9.tgz",
|
||||||
|
"integrity": "sha512-zurD1ibz21BRlAOIKP8yhrxlqKx6L9VCwkB5kMiP6nZAhoF5MvC7qS1qPA7nRcr1GJolfkQC7/EAL4hdYejLtg=="
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "14.14.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz",
|
||||||
|
"integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ=="
|
||||||
|
},
|
||||||
|
"JSONStream": {
|
||||||
|
"version": "0.10.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.10.0.tgz",
|
||||||
|
"integrity": "sha1-dDSdDYlSK3HzDwoD/5vSDKbxKsA=",
|
||||||
|
"requires": {
|
||||||
|
"jsonparse": "0.0.5",
|
||||||
|
"through": ">=2.2.7 <3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"accepts": {
|
||||||
|
"version": "1.3.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
|
||||||
|
"integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
|
||||||
|
"requires": {
|
||||||
|
"mime-types": "~2.1.18",
|
||||||
|
"negotiator": "0.6.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"append-field": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/append-field/-/append-field-0.1.0.tgz",
|
||||||
|
"integrity": "sha1-bdxY+gg8e8VF08WZWygwzCNm1Eo="
|
||||||
|
},
|
||||||
|
"array-flatten": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||||
|
},
|
||||||
|
"base64-arraybuffer": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-mBjHngWbE1X5fgQooBfIOOkLqBI="
|
||||||
|
},
|
||||||
|
"base64id": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog=="
|
||||||
|
},
|
||||||
|
"body-parser": {
|
||||||
|
"version": "1.18.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
|
||||||
|
"integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
|
||||||
|
"requires": {
|
||||||
|
"bytes": "3.0.0",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.1",
|
||||||
|
"http-errors": "~1.6.2",
|
||||||
|
"iconv-lite": "0.4.19",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"qs": "6.5.1",
|
||||||
|
"raw-body": "2.3.2",
|
||||||
|
"type-is": "~1.6.15"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
|
||||||
|
},
|
||||||
|
"busboy": {
|
||||||
|
"version": "0.2.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/busboy/-/busboy-0.2.14.tgz",
|
||||||
|
"integrity": "sha1-bCpiLvz0fFe7vh4qnDetNseSVFM=",
|
||||||
|
"requires": {
|
||||||
|
"dicer": "0.2.5",
|
||||||
|
"readable-stream": "1.1.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bytes": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
|
||||||
|
},
|
||||||
|
"component-emitter": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz",
|
||||||
|
"integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg=="
|
||||||
|
},
|
||||||
|
"concat-stream": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
|
||||||
|
"integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "^1.0.0",
|
||||||
|
"inherits": "^2.0.3",
|
||||||
|
"readable-stream": "^2.2.2",
|
||||||
|
"typedarray": "^0.0.6"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"isarray": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "2.3.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||||
|
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.3",
|
||||||
|
"isarray": "~1.0.0",
|
||||||
|
"process-nextick-args": "~2.0.0",
|
||||||
|
"safe-buffer": "~5.1.1",
|
||||||
|
"string_decoder": "~1.1.1",
|
||||||
|
"util-deprecate": "~1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||||
|
"requires": {
|
||||||
|
"safe-buffer": "~5.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"content-disposition": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
|
||||||
|
},
|
||||||
|
"content-type": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
|
||||||
|
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
|
||||||
|
},
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
|
||||||
|
"integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
|
||||||
|
},
|
||||||
|
"cookie-signature": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||||
|
},
|
||||||
|
"core-util-is": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||||
|
},
|
||||||
|
"cors": {
|
||||||
|
"version": "2.8.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz",
|
||||||
|
"integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==",
|
||||||
|
"requires": {
|
||||||
|
"object-assign": "^4",
|
||||||
|
"vary": "^1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"object-assign": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "2.6.9",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||||
|
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"depd": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
|
||||||
|
},
|
||||||
|
"destroy": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||||
|
},
|
||||||
|
"dicer": {
|
||||||
|
"version": "0.2.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/dicer/-/dicer-0.2.5.tgz",
|
||||||
|
"integrity": "sha1-WZbAhrszIYyBLAkL3cCc0S+stw8=",
|
||||||
|
"requires": {
|
||||||
|
"readable-stream": "1.1.x",
|
||||||
|
"streamsearch": "0.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"docker-modem": {
|
||||||
|
"version": "0.3.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/docker-modem/-/docker-modem-0.3.7.tgz",
|
||||||
|
"integrity": "sha1-P1ENCfXTNNwhNCKPkr00RnEiffQ=",
|
||||||
|
"requires": {
|
||||||
|
"JSONStream": "0.10.0",
|
||||||
|
"debug": "^2.6.0",
|
||||||
|
"readable-stream": "~1.0.26-4",
|
||||||
|
"split-ca": "^1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "1.0.34",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
|
||||||
|
"integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.1",
|
||||||
|
"isarray": "0.0.1",
|
||||||
|
"string_decoder": "~0.10.x"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ee-first": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||||
|
},
|
||||||
|
"encodeurl": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
|
||||||
|
},
|
||||||
|
"engine.io": {
|
||||||
|
"version": "4.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io/-/engine.io-4.0.5.tgz",
|
||||||
|
"integrity": "sha512-Ri+whTNr2PKklxQkfbGjwEo+kCBUM4Qxk4wtLqLrhH+b1up2NFL9g9pjYWiCV/oazwB0rArnvF/ZmZN2ab5Hpg==",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "2.0.0",
|
||||||
|
"cookie": "~0.4.1",
|
||||||
|
"cors": "~2.8.5",
|
||||||
|
"debug": "~4.1.0",
|
||||||
|
"engine.io-parser": "~4.0.0",
|
||||||
|
"ws": "^7.1.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"cookie": {
|
||||||
|
"version": "0.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz",
|
||||||
|
"integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA=="
|
||||||
|
},
|
||||||
|
"debug": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"engine.io-parser": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==",
|
||||||
|
"requires": {
|
||||||
|
"base64-arraybuffer": "0.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"escape-html": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||||
|
},
|
||||||
|
"etag": {
|
||||||
|
"version": "1.8.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||||
|
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
|
||||||
|
},
|
||||||
|
"express": {
|
||||||
|
"version": "4.16.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
|
||||||
|
"integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
|
||||||
|
"requires": {
|
||||||
|
"accepts": "~1.3.5",
|
||||||
|
"array-flatten": "1.1.1",
|
||||||
|
"body-parser": "1.18.2",
|
||||||
|
"content-disposition": "0.5.2",
|
||||||
|
"content-type": "~1.0.4",
|
||||||
|
"cookie": "0.3.1",
|
||||||
|
"cookie-signature": "1.0.6",
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"finalhandler": "1.1.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"merge-descriptors": "1.0.1",
|
||||||
|
"methods": "~1.1.2",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.2",
|
||||||
|
"path-to-regexp": "0.1.7",
|
||||||
|
"proxy-addr": "~2.0.3",
|
||||||
|
"qs": "6.5.1",
|
||||||
|
"range-parser": "~1.2.0",
|
||||||
|
"safe-buffer": "5.1.1",
|
||||||
|
"send": "0.16.2",
|
||||||
|
"serve-static": "1.13.2",
|
||||||
|
"setprototypeof": "1.1.0",
|
||||||
|
"statuses": "~1.4.0",
|
||||||
|
"type-is": "~1.6.16",
|
||||||
|
"utils-merge": "1.0.1",
|
||||||
|
"vary": "~1.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"finalhandler": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
|
||||||
|
"integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"parseurl": "~1.3.2",
|
||||||
|
"statuses": "~1.4.0",
|
||||||
|
"unpipe": "~1.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"forwarded": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
|
||||||
|
},
|
||||||
|
"fresh": {
|
||||||
|
"version": "0.5.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||||
|
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
|
||||||
|
},
|
||||||
|
"http-errors": {
|
||||||
|
"version": "1.6.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
|
||||||
|
"integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
|
||||||
|
"requires": {
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.1.0",
|
||||||
|
"statuses": ">= 1.4.0 < 2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"iconv-lite": {
|
||||||
|
"version": "0.4.19",
|
||||||
|
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
|
||||||
|
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||||
|
},
|
||||||
|
"ipaddr.js": {
|
||||||
|
"version": "1.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
|
||||||
|
"integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs="
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
|
||||||
|
},
|
||||||
|
"jsonparse": {
|
||||||
|
"version": "0.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-0.0.5.tgz",
|
||||||
|
"integrity": "sha1-MwVCrT8KZUZlt3jz6y2an6UHrGQ="
|
||||||
|
},
|
||||||
|
"media-typer": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
|
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||||
|
},
|
||||||
|
"memorystream": {
|
||||||
|
"version": "0.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/memorystream/-/memorystream-0.3.1.tgz",
|
||||||
|
"integrity": "sha1-htcJCzDORV1j+64S3aUaR93K+bI="
|
||||||
|
},
|
||||||
|
"merge-descriptors": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||||
|
},
|
||||||
|
"methods": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
|
||||||
|
},
|
||||||
|
"mime": {
|
||||||
|
"version": "1.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
|
||||||
|
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
|
||||||
|
},
|
||||||
|
"mime-db": {
|
||||||
|
"version": "1.33.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
|
||||||
|
"integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
|
||||||
|
},
|
||||||
|
"mime-types": {
|
||||||
|
"version": "2.1.18",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
|
||||||
|
"integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
|
||||||
|
"requires": {
|
||||||
|
"mime-db": "~1.33.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||||
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||||
|
"requires": {
|
||||||
|
"minimist": "0.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||||
|
},
|
||||||
|
"multer": {
|
||||||
|
"version": "1.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/multer/-/multer-1.3.0.tgz",
|
||||||
|
"integrity": "sha1-CSsmcPaEb6SRSWXvyM+Uwg/sbNI=",
|
||||||
|
"requires": {
|
||||||
|
"append-field": "^0.1.0",
|
||||||
|
"busboy": "^0.2.11",
|
||||||
|
"concat-stream": "^1.5.0",
|
||||||
|
"mkdirp": "^0.5.1",
|
||||||
|
"object-assign": "^3.0.0",
|
||||||
|
"on-finished": "^2.3.0",
|
||||||
|
"type-is": "^1.6.4",
|
||||||
|
"xtend": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"negotiator": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
|
||||||
|
},
|
||||||
|
"node-docker-api": {
|
||||||
|
"version": "1.1.22",
|
||||||
|
"resolved": "https://registry.npmjs.org/node-docker-api/-/node-docker-api-1.1.22.tgz",
|
||||||
|
"integrity": "sha1-IwMn79MJpuxzAr8/QEq3YAQKWAY=",
|
||||||
|
"requires": {
|
||||||
|
"docker-modem": "^0.3.1",
|
||||||
|
"memorystream": "^0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"object-assign": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I="
|
||||||
|
},
|
||||||
|
"on-finished": {
|
||||||
|
"version": "2.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||||
|
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||||
|
"requires": {
|
||||||
|
"ee-first": "1.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parseurl": {
|
||||||
|
"version": "1.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
|
||||||
|
"integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
|
||||||
|
},
|
||||||
|
"path-to-regexp": {
|
||||||
|
"version": "0.1.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
|
||||||
|
"integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
|
||||||
|
},
|
||||||
|
"process-nextick-args": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||||
|
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||||
|
},
|
||||||
|
"proxy-addr": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
|
||||||
|
"requires": {
|
||||||
|
"forwarded": "~0.1.2",
|
||||||
|
"ipaddr.js": "1.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"qs": {
|
||||||
|
"version": "6.5.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
|
||||||
|
"integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
|
||||||
|
},
|
||||||
|
"range-parser": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
|
||||||
|
},
|
||||||
|
"raw-body": {
|
||||||
|
"version": "2.3.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
|
||||||
|
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
|
||||||
|
"requires": {
|
||||||
|
"bytes": "3.0.0",
|
||||||
|
"http-errors": "1.6.2",
|
||||||
|
"iconv-lite": "0.4.19",
|
||||||
|
"unpipe": "1.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"depd": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
|
||||||
|
},
|
||||||
|
"http-errors": {
|
||||||
|
"version": "1.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
|
||||||
|
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
|
||||||
|
"requires": {
|
||||||
|
"depd": "1.1.1",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"setprototypeof": "1.0.3",
|
||||||
|
"statuses": ">= 1.3.1 < 2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"setprototypeof": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"readable-stream": {
|
||||||
|
"version": "1.1.14",
|
||||||
|
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
|
||||||
|
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
|
||||||
|
"requires": {
|
||||||
|
"core-util-is": "~1.0.0",
|
||||||
|
"inherits": "~2.0.1",
|
||||||
|
"isarray": "0.0.1",
|
||||||
|
"string_decoder": "~0.10.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"safe-buffer": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||||
|
},
|
||||||
|
"send": {
|
||||||
|
"version": "0.16.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
|
||||||
|
"integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
|
||||||
|
"requires": {
|
||||||
|
"debug": "2.6.9",
|
||||||
|
"depd": "~1.1.2",
|
||||||
|
"destroy": "~1.0.4",
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"etag": "~1.8.1",
|
||||||
|
"fresh": "0.5.2",
|
||||||
|
"http-errors": "~1.6.2",
|
||||||
|
"mime": "1.4.1",
|
||||||
|
"ms": "2.0.0",
|
||||||
|
"on-finished": "~2.3.0",
|
||||||
|
"range-parser": "~1.2.0",
|
||||||
|
"statuses": "~1.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"serve-static": {
|
||||||
|
"version": "1.13.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
|
||||||
|
"integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
|
||||||
|
"requires": {
|
||||||
|
"encodeurl": "~1.0.2",
|
||||||
|
"escape-html": "~1.0.3",
|
||||||
|
"parseurl": "~1.3.2",
|
||||||
|
"send": "0.16.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"setprototypeof": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
|
||||||
|
},
|
||||||
|
"socket.io": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io/-/socket.io-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-Vj1jUoO75WGc9txWd311ZJJqS9Dr8QtNJJ7gk2r7dcM/yGe9sit7qOijQl3GAwhpBOz/W8CwkD7R6yob07nLbA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/cookie": "^0.4.0",
|
||||||
|
"@types/cors": "^2.8.8",
|
||||||
|
"@types/node": "^14.14.7",
|
||||||
|
"accepts": "~1.3.4",
|
||||||
|
"base64id": "~2.0.0",
|
||||||
|
"debug": "~4.1.0",
|
||||||
|
"engine.io": "~4.0.0",
|
||||||
|
"socket.io-adapter": "~2.0.3",
|
||||||
|
"socket.io-parser": "~4.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"socket.io-adapter": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.0.3.tgz",
|
||||||
|
"integrity": "sha512-2wo4EXgxOGSFueqvHAdnmi5JLZzWqMArjuP4nqC26AtLh5PoCPsaRbRdah2xhcwTAMooZfjYiNVNkkmmSMaxOQ=="
|
||||||
|
},
|
||||||
|
"socket.io-parser": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-Bs3IYHDivwf+bAAuW/8xwJgIiBNtlvnjYRc4PbXgniLmcP1BrakBoq/QhO24rgtgW7VZ7uAaswRGxutUnlAK7g==",
|
||||||
|
"requires": {
|
||||||
|
"@types/component-emitter": "^1.2.10",
|
||||||
|
"component-emitter": "~1.3.0",
|
||||||
|
"debug": "~4.1.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"debug": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
|
||||||
|
"integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
|
||||||
|
"requires": {
|
||||||
|
"ms": "^2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ms": {
|
||||||
|
"version": "2.1.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
|
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"split-ca": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/split-ca/-/split-ca-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-bIOv82kvphJW4M0ZfgXp3hV2kaY="
|
||||||
|
},
|
||||||
|
"statuses": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
|
||||||
|
},
|
||||||
|
"streamsearch": {
|
||||||
|
"version": "0.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
|
||||||
|
"integrity": "sha1-gIudDlb8Jz2Am6VzOOkpkZoanxo="
|
||||||
|
},
|
||||||
|
"string_decoder": {
|
||||||
|
"version": "0.10.31",
|
||||||
|
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
|
||||||
|
"integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
|
||||||
|
},
|
||||||
|
"through": {
|
||||||
|
"version": "2.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
|
||||||
|
"integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
|
||||||
|
},
|
||||||
|
"type-is": {
|
||||||
|
"version": "1.6.16",
|
||||||
|
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
|
||||||
|
"integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
|
||||||
|
"requires": {
|
||||||
|
"media-typer": "0.3.0",
|
||||||
|
"mime-types": "~2.1.18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typedarray": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
|
||||||
|
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
|
||||||
|
},
|
||||||
|
"unpipe": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||||
|
},
|
||||||
|
"util-deprecate": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||||
|
},
|
||||||
|
"utils-merge": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||||
|
},
|
||||||
|
"vary": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||||
|
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||||
|
},
|
||||||
|
"ws": {
|
||||||
|
"version": "7.4.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
|
||||||
|
"integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ=="
|
||||||
|
},
|
||||||
|
"xtend": {
|
||||||
|
"version": "4.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
|
||||||
|
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"name": "nodejs-express-multer-multipartfile-ajax-jquery-bootstrap",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Building a NodeJS/Express web-application that uses Multer middleware to upload MultipartFile with Ajax-JQuery & Bootstrap view",
|
||||||
|
"main": "server.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"NodeJS",
|
||||||
|
"Express",
|
||||||
|
"Multer",
|
||||||
|
"Bootstrap",
|
||||||
|
"Ajax-Jquery"
|
||||||
|
],
|
||||||
|
"author": "JavaSampleApproach.com",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"express": "^4.16.3",
|
||||||
|
"multer": "^1.3.0",
|
||||||
|
"node-docker-api": "^1.1.22",
|
||||||
|
"socket.io": "^3.0.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,129 @@
|
||||||
|
body {
|
||||||
|
overflow-x: hidden;
|
||||||
|
font-size: 18px;
|
||||||
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
position: relative;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
body::after {
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
height: 220px;
|
||||||
|
/* Set same as footer's height */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-------- Navbar --------*/
|
||||||
|
|
||||||
|
.navbar .nav-link {
|
||||||
|
font-size: 20px;
|
||||||
|
background-color: #04021c;
|
||||||
|
padding-left: 1rem !important;
|
||||||
|
padding-right: 1rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-dark {
|
||||||
|
background-color: #04021c!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav > li > a:hover {
|
||||||
|
transition: all 0.3s;
|
||||||
|
color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .active {
|
||||||
|
background: #FFF !important;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav > li > a:hover {
|
||||||
|
cursor:pointer;
|
||||||
|
background-color: #FFF;
|
||||||
|
color: #000 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
#console-box {
|
||||||
|
height: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#console {
|
||||||
|
list-style: none;
|
||||||
|
-webkit-padding-start: 0;
|
||||||
|
-webkit-margin-after: 0;
|
||||||
|
-webkit-margin-before: 1em;
|
||||||
|
border: 1px solid #000;
|
||||||
|
overflow-y: auto;
|
||||||
|
width: 100%;
|
||||||
|
background: #333;
|
||||||
|
color: #fff;
|
||||||
|
height: 200px;
|
||||||
|
max-height: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box-shadow {
|
||||||
|
box-shadow: 0px 10px 50px rgba(0, 0, 0, 0.6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.subfooter {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 60px;
|
||||||
|
width: 100%;
|
||||||
|
height: 160px;
|
||||||
|
background-color: #04021c/*#2d3436*/;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-footer li {
|
||||||
|
font-size: .8125rem;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-footer a {
|
||||||
|
color: #15abe2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-footer a:visited {
|
||||||
|
border-bottom: #D7D7D7;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sub-footer a, a:link {
|
||||||
|
transition: all .4s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.exeter {
|
||||||
|
margin-top: 10%;
|
||||||
|
margin-left: 40%;
|
||||||
|
width: 80%;
|
||||||
|
content:url("/static/img/exeter.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
.russell {
|
||||||
|
margin-top: 5%;
|
||||||
|
margin-left: 40%;
|
||||||
|
width: 80%;
|
||||||
|
content:url("/static/img/russell.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
#main-footer {
|
||||||
|
background: #000;
|
||||||
|
color: #636e72;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 60px;
|
||||||
|
line-height: 60px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,98 @@
|
||||||
|
body{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
overflow:hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
p{
|
||||||
|
text-align: center;
|
||||||
|
overflow: overlay;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
body{
|
||||||
|
-webkit-touch-callout: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-ms-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
background-color: rgb(248, 248, 248)
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbox{
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
margin-left: 1em;
|
||||||
|
border: 2px solid #EEEEEE;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 1em;
|
||||||
|
z-index: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#toolbox input{
|
||||||
|
width: 30px;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
#toolbox input:hover{
|
||||||
|
opacity: 1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hidden-file-upload{
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#download-input{
|
||||||
|
margin: 0 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.conceptG text{
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
marker{
|
||||||
|
fill: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
g.conceptG circle{
|
||||||
|
fill: #F6FBFF;
|
||||||
|
stroke: #333;
|
||||||
|
stroke-width: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
g.conceptG:hover circle{
|
||||||
|
fill: rgb(200, 238, 241);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.selected circle{
|
||||||
|
fill: rgb(250, 232, 255);
|
||||||
|
}
|
||||||
|
g.selected:hover circle{
|
||||||
|
fill: rgb(250, 232, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
path.link {
|
||||||
|
fill: none;
|
||||||
|
stroke: #333;
|
||||||
|
stroke-width: 6px;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.link:hover{
|
||||||
|
stroke: rgb(94, 196, 204);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.connect-node circle{
|
||||||
|
fill: #BEFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.link.hidden{
|
||||||
|
stroke-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
path.link.selected {
|
||||||
|
stroke: rgb(229, 172, 247);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,648 @@
|
||||||
|
var docEl = document.documentElement,
|
||||||
|
bodyEl = document.getElementsByTagName('body')[0];
|
||||||
|
|
||||||
|
var width = window.innerWidth || docEl.clientWidth || bodyEl.clientWidth,
|
||||||
|
height = window.innerHeight || docEl.clientHeight || bodyEl.clientHeight;
|
||||||
|
|
||||||
|
function fitscreen(nodes, width, height) {
|
||||||
|
var minX = nodes[0].x;
|
||||||
|
var maxX = nodes[0].x;
|
||||||
|
var minY = nodes[0].y;
|
||||||
|
var maxY = nodes[0].y;
|
||||||
|
var offsetX = 0, offsetY = 0;
|
||||||
|
|
||||||
|
nodes.forEach(function (e, i) {
|
||||||
|
if (e.x > maxX) {
|
||||||
|
maxX = e.x
|
||||||
|
}
|
||||||
|
if (e.x < minX) {
|
||||||
|
minX = e.x
|
||||||
|
}
|
||||||
|
if (e.y < minY) {
|
||||||
|
minY = e.y
|
||||||
|
}
|
||||||
|
if (e.y < minY) {
|
||||||
|
minY = e.y
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (minX < 0) {
|
||||||
|
offsetX = - minX;
|
||||||
|
minX += offsetX;
|
||||||
|
maxX += offsetX;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (minY < 0) {
|
||||||
|
offsetY = -minY;
|
||||||
|
minY += offsetY
|
||||||
|
maxY += offsetY;
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes.forEach(function (e, i) {
|
||||||
|
e.x += offsetX;
|
||||||
|
e.y += offsetY;
|
||||||
|
e.x = (e.x - minX) * width * 0.8 / (maxX - minX) + 0.25 * width;
|
||||||
|
e.y = (e.y - minY) * height * 0.8 / (maxY - minY) + 0.25 * height;
|
||||||
|
});
|
||||||
|
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.onload = (function (d3, saveAs, Blob, undefined) {
|
||||||
|
// define graphcreator object
|
||||||
|
var GraphCreator = function (svg, nodes, edges) {
|
||||||
|
var thisGraph = this;
|
||||||
|
thisGraph.idct = 0;
|
||||||
|
|
||||||
|
thisGraph.nodes = nodes || [];
|
||||||
|
thisGraph.edges = edges || [];
|
||||||
|
|
||||||
|
thisGraph.state = {
|
||||||
|
selectedNode: null,
|
||||||
|
selectedEdge: null,
|
||||||
|
mouseDownNode: null,
|
||||||
|
mouseDownLink: null,
|
||||||
|
justDragged: false,
|
||||||
|
justScaleTransGraph: false,
|
||||||
|
lastKeyDown: -1,
|
||||||
|
shiftNodeDrag: false,
|
||||||
|
selectedText: null
|
||||||
|
};
|
||||||
|
|
||||||
|
// define arrow markers for graph links
|
||||||
|
var defs = svg.append('svg:defs');
|
||||||
|
defs.append('svg:marker')
|
||||||
|
.attr('id', 'end-arrow')
|
||||||
|
.attr('viewBox', '0 -5 10 10')
|
||||||
|
.attr('refX', "20")
|
||||||
|
.attr('markerWidth', 3.5)
|
||||||
|
.attr('markerHeight', 3.5)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('svg:path')
|
||||||
|
.attr('d', 'M0,-5L10,0L0,5');
|
||||||
|
|
||||||
|
// define arrow markers for leading arrow
|
||||||
|
defs.append('svg:marker')
|
||||||
|
.attr('id', 'mark-end-arrow')
|
||||||
|
.attr('viewBox', '0 -5 10 10')
|
||||||
|
.attr('refX', 7)
|
||||||
|
.attr('markerWidth', 3.5)
|
||||||
|
.attr('markerHeight', 3.5)
|
||||||
|
.attr('orient', 'auto')
|
||||||
|
.append('svg:path')
|
||||||
|
.attr('d', 'M0,-5L10,0L0,5');
|
||||||
|
|
||||||
|
thisGraph.svg = svg;
|
||||||
|
thisGraph.svgG = svg.append("g")
|
||||||
|
.classed(thisGraph.consts.graphClass, true);
|
||||||
|
var svgG = thisGraph.svgG;
|
||||||
|
|
||||||
|
// displayed when dragging between nodes
|
||||||
|
thisGraph.dragLine = svgG.append('svg:path')
|
||||||
|
.attr('class', 'link dragline hidden')
|
||||||
|
.attr('d', 'M0,0L0,0')
|
||||||
|
.style('marker-end', 'url(#mark-end-arrow)');
|
||||||
|
|
||||||
|
// svg nodes and edges
|
||||||
|
thisGraph.paths = svgG.append("g").selectAll("g");
|
||||||
|
thisGraph.circles = svgG.append("g").selectAll("g");
|
||||||
|
|
||||||
|
thisGraph.drag = d3.behavior.drag()
|
||||||
|
.origin(function (d) {
|
||||||
|
return { x: d.x, y: d.y };
|
||||||
|
})
|
||||||
|
.on("drag", function (args) {
|
||||||
|
thisGraph.state.justDragged = true;
|
||||||
|
thisGraph.dragmove.call(thisGraph, args);
|
||||||
|
})
|
||||||
|
.on("dragend", function () {
|
||||||
|
// todo check if edge-mode is selected
|
||||||
|
});
|
||||||
|
|
||||||
|
// listen for key events
|
||||||
|
d3.select(window).on("keydown", function () {
|
||||||
|
thisGraph.svgKeyDown.call(thisGraph);
|
||||||
|
})
|
||||||
|
.on("keyup", function () {
|
||||||
|
thisGraph.svgKeyUp.call(thisGraph);
|
||||||
|
});
|
||||||
|
svg.on("mousedown", function (d) { thisGraph.svgMouseDown.call(thisGraph, d); });
|
||||||
|
svg.on("mouseup", function (d) { thisGraph.svgMouseUp.call(thisGraph, d); });
|
||||||
|
|
||||||
|
// listen for dragging
|
||||||
|
var dragSvg = d3.behavior.zoom()
|
||||||
|
.on("zoom", function () {
|
||||||
|
if (d3.event.sourceEvent.shiftKey) {
|
||||||
|
// TODO the internal d3 state is still changing
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
thisGraph.zoomed.call(thisGraph);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
})
|
||||||
|
.on("zoomstart", function () {
|
||||||
|
var ael = d3.select("#" + thisGraph.consts.activeEditId).node();
|
||||||
|
if (ael) {
|
||||||
|
ael.blur();
|
||||||
|
}
|
||||||
|
if (!d3.event.sourceEvent.shiftKey) d3.select('body').style("cursor", "move");
|
||||||
|
})
|
||||||
|
.on("zoomend", function () {
|
||||||
|
d3.select('body').style("cursor", "auto");
|
||||||
|
});
|
||||||
|
|
||||||
|
svg.call(dragSvg).on("dblclick.zoom", null);
|
||||||
|
|
||||||
|
// listen for resize
|
||||||
|
window.onresize = function () { thisGraph.updateWindow(svg); };
|
||||||
|
|
||||||
|
// handle download data
|
||||||
|
d3.select("#download-input").on("click", function () {
|
||||||
|
var saveEdges = [];
|
||||||
|
thisGraph.edges.forEach(function (val, i) {
|
||||||
|
saveEdges.push({ source: val.source.id, target: val.target.id });
|
||||||
|
});
|
||||||
|
var blob = new Blob([window.JSON.stringify({ "nodes": thisGraph.nodes, "edges": saveEdges })], { type: "text/plain;charset=utf-8" });
|
||||||
|
saveAs(blob, "mydag.json");
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// handle uploaded data
|
||||||
|
d3.select("#upload-input").on("click", function () {
|
||||||
|
document.getElementById("hidden-file-upload").click();
|
||||||
|
});
|
||||||
|
d3.select("#hidden-file-upload").on("change", function () {
|
||||||
|
if (window.File && window.FileReader && window.FileList && window.Blob) {
|
||||||
|
var uploadFile = this.files[0];
|
||||||
|
var filereader = new window.FileReader();
|
||||||
|
|
||||||
|
filereader.onload = function () {
|
||||||
|
var txtRes = filereader.result;
|
||||||
|
// TODO better error handling
|
||||||
|
try {
|
||||||
|
var jsonObj = JSON.parse(txtRes);
|
||||||
|
jsonObj.nodes = fitscreen(jsonObj.nodes, width, height)
|
||||||
|
thisGraph.deleteGraph(true);
|
||||||
|
thisGraph.nodes = jsonObj.nodes;
|
||||||
|
thisGraph.setIdCt(jsonObj.nodes.length);
|
||||||
|
var newEdges = jsonObj.edges;
|
||||||
|
newEdges.forEach(function (e, i) {
|
||||||
|
newEdges[i] = {
|
||||||
|
source: thisGraph.nodes.filter(function (n) { return n.id == e.source; })[0],
|
||||||
|
target: thisGraph.nodes.filter(function (n) { return n.id == e.target; })[0]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
thisGraph.edges = newEdges;
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
} catch (err) {
|
||||||
|
window.alert("Error parsing uploaded file\nerror message: " + err.message);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
filereader.readAsText(uploadFile);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert("Your browser won't let you save this graph -- try upgrading your browser to IE 10+ or Chrome or Firefox.");
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// handle delete graph
|
||||||
|
d3.select("#delete-graph").on("click", function () {
|
||||||
|
thisGraph.deleteGraph(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.setIdCt = function (idct) {
|
||||||
|
this.idct = idct;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.consts = {
|
||||||
|
selectedClass: "selected",
|
||||||
|
connectClass: "connect-node",
|
||||||
|
circleGClass: "conceptG",
|
||||||
|
graphClass: "graph",
|
||||||
|
activeEditId: "active-editing",
|
||||||
|
BACKSPACE_KEY: 8,
|
||||||
|
DELETE_KEY: 46,
|
||||||
|
ENTER_KEY: 13,
|
||||||
|
nodeRadius: 25
|
||||||
|
};
|
||||||
|
|
||||||
|
/* PROTOTYPE FUNCTIONS */
|
||||||
|
|
||||||
|
GraphCreator.prototype.dragmove = function (d) {
|
||||||
|
var thisGraph = this;
|
||||||
|
if (thisGraph.state.shiftNodeDrag) {
|
||||||
|
thisGraph.dragLine.attr('d', 'M' + d.x + ',' + d.y + 'L' + d3.mouse(thisGraph.svgG.node())[0] + ',' + d3.mouse(this.svgG.node())[1]);
|
||||||
|
} else {
|
||||||
|
d.x += d3.event.dx;
|
||||||
|
d.y += d3.event.dy;
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.deleteGraph = function (skipPrompt) {
|
||||||
|
var thisGraph = this,
|
||||||
|
doDelete = true;
|
||||||
|
if (!skipPrompt) {
|
||||||
|
doDelete = window.confirm("Press OK to delete this graph");
|
||||||
|
}
|
||||||
|
if (doDelete) {
|
||||||
|
thisGraph.nodes = [];
|
||||||
|
thisGraph.edges = [];
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* select all text in element: taken from http://stackoverflow.com/questions/6139107/programatically-select-text-in-a-contenteditable-html-element */
|
||||||
|
GraphCreator.prototype.selectElementContents = function (el) {
|
||||||
|
var range = document.createRange();
|
||||||
|
range.selectNodeContents(el);
|
||||||
|
var sel = window.getSelection();
|
||||||
|
sel.removeAllRanges();
|
||||||
|
sel.addRange(range);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* insert svg line breaks: taken from http://stackoverflow.com/questions/13241475/how-do-i-include-newlines-in-labels-in-d3-charts */
|
||||||
|
GraphCreator.prototype.insertTitleLinebreaks = function (gEl, title) {
|
||||||
|
var words = title.split(/\s+/g),
|
||||||
|
nwords = words.length;
|
||||||
|
var el = gEl.append("text")
|
||||||
|
.attr("text-anchor", "middle")
|
||||||
|
.attr("dy", "-" + (nwords - 1) * 7.5);
|
||||||
|
|
||||||
|
for (var i = 0; i < words.length; i++) {
|
||||||
|
var tspan = el.append('tspan').text(words[i]);
|
||||||
|
if (i > 0)
|
||||||
|
tspan.attr('x', 0).attr('dy', '15');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// remove edges associated with a node
|
||||||
|
GraphCreator.prototype.spliceLinksForNode = function (node) {
|
||||||
|
var thisGraph = this,
|
||||||
|
toSplice = thisGraph.edges.filter(function (l) {
|
||||||
|
return (l.source === node || l.target === node);
|
||||||
|
});
|
||||||
|
toSplice.map(function (l) {
|
||||||
|
thisGraph.edges.splice(thisGraph.edges.indexOf(l), 1);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.replaceSelectEdge = function (d3Path, edgeData) {
|
||||||
|
var thisGraph = this;
|
||||||
|
d3Path.classed(thisGraph.consts.selectedClass, true);
|
||||||
|
if (thisGraph.state.selectedEdge) {
|
||||||
|
thisGraph.removeSelectFromEdge();
|
||||||
|
}
|
||||||
|
thisGraph.state.selectedEdge = edgeData;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.replaceSelectNode = function (d3Node, nodeData) {
|
||||||
|
var thisGraph = this;
|
||||||
|
d3Node.classed(this.consts.selectedClass, true);
|
||||||
|
if (thisGraph.state.selectedNode) {
|
||||||
|
thisGraph.removeSelectFromNode();
|
||||||
|
}
|
||||||
|
thisGraph.state.selectedNode = nodeData;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.removeSelectFromNode = function () {
|
||||||
|
var thisGraph = this;
|
||||||
|
thisGraph.circles.filter(function (cd) {
|
||||||
|
return cd.id === thisGraph.state.selectedNode.id;
|
||||||
|
}).classed(thisGraph.consts.selectedClass, false);
|
||||||
|
thisGraph.state.selectedNode = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.removeSelectFromEdge = function () {
|
||||||
|
var thisGraph = this;
|
||||||
|
thisGraph.paths.filter(function (cd) {
|
||||||
|
return cd === thisGraph.state.selectedEdge;
|
||||||
|
}).classed(thisGraph.consts.selectedClass, false);
|
||||||
|
thisGraph.state.selectedEdge = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.pathMouseDown = function (d3path, d) {
|
||||||
|
var thisGraph = this,
|
||||||
|
state = thisGraph.state;
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
state.mouseDownLink = d;
|
||||||
|
|
||||||
|
if (state.selectedNode) {
|
||||||
|
thisGraph.removeSelectFromNode();
|
||||||
|
}
|
||||||
|
|
||||||
|
var prevEdge = state.selectedEdge;
|
||||||
|
if (!prevEdge || prevEdge !== d) {
|
||||||
|
thisGraph.replaceSelectEdge(d3path, d);
|
||||||
|
} else {
|
||||||
|
thisGraph.removeSelectFromEdge();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// mousedown on node
|
||||||
|
GraphCreator.prototype.circleMouseDown = function (d3node, d) {
|
||||||
|
var thisGraph = this,
|
||||||
|
state = thisGraph.state;
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
state.mouseDownNode = d;
|
||||||
|
if (d3.event.shiftKey) {
|
||||||
|
state.shiftNodeDrag = d3.event.shiftKey;
|
||||||
|
// reposition dragged directed edge
|
||||||
|
thisGraph.dragLine.classed('hidden', false)
|
||||||
|
.attr('d', 'M' + d.x + ',' + d.y + 'L' + d.x + ',' + d.y);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/* place editable text on node in place of svg text */
|
||||||
|
GraphCreator.prototype.changeTextOfNode = function (d3node, d) {
|
||||||
|
var thisGraph = this,
|
||||||
|
consts = thisGraph.consts,
|
||||||
|
htmlEl = d3node.node();
|
||||||
|
d3node.selectAll("text").remove();
|
||||||
|
var nodeBCR = htmlEl.getBoundingClientRect(),
|
||||||
|
curScale = nodeBCR.width / consts.nodeRadius,
|
||||||
|
placePad = 5 * curScale,
|
||||||
|
useHW = curScale > 1 ? nodeBCR.width * 0.71 : consts.nodeRadius * 1.42;
|
||||||
|
// replace with editableconent text
|
||||||
|
var d3txt = thisGraph.svg.selectAll("foreignObject")
|
||||||
|
.data([d])
|
||||||
|
.enter()
|
||||||
|
.append("foreignObject")
|
||||||
|
.attr("x", nodeBCR.left + placePad)
|
||||||
|
.attr("y", nodeBCR.top + placePad)
|
||||||
|
.attr("height", 2 * useHW)
|
||||||
|
.attr("width", useHW)
|
||||||
|
.append("xhtml:p")
|
||||||
|
.attr("id", consts.activeEditId)
|
||||||
|
.attr("contentEditable", "true")
|
||||||
|
.text(d.title)
|
||||||
|
.on("mousedown", function (d) {
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
})
|
||||||
|
.on("keydown", function (d) {
|
||||||
|
d3.event.stopPropagation();
|
||||||
|
if (d3.event.keyCode == consts.ENTER_KEY && !d3.event.shiftKey) {
|
||||||
|
this.blur();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("blur", function (d) {
|
||||||
|
d.title = this.textContent;
|
||||||
|
thisGraph.insertTitleLinebreaks(d3node, d.title);
|
||||||
|
d3.select(this.parentElement).remove();
|
||||||
|
});
|
||||||
|
return d3txt;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mouseup on nodes
|
||||||
|
GraphCreator.prototype.circleMouseUp = function (d3node, d) {
|
||||||
|
var thisGraph = this,
|
||||||
|
state = thisGraph.state,
|
||||||
|
consts = thisGraph.consts;
|
||||||
|
// reset the states
|
||||||
|
state.shiftNodeDrag = false;
|
||||||
|
d3node.classed(consts.connectClass, false);
|
||||||
|
|
||||||
|
var mouseDownNode = state.mouseDownNode;
|
||||||
|
|
||||||
|
if (!mouseDownNode) return;
|
||||||
|
|
||||||
|
thisGraph.dragLine.classed("hidden", true);
|
||||||
|
|
||||||
|
if (mouseDownNode !== d) {
|
||||||
|
// we're in a different node: create new edge for mousedown edge and add to graph
|
||||||
|
var newEdge = { source: mouseDownNode, target: d };
|
||||||
|
var filtRes = thisGraph.paths.filter(function (d) {
|
||||||
|
if (d.source === newEdge.target && d.target === newEdge.source) {
|
||||||
|
thisGraph.edges.splice(thisGraph.edges.indexOf(d), 1);
|
||||||
|
}
|
||||||
|
return d.source === newEdge.source && d.target === newEdge.target;
|
||||||
|
});
|
||||||
|
if (!filtRes[0].length) {
|
||||||
|
thisGraph.edges.push(newEdge);
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// we're in the same node
|
||||||
|
if (state.justDragged) {
|
||||||
|
// dragged, not clicked
|
||||||
|
state.justDragged = false;
|
||||||
|
} else {
|
||||||
|
// clicked, not dragged
|
||||||
|
if (d3.event.shiftKey) {
|
||||||
|
// shift-clicked node: edit text content
|
||||||
|
var d3txt = thisGraph.changeTextOfNode(d3node, d);
|
||||||
|
var txtNode = d3txt.node();
|
||||||
|
thisGraph.selectElementContents(txtNode);
|
||||||
|
txtNode.focus();
|
||||||
|
} else {
|
||||||
|
if (state.selectedEdge) {
|
||||||
|
thisGraph.removeSelectFromEdge();
|
||||||
|
}
|
||||||
|
var prevNode = state.selectedNode;
|
||||||
|
|
||||||
|
if (!prevNode || prevNode.id !== d.id) {
|
||||||
|
thisGraph.replaceSelectNode(d3node, d);
|
||||||
|
} else {
|
||||||
|
thisGraph.removeSelectFromNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
state.mouseDownNode = null;
|
||||||
|
return;
|
||||||
|
|
||||||
|
}; // end of circles mouseup
|
||||||
|
|
||||||
|
// mousedown on main svg
|
||||||
|
GraphCreator.prototype.svgMouseDown = function () {
|
||||||
|
this.state.graphMouseDown = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// mouseup on main svg
|
||||||
|
GraphCreator.prototype.svgMouseUp = function () {
|
||||||
|
var thisGraph = this,
|
||||||
|
state = thisGraph.state;
|
||||||
|
if (state.justScaleTransGraph) {
|
||||||
|
// dragged not clicked
|
||||||
|
state.justScaleTransGraph = false;
|
||||||
|
} else if (state.graphMouseDown && d3.event.shiftKey) {
|
||||||
|
// clicked not dragged from svg
|
||||||
|
var xycoords = d3.mouse(thisGraph.svgG.node()),
|
||||||
|
d = { id: thisGraph.idct, title: (this.idct).toString(), x: xycoords[0], y: xycoords[1] };
|
||||||
|
thisGraph.idct++;
|
||||||
|
thisGraph.nodes.push(d);
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
// make title of text immediently editable
|
||||||
|
var d3txt = thisGraph.changeTextOfNode(thisGraph.circles.filter(function (dval) {
|
||||||
|
return dval.id === d.id;
|
||||||
|
}), d),
|
||||||
|
txtNode = d3txt.node();
|
||||||
|
thisGraph.selectElementContents(txtNode);
|
||||||
|
txtNode.focus();
|
||||||
|
} else if (state.shiftNodeDrag) {
|
||||||
|
// dragged from node
|
||||||
|
state.shiftNodeDrag = false;
|
||||||
|
thisGraph.dragLine.classed("hidden", true);
|
||||||
|
}
|
||||||
|
state.graphMouseDown = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
// keydown on main svg
|
||||||
|
GraphCreator.prototype.svgKeyDown = function () {
|
||||||
|
var thisGraph = this,
|
||||||
|
state = thisGraph.state,
|
||||||
|
consts = thisGraph.consts;
|
||||||
|
// make sure repeated key presses don't register for each keydown
|
||||||
|
if (state.lastKeyDown !== -1) return;
|
||||||
|
|
||||||
|
state.lastKeyDown = d3.event.keyCode;
|
||||||
|
var selectedNode = state.selectedNode,
|
||||||
|
selectedEdge = state.selectedEdge;
|
||||||
|
|
||||||
|
switch (d3.event.keyCode) {
|
||||||
|
case consts.BACKSPACE_KEY:
|
||||||
|
case consts.DELETE_KEY:
|
||||||
|
d3.event.preventDefault();
|
||||||
|
if (selectedNode) {
|
||||||
|
thisGraph.nodes.splice(thisGraph.nodes.indexOf(selectedNode), 1);
|
||||||
|
thisGraph.spliceLinksForNode(selectedNode);
|
||||||
|
state.selectedNode = null;
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
} else if (selectedEdge) {
|
||||||
|
thisGraph.edges.splice(thisGraph.edges.indexOf(selectedEdge), 1);
|
||||||
|
state.selectedEdge = null;
|
||||||
|
thisGraph.updateGraph();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.svgKeyUp = function () {
|
||||||
|
this.state.lastKeyDown = -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
// call to propagate changes to graph
|
||||||
|
GraphCreator.prototype.updateGraph = function () {
|
||||||
|
|
||||||
|
var thisGraph = this,
|
||||||
|
consts = thisGraph.consts,
|
||||||
|
state = thisGraph.state;
|
||||||
|
|
||||||
|
thisGraph.paths = thisGraph.paths.data(thisGraph.edges, function (d) {
|
||||||
|
return String(d.source.id) + "+" + String(d.target.id);
|
||||||
|
});
|
||||||
|
var paths = thisGraph.paths;
|
||||||
|
// update existing paths
|
||||||
|
paths.style('marker-end', 'url(#end-arrow)')
|
||||||
|
.classed(consts.selectedClass, function (d) {
|
||||||
|
return d === state.selectedEdge;
|
||||||
|
})
|
||||||
|
.attr("d", function (d) {
|
||||||
|
return "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
|
||||||
|
});
|
||||||
|
|
||||||
|
// add new paths
|
||||||
|
paths.enter()
|
||||||
|
.append("path")
|
||||||
|
.style('marker-end', 'url(#end-arrow)')
|
||||||
|
.classed("link", true)
|
||||||
|
.attr("d", function (d) {
|
||||||
|
return "M" + d.source.x + "," + d.source.y + "L" + d.target.x + "," + d.target.y;
|
||||||
|
})
|
||||||
|
.on("mousedown", function (d) {
|
||||||
|
thisGraph.pathMouseDown.call(thisGraph, d3.select(this), d);
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.on("mouseup", function (d) {
|
||||||
|
state.mouseDownLink = null;
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove old links
|
||||||
|
paths.exit().remove();
|
||||||
|
|
||||||
|
// update existing nodes
|
||||||
|
thisGraph.circles = thisGraph.circles.data(thisGraph.nodes, function (d) { return d.id; });
|
||||||
|
thisGraph.circles.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; });
|
||||||
|
|
||||||
|
// add new nodes
|
||||||
|
var newGs = thisGraph.circles.enter()
|
||||||
|
.append("g");
|
||||||
|
|
||||||
|
newGs.classed(consts.circleGClass, true)
|
||||||
|
.attr("transform", function (d) { return "translate(" + d.x + "," + d.y + ")"; })
|
||||||
|
.on("mouseover", function (d) {
|
||||||
|
if (state.shiftNodeDrag) {
|
||||||
|
d3.select(this).classed(consts.connectClass, true);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.on("mouseout", function (d) {
|
||||||
|
d3.select(this).classed(consts.connectClass, false);
|
||||||
|
})
|
||||||
|
.on("mousedown", function (d) {
|
||||||
|
thisGraph.circleMouseDown.call(thisGraph, d3.select(this), d);
|
||||||
|
})
|
||||||
|
.on("mouseup", function (d) {
|
||||||
|
thisGraph.circleMouseUp.call(thisGraph, d3.select(this), d);
|
||||||
|
})
|
||||||
|
.call(thisGraph.drag);
|
||||||
|
|
||||||
|
newGs.append("circle")
|
||||||
|
.attr("r", String(consts.nodeRadius));
|
||||||
|
|
||||||
|
newGs.each(function (d) {
|
||||||
|
thisGraph.insertTitleLinebreaks(d3.select(this), d.title);
|
||||||
|
});
|
||||||
|
|
||||||
|
// remove old nodes
|
||||||
|
thisGraph.circles.exit().remove();
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.zoomed = function () {
|
||||||
|
this.state.justScaleTransGraph = true;
|
||||||
|
d3.select("." + this.consts.graphClass)
|
||||||
|
.attr("transform", "translate(" + d3.event.translate + ") scale(" + d3.event.scale + ")");
|
||||||
|
};
|
||||||
|
|
||||||
|
GraphCreator.prototype.updateWindow = function (svg) {
|
||||||
|
var docEl = document.documentElement,
|
||||||
|
bodyEl = document.getElementsByTagName('body')[0];
|
||||||
|
var x = window.innerWidth || docEl.clientWidth || bodyEl.clientWidth;
|
||||||
|
var y = window.innerHeight || docEl.clientHeight || bodyEl.clientHeight;
|
||||||
|
svg.attr("width", x).attr("height", y);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**** MAIN ****/
|
||||||
|
|
||||||
|
// warn the user when leaving
|
||||||
|
// window.onbeforeunload = function(){
|
||||||
|
// return "Make sure to save your graph locally before leaving";
|
||||||
|
// };
|
||||||
|
|
||||||
|
// initial node data
|
||||||
|
var obj = JSON.parse('{"nodes": [{"title": "0", "id": 0, "x": 38, "y": 20}, {"title": "1", "id": 1, "x": 39, "y": 26}, {"title": "2", "id": 2, "x": 40, "y": 25}, {"title": "3", "id": 3, "x": 36, "y": 23}, {"title": "4", "id": 4, "x": 33, "y": 10}, {"title": "5", "id": 5, "x": 37, "y": 12}, {"title": "6", "id": 6, "x": 38, "y": 13}, {"title": "7", "id": 7, "x": 37, "y": 20}, {"title": "8", "id": 8, "x": 41, "y": 9}, {"title": "9", "id": 9, "x": 41, "y": 13}, {"title": "10", "id": 10, "x": 36, "y": -5}, {"title": "11", "id": 11, "x": 38, "y": 15}, {"title": "12", "id": 12, "x": 38, "y": 15}, {"title": "13", "id": 13, "x": 37, "y": 15}, {"title": "14", "id": 14, "x": 35, "y": 14}, {"title": "15", "id": 15, "x": 39, "y": 19}], "edges": [{"source": 8, "target": 10}, {"source": 10, "target": 4}, {"source": 4, "target": 14}, {"source": 14, "target": 0}, {"source": 0, "target": 7}, {"source": 7, "target": 3}, {"source": 3, "target": 1}, {"source": 1, "target": 2}, {"source": 2, "target": 15}, {"source": 15, "target": 11}, {"source": 11, "target": 12}, {"source": 12, "target": 13}, {"source": 13, "target": 5}, {"source": 5, "target": 6}, {"source": 6, "target": 9}, {"source": 9, "target": 8}]}')
|
||||||
|
obj.nodes = fitscreen(obj.nodes, width, height);
|
||||||
|
|
||||||
|
var newEdges = obj.edges;
|
||||||
|
newEdges.forEach(function (e, i) {
|
||||||
|
newEdges[i] = {
|
||||||
|
source: obj.nodes.filter(function (n) { return n.id == e.source; })[0],
|
||||||
|
target: obj.nodes.filter(function (n) { return n.id == e.target; })[0]
|
||||||
|
};
|
||||||
|
});
|
||||||
|
obj.edges = newEdges;
|
||||||
|
|
||||||
|
/** MAIN SVG **/
|
||||||
|
var svg = d3.select("body").append("svg")
|
||||||
|
.attr("width", width)
|
||||||
|
.attr("height", height);
|
||||||
|
var graph = new GraphCreator(svg, obj.nodes, obj.edges);
|
||||||
|
graph.setIdCt(obj.nodes.length);
|
||||||
|
graph.updateGraph();
|
||||||
|
|
||||||
|
})(window.d3, window.saveAs, window.Blob);
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 5.3 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
|
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-giJF6kkoqNQ00vy+HMDP7azOuL0xtbfIcaT9wjKHr8RbDVddVHyTfAAsrekwKmP1" crossorigin="anonymous">
|
||||||
|
<title>Document</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<h1>Hello</h1>
|
||||||
|
<div class="ratio ratio-16x9">
|
||||||
|
<iframe src="preview.html" title="YouTube video" allowfullscreen></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<section>
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<h1>Leader</h1>
|
||||||
|
<label for="formFileLg" class="form-label">Large file input example</label>
|
||||||
|
<input class="form-control form-control-lg" id="formFileLg" type="file" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
$( document ).ready( () => {
|
||||||
|
|
||||||
|
$('body').scrollspy({ target: '#main-nav', offset: 130 })
|
||||||
|
|
||||||
|
$('#fullpage').fullpage({
|
||||||
|
// anchors: ['underPage', 'gradPage', 'phdPage'],
|
||||||
|
sectionsColor: ['#ffffff', '#f8f8f8'],
|
||||||
|
autoScrolling: false,
|
||||||
|
css3: true,
|
||||||
|
fitToSection: false,
|
||||||
|
afterLoad: function(anchorLink, index) {
|
||||||
|
// history.pushState(null, null, "");
|
||||||
|
// console.log(anchorLink);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$("a").on('click', function(event) {
|
||||||
|
// Make sure this.hash has a value before overriding default behavior
|
||||||
|
if (this.hash !== "") {
|
||||||
|
// Prevent default anchor click behavior
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Store hash
|
||||||
|
var hash = this.hash;
|
||||||
|
|
||||||
|
// Using jQuery's animate() method to add smooth page scroll
|
||||||
|
// The optional number (800) specifies the number of milliseconds it takes to scroll to the specified area
|
||||||
|
var offset = 0;
|
||||||
|
if (hash === "#home")
|
||||||
|
{
|
||||||
|
offset = -100;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset = -60;
|
||||||
|
}
|
||||||
|
$('html, body').animate({
|
||||||
|
scrollTop: ($(hash).offset().top + offset)
|
||||||
|
}, 1000, function(){
|
||||||
|
// Add hash (#) to URL when done scrolling (default click behavior)
|
||||||
|
// window.location.hash = hash;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// initialize with defaults
|
||||||
|
// $("#uploadfile").fileinput();
|
||||||
|
|
||||||
|
// with plugin options
|
||||||
|
$("#uploadfile").fileinput({
|
||||||
|
// theme: "fa",
|
||||||
|
'theme': 'fas',
|
||||||
|
showUpload:false,
|
||||||
|
previewFileType:'py',
|
||||||
|
maxFileCount: 1,
|
||||||
|
allowedFileExtensions: ["py"]
|
||||||
|
});
|
||||||
|
|
||||||
|
ConsoleLogHTML.connect(document.getElementById("console")); // Redirect log messages
|
||||||
|
// ConsoleLogHTML.disconnect(); // Stop redirecting
|
||||||
|
|
||||||
|
var url = window.location;
|
||||||
|
|
||||||
|
// GET REQUEST
|
||||||
|
$("#btnGetFiles").click( (event) => {
|
||||||
|
event.preventDefault();
|
||||||
|
ajaxGet();
|
||||||
|
});
|
||||||
|
|
||||||
|
// DO GET
|
||||||
|
function ajaxGet(){
|
||||||
|
$.ajax({
|
||||||
|
type : "GET",
|
||||||
|
url : "/api/files/getall",
|
||||||
|
success: (data) => {
|
||||||
|
//clear old data
|
||||||
|
$("#listFiles").html("");
|
||||||
|
|
||||||
|
/*
|
||||||
|
render list of files
|
||||||
|
*/
|
||||||
|
$("#listFiles").append('<ul>');
|
||||||
|
$.each(data, (index, filename) => {
|
||||||
|
$("#listFiles").append('<li><a href=' + url + 'api/files/' + filename +'>' + filename + '</a></li>');
|
||||||
|
});
|
||||||
|
$("#listFiles").append('</ul>');
|
||||||
|
},
|
||||||
|
error : (err) => {
|
||||||
|
$("#listFiles").html(err.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
// warn the user when leaving
|
||||||
|
window.onbeforeunload = function(){
|
||||||
|
return "Make sure to save your graph locally before leaving";
|
||||||
|
};
|
||||||
|
|
||||||
|
var socket = io();
|
||||||
|
|
||||||
|
socket.on('connect', () => {
|
||||||
|
$("#session_id").text(socket.id);
|
||||||
|
window.id = socket.id
|
||||||
|
console.log('Session Id: ', socket.id); // an alphanumeric id...
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('users_count', (clients) => {
|
||||||
|
$("#user_counts").text(clients);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('start', () => {
|
||||||
|
console.log('Building start');
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).ready( () => {
|
||||||
|
$("#btnSubmit").click((event) => {
|
||||||
|
//stop submit the form, we will post it manually.
|
||||||
|
event.preventDefault();
|
||||||
|
doAjax();
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#uploadfile').change(function(e){
|
||||||
|
if(e.target.files[0])
|
||||||
|
{
|
||||||
|
var fileName = e.target.files[0].name;
|
||||||
|
if(fileName !== "my_model.py")
|
||||||
|
{
|
||||||
|
alert('Please upload my_model.py');
|
||||||
|
$('#btnSubmit').prop('disabled', true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$('#btnSubmit').prop('disabled', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
function doAjax() {
|
||||||
|
|
||||||
|
// Get form
|
||||||
|
var form = $('#fileUploadForm')[0];
|
||||||
|
|
||||||
|
var data = new FormData(form);
|
||||||
|
var file = data.get('uploadfile');
|
||||||
|
|
||||||
|
var renameFile =new File([file], window.id + '.py' ,{type:file.type});
|
||||||
|
var formdata = new FormData();
|
||||||
|
formdata.append('uploadfile', renameFile);
|
||||||
|
// console.log(formdata.get('uploadfile'))
|
||||||
|
if(window.id) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
enctype: 'multipart/form-data',
|
||||||
|
url: "/api/files/upload",
|
||||||
|
data: formdata,
|
||||||
|
processData: false, //prevent jQuery from automatically transforming the data into a query string
|
||||||
|
contentType: false,
|
||||||
|
cache: false,
|
||||||
|
success: (data) => {
|
||||||
|
// $("#listFiles").text(data);
|
||||||
|
console.log('Emit build request')
|
||||||
|
socket.emit('build', {});
|
||||||
|
},
|
||||||
|
error: (e) => {
|
||||||
|
$("#listFiles").text(e.responseText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
alert('Failed to connect to server');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="graph-creator.css" />
|
||||||
|
<script src="https://d3js.org/d3.v3.min.js"></script>
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.0/FileSaver.min.js"></script>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div id="toolbox">
|
||||||
|
<input type="file" id="hidden-file-upload"><input id="upload-input" type="image" title="upload graph" src="upload-icon.png" alt="upload graph">
|
||||||
|
<!-- <input type="image" id="download-input" title="download graph" src="download-icon.png" alt="download graph"> -->
|
||||||
|
<input type="image" id="delete-graph" title="delete graph" src="trash-icon.png" alt="delete graph">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script src="graph-creator.js"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading
|
||||||
|
* font awesome 5.x CSS and `fileinput.css`.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
.theme-explorer-fas .file-preview-frame {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
margin: 2px 0;
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-actions,
|
||||||
|
.theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle, .theme-explorer-fas .explorer-frame .kv-file-content, .theme-explorer-fas .file-actions, .explorer-frame .file-preview-other {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-upload-indicator, .theme-explorer-fas .file-drag-handle {
|
||||||
|
position: absolute;
|
||||||
|
display: inline-block;
|
||||||
|
bottom: 8px;
|
||||||
|
right: 4px;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-thumb-progress .progress, .theme-explorer-fas .explorer-caption {
|
||||||
|
display: block;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-thumb-progress .progress {
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .explorer-caption,
|
||||||
|
.theme-explorer-fas .file-footer-buttons {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-footer-buttons {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .explorer-caption {
|
||||||
|
color: #777;
|
||||||
|
padding-top: 5px;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .kvsortable-ghost {
|
||||||
|
opacity: 0.6;
|
||||||
|
background: #e1edf7;
|
||||||
|
border: 2px solid #a1abff;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-preview .table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-error-message ul {
|
||||||
|
padding: 5px 0 0 20px;
|
||||||
|
}
|
||||||
|
.explorer-frame .file-preview-text {
|
||||||
|
display: inline-block;
|
||||||
|
color: #428bca;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
||||||
|
outline: none;
|
||||||
|
padding: 8px;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
.explorer-frame .file-preview-html {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.explorer-frame .file-other-icon {
|
||||||
|
font-size: 2.6em;
|
||||||
|
}
|
||||||
|
.explorer-frame:hover {
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-preview-frame samp {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .explorer-frame .kv-file-content {
|
||||||
|
width: 160px;
|
||||||
|
height: 80px;
|
||||||
|
padding: 5px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-details-cell {
|
||||||
|
width: 60%;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
text-align: left;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
.theme-explorer-fas .file-actions-cell {
|
||||||
|
position: relative;
|
||||||
|
height: 80px;
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
/*noinspection CssOverwrittenProperties*/
|
||||||
|
.file-zoom-dialog .explorer-frame .file-other-icon {
|
||||||
|
font-size: 22em;
|
||||||
|
font-size: 50vmin;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 1249px) {
|
||||||
|
.theme-explorer-fas .file-preview-frame .file-details-cell {
|
||||||
|
width: 40%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 1023px) {
|
||||||
|
.theme-explorer-fas .file-preview-frame .file-details-cell {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 767px) {
|
||||||
|
.theme-explorer-fas .file-preview-frame .file-details-cell {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 575px) {
|
||||||
|
.theme-explorer-fas .file-preview-frame {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-explorer-fas .file-preview-frame .kv-file-content {
|
||||||
|
width: auto;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-explorer-fas .file-details-cell {
|
||||||
|
width: 100px;
|
||||||
|
text-align: center;
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-explorer-fas .file-preview-frame .kv-file-content,
|
||||||
|
.theme-explorer-fas .file-details-cell,
|
||||||
|
.theme-explorer-fas .file-actions-cell {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-explorer-fas .file-actions-cell {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-explorer-fas .file-footer-buttons {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput.
|
||||||
|
* Load this theme file after loading `fileinput.js`. Ensure that
|
||||||
|
* font awesome assets and CSS are loaded on the page as well.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
(function ($) {
|
||||||
|
'use strict';
|
||||||
|
$.fn.fileinputThemes['explorer-fas'] = {
|
||||||
|
layoutTemplates: {
|
||||||
|
footer: '<div class="file-details-cell">' +
|
||||||
|
'<div class="explorer-caption" title="{caption}">{caption}</div> ' + '{size}{progress}' +
|
||||||
|
'</div>' +
|
||||||
|
'<div class="file-actions-cell">{indicator} {actions}</div>',
|
||||||
|
actions: '{drag}\n' +
|
||||||
|
'<div class="file-actions">\n' +
|
||||||
|
' <div class="file-footer-buttons">\n' +
|
||||||
|
' {upload} {download} {delete} {zoom} {other} ' +
|
||||||
|
' </div>\n' +
|
||||||
|
'</div>',
|
||||||
|
fileIcon: '<i class="fas fa-file kv-caption-icon"></i> '
|
||||||
|
},
|
||||||
|
previewSettings: {
|
||||||
|
html: {width: '100px', height: '60px'},
|
||||||
|
text: {width: '100px', height: '60px'},
|
||||||
|
video: {width: 'auto', height: '60px'},
|
||||||
|
audio: {width: 'auto', height: '60px'},
|
||||||
|
flash: {width: '100%', height: '60px'},
|
||||||
|
object: {width: '100%', height: '60px'},
|
||||||
|
pdf: {width: '100px', height: '60px'},
|
||||||
|
other: {width: '100%', height: '60px'}
|
||||||
|
},
|
||||||
|
frameClass: 'explorer-frame',
|
||||||
|
fileActionSettings: {
|
||||||
|
removeIcon: '<i class="fas fa-trash-alt"></i>',
|
||||||
|
uploadIcon: '<i class="fas fa-upload"></i>',
|
||||||
|
uploadRetryIcon: '<i class="fas fa-redo-alt"></i>',
|
||||||
|
downloadIcon: '<i class="fas fa-download"></i>',
|
||||||
|
zoomIcon: '<i class="fas fa-search-plus"></i>',
|
||||||
|
dragIcon: '<i class="fas fa-arrows-alt"></i>',
|
||||||
|
indicatorNew: '<i class="fas fa-plus-circle text-warning"></i>',
|
||||||
|
indicatorSuccess: '<i class="fas fa-check-circle text-success"></i>',
|
||||||
|
indicatorError: '<i class="fas fa-exclamation-circle text-danger"></i>',
|
||||||
|
indicatorLoading: '<i class="fas fa-hourglass text-muted"></i>',
|
||||||
|
indicatorPaused: '<i class="fa fa-pause text-info"></i>'
|
||||||
|
},
|
||||||
|
previewZoomButtonIcons: {
|
||||||
|
prev: '<i class="fas fa-caret-left fa-lg"></i>',
|
||||||
|
next: '<i class="fas fa-caret-right fa-lg"></i>',
|
||||||
|
toggleheader: '<i class="fas fa-fw fa-arrows-alt-v"></i>',
|
||||||
|
fullscreen: '<i class="fas fa-fw fa-arrows-alt"></i>',
|
||||||
|
borderless: '<i class="fas fa-fw fa-external-link-alt"></i>',
|
||||||
|
close: '<i class="fas fa-fw fa-times"></i>'
|
||||||
|
},
|
||||||
|
previewFileIcon: '<i class="fas fa-file"></i>',
|
||||||
|
browseIcon: '<i class="fas fa-folder-open"></i>',
|
||||||
|
removeIcon: '<i class="fas fa-trash-alt"></i>',
|
||||||
|
cancelIcon: '<i class="fas fa-ban"></i>',
|
||||||
|
pauseIcon: '<i class="fas fa-pause"></i>',
|
||||||
|
uploadIcon: '<i class="fas fa-upload"></i>',
|
||||||
|
msgValidationErrorIcon: '<i class="fas fa-exclamation-circle"></i> '
|
||||||
|
};
|
||||||
|
})(window.jQuery);
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Krajee Explorer Font Awesome 5.x theme style for bootstrap-fileinput. Load this theme file after loading
|
||||||
|
* font awesome 5.x CSS and `fileinput.css`.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/.theme-explorer-fas .file-preview-frame{border:1px solid #ddd;margin:2px 0;width:100%;display:flex;justify-content:space-between;align-items:center}.explorer-frame .file-preview-other,.theme-explorer-fas .explorer-frame .kv-file-content,.theme-explorer-fas .file-actions,.theme-explorer-fas .file-drag-handle,.theme-explorer-fas .file-upload-indicator{text-align:center}.theme-explorer-fas .file-drag-handle,.theme-explorer-fas .file-upload-indicator{position:absolute;display:inline-block;bottom:8px;right:4px;width:16px;height:16px;font-size:16px}.theme-explorer-fas .explorer-caption,.theme-explorer-fas .file-thumb-progress .progress{display:block;white-space:nowrap;text-overflow:ellipsis;overflow:hidden}.theme-explorer-fas .file-thumb-progress .progress{margin-top:5px}.theme-explorer-fas .explorer-caption,.theme-explorer-fas .file-footer-buttons{padding:5px}.theme-explorer-fas .file-footer-buttons{text-align:right}.theme-explorer-fas .explorer-caption{color:#777;padding-top:5px}.theme-explorer-fas .kvsortable-ghost{opacity:.6;background:#e1edf7;border:2px solid #a1abff}.theme-explorer-fas .file-preview .table{margin:0}.theme-explorer-fas .file-error-message ul{padding:5px 0 0 20px}.explorer-frame .file-preview-text{display:inline-block;color:#428bca;border:1px solid #ddd;font-family:Menlo,Monaco,Consolas,"Courier New",monospace;outline:0;padding:8px;resize:none}.explorer-frame .file-preview-html{display:inline-block;border:1px solid #ddd;padding:8px;overflow:auto}.explorer-frame .file-other-icon{font-size:2.6em}.explorer-frame:hover{background-color:#f5f5f5}.theme-explorer-fas .file-preview-frame samp{font-size:.9rem}.theme-explorer-fas .explorer-frame .kv-file-content{width:160px;height:80px;padding:5px;text-align:left}.theme-explorer-fas .file-details-cell{width:60%;font-size:.95rem;text-align:left;margin-right:auto}.theme-explorer-fas .file-actions-cell{position:relative;height:80px;width:200px}.file-zoom-dialog .explorer-frame .file-other-icon{font-size:22em;font-size:50vmin}@media only screen and (max-width:1249px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:40%}}@media only screen and (max-width:1023px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:30%}}@media only screen and (max-width:767px){.theme-explorer-fas .file-preview-frame .file-details-cell{width:200px}}@media only screen and (max-width:575px){.theme-explorer-fas .file-preview-frame{flex-direction:column}.theme-explorer-fas .file-preview-frame .kv-file-content{text-align:center}.theme-explorer-fas .file-details-cell{text-align:center;margin-right:0}.theme-explorer-fas .file-actions-cell,.theme-explorer-fas .file-details-cell,.theme-explorer-fas .file-preview-frame .kv-file-content{width:100%}.theme-explorer-fas .file-actions-cell{height:auto}.theme-explorer-fas .file-footer-buttons{text-align:left}}
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Krajee Explorer Font Awesome theme configuration for bootstrap-fileinput.
|
||||||
|
* Load this theme file after loading `fileinput.js`. Ensure that
|
||||||
|
* font awesome assets and CSS are loaded on the page as well.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/!function(a){"use strict";a.fn.fileinputThemes["explorer-fas"]={layoutTemplates:{footer:'<div class="file-details-cell"><div class="explorer-caption" title="{caption}">{caption}</div> {size}{progress}</div><div class="file-actions-cell">{indicator} {actions}</div>',actions:'{drag}\n<div class="file-actions">\n <div class="file-footer-buttons">\n {upload} {download} {delete} {zoom} {other} </div>\n</div>',fileIcon:'<i class="fas fa-file kv-caption-icon"></i> '},previewSettings:{html:{width:"100px",height:"60px"},text:{width:"100px",height:"60px"},video:{width:"auto",height:"60px"},audio:{width:"auto",height:"60px"},flash:{width:"100%",height:"60px"},object:{width:"100%",height:"60px"},pdf:{width:"100px",height:"60px"},other:{width:"100%",height:"60px"}},frameClass:"explorer-frame",fileActionSettings:{removeIcon:'<i class="fas fa-trash-alt"></i>',uploadIcon:'<i class="fas fa-upload"></i>',uploadRetryIcon:'<i class="fas fa-redo-alt"></i>',downloadIcon:'<i class="fas fa-download"></i>',zoomIcon:'<i class="fas fa-search-plus"></i>',dragIcon:'<i class="fas fa-arrows-alt"></i>',indicatorNew:'<i class="fas fa-plus-circle text-warning"></i>',indicatorSuccess:'<i class="fas fa-check-circle text-success"></i>',indicatorError:'<i class="fas fa-exclamation-circle text-danger"></i>',indicatorLoading:'<i class="fas fa-hourglass text-muted"></i>',indicatorPaused:'<i class="fa fa-pause text-info"></i>'},previewZoomButtonIcons:{prev:'<i class="fas fa-caret-left fa-lg"></i>',next:'<i class="fas fa-caret-right fa-lg"></i>',toggleheader:'<i class="fas fa-fw fa-arrows-alt-v"></i>',fullscreen:'<i class="fas fa-fw fa-arrows-alt"></i>',borderless:'<i class="fas fa-fw fa-external-link-alt"></i>',close:'<i class="fas fa-fw fa-times"></i>'},previewFileIcon:'<i class="fas fa-file"></i>',browseIcon:'<i class="fas fa-folder-open"></i>',removeIcon:'<i class="fas fa-trash-alt"></i>',cancelIcon:'<i class="fas fa-ban"></i>',pauseIcon:'<i class="fas fa-pause"></i>',uploadIcon:'<i class="fas fa-upload"></i>',msgValidationErrorIcon:'<i class="fas fa-exclamation-circle"></i> '}}(window.jQuery);
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/
|
||||||
|
(function ($) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
$.fn.fileinputThemes.fas = {
|
||||||
|
fileActionSettings: {
|
||||||
|
removeIcon: '<i class="fas fa-trash-alt"></i>',
|
||||||
|
uploadIcon: '<i class="fas fa-upload"></i>',
|
||||||
|
uploadRetryIcon: '<i class="fas fa-redo-alt"></i>',
|
||||||
|
downloadIcon: '<i class="fas fa-download"></i>',
|
||||||
|
zoomIcon: '<i class="fas fa-search-plus"></i>',
|
||||||
|
dragIcon: '<i class="fas fa-arrows-alt"></i>',
|
||||||
|
indicatorNew: '<i class="fas fa-plus-circle text-warning"></i>',
|
||||||
|
indicatorSuccess: '<i class="fas fa-check-circle text-success"></i>',
|
||||||
|
indicatorError: '<i class="fas fa-exclamation-circle text-danger"></i>',
|
||||||
|
indicatorLoading: '<i class="fas fa-hourglass text-muted"></i>',
|
||||||
|
indicatorPaused: '<i class="fa fa-pause text-info"></i>'
|
||||||
|
},
|
||||||
|
layoutTemplates: {
|
||||||
|
fileIcon: '<i class="fas fa-file kv-caption-icon"></i> '
|
||||||
|
},
|
||||||
|
previewZoomButtonIcons: {
|
||||||
|
prev: '<i class="fas fa-caret-left fa-lg"></i>',
|
||||||
|
next: '<i class="fas fa-caret-right fa-lg"></i>',
|
||||||
|
toggleheader: '<i class="fas fa-fw fa-arrows-alt-v"></i>',
|
||||||
|
fullscreen: '<i class="fas fa-fw fa-arrows-alt"></i>',
|
||||||
|
borderless: '<i class="fas fa-fw fa-external-link-alt"></i>',
|
||||||
|
close: '<i class="fas fa-fw fa-times"></i>'
|
||||||
|
},
|
||||||
|
previewFileIcon: '<i class="fas fa-file"></i>',
|
||||||
|
browseIcon: '<i class="fas fa-folder-open"></i>',
|
||||||
|
removeIcon: '<i class="fas fa-trash-alt"></i>',
|
||||||
|
cancelIcon: '<i class="fas fa-ban"></i>',
|
||||||
|
pauseIcon: '<i class="fas fa-pause"></i>',
|
||||||
|
uploadIcon: '<i class="fas fa-upload"></i>',
|
||||||
|
msgValidationErrorIcon: '<i class="fas fa-exclamation-circle"></i> '
|
||||||
|
};
|
||||||
|
})(window.jQuery);
|
||||||
|
|
@ -0,0 +1,12 @@
|
||||||
|
/*!
|
||||||
|
* bootstrap-fileinput v5.1.3
|
||||||
|
* http://plugins.krajee.com/file-input
|
||||||
|
*
|
||||||
|
* Font Awesome 5 icon theme configuration for bootstrap-fileinput. Requires font awesome 5 assets to be loaded.
|
||||||
|
*
|
||||||
|
* Author: Kartik Visweswaran
|
||||||
|
* Copyright: 2014 - 2020, Kartik Visweswaran, Krajee.com
|
||||||
|
*
|
||||||
|
* Licensed under the BSD-3-Clause
|
||||||
|
* https://github.com/kartik-v/bootstrap-fileinput/blob/master/LICENSE.md
|
||||||
|
*/!function(a){"use strict";a.fn.fileinputThemes.fas={fileActionSettings:{removeIcon:'<i class="fas fa-trash-alt"></i>',uploadIcon:'<i class="fas fa-upload"></i>',uploadRetryIcon:'<i class="fas fa-redo-alt"></i>',downloadIcon:'<i class="fas fa-download"></i>',zoomIcon:'<i class="fas fa-search-plus"></i>',dragIcon:'<i class="fas fa-arrows-alt"></i>',indicatorNew:'<i class="fas fa-plus-circle text-warning"></i>',indicatorSuccess:'<i class="fas fa-check-circle text-success"></i>',indicatorError:'<i class="fas fa-exclamation-circle text-danger"></i>',indicatorLoading:'<i class="fas fa-hourglass text-muted"></i>',indicatorPaused:'<i class="fa fa-pause text-info"></i>'},layoutTemplates:{fileIcon:'<i class="fas fa-file kv-caption-icon"></i> '},previewZoomButtonIcons:{prev:'<i class="fas fa-caret-left fa-lg"></i>',next:'<i class="fas fa-caret-right fa-lg"></i>',toggleheader:'<i class="fas fa-fw fa-arrows-alt-v"></i>',fullscreen:'<i class="fas fa-fw fa-arrows-alt"></i>',borderless:'<i class="fas fa-fw fa-external-link-alt"></i>',close:'<i class="fas fa-fw fa-times"></i>'},previewFileIcon:'<i class="fas fa-file"></i>',browseIcon:'<i class="fas fa-folder-open"></i>',removeIcon:'<i class="fas fa-trash-alt"></i>',cancelIcon:'<i class="fas fa-ban"></i>',pauseIcon:'<i class="fas fa-pause"></i>',uploadIcon:'<i class="fas fa-upload"></i>',msgValidationErrorIcon:'<i class="fas fa-exclamation-circle"></i> '}}(window.jQuery);
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 133 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.1 KiB |
|
|
@ -0,0 +1,71 @@
|
||||||
|
var express = require('express');
|
||||||
|
var app = express();
|
||||||
|
var router = express.Router();
|
||||||
|
var upload = require('./app/config/multer.config.js');
|
||||||
|
|
||||||
|
const {Docker} = require('node-docker-api');
|
||||||
|
|
||||||
|
const docker = new Docker({ socketPath: '/var/run/docker.sock' });
|
||||||
|
|
||||||
|
global.__basedir = __dirname;
|
||||||
|
|
||||||
|
app.use(express.static('resources'));
|
||||||
|
|
||||||
|
var http = require('http').createServer(app);
|
||||||
|
var io = require('socket.io')(http);
|
||||||
|
|
||||||
|
var docker_build = (socket, sessionID) => {
|
||||||
|
console.log('[server][start]', sessionID);
|
||||||
|
socket.emit('start')
|
||||||
|
|
||||||
|
docker.container.create({
|
||||||
|
Image: 'python:3.8',
|
||||||
|
name: sessionID,
|
||||||
|
Cmd: [ '/bin/bash', '-c', 'ls /output' ],
|
||||||
|
Volumes: {
|
||||||
|
"/output": `./uploads / {sessionID}`
|
||||||
|
},
|
||||||
|
})
|
||||||
|
.then(container => container.logs({
|
||||||
|
follow: true,
|
||||||
|
stdout: true,
|
||||||
|
stderr: true
|
||||||
|
}))
|
||||||
|
.then(stream => {
|
||||||
|
stream.on('data', info => console.log(info))
|
||||||
|
stream.on('error', err => console.log(err))
|
||||||
|
})
|
||||||
|
.catch(error => console.log(error));
|
||||||
|
};
|
||||||
|
|
||||||
|
var clients = 0;
|
||||||
|
|
||||||
|
io.on('connection', (socket) => {
|
||||||
|
const sessionID = socket.id;
|
||||||
|
console.log('[client][connection]', sessionID);
|
||||||
|
clients = clients + 1;
|
||||||
|
io.sockets.emit('users_count', clients);
|
||||||
|
|
||||||
|
socket.on('disconnect', () => {
|
||||||
|
clients = clients - 1;
|
||||||
|
console.log('[client][disconnect]', sessionID)
|
||||||
|
io.sockets.emit('users_count', clients);
|
||||||
|
});
|
||||||
|
|
||||||
|
socket.on('build', () => {
|
||||||
|
console.log('[client][build]', sessionID);
|
||||||
|
docker_build(socket, sessionID);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
require('./app/routers/file.router.js')(app, router, upload);
|
||||||
|
|
||||||
|
// Create a Server
|
||||||
|
var server = http.listen(8081, () => {
|
||||||
|
|
||||||
|
var host = server.address().address
|
||||||
|
var port = server.address().port
|
||||||
|
|
||||||
|
console.log("App listening at http://%s:%s", host, port);
|
||||||
|
})
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>404 Error!</title>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
|
||||||
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<div class="jumbotron text-center">
|
||||||
|
<h1>404 Error!</h1>
|
||||||
|
<p>PAGE NOT FOUND</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,348 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>COM2014 TSP Workshop</title>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
|
||||||
|
<!-- Bootstrap -->
|
||||||
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
|
||||||
|
|
||||||
|
<!-- Jquery -->
|
||||||
|
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
|
||||||
|
|
||||||
|
<!-- SocketIO -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/3.0.4/socket.io.js"></script>
|
||||||
|
|
||||||
|
<!-- Console Log -->
|
||||||
|
<script type="application/javascript" src="//cdn.rawgit.com/Alorel/console-log-html/master/console-log-html.min.js"></script>
|
||||||
|
|
||||||
|
<!-- FullPage -->
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/2.9.7/jquery.fullpage.css">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/fullPage.js/2.9.7/jquery.fullpage.js"></script>
|
||||||
|
|
||||||
|
<!-- File Input -->
|
||||||
|
<link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.1.3/css/fileinput.min.css" media="all" rel="stylesheet" type="text/css" />
|
||||||
|
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.5.0/css/all.css" crossorigin="anonymous">
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/5.1.3/js/fileinput.min.js"></script>
|
||||||
|
<script src="/static/themes/fas/theme.js" type="text/javascript"></script>
|
||||||
|
<script src="/static/themes/explorer-fas/theme.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<!-- My Script -->
|
||||||
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
|
<script src="/static/js/postrequest.js"></script>
|
||||||
|
<script src="/static/js/getrequest.js"></script>
|
||||||
|
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body data-spy="scroll" data-target="#main-nav" data-offset="0">
|
||||||
|
<!-- Navbar -->
|
||||||
|
<nav class="navbar navbar-expand-md bg-dark navbar-dark sticky-top" id="main-nav">
|
||||||
|
<a class="navbar-brand" href="/">TSP Workshop <span class="badge badge-primary"><span id="user_counts">0</span> Online</span></a>
|
||||||
|
<button class="navbar-toggler" data-toggle="collapse" data-target="#navbarCollapse">
|
||||||
|
<span class="navbar-toggler-icon "></span>
|
||||||
|
</button>
|
||||||
|
<div class="collapse navbar-collapse navbar-right" id="navbarCollapse">
|
||||||
|
<ul class="nav navbar-nav ml-auto">
|
||||||
|
<li class="nav-item" >
|
||||||
|
<a class="nav-link" href="#overview">Overview</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" >
|
||||||
|
<a class="nav-link" href="#leaderboard">Leaderboard</a>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item" >
|
||||||
|
<a class="nav-link" href="#submission">Submission</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<div id="fullpage">
|
||||||
|
<div id="overview">
|
||||||
|
<section class="section" id="section2">
|
||||||
|
<div class="slide">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="display-4 mt-5 mb-5 text-center">Traveling Salesman Problem</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mb-5">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="embed-responsive embed-responsive-16by9 box-shadow">
|
||||||
|
<iframe class="embed-responsive-item" src="/static/preview.html" allowfullscreen></iframe>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="leaderboard">
|
||||||
|
<section class="section" id="section0">
|
||||||
|
<div class="slide">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row text-center">
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="display-3 mb-5">Leaderboard</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<table class="table">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">ulysses16.tsp</th>
|
||||||
|
<th scope="col">att48.tsp</th>
|
||||||
|
<th scope="col">st70.tsp</th>
|
||||||
|
<th scope="col">a280.tsp</th>
|
||||||
|
<th scope="col">pcb442.tsp</th>
|
||||||
|
<th scope="col">dsj1000.tsp</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">1</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">2</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">3</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">4</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">5</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">6</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">7</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">8</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">9</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="row">10</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="submission">
|
||||||
|
<section class="section" id="section1">
|
||||||
|
<div class="slide">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-12">
|
||||||
|
<h1 class="mt-5 mb-5">Your Submission</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-12">
|
||||||
|
<table class="table">
|
||||||
|
<thead class="thead-dark">
|
||||||
|
<tr>
|
||||||
|
<th scope="col">Problem</th>
|
||||||
|
<th scope="col">Your Solution</th>
|
||||||
|
<th scope="col">Best Solution</th>
|
||||||
|
<th scope="col"></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">ulysses16.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">att48.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">st70.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">a280.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">pcb442.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">dsj1000.tsp</th>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>Inf</td>
|
||||||
|
<td>
|
||||||
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mb-3">
|
||||||
|
<div class="col col-4">
|
||||||
|
<label for="">Your Name</label>
|
||||||
|
<input class="form-control form-control-lg" type="text" placeholder="Your Name">
|
||||||
|
</div>
|
||||||
|
<div class="col col-8">
|
||||||
|
<label for="">Description</label>
|
||||||
|
<input class="form-control form-control-lg" type="text" placeholder="Precisely describe your submission.">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-12">
|
||||||
|
<form class="" method="POST" enctype="multipart/form-data" id="fileUploadForm">
|
||||||
|
<div class="form-group">
|
||||||
|
<input type="file" class="form-control form-control-lg form-control-file mb-3" id="uploadfile" placeholder="Upload File" name="uploadfile" accept=".py" data-browse-on-zone-click="true" data-allowed-file-extensions='["py"]' ></input>
|
||||||
|
<button type="submit" class="btn btn-primary form-control mt-3" id="btnSubmit" disabled>Upload</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr/>
|
||||||
|
<div class="row mb-5" id="console-box">
|
||||||
|
<ul id="console"></ul> <!-- I will hold the log messages -->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- SubFooter -->
|
||||||
|
<footer id="sub-footer" class="subfooter">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row p-4">
|
||||||
|
<div class="col-md-4 about">
|
||||||
|
<span>ABOUT ETAL</span>
|
||||||
|
<p class="text-justify font-weight-light small">
|
||||||
|
Exeter Trustworthy AI Lab (ETAL) Group is affiliated with College of Engineering, Mathematics and Physical Sciences, University of Exeter, UK.</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="d-none d-md-block col-md-4 link">
|
||||||
|
<img class="exeter" alt="" srcset="">
|
||||||
|
</div>
|
||||||
|
<div class="d-none d-md-block col-md-4 link">
|
||||||
|
<img class="russell" alt="" srcset="">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<!-- Footer -->
|
||||||
|
<footer id="main-footer" class="footer text-center">
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<span>Copyright © Exeter Trustworthy AI Lab</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Loading…
Reference in New Issue