remove **everything** in preparations for v3
This commit is contained in:
parent
b9ef21cbea
commit
c5f3305c23
|
@ -4,3 +4,4 @@ lxc/i
|
|||
lxc/lockfile
|
||||
container/build.yaml
|
||||
container/*.tar.xz
|
||||
node_modules
|
|
@ -1 +0,0 @@
|
|||
node_modules
|
|
@ -1,903 +0,0 @@
|
|||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"express-validator": "^6.9.2"
|
||||
}
|
||||
},
|
||||
"node_modules/accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"dependencies": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"node_modules/body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"dependencies": {
|
||||
"safe-buffer": "5.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/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==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"node_modules/debug": {
|
||||
"version": "2.6.9",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
|
||||
"integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
|
||||
"dependencies": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/depd": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
|
||||
"integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/destroy": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
|
||||
"integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"node_modules/encodeurl": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
|
||||
"integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/escape-html": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
|
||||
"integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
|
||||
},
|
||||
"node_modules/etag": {
|
||||
"version": "1.8.1",
|
||||
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
|
||||
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/express": {
|
||||
"version": "4.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"dependencies": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"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.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/express-validator": {
|
||||
"version": "6.9.2",
|
||||
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.9.2.tgz",
|
||||
"integrity": "sha512-Yqlsw2/uBobtBVkP+gnds8OMmVAEb3uTI4uXC93l0Ym5JGHgr8Vd4ws7oSo7GGYpWn5YCq4UePMEppKchURXrw==",
|
||||
"dependencies": {
|
||||
"lodash": "^4.17.20",
|
||||
"validator": "^13.5.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"dependencies": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.0",
|
||||
"unpipe": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/forwarded": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
|
||||
"integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/fresh": {
|
||||
"version": "0.5.2",
|
||||
"resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
|
||||
"integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/http-errors": {
|
||||
"version": "1.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"dependencies": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"node_modules/ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"node_modules/media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/merge-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
|
||||
},
|
||||
"node_modules/methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
|
||||
"bin": {
|
||||
"mime": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.45.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.28",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.45.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"node_modules/negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/on-finished": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
|
||||
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
|
||||
"dependencies": {
|
||||
"ee-first": "1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/parseurl": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/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="
|
||||
},
|
||||
"node_modules/proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"dependencies": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"dependencies": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"node_modules/send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"dependencies": {
|
||||
"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.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/send/node_modules/ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
},
|
||||
"node_modules/serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"dependencies": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"node_modules/statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==",
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"dependencies": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/validator": {
|
||||
"version": "13.5.2",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
|
||||
"integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ==",
|
||||
"engines": {
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"accepts": {
|
||||
"version": "1.3.7",
|
||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
|
||||
"integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
|
||||
"requires": {
|
||||
"mime-types": "~2.1.24",
|
||||
"negotiator": "0.6.2"
|
||||
}
|
||||
},
|
||||
"array-flatten": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
|
||||
"integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
|
||||
},
|
||||
"body-parser": {
|
||||
"version": "1.19.0",
|
||||
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
|
||||
"integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"content-type": "~1.0.4",
|
||||
"debug": "2.6.9",
|
||||
"depd": "~1.1.2",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"on-finished": "~2.3.0",
|
||||
"qs": "6.7.0",
|
||||
"raw-body": "2.4.0",
|
||||
"type-is": "~1.6.17"
|
||||
}
|
||||
},
|
||||
"bytes": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
|
||||
"integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
|
||||
},
|
||||
"content-disposition": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
|
||||
"integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.2"
|
||||
}
|
||||
},
|
||||
"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.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
|
||||
"integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
|
||||
},
|
||||
"cookie-signature": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"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.17.1",
|
||||
"resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
|
||||
"integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
|
||||
"requires": {
|
||||
"accepts": "~1.3.7",
|
||||
"array-flatten": "1.1.1",
|
||||
"body-parser": "1.19.0",
|
||||
"content-disposition": "0.5.3",
|
||||
"content-type": "~1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"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.2",
|
||||
"fresh": "0.5.2",
|
||||
"merge-descriptors": "1.0.1",
|
||||
"methods": "~1.1.2",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"path-to-regexp": "0.1.7",
|
||||
"proxy-addr": "~2.0.5",
|
||||
"qs": "6.7.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"safe-buffer": "5.1.2",
|
||||
"send": "0.17.1",
|
||||
"serve-static": "1.14.1",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": "~1.5.0",
|
||||
"type-is": "~1.6.18",
|
||||
"utils-merge": "1.0.1",
|
||||
"vary": "~1.1.2"
|
||||
}
|
||||
},
|
||||
"express-validator": {
|
||||
"version": "6.9.2",
|
||||
"resolved": "https://registry.npmjs.org/express-validator/-/express-validator-6.9.2.tgz",
|
||||
"integrity": "sha512-Yqlsw2/uBobtBVkP+gnds8OMmVAEb3uTI4uXC93l0Ym5JGHgr8Vd4ws7oSo7GGYpWn5YCq4UePMEppKchURXrw==",
|
||||
"requires": {
|
||||
"lodash": "^4.17.20",
|
||||
"validator": "^13.5.2"
|
||||
}
|
||||
},
|
||||
"finalhandler": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
|
||||
"integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
|
||||
"requires": {
|
||||
"debug": "2.6.9",
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"on-finished": "~2.3.0",
|
||||
"parseurl": "~1.3.3",
|
||||
"statuses": "~1.5.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.7.2",
|
||||
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
|
||||
"integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
|
||||
"requires": {
|
||||
"depd": "~1.1.2",
|
||||
"inherits": "2.0.3",
|
||||
"setprototypeof": "1.1.1",
|
||||
"statuses": ">= 1.5.0 < 2",
|
||||
"toidentifier": "1.0.0"
|
||||
}
|
||||
},
|
||||
"iconv-lite": {
|
||||
"version": "0.4.24",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
|
||||
"integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
|
||||
"requires": {
|
||||
"safer-buffer": ">= 2.1.2 < 3"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ipaddr.js": {
|
||||
"version": "1.9.1",
|
||||
"resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
|
||||
"integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g=="
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.20",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz",
|
||||
"integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA=="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
"integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
|
||||
},
|
||||
"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.6.0",
|
||||
"resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
|
||||
"integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.45.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz",
|
||||
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.28",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz",
|
||||
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==",
|
||||
"requires": {
|
||||
"mime-db": "1.45.0"
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
|
||||
},
|
||||
"negotiator": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
|
||||
"integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
|
||||
},
|
||||
"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.3",
|
||||
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
|
||||
"integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
|
||||
},
|
||||
"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="
|
||||
},
|
||||
"proxy-addr": {
|
||||
"version": "2.0.6",
|
||||
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz",
|
||||
"integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==",
|
||||
"requires": {
|
||||
"forwarded": "~0.1.2",
|
||||
"ipaddr.js": "1.9.1"
|
||||
}
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.7.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
|
||||
"integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
|
||||
},
|
||||
"range-parser": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
|
||||
"integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
|
||||
},
|
||||
"raw-body": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
|
||||
"integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
|
||||
"requires": {
|
||||
"bytes": "3.1.0",
|
||||
"http-errors": "1.7.2",
|
||||
"iconv-lite": "0.4.24",
|
||||
"unpipe": "1.0.0"
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
|
||||
},
|
||||
"send": {
|
||||
"version": "0.17.1",
|
||||
"resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
|
||||
"integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
|
||||
"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.7.2",
|
||||
"mime": "1.6.0",
|
||||
"ms": "2.1.1",
|
||||
"on-finished": "~2.3.0",
|
||||
"range-parser": "~1.2.1",
|
||||
"statuses": "~1.5.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"ms": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
|
||||
"integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"serve-static": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
|
||||
"integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
|
||||
"requires": {
|
||||
"encodeurl": "~1.0.2",
|
||||
"escape-html": "~1.0.3",
|
||||
"parseurl": "~1.3.3",
|
||||
"send": "0.17.1"
|
||||
}
|
||||
},
|
||||
"setprototypeof": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
|
||||
"integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
|
||||
},
|
||||
"statuses": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
|
||||
"integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
|
||||
},
|
||||
"toidentifier": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
|
||||
"integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
|
||||
},
|
||||
"type-is": {
|
||||
"version": "1.6.18",
|
||||
"resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
|
||||
"integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
|
||||
"requires": {
|
||||
"media-typer": "0.3.0",
|
||||
"mime-types": "~2.1.24"
|
||||
}
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
|
||||
},
|
||||
"utils-merge": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
|
||||
"integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
|
||||
},
|
||||
"validator": {
|
||||
"version": "13.5.2",
|
||||
"resolved": "https://registry.npmjs.org/validator/-/validator-13.5.2.tgz",
|
||||
"integrity": "sha512-mD45p0rvHVBlY2Zuy3F3ESIe1h5X58GPfAtslBjY7EtTqGquZTj+VX/J4RnHWN8FKq0C9WRVt1oWAcytWRuYLQ=="
|
||||
},
|
||||
"vary": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
|
||||
"integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
{
|
||||
"name": "api",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"express": "^4.17.1",
|
||||
"express-validator": "^6.9.2"
|
||||
}
|
||||
}
|
|
@ -1,79 +0,0 @@
|
|||
const express = require('express');
|
||||
const { execute } = require('../../lxc/execute.js');
|
||||
const { languages } = require('./languages');
|
||||
const { checkSchema, validationResult } = require('express-validator');
|
||||
|
||||
const PORT = 2000;
|
||||
|
||||
const app = express();
|
||||
app.use(express.json());
|
||||
|
||||
app.post(
|
||||
'/execute',
|
||||
checkSchema({
|
||||
language: {
|
||||
in: 'body',
|
||||
notEmpty: {
|
||||
errorMessage: 'No language supplied',
|
||||
},
|
||||
isString: {
|
||||
errorMessage: 'Supplied language is not a string',
|
||||
},
|
||||
custom: {
|
||||
options: value => value && languages.find(language => language.aliases.includes(value.toLowerCase())),
|
||||
errorMessage: 'Supplied language is not supported by Piston',
|
||||
},
|
||||
},
|
||||
source: {
|
||||
in: 'body',
|
||||
notEmpty: {
|
||||
errorMessage: 'No source supplied',
|
||||
},
|
||||
isString: {
|
||||
errorMessage: 'Supplied source is not a string',
|
||||
},
|
||||
},
|
||||
args: {
|
||||
in: 'body',
|
||||
optional: true,
|
||||
isArray: {
|
||||
errorMessage: 'Supplied args is not an array',
|
||||
},
|
||||
},
|
||||
stdin: {
|
||||
in: 'body',
|
||||
optional: true,
|
||||
isString: {
|
||||
errorMessage: 'Supplied stdin is not a string',
|
||||
},
|
||||
}
|
||||
}),
|
||||
async (req, res) => {
|
||||
const errors = validationResult(req).array();
|
||||
|
||||
if (errors.length === 0) {
|
||||
const language = languages.find(language =>
|
||||
language.aliases.includes(req.body.language.toLowerCase())
|
||||
);
|
||||
|
||||
const { stdout, stderr, output, ran } = await execute(language, req.body.source, req.body.stdin, req.body.args);
|
||||
|
||||
res.status(200).json({
|
||||
ran,
|
||||
language: language.name,
|
||||
version: language.version,
|
||||
stdout,
|
||||
stderr,
|
||||
output,
|
||||
});
|
||||
} else {
|
||||
res.status(400).json({
|
||||
message: errors[0].msg,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
app.get('/versions', (_, res) => res.json(languages));
|
||||
|
||||
app.listen(PORT, () => console.log(`Listening on port ${PORT}`));
|
|
@ -1,39 +0,0 @@
|
|||
const { spawn } = require('child_process');
|
||||
const languages = require('../../config/languages.json');
|
||||
|
||||
{
|
||||
const process = spawn(__dirname + '/../../lxc/util/versions');
|
||||
|
||||
let output = '';
|
||||
process.stderr.on('data', chunk => output += chunk);
|
||||
process.stdout.on('data', chunk => output += chunk);
|
||||
|
||||
process.on('exit', () => {
|
||||
const sections = output.toLowerCase().split('---');
|
||||
const versions = {};
|
||||
|
||||
for (const section of sections) {
|
||||
const lines = section.trim().split('\n');
|
||||
|
||||
if (lines.length >= 2) {
|
||||
const language = lines[0];
|
||||
|
||||
if (language === 'java') {
|
||||
versions[language] = /\d+/.exec(lines[1])?.[0];
|
||||
} else if (language === 'emacs') {
|
||||
versions[language] = /\d+\.\d+/.exec(lines[1])?.[0];
|
||||
} else {
|
||||
versions[language] = /\d+\.\d+\.\d+/.exec(section)?.[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const language of languages) {
|
||||
language.version = versions[language.name];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
languages,
|
||||
};
|
32
cli/execute
32
cli/execute
|
@ -1,32 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
const { execute } = require('../lxc/execute.js');
|
||||
const { readFileSync } = require('fs');
|
||||
const languages = require('../config/languages.json');
|
||||
|
||||
const [languageName, sourceFile, ...args] = process.argv.slice(2);
|
||||
|
||||
(async () => {
|
||||
if (!languageName) {
|
||||
console.error('Provide a language name');
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sourceFile) {
|
||||
console.error('Provide a source file');
|
||||
return;
|
||||
}
|
||||
|
||||
const source = readFileSync(sourceFile).toString();
|
||||
|
||||
const language = languages.find(language => language.aliases.includes(languageName.toLowerCase()));
|
||||
|
||||
if (!language) {
|
||||
console.error(`${languageName} is not supported by Piston`);
|
||||
return;
|
||||
}
|
||||
|
||||
const { output } = await execute(language, source, '', args);
|
||||
|
||||
console.log(output);
|
||||
})();
|
|
@ -1,267 +0,0 @@
|
|||
[
|
||||
{
|
||||
"name": "nasm",
|
||||
"aliases": [
|
||||
"asm",
|
||||
"nasm"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nasm64",
|
||||
"aliases": [
|
||||
"asm64",
|
||||
"nasm64"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "awk",
|
||||
"aliases": [
|
||||
"awk"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "bash",
|
||||
"aliases": [
|
||||
"bash",
|
||||
"sh"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "brainfuck",
|
||||
"aliases": [
|
||||
"bf",
|
||||
"brainfuck"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"aliases": [
|
||||
"c"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "crystal",
|
||||
"aliases": [
|
||||
"crystal",
|
||||
"cr"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "lisp",
|
||||
"aliases": [
|
||||
"lisp",
|
||||
"commonlisp",
|
||||
"clisp",
|
||||
"cl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "csharp",
|
||||
"aliases": [
|
||||
"c#",
|
||||
"cs",
|
||||
"csharp"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cpp",
|
||||
"aliases": [
|
||||
"c++",
|
||||
"cpp",
|
||||
"cc",
|
||||
"cxx"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "d",
|
||||
"aliases": [
|
||||
"dlang",
|
||||
"d"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "deno",
|
||||
"aliases": [
|
||||
"deno",
|
||||
"denojs",
|
||||
"denots"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "dash",
|
||||
"aliases": [
|
||||
"dash"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "ruby",
|
||||
"aliases": [
|
||||
"duby",
|
||||
"rb",
|
||||
"ruby"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "emacs",
|
||||
"aliases": [
|
||||
"el",
|
||||
"elisp",
|
||||
"emacs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "elixir",
|
||||
"aliases": [
|
||||
"elixir",
|
||||
"exs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "haskell",
|
||||
"aliases": [
|
||||
"haskell",
|
||||
"hs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "go",
|
||||
"aliases": [
|
||||
"go",
|
||||
"golang"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "java",
|
||||
"aliases": [
|
||||
"java"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "nim",
|
||||
"aliases": [
|
||||
"nim"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "node",
|
||||
"aliases": [
|
||||
"javascript",
|
||||
"js",
|
||||
"node",
|
||||
"node.js"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "jelly",
|
||||
"aliases": [
|
||||
"jelly"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "julia",
|
||||
"aliases": [
|
||||
"jl",
|
||||
"julia"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "kotlin",
|
||||
"aliases": [
|
||||
"kotlin",
|
||||
"kt"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "lua",
|
||||
"aliases": [
|
||||
"lua"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "paradoc",
|
||||
"aliases": [
|
||||
"paradoc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "perl",
|
||||
"aliases": [
|
||||
"perl",
|
||||
"pl"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "php",
|
||||
"aliases": [
|
||||
"php",
|
||||
"php3",
|
||||
"php4",
|
||||
"php5"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "prolog",
|
||||
"aliases": [
|
||||
"prolog",
|
||||
"plg"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "python3",
|
||||
"aliases": [
|
||||
"py",
|
||||
"py3",
|
||||
"python",
|
||||
"python3"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "python2",
|
||||
"aliases": [
|
||||
"python2",
|
||||
"py2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rust",
|
||||
"aliases": [
|
||||
"rs",
|
||||
"rust"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "scala",
|
||||
"aliases": [
|
||||
"scala",
|
||||
"sc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "swift",
|
||||
"aliases": [
|
||||
"swift"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "typescript",
|
||||
"aliases": [
|
||||
"ts",
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "zig",
|
||||
"aliases": [
|
||||
"zig"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "osabie",
|
||||
"aliases": [
|
||||
"osabie",
|
||||
"05AB1E",
|
||||
"osable",
|
||||
"usable"
|
||||
]
|
||||
}
|
||||
]
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
python3 -m pip install pyyaml
|
||||
python3 configure.py
|
||||
distrobuilder build-lxc build.yaml
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import yaml
|
||||
|
||||
|
||||
with open('piston.yaml') as dbc:
|
||||
with open('install_script.sh') as install_script_file:
|
||||
with open('build.yaml' , 'w+') as distrobuilder_config_file_new:
|
||||
distrobuilder_config = yaml.safe_load(dbc)
|
||||
distrobuilder_config['actions'].append({
|
||||
'trigger': 'post-packages',
|
||||
'action': install_script_file.read(),
|
||||
|
||||
})
|
||||
yaml.dump(distrobuilder_config, distrobuilder_config_file_new)
|
|
@ -1,323 +0,0 @@
|
|||
#!/bin/bash
|
||||
#echo "Don't run this on your system!" && exit 0
|
||||
|
||||
# install all necessary piston dependencies
|
||||
echo 'source /opt/.profile' >> /opt/.bashrc
|
||||
echo 'export HOME=/opt' >> /opt/.profile
|
||||
echo 'export TERM=linux' >> /opt/.profile
|
||||
echo 'export PATH=$PATH:/opt/.local/bin' >> /opt/.profile
|
||||
export HOME=/opt
|
||||
export TERM=linux
|
||||
sed -i 's/\/root/\/opt/' /etc/passwd
|
||||
sed -i \
|
||||
's/http:\/\/archive.ubuntu.com\/ubuntu/http:\/\/mirror.math.princeton.edu\/pub\/ubuntu/' \
|
||||
/etc/apt/sources.list
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
nano wget build-essential pkg-config libxml2-dev \
|
||||
libsqlite3-dev mono-complete curl cmake libpython2.7-dev \
|
||||
ruby libtinfo-dev unzip git openssl libssl-dev sbcl libevent-dev
|
||||
|
||||
# install python2
|
||||
# final binary: /opt/python2/Python-2.7.17/python
|
||||
# get version: /opt/python2/Python-2.7.17/python -V
|
||||
cd /opt && mkdir python2 && cd python2
|
||||
wget https://www.python.org/ftp/python/2.7.17/Python-2.7.17.tar.xz
|
||||
unxz Python-2.7.17.tar.xz
|
||||
tar -xf Python-2.7.17.tar
|
||||
cd Python-2.7.17
|
||||
./configure
|
||||
# open Modules/Setup and uncomment zlib line
|
||||
make
|
||||
echo 'export PATH=$PATH:/opt/python2/Python-2.7.17' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install python3
|
||||
# final binary: /opt/python3/Python-3.9.1/python
|
||||
# get version: /opt/python3/Python-3.9.1/python -V
|
||||
cd /opt && mkdir python3 && cd python3
|
||||
wget https://www.python.org/ftp/python/3.9.1/Python-3.9.1.tar.xz
|
||||
unxz Python-3.9.1.tar.xz
|
||||
tar -xf Python-3.9.1.tar
|
||||
cd Python-3.9.1
|
||||
./configure
|
||||
make
|
||||
ln -s python python3.9
|
||||
echo 'export PATH=$PATH:/opt/python3/Python-3.9.1' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install paradoc
|
||||
# this is not a binary, it is a python module
|
||||
# therefore it cannot be run directly as it requires python3 to be installed
|
||||
cd /opt && mkdir paradoc && cd paradoc
|
||||
git clone https://github.com/betaveros/paradoc.git
|
||||
|
||||
# install node.js
|
||||
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/node
|
||||
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/node -v
|
||||
cd /opt && mkdir nodejs && cd nodejs
|
||||
wget https://nodejs.org/dist/v12.16.1/node-v12.16.1-linux-x64.tar.xz
|
||||
unxz node-v12.16.1-linux-x64.tar.xz
|
||||
tar -xf node-v12.16.1-linux-x64.tar
|
||||
echo 'export PATH=$PATH:/opt/nodejs/node-v12.16.1-linux-x64/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install typescript
|
||||
# final binary: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc
|
||||
# get version: /opt/nodejs/node-v12.16.1-linux-x64/bin/tsc -v
|
||||
/opt/nodejs/node-v12.16.1-linux-x64/bin/npm i -g typescript
|
||||
|
||||
# install golang
|
||||
# final binary: /opt/go/go/bin/go
|
||||
# get version: /opt/go/go/bin/go version
|
||||
cd /opt && mkdir go && cd go
|
||||
wget https://dl.google.com/go/go1.14.1.linux-amd64.tar.gz
|
||||
tar -xzf go1.14.1.linux-amd64.tar.gz
|
||||
echo 'export PATH=$PATH:/opt/go/go/bin' >> /opt/.profile
|
||||
echo 'export GOROOT=/opt/go/go' >> /opt/.profile
|
||||
echo 'export GOCACHE=/tmp' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install php
|
||||
# final binary: /usr/local/bin/php
|
||||
# get version: /usr/local/bin/php -v
|
||||
cd /opt && mkdir php && cd php
|
||||
wget https://www.php.net/distributions/php-8.0.0.tar.gz
|
||||
tar -xzf php-8.0.0.tar.gz
|
||||
cd php-8.0.0
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
|
||||
# install rust
|
||||
# final binary: /usr/local/bin/rustc
|
||||
# get version: /usr/local/bin/rustc --version
|
||||
cd /opt && mkdir rust && cd rust
|
||||
wget https://static.rust-lang.org/dist/rust-1.49.0-x86_64-unknown-linux-gnu.tar.gz
|
||||
tar -xzf rust-1.49.0-x86_64-unknown-linux-gnu.tar.gz
|
||||
cd rust-1.49.0-x86_64-unknown-linux-gnu
|
||||
./install.sh
|
||||
|
||||
# install scala
|
||||
# final binary: /opt/scala/scala3-3.0.0-M3/bin/scala
|
||||
# get version: /opt/scala/scala3-3.0.0-M3/bin/scala -version
|
||||
cd /opt && mkdir scala && cd scala
|
||||
wget https://github.com/lampepfl/dotty/releases/download/3.0.0-M3/scala3-3.0.0-M3.tar.gz
|
||||
tar -xzf scala3-3.0.0-M3.tar.gz
|
||||
echo 'export PATH=$PATH:/opt/scala/scala3-3.0.0-M3/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install swift
|
||||
# final binary: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift
|
||||
# get version: /opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin/swift --version
|
||||
cd /opt && mkdir swift && cd swift
|
||||
wget https://swift.org/builds/swift-5.1.5-release/ubuntu1804/swift-5.1.5-RELEASE/swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
||||
tar -xzf swift-5.1.5-RELEASE-ubuntu18.04.tar.gz
|
||||
echo 'export PATH=$PATH:/opt/swift/swift-5.1.5-RELEASE-ubuntu18.04/usr/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install nasm
|
||||
# final binary: /opt/nasm/nasm-2.14.02/nasm
|
||||
# get version: /opt/nasm/nasm-2.14.02/nasm -v
|
||||
cd /opt && mkdir nasm && cd nasm
|
||||
wget https://www.nasm.us/pub/nasm/releasebuilds/2.14.02/nasm-2.14.02.tar.gz
|
||||
tar -xzf nasm-2.14.02.tar.gz
|
||||
cd nasm-2.14.02
|
||||
./configure
|
||||
make
|
||||
echo 'export PATH=$PATH:/opt/nasm/nasm-2.14.02' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install java
|
||||
# final binary: /opt/java/jdk-14/bin/java
|
||||
# get version: /opt/java/jdk-14/bin/java -version
|
||||
cd /opt && mkdir java && cd java
|
||||
wget https://download.java.net/java/GA/jdk14/076bab302c7b4508975440c56f6cc26a/36/GPL/openjdk-14_linux-x64_bin.tar.gz
|
||||
tar -xzf openjdk-14_linux-x64_bin.tar.gz
|
||||
echo 'export PATH=$PATH:/opt/java/jdk-14/bin' >> /opt/.profile
|
||||
# Scala will complain if JAVA_HOME isn't set
|
||||
echo 'export JAVA_HOME=/opt/java/jdk-14' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install jelly
|
||||
cd /opt && mkdir jelly && cd jelly
|
||||
wget https://github.com/DennisMitchell/jellylanguage/archive/master.zip
|
||||
unzip master.zip
|
||||
cd jellylanguage-master
|
||||
python3.8 -m pip install .
|
||||
sed -i 's/\/usr\/local\/bin\/python3.8/\/opt\/python3\/Python-3.8.2\/python3.8/' /usr/local/bin/jelly
|
||||
|
||||
# install julia
|
||||
# final binary: /opt/julia/julia-1.5.0/bin/julia
|
||||
# get version: /opt/julia/julia-1.5.0/bin/julia --version
|
||||
cd /opt && mkdir julia && cd julia
|
||||
wget https://julialang-s3.julialang.org/bin/linux/x64/1.5/julia-1.5.0-linux-x86_64.tar.gz
|
||||
tar -xzf julia-1.5.0-linux-x86_64.tar.gz
|
||||
echo 'export PATH=$PATH:/opt/julia/julia-1.5.0/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install kotlin
|
||||
# final binary: /opt/kotlinc/bin/kotlinc
|
||||
# get version: /opt/kotlinc/bin/kotlinc -version
|
||||
cd /opt
|
||||
wget https://github.com/JetBrains/kotlin/releases/download/v1.4.10/kotlin-compiler-1.4.10.zip
|
||||
unzip kotlin-compiler-1.4.10.zip
|
||||
rm kotlin-compiler-1.4.10.zip
|
||||
echo 'export PATH=$PATH:/opt/kotlinc/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install elixir and erlang
|
||||
# final binary: /opt/elixir/bin/elixir
|
||||
# get version: /opt/elixir/bin/elixir --version
|
||||
# erlang
|
||||
cd /opt && mkdir erlang && cd erlang
|
||||
wget http://erlang.org/download/otp_src_23.0.tar.gz
|
||||
gunzip -c otp_src_23.0.tar.gz | tar xf -
|
||||
cd otp_src_23.0 && ./configure
|
||||
make
|
||||
echo 'export PATH=$PATH:/opt/erlang/otp_src_23.0/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
# elixir
|
||||
cd /opt && mkdir elixir && cd elixir
|
||||
wget https://github.com/elixir-lang/elixir/releases/download/v1.10.3/Precompiled.zip
|
||||
mkdir elixir-1.10.3 && unzip Precompiled.zip -d elixir-1.10.3/
|
||||
echo 'export PATH=$PATH:/opt/elixir/elixir-1.10.3/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install emacs
|
||||
# final binary: /opt/emacs/emacs-26.3/src/emacs
|
||||
# get version: /opt/emacs/emacs-26.3/src/emacs --version
|
||||
cd /opt && mkdir emacs && cd emacs
|
||||
wget https://mirrors.ocf.berkeley.edu/gnu/emacs/emacs-26.3.tar.xz
|
||||
tar -xf emacs-26.3.tar.xz
|
||||
rm emacs-26.3.tar.xz
|
||||
cd emacs-26.3
|
||||
./configure --with-gnutls=no
|
||||
make
|
||||
echo 'export PATH=$PATH:/opt/emacs/emacs-26.3/src' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install lua
|
||||
# final binary: /opt/lua/lua54/src/lua
|
||||
# get version: /opt/lua/lua54/src/lua -v
|
||||
cd /opt && mkdir lua && cd lua
|
||||
wget https://sourceforge.net/projects/luabinaries/files/5.4.0/Docs%20and%20Sources/lua-5.4.0_Sources.tar.gz/download
|
||||
tar -xzf download
|
||||
cd lua54
|
||||
make
|
||||
echo 'export PATH=$PATH:/opt/lua/lua54/src' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install haskell
|
||||
# final binary: /usr/bin/ghc
|
||||
# get version: /usr/bin/ghc --version
|
||||
apt install -y ghc
|
||||
|
||||
# install deno
|
||||
# final binary: /opt/.deno/bin/deno
|
||||
# get version: /opt/.deno/bin/deno --version
|
||||
cd /opt && mkdir deno && cd deno
|
||||
curl -fsSL https://deno.land/x/install/install.sh | sh
|
||||
echo 'export DENO_INSTALL="/opt/.deno"' >> /opt/.profile
|
||||
echo 'export PATH="$DENO_INSTALL/bin:$PATH"' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install brainfuck
|
||||
cd /opt && mkdir bf && cd bf
|
||||
git clone https://github.com/texus/Brainfuck-interpreter
|
||||
cd Brainfuck-interpreter
|
||||
echo 'export PATH=$PATH:/opt/bf/Brainfuck-interpreter' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install crystal
|
||||
# final binary: /opt/crystal/crystal-0.35.1-1/bin/crystal
|
||||
# get version: /opt/crystal/crystal-0.35.1-1/bin/crystal -v
|
||||
cd /opt && mkdir crystal && cd crystal
|
||||
wget https://github.com/crystal-lang/crystal/releases/download/0.35.1/crystal-0.35.1-1-linux-x86_64.tar.gz
|
||||
tar -xzf crystal-0.35.1-1-linux-x86_64.tar.gz
|
||||
echo 'export PATH="$PATH:/opt/crystal/crystal-0.35.1-1/bin:$PATH"' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install d
|
||||
# final binary: /opt/d/dmd2/linux/bin64/dmd
|
||||
# get version: /opt/d/dmd2/linux/bin64/dmd --version
|
||||
cd /opt && mkdir d && cd d
|
||||
wget http://downloads.dlang.org/releases/2.x/2.095.0/dmd.2.095.0.linux.tar.xz
|
||||
unxz dmd.2.095.0.linux.tar.xz
|
||||
tar -xf dmd.2.095.0.linux.tar
|
||||
echo 'export PATH=$PATH:/opt/d/dmd2/linux/bin64' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install zig
|
||||
# final binary: /opt/zig/zig
|
||||
# get version: /opt/zig/zig version
|
||||
cd /opt && mkdir zig && cd zig
|
||||
wget https://ziglang.org/download/0.7.1/zig-linux-x86_64-0.7.1.tar.xz
|
||||
tar -xf zig-linux-x86_64-0.7.1.tar.xz
|
||||
mv zig-linux-x86_64-0.7.1 zig
|
||||
rm zig-linux-x86_64-0.7.1.tar.xz
|
||||
echo 'export PATH=$PATH:/opt/zig/zig' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install nim
|
||||
# final binary: /opt/nim/bin/nim
|
||||
# get version: /opt/nim/bin/nim -v
|
||||
cd /opt && mkdir nim && cd nim
|
||||
wget https://nim-lang.org/download/nim-1.4.0-linux_x64.tar.xz
|
||||
unxz nim-1.4.0-linux_x64.tar.xz
|
||||
tar -xf nim-1.4.0-linux_x64.tar
|
||||
cd nim-1.4.0
|
||||
./install.sh /opt
|
||||
echo 'export PATH=$PATH:/opt/nim/bin' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# install 05AB1E
|
||||
# final binary: /opt/05AB1E/05AB1E/osabie
|
||||
# requires Elixir to install
|
||||
cd /opt && mkdir 05AB1E && cd 05AB1E
|
||||
git clone https://github.com/Adriandmen/05AB1E.git
|
||||
cd 05AB1E
|
||||
mix local.hex --force
|
||||
mix deps.get --force
|
||||
MIX_ENV=prod mix escript.build --force
|
||||
echo 'export PATH=$PATH:/opt/05AB1E/05AB1E' >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
|
||||
# install prolog
|
||||
# final binary: /opt/swipl/swipl-<version>/build/src/swipl
|
||||
cd /opt && mkdir swipl && cd swipl
|
||||
SUB_DIR=swipl-8.2.4
|
||||
wget https://www.swi-prolog.org/download/stable/src/$SUB_DIR.tar.gz
|
||||
tar -xf $SUB_DIR.tar.gz
|
||||
rm $SUB_DIR.tar.gz
|
||||
cd $SUB_DIR
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DSWIPL_PACKAGES_JAVA=OFF -DSWIPL_PACKAGES_X=OFF -DMULTI_THREADED=OFF -G Ninja ..
|
||||
ninja
|
||||
echo "export PATH=\$PATH:/opt/swipl/$SUB_DIR/build/src" >> /opt/.profile
|
||||
source /opt/.profile
|
||||
|
||||
# create runnable users and apply limits
|
||||
for i in {1..150}; do
|
||||
useradd -M runner$i
|
||||
usermod -d /tmp runner$i
|
||||
echo "runner$i soft nproc 64" >> /etc/security/limits.conf
|
||||
echo "runner$i hard nproc 64" >> /etc/security/limits.conf
|
||||
echo "runner$i soft nofile 2048" >> /etc/security/limits.conf
|
||||
echo "runner$i hard nofile 2048" >> /etc/security/limits.conf
|
||||
done
|
||||
|
||||
# remove any lingering write access to others
|
||||
cd /opt
|
||||
chown -R root: *
|
||||
chmod -R o-w *
|
||||
|
||||
# cleanup
|
||||
rm -rf /home/ubuntu
|
||||
chmod 777 /tmp
|
||||
|
||||
# disable cron
|
||||
systemctl stop cron
|
||||
systemctl disable cron
|
|
@ -1,355 +0,0 @@
|
|||
image:
|
||||
name: ubuntu-bionic-x86_64-piston
|
||||
distribution: ubuntu
|
||||
release: bionic
|
||||
description: |-
|
||||
Ubuntu {{ image.release }} preconfigured for Piston
|
||||
architecture: x86_64
|
||||
|
||||
source:
|
||||
downloader: debootstrap
|
||||
same_as: bionic
|
||||
url: http://archive.ubuntu.com/ubuntu
|
||||
keyserver: keyserver.ubuntu.com
|
||||
keys:
|
||||
- '0x790BC7277767219C42C86F933B4FE6ACC0B21F32'
|
||||
- '0xf6ecb3762474eda9d21b7022871920d1991bc93c'
|
||||
|
||||
targets:
|
||||
lxc:
|
||||
create-message: |-
|
||||
You just created an {{ image.description }} container.
|
||||
To enable SSH, run: apt install openssh-server
|
||||
No default root or user password are set by LXC.
|
||||
config:
|
||||
- type: all
|
||||
before: 5
|
||||
content: |-
|
||||
lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.common.conf
|
||||
- type: user
|
||||
before: 5
|
||||
content: |-
|
||||
lxc.include = LXC_TEMPLATE_CONFIG/ubuntu.userns.conf
|
||||
- type: all
|
||||
after: 4
|
||||
content: |-
|
||||
lxc.include = LXC_TEMPLATE_CONFIG/common.conf
|
||||
# For Ubuntu 14.04
|
||||
lxc.mount.entry = /sys/kernel/debug sys/kernel/debug none bind,optional 0 0
|
||||
lxc.mount.entry = /sys/kernel/security sys/kernel/security none bind,optional 0 0
|
||||
lxc.mount.entry = /sys/fs/pstore sys/fs/pstore none bind,optional 0 0
|
||||
lxc.mount.entry = mqueue dev/mqueue mqueue rw,relatime,create=dir,optional 0 0
|
||||
- type: user
|
||||
after: 4
|
||||
content: |-
|
||||
lxc.include = LXC_TEMPLATE_CONFIG/userns.conf
|
||||
# For Ubuntu 14.04
|
||||
lxc.mount.entry = /sys/firmware/efi/efivars sys/firmware/efi/efivars none bind,optional 0 0
|
||||
lxc.mount.entry = /proc/sys/fs/binfmt_misc proc/sys/fs/binfmt_misc none bind,optional 0 0
|
||||
- type: all
|
||||
content: |-
|
||||
lxc.arch = {{ image.architecture_personality }}
|
||||
files:
|
||||
- path: /etc/hostname
|
||||
generator: hostname
|
||||
|
||||
- path: /etc/hosts
|
||||
generator: hosts
|
||||
|
||||
- path: /etc/resolvconf/resolv.conf.d/original
|
||||
generator: remove
|
||||
|
||||
- path: /etc/resolvconf/resolv.conf.d/tail
|
||||
generator: remove
|
||||
|
||||
- path: /etc/machine-id
|
||||
generator: dump
|
||||
|
||||
|
||||
- path: /var/lib/dbus/machine-id
|
||||
generator: remove
|
||||
|
||||
- path: /etc/netplan/10-lxc.yaml
|
||||
generator: dump
|
||||
content: |-
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
eth0:
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
releases:
|
||||
- bionic
|
||||
- eoan
|
||||
- focal
|
||||
- groovy
|
||||
types:
|
||||
- container
|
||||
variants:
|
||||
- default
|
||||
|
||||
- path: /etc/network/interfaces
|
||||
generator: dump
|
||||
content: |-
|
||||
# This file describes the network interfaces available on your system
|
||||
# and how to activate them. For more information, see interfaces(5).
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
auto eth0
|
||||
iface eth0 inet dhcp
|
||||
source /etc/network/interfaces.d/*.cfg
|
||||
releases:
|
||||
- trusty
|
||||
- xenial
|
||||
types:
|
||||
- container
|
||||
|
||||
- path: /etc/netplan/10-lxc.yaml
|
||||
generator: dump
|
||||
content: |-
|
||||
network:
|
||||
version: 2
|
||||
ethernets:
|
||||
enp5s0:
|
||||
dhcp4: true
|
||||
dhcp-identifier: mac
|
||||
releases:
|
||||
- bionic
|
||||
- eoan
|
||||
- focal
|
||||
- groovy
|
||||
types:
|
||||
- vm
|
||||
variants:
|
||||
- default
|
||||
|
||||
- path: /etc/network/interfaces
|
||||
generator: dump
|
||||
content: |-
|
||||
# This file describes the network interfaces available on your system
|
||||
# and how to activate them. For more information, see interfaces(5).
|
||||
# The loopback network interface
|
||||
auto lo
|
||||
iface lo inet loopback
|
||||
auto enp5s0
|
||||
iface enp5s0 inet dhcp
|
||||
source /etc/network/interfaces.d/*.cfg
|
||||
releases:
|
||||
- trusty
|
||||
- xenial
|
||||
types:
|
||||
- vm
|
||||
|
||||
- path: /etc/init/lxc-tty.conf
|
||||
generator: upstart-tty
|
||||
releases:
|
||||
- trusty
|
||||
types:
|
||||
- container
|
||||
|
||||
- name: meta-data
|
||||
generator: cloud-init
|
||||
variants:
|
||||
- cloud
|
||||
|
||||
- name: network-config
|
||||
generator: cloud-init
|
||||
variants:
|
||||
- cloud
|
||||
|
||||
- name: user-data
|
||||
generator: cloud-init
|
||||
variants:
|
||||
- cloud
|
||||
|
||||
- name: vendor-data
|
||||
generator: cloud-init
|
||||
variants:
|
||||
- cloud
|
||||
|
||||
- name: ext4
|
||||
generator: fstab
|
||||
types:
|
||||
- vm
|
||||
|
||||
- name: lxd-agent
|
||||
generator: lxd-agent
|
||||
types:
|
||||
- vm
|
||||
|
||||
- path: /etc/default/grub.d/50-lxd.cfg
|
||||
generator: dump
|
||||
content: |-
|
||||
GRUB_RECORDFAIL_TIMEOUT=0
|
||||
GRUB_TIMEOUT=0
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="${GRUB_CMDLINE_LINUX_DEFAULT} console=tty1 console=ttyS0"
|
||||
GRUB_TERMINAL=console
|
||||
types:
|
||||
- vm
|
||||
|
||||
- path: /etc/sudoers.d/90-lxd
|
||||
generator: dump
|
||||
mode: '0440'
|
||||
content: |-
|
||||
# User rules for ubuntu
|
||||
ubuntu ALL=(ALL) NOPASSWD:ALL
|
||||
variants:
|
||||
- default
|
||||
|
||||
packages:
|
||||
manager: apt
|
||||
update: true
|
||||
cleanup: true
|
||||
sets:
|
||||
- packages:
|
||||
- apt-transport-https
|
||||
- fuse
|
||||
- language-pack-en
|
||||
- openssh-client
|
||||
- vim
|
||||
action: install
|
||||
|
||||
- packages:
|
||||
- cloud-init
|
||||
action: install
|
||||
variants:
|
||||
- cloud
|
||||
|
||||
- packages:
|
||||
- acpid
|
||||
action: install
|
||||
architectures:
|
||||
- amd64
|
||||
- arm64
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- grub-efi-amd64-signed
|
||||
- shim-signed
|
||||
action: install
|
||||
architectures:
|
||||
- amd64
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- grub-efi-arm64-signed
|
||||
action: install
|
||||
architectures:
|
||||
- arm64
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- shim-signed
|
||||
action: install
|
||||
architectures:
|
||||
- arm64
|
||||
releases:
|
||||
- disco
|
||||
- eoan
|
||||
- focal
|
||||
- groovy
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- linux-virtual-hwe-16.04
|
||||
action: install
|
||||
releases:
|
||||
- xenial
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- linux-virtual
|
||||
action: install
|
||||
releases:
|
||||
- bionic
|
||||
- eoan
|
||||
- focal
|
||||
- groovy
|
||||
types:
|
||||
- vm
|
||||
|
||||
- packages:
|
||||
- os-prober
|
||||
action: remove
|
||||
types:
|
||||
- vm
|
||||
|
||||
repositories:
|
||||
- name: sources.list
|
||||
url: |-
|
||||
deb http://archive.ubuntu.com/ubuntu {{ image.release }} main restricted universe multiverse
|
||||
deb http://archive.ubuntu.com/ubuntu {{ image.release }}-updates main restricted universe multiverse
|
||||
deb http://security.ubuntu.com/ubuntu {{ image.release }}-security main restricted universe multiverse
|
||||
architectures:
|
||||
- amd64
|
||||
- i386
|
||||
|
||||
- name: sources.list
|
||||
url: |-
|
||||
deb http://ports.ubuntu.com/ubuntu-ports {{ image.release }} main restricted universe multiverse
|
||||
deb http://ports.ubuntu.com/ubuntu-ports {{ image.release }}-updates main restricted universe multiverse
|
||||
deb http://ports.ubuntu.com/ubuntu-ports {{ image.release }}-security main restricted universe multiverse
|
||||
architectures:
|
||||
- armhf
|
||||
- arm64
|
||||
- powerpc
|
||||
- powerpc64
|
||||
- ppc64el
|
||||
|
||||
actions:
|
||||
- trigger: post-update
|
||||
action: |-
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
# Create the ubuntu user account
|
||||
getent group sudo >/dev/null 2>&1 || groupadd --system sudo
|
||||
useradd --create-home -s /bin/bash -G sudo -U ubuntu
|
||||
variants:
|
||||
- default
|
||||
|
||||
- trigger: post-packages
|
||||
action: |-
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
# Enable systemd-networkd
|
||||
systemctl enable systemd-networkd
|
||||
releases:
|
||||
- bionic
|
||||
- eoan
|
||||
- focal
|
||||
- groovy
|
||||
|
||||
- trigger: post-packages
|
||||
action: |-
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
# Make sure the locale is built and functional
|
||||
locale-gen en_US.UTF-8
|
||||
update-locale LANG=en_US.UTF-8
|
||||
# Cleanup underlying /run
|
||||
mount -o bind / /mnt
|
||||
rm -rf /mnt/run/*
|
||||
umount /mnt
|
||||
# Cleanup temporary shadow paths
|
||||
rm /etc/*-
|
||||
- trigger: post-files
|
||||
action: |-
|
||||
#!/bin/sh
|
||||
set -eux
|
||||
TARGET="x86_64"
|
||||
[ "$(uname -m)" = "aarch64" ] && TARGET="arm64"
|
||||
update-grub
|
||||
grub-install --uefi-secure-boot --target="${TARGET}-efi" --no-nvram --removable
|
||||
update-grub
|
||||
sed -i "s#root=[^ ]*#root=/dev/sda2#g" /boot/grub/grub.cfg
|
||||
types:
|
||||
- vm
|
||||
|
||||
mappings:
|
||||
architecture_map: debian
|
|
@ -1,7 +0,0 @@
|
|||
# LXC Container Build
|
||||
|
||||
Requires: `lxc`, `lxc-net`, `packer` (Hashicorp Packer)
|
||||
|
||||
To build: `packer build -var 'apt_mirror=[apt mirror]' -var 'make_threads=[-j flag]' piston.pkr.hcl`
|
||||
|
||||
After roughly 30 minutes (on an i7-4790k), you should have an image built
|
|
@ -1,32 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Logo" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 1024 1024" style="enable-background:new 0 0 1024 1024;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:url(#Circle_1_);}
|
||||
.st1{fill:#00E300;}
|
||||
.st2{fill:#FFFFFF;}
|
||||
</style>
|
||||
<radialGradient id="Circle_1_" cx="512" cy="512" r="512" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" style="stop-color:#0B0B0B"/>
|
||||
<stop offset="1" style="stop-color:#1B1B1B"/>
|
||||
</radialGradient>
|
||||
<path id="Circle" class="st0" d="M512,1024L512,1024c282.77,0,512-229.23,512-512v0C1024,229.23,794.77,0,512,0h0
|
||||
C229.23,0,0,229.23,0,512v0C0,794.77,229.23,1024,512,1024z"/>
|
||||
<g id="E">
|
||||
<path class="st1" d="M218,840.5c-4.31,0-8.4-1.92-11.15-5.23c-2.75-3.32-3.89-7.68-3.1-11.92l117-628
|
||||
c1.28-6.87,7.27-11.84,14.25-11.84h427c3.58,0,7.03,1.32,9.69,3.72l99,89c4.47,4.01,5.99,10.37,3.84,15.97
|
||||
c-2.15,5.61-7.53,9.31-13.54,9.31H481.02l-28.52,151H541c3.58,0,7.03,1.32,9.69,3.72l99,89c4.47,4.01,5.99,10.37,3.84,15.97
|
||||
c-2.15,5.61-7.53,9.31-13.54,9.31H430.03l-28.55,152H771c6.37,0,11.99,4.15,13.86,10.24c1.87,6.08-0.45,12.68-5.71,16.26l-131,89
|
||||
c-2.4,1.63-5.24,2.51-8.15,2.51H218z"/>
|
||||
<path d="M762,198l99,89H469l-34,180h106l99,89H418l-34,181h387l-131,89H218l117-628H762 M762,169H335
|
||||
c-13.97,0-25.95,9.96-28.51,23.69l-117,628c-1.58,8.48,0.69,17.21,6.2,23.84C201.2,851.16,209.38,855,218,855h422
|
||||
c5.81,0,11.49-1.75,16.3-5.01l131-89c10.53-7.16,15.16-20.34,11.42-32.51C794.98,716.3,783.73,708,771,708H418.95l23.1-123H640
|
||||
c12.01,0,22.78-7.4,27.08-18.62c4.3-11.21,1.24-23.92-7.69-31.95l-99-89c-5.32-4.79-12.23-7.43-19.39-7.43h-71.01l23.04-122H861
|
||||
c12.01,0,22.78-7.4,27.08-18.62c4.3-11.21,1.24-23.92-7.69-31.95l-99-89C776.06,171.65,769.16,169,762,169L762,169z"/>
|
||||
</g>
|
||||
<g id="Highlight">
|
||||
<polygon id="Top" class="st2" points="640,556 541,467 435,467 469,287 645.78,287 632.79,198 378,198 430.19,556 "/>
|
||||
<polygon id="Bottom" class="st2" points="456.57,737 469.55,826 640,826 716.83,773.81 711.45,737 "/>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
19
license
19
license
|
@ -1,19 +0,0 @@
|
|||
Copyright (c) 2018 Brian Seymour, EMKC Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
55
lxc/execute
55
lxc/execute
|
@ -1,55 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
dir="$( cd "$( dirname "$0" )" && pwd )"
|
||||
|
||||
touch $dir/lockfile
|
||||
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "invalid args"
|
||||
exit
|
||||
fi
|
||||
|
||||
language=$1
|
||||
id=$2
|
||||
|
||||
basepath="/var/lib/lxc/piston/rootfs"
|
||||
|
||||
# process incrementor
|
||||
exec 200>$dir/lockfile
|
||||
flock 200
|
||||
|
||||
touch $dir/i
|
||||
runner=$(cat $dir/i)
|
||||
let 'runner = runner % 150 + 1'
|
||||
|
||||
echo $runner > $dir/i
|
||||
exec 200>&-
|
||||
|
||||
# prevent users from spying on each other
|
||||
lxc-attach --clear-env -n piston -- \
|
||||
/bin/bash -l -c "
|
||||
chown runner$runner: -R /tmp/$id
|
||||
chmod 700 /tmp/$id
|
||||
" > /dev/null 2>&1
|
||||
|
||||
# runner
|
||||
timeout -s KILL 20 \
|
||||
lxc-attach --clear-env -n piston -- \
|
||||
/bin/bash -l -c "runuser runner$runner /exec/$language $id"
|
||||
|
||||
# process janitor
|
||||
lxc-attach --clear-env -n piston -- \
|
||||
/bin/bash -l -c "
|
||||
for i in {1..100}
|
||||
do
|
||||
pkill -u runner$runner --signal SIGKILL
|
||||
done
|
||||
|
||||
find /tmp -user runner$runner -delete
|
||||
find /var/tmp -user runner$runner -delete
|
||||
find /var/lock -user runner$runner -delete
|
||||
find /dev/shm -user runner$runner -delete
|
||||
find /run/lock -user runner$runner -delete
|
||||
" > /dev/null 2>&1 &
|
||||
|
||||
rm -rf $basepath/tmp/$id
|
|
@ -1,56 +0,0 @@
|
|||
const { writeFileSync, unlinkSync, mkdirSync } = require('fs');
|
||||
const { spawn } = require('child_process');
|
||||
|
||||
const OUTPUT_LIMIT = 65535;
|
||||
const LXC_ROOT = '/var/lib/lxc/piston/rootfs';
|
||||
|
||||
function execute(language, source, stdin = '', args = []) {
|
||||
return new Promise(resolve => {
|
||||
const id = new Date().getTime() + '_' + Math.floor(Math.random() * 10000000);
|
||||
|
||||
mkdirSync(`${LXC_ROOT}/tmp/${id}`);
|
||||
writeFileSync(`${LXC_ROOT}/tmp/${id}/code.code`, source);
|
||||
writeFileSync(`${LXC_ROOT}/tmp/${id}/stdin.stdin`, stdin);
|
||||
writeFileSync(`${LXC_ROOT}/tmp/${id}/args.args`, args.join('\n'));
|
||||
|
||||
const process = spawn(__dirname + '/execute', [
|
||||
language.name,
|
||||
id,
|
||||
]);
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
let output = '';
|
||||
|
||||
process.stderr.on('data', chunk => {
|
||||
if (stderr.length >= OUTPUT_LIMIT) return;
|
||||
|
||||
stderr += chunk;
|
||||
output += chunk;
|
||||
});
|
||||
|
||||
process.stdout.on('data', chunk => {
|
||||
if (stdout.length >= OUTPUT_LIMIT) return;
|
||||
|
||||
stdout += chunk;
|
||||
output += chunk;
|
||||
});
|
||||
|
||||
process.on('exit', code => {
|
||||
stderr = stderr.trim().substring(0, OUTPUT_LIMIT);
|
||||
stdout = stdout.trim().substring(0, OUTPUT_LIMIT);
|
||||
output = output.trim().substring(0, OUTPUT_LIMIT);
|
||||
|
||||
resolve({
|
||||
stdout,
|
||||
stderr,
|
||||
output,
|
||||
ran: code === 0,
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
execute,
|
||||
};
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' awk -f code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
xargs -a args.args -d '\n' timeout -s KILL 3 bash code.code < stdin.stdin
|
|
@ -1,36 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
sedarg="\
|
||||
s/+/P/g;\
|
||||
s/-/M/g;\
|
||||
s/>/++p;/g;\
|
||||
s/</--p;/g;\
|
||||
s/P/++*p;/g;\
|
||||
s/M/--*p;/g;\
|
||||
s/\\./putchar(*p);/g;\
|
||||
s/,/*p=(c=getchar())==EOF?0:c;/g;\
|
||||
s/\\[/while(*p){/g;\
|
||||
s/]/}/g\
|
||||
"
|
||||
|
||||
# compilation
|
||||
MEMSIZE=15
|
||||
cat <<EOF > code.c
|
||||
#include <stdio.h>
|
||||
|
||||
char mem[1<<$MEMSIZE];
|
||||
char *p = mem + (1<<$((MEMSIZE - 1)));
|
||||
int c;
|
||||
|
||||
int main() {
|
||||
$(timeout -s KILL 3 sed 's/[^][<>.,+-]//g' code.code | timeout -s KILL 3 sed $sedarg)
|
||||
}
|
||||
EOF
|
||||
timeout -s KILL 3 gcc -std=c11 -o binary code.c
|
||||
|
||||
# Merging args.args and stdin.stdin for emkc challenges
|
||||
cat stdin.stdin >> args.args
|
||||
|
||||
# execution
|
||||
timeout -s KILL 3 ./binary < args.args
|
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 10 gcc -std=c11 -o binary -x c code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 10 g++ -std=c++17 -o binary -x c++ code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 10 crystal build code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./code < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
mcs $(echo code.code | sed 's/\///') -nowarn:0219 -out:binary
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' mono binary < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code code.d
|
||||
timeout -s KILL 10 dmd code.d
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./code
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
xargs -a args.args -d '\n' timeout -s KILL 3 dash code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' deno run code.code < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' elixir code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' emacs -Q --script code.code < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code interim.go
|
||||
go build interim.go
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./interim < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code code.hs
|
||||
ghc -dynamic -o binary code.hs > /dev/null 2>&1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code interim.java
|
||||
timeout -s KILL 10 xargs -a args.args -d '\n' java interim.java < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' jelly fu code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' julia code.code < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code code.kt
|
||||
kotlinc code.kt -include-runtime -d code.jar
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' java -jar code.jar < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' sbcl --script code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' lua code.code < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
nasm -f elf32 -o binary.o code.code
|
||||
ld -m elf_i386 binary.o -o binary
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
nasm -f elf64 -o binary.o code.code
|
||||
ld -m elf_x86_64 binary.o -o binary
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 10 nim --hints:off c code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./code
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' node code.code < stdin.stdin
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
# osabie uses Elixir, which expects UTF-8 native encoding
|
||||
export LC_ALL="en_US.UTF-8"
|
||||
|
||||
# osabie will break if you try using it with xargs
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 osabie code.code < args.args
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
export PYTHONPATH=$PYTHONPATH:/opt/paradoc
|
||||
timeout -s KILL 3 python3.8 -m paradoc code.code < args.args
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' perl code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' php code.code < stdin.stdin
|
|
@ -1,9 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
|
||||
sed 's/^.*$/:- forall((Goal = (\0), call(Goal)), (write(Goal), nl))./' input.input |
|
||||
cat code.code - > code.pl
|
||||
|
||||
timeout -s KILL 3 swipl -g true -t halt code.pl
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' python code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' python3.8 code.code < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ruby code.code < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 10 rustc -o binary code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./binary < stdin.stdin
|
|
@ -1,5 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code interim.scala
|
||||
timeout -s KILL 10 xargs -a args.args -d '\n' scala interim.scala < stdin.stdin
|
|
@ -1,4 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' swift code.code < stdin.stdin
|
|
@ -1,8 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
mv code.code interim.ts
|
||||
tsc interim.ts
|
||||
rm -f interim.ts
|
||||
mv interim.js code.code
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' node code.code < stdin.stdin
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
cd /tmp/$1
|
||||
cp code.code main.zig
|
||||
timeout -s KILL 10 zig build-exe main.zig && \
|
||||
timeout -s KILL 3 xargs -a args.args -d '\n' ./main
|
|
@ -1,9 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
mkdir -p /var/lib/lxc/piston/rootfs/exec
|
||||
rm -f /var/lib/lxc/piston/rootfs/exec/*
|
||||
cp -f executors/* /var/lib/lxc/piston/rootfs/exec
|
||||
chmod 555 /var/lib/lxc/piston/rootfs/exec/*
|
||||
chown -R root:root /var/lib/lxc/piston/rootfs/exec
|
||||
|
||||
lxc-start -n piston -d
|
|
@ -1,72 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
echo -n 'testing awk = '
|
||||
../../cli/execute awk awk.awk
|
||||
echo -n 'testing bash = '
|
||||
../../cli/execute bash bash.sh
|
||||
echo -n 'testing c = '
|
||||
../../cli/execute c c.c
|
||||
echo -n 'testing cpp = '
|
||||
../../cli/execute cpp cpp.cpp
|
||||
echo -n 'testing crystal = '
|
||||
../../cli/execute crystal crystal.cr
|
||||
echo -n 'testing csharp = '
|
||||
../../cli/execute csharp csharp.cs
|
||||
echo -n 'testing d = '
|
||||
../../cli/execute d d.d
|
||||
echo -n 'testing dash = '
|
||||
../../cli/execute dash dash.sh
|
||||
echo -n 'testing deno = '
|
||||
../../cli/execute deno deno.ts
|
||||
echo -n 'testing elixir = '
|
||||
../../cli/execute elixir elixir.exs
|
||||
echo -n 'testing emacs = '
|
||||
../../cli/execute emacs emacs.el
|
||||
echo -n 'testing go = '
|
||||
../../cli/execute go go.go
|
||||
echo -n 'testing haskell = '
|
||||
../../cli/execute haskell haskell.hs
|
||||
echo -n 'testing java = '
|
||||
../../cli/execute java java.java
|
||||
echo -n 'testing jelly = '
|
||||
../../cli/execute jelly jelly.jelly good
|
||||
echo -n 'testing julia = '
|
||||
../../cli/execute julia julia.jl
|
||||
echo -n 'testing kotlin = '
|
||||
../../cli/execute kotlin kotlin.kt
|
||||
echo -n 'testing lisp = '
|
||||
../../cli/execute lisp lisp.cl
|
||||
echo -n 'testing nasm 32 bit = '
|
||||
../../cli/execute nasm nasm.nasm
|
||||
echo -n 'testing nasm 64 bit = '
|
||||
../../cli/execute nasm64 nasm64.nasm
|
||||
echo -n 'testing nim = '
|
||||
../../cli/execute nim nim.nim
|
||||
echo -n 'testing node = '
|
||||
../../cli/execute node node.js
|
||||
echo -n 'testing osabie = '
|
||||
../../cli/execute osabie osabie.abe
|
||||
echo -n 'testing paradoc = '
|
||||
../../cli/execute bash paradoc.sh
|
||||
echo -n 'testing perl = '
|
||||
../../cli/execute perl perl.pl
|
||||
echo -n 'testing php = '
|
||||
../../cli/execute php php.php
|
||||
echo -n 'testing prolog = '
|
||||
../../cli/execute prolog prolog.pl
|
||||
echo -n 'testing python2 = '
|
||||
../../cli/execute python2 python2.py
|
||||
echo -n 'testing python3 = '
|
||||
../../cli/execute python3 python3.py
|
||||
echo -n 'testing ruby = '
|
||||
../../cli/execute ruby ruby.rb
|
||||
echo -n 'testing rust = '
|
||||
../../cli/execute rust rust.rs
|
||||
echo -n 'testing scala = '
|
||||
../../cli/execute scala scala.scala
|
||||
echo -n 'testing swift = '
|
||||
../../cli/execute swift swift.swift
|
||||
echo -n 'testing typescript = '
|
||||
../../cli/execute typescript typescript.ts
|
||||
echo -n 'testing zig = '
|
||||
../../cli/execute zig zig.zig
|
|
@ -1 +0,0 @@
|
|||
BEGIN{ print "good" }
|
|
@ -1 +0,0 @@
|
|||
echo 'good'
|
|
@ -1,5 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
void main(void) {
|
||||
printf("good\n");
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
#include <iostream>
|
||||
|
||||
int main(void) {
|
||||
printf("good\n");
|
||||
return 0;
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
puts "good"
|
|
@ -1,9 +0,0 @@
|
|||
using System;
|
||||
|
||||
namespace HelloWorld {
|
||||
class Hello {
|
||||
static void Main() {
|
||||
Console.WriteLine("good");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
import std.stdio;
|
||||
|
||||
void main() {
|
||||
writeln("good");
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
echo 'good'
|
|
@ -1 +0,0 @@
|
|||
console.log('good')
|
|
@ -1 +0,0 @@
|
|||
IO.puts("good")
|
|
@ -1 +0,0 @@
|
|||
(message "good")
|
|
@ -1,7 +0,0 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("good")
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
main = putStrLn "good"
|
|
@ -1,5 +0,0 @@
|
|||
public class HelloWorld {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("good");
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
³
|
|
@ -1 +0,0 @@
|
|||
println("good")
|
|
@ -1,3 +0,0 @@
|
|||
fun main() {
|
||||
println("good")
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
(write-line "good")
|
|
@ -1,16 +0,0 @@
|
|||
SECTION .DATA
|
||||
good: db 'good',10
|
||||
txtlen: equ $-good
|
||||
|
||||
SECTION .TEXT
|
||||
GLOBAL _start
|
||||
|
||||
_start:
|
||||
mov eax,4
|
||||
mov ebx,1
|
||||
mov ecx,good
|
||||
mov edx,txtlen
|
||||
int 80h
|
||||
mov eax,1
|
||||
mov ebx,0
|
||||
int 80h
|
|
@ -1,18 +0,0 @@
|
|||
SECTION .data
|
||||
good: db "good", 0x0
|
||||
txtlen: equ $ - good
|
||||
|
||||
SECTION .text
|
||||
GLOBAL _start
|
||||
|
||||
_start:
|
||||
;sys_write
|
||||
mov rax, 1
|
||||
mov rdi, 1
|
||||
mov rsi, good
|
||||
mov rdx, txtlen
|
||||
syscall
|
||||
;sys_exit
|
||||
mov rax, 60
|
||||
mov rdi, 0
|
||||
syscall
|
|
@ -1 +0,0 @@
|
|||
echo("good")
|
|
@ -1 +0,0 @@
|
|||
console.log('good')
|
|
@ -1 +0,0 @@
|
|||
"good
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
# add paradoc module to python python
|
||||
export PYTHONPATH=$PYTHONPATH:/opt/paradoc
|
||||
# file for test code
|
||||
test_code=/tmp/paradoc.test
|
||||
# save test code to file
|
||||
echo -n iP>$test_code
|
||||
# pass param to paradoc module and have it print it
|
||||
echo good | python3.8 -m paradoc $test_code
|
||||
# clean test code
|
||||
rm -f $test_code
|
|
@ -1 +0,0 @@
|
|||
print "good\n";
|
|
@ -1,3 +0,0 @@
|
|||
<?php
|
||||
|
||||
echo 'good' . "\n";
|
|
@ -1 +0,0 @@
|
|||
:- write('good'), nl.
|
|
@ -1 +0,0 @@
|
|||
print 'good'
|
|
@ -1 +0,0 @@
|
|||
print('good')
|
|
@ -1 +0,0 @@
|
|||
puts 'good'
|
|
@ -1,3 +0,0 @@
|
|||
fn main() {
|
||||
println!("good");
|
||||
}
|
|
@ -1,3 +0,0 @@
|
|||
@main def run(): Unit = {
|
||||
println("good")
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
print("good")
|
|
@ -1 +0,0 @@
|
|||
console.log('good')
|
|
@ -1,6 +0,0 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() !void {
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
try stdout.print("good\n", .{});
|
||||
}
|
|
@ -1,2 +0,0 @@
|
|||
iptables -I INPUT -i virbr0 -j REJECT
|
||||
iptables -I OUTPUT -o virbr0 -j DROP
|
|
@ -1,2 +0,0 @@
|
|||
iptables -D INPUT -i virbr0 -j REJECT
|
||||
iptables -D OUTPUT -o virbr0 -j DROP
|
|
@ -1,150 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
echo '---'
|
||||
|
||||
echo 'awk'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "awk -W version"
|
||||
echo '---'
|
||||
|
||||
echo 'bash'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "bash --version"
|
||||
echo '---'
|
||||
|
||||
echo 'brainfuck'
|
||||
echo '1.0.0'
|
||||
echo '---'
|
||||
|
||||
echo 'c'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "gcc --version"
|
||||
echo '---'
|
||||
|
||||
echo 'cpp'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "g++ --version"
|
||||
echo '---'
|
||||
|
||||
echo 'crystal'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "crystal -v"
|
||||
echo '---'
|
||||
|
||||
echo 'csharp'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "mcs --version"
|
||||
echo '---'
|
||||
|
||||
echo "elixir"
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "elixir --version"
|
||||
echo '---'
|
||||
|
||||
echo 'd'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "dmd --version"
|
||||
echo '---'
|
||||
|
||||
echo 'dash'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "dpkg -s dash"
|
||||
echo '---'
|
||||
|
||||
echo 'deno'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "deno --version"
|
||||
echo '---'
|
||||
|
||||
echo "emacs"
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "emacs --version"
|
||||
echo '---'
|
||||
|
||||
echo 'go'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "go version"
|
||||
echo '---'
|
||||
|
||||
echo 'haskell'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "ghc --version"
|
||||
echo '---'
|
||||
|
||||
echo 'java'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "java -version"
|
||||
echo '---'
|
||||
|
||||
echo 'jelly'
|
||||
echo '1.0.0'
|
||||
echo '---'
|
||||
|
||||
echo 'julia'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "julia --version"
|
||||
echo '---'
|
||||
|
||||
echo 'kotlin'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "kotlinc -version 2>&1 | grep kotlin"
|
||||
echo '---'
|
||||
|
||||
echo 'lisp'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "sbcl --version"
|
||||
echo '---'
|
||||
|
||||
echo 'lua'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "lua -v"
|
||||
echo '---'
|
||||
|
||||
echo 'nasm'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nasm -version"
|
||||
echo '---'
|
||||
|
||||
echo 'nasm64'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nasm -version"
|
||||
echo '---'
|
||||
|
||||
echo 'nim'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "nim -v"
|
||||
echo '---'
|
||||
|
||||
echo 'node'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "node --version"
|
||||
echo '---'
|
||||
|
||||
echo 'perl'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "perl --version | grep x86"
|
||||
echo '---'
|
||||
|
||||
echo 'php'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "php -v"
|
||||
echo '---'
|
||||
|
||||
echo 'prolog'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "swipl --version"
|
||||
echo '---'
|
||||
|
||||
echo 'python2'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python -V"
|
||||
echo '---'
|
||||
|
||||
echo 'python3'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3.8 -V"
|
||||
echo '---'
|
||||
|
||||
echo 'paradoc'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "python3.8 -m paradoc --version"
|
||||
echo '---'
|
||||
|
||||
echo 'ruby'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "ruby --version"
|
||||
echo '---'
|
||||
|
||||
echo 'rust'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "rustc --version"
|
||||
echo '---'
|
||||
|
||||
echo 'scala'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "scala -version"
|
||||
echo '---'
|
||||
|
||||
echo 'swift'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "swift --version"
|
||||
echo '---'
|
||||
|
||||
echo 'typescript'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "tsc --version"
|
||||
echo '---'
|
||||
|
||||
echo 'zig'
|
||||
lxc-attach --clear-env -n piston -- /bin/bash -l -c "zig version"
|
||||
echo '---'
|
||||
|
||||
echo 'osabie'
|
||||
echo '1.0.1'
|
||||
echo '---'
|
323
readme.md
323
readme.md
|
@ -1,323 +0,0 @@
|
|||
<h1 align="center">
|
||||
<a href="https://github.com/engineer-man/piston"><img src="images/icon_circle.svg" width="25" height="25" alt="engineer-man piston"></a>
|
||||
Piston
|
||||
</h1>
|
||||
|
||||
<h3 align="center">A high performance general purpose code execution engine.</h3>
|
||||
<br>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/engineer-man/piston/commits/master">
|
||||
<img src="https://img.shields.io/github/last-commit/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||
alt="GitHub last commit">
|
||||
<a href="https://github.com/engineer-man/piston/issues">
|
||||
<img src="https://img.shields.io/github/issues/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||
alt="GitHub issues">
|
||||
<a href="https://github.com/engineer-man/piston/pulls">
|
||||
<img src="https://img.shields.io/github/issues-pr-raw/engineer-man/piston.svg?style=for-the-badge&logo=github&logoColor=white"
|
||||
alt="GitHub pull requests">
|
||||
</p>
|
||||
|
||||
---
|
||||
|
||||
<h4 align="center">
|
||||
<a href="#About">About</a> •
|
||||
<a href="#Public-API">Public API</a> •
|
||||
<a href="#Getting-Started">Getting Started</a> •
|
||||
<a href="#Usage">Usage</a> •
|
||||
<a href="#Supported-Languages">Supported Languages</a> •
|
||||
<a href="#Principle-of-Operation">Principles</a> •
|
||||
<a href="#Security">Security</a> •
|
||||
<a href="#License">License</a>
|
||||
</h4>
|
||||
|
||||
---
|
||||
<br>
|
||||
|
||||
# About
|
||||
|
||||
<h4>
|
||||
Piston is a high performance general purpose code execution engine. It excels at running untrusted and
|
||||
possibly malicious code without fear from any harmful effects.
|
||||
</h4>
|
||||
<br>
|
||||
|
||||
It's used in numerous places including:
|
||||
* [EMKC Challenges](https://emkc.org/challenges),
|
||||
* [EMKC Weekly Contests](https://emkc.org/contests),
|
||||
* [Engineer Man Discord Server](https://discord.gg/engineerman),
|
||||
* [I Run Code (Discord Bot)](https://github.com/engineer-man/piston-bot) bot as well as 1300+ other servers
|
||||
and 100+ direct integrations.
|
||||
|
||||
To get it in your own server, go here: https://emkc.org/run.
|
||||
|
||||
<br>
|
||||
|
||||
# Public API
|
||||
|
||||
- Requires no installation and you can use it immediately.
|
||||
- Reference the Versions/Execute sections below to learn about the request and response formats.
|
||||
|
||||
<br>
|
||||
|
||||
When using the public Piston API, use the base URL:
|
||||
|
||||
```
|
||||
https://emkc.org/api/v1/piston
|
||||
```
|
||||
|
||||
#### GET
|
||||
```
|
||||
https://emkc.org/api/v1/piston/versions
|
||||
```
|
||||
#### POST
|
||||
```
|
||||
https://emkc.org/api/v1/piston/execute
|
||||
```
|
||||
|
||||
> Important Note: The Piston API is rate limited to 5 requests per second. If you have a need for more requests than that
|
||||
and it's for a good cause, please reach out to me (EngineerMan#0001) on [Discord](https://discord.gg/engineerman)
|
||||
so we can discuss potentially getting you an unlimited key.
|
||||
|
||||
<br>
|
||||
|
||||
# Getting Started
|
||||
|
||||
### Host System Package Dependencies
|
||||
|
||||
* NodeJS
|
||||
* lxc
|
||||
* libvirt
|
||||
|
||||
<br>
|
||||
|
||||
If your OS is not documented below, please open pull requests with the correct commands for your OS.
|
||||
|
||||
<details>
|
||||
<summary><span style="font-size:1.43em;">CentOS / RHEL</span></summary>
|
||||
|
||||
```sh
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||
nvm install --lts
|
||||
nvm use --lts
|
||||
|
||||
yum install -y epel-release
|
||||
yum install -y lxc lxc-templates debootstrap libvirt
|
||||
systemctl start libvirtd
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><span style="font-size:1.43em;">Ubuntu (18.04)</span></summary>
|
||||
|
||||
```sh
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||
nvm install --lts
|
||||
nvm use --lts
|
||||
|
||||
apt install -y lxc lxc-templates debootstrap libvirt0
|
||||
```
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary><span style="font-size:1.43em;">Arch Linux</span></summary>
|
||||
|
||||
```sh
|
||||
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
|
||||
nvm install --lts
|
||||
nvm use --lts
|
||||
|
||||
pacman -S lxc libvirt unzip
|
||||
```
|
||||
</details>
|
||||
|
||||
#### After system dependencies are installed, clone this repository:
|
||||
|
||||
```sh
|
||||
# clone and enter repo
|
||||
git clone https://github.com/engineer-man/piston
|
||||
```
|
||||
|
||||
#### Installation (simple)
|
||||
|
||||
- Install additional dependencies python3, pip and distrobuilder
|
||||
- `cd container && ./build.sh`
|
||||
- Wait, it may take up to an hour.
|
||||
- `lxc-create -n piston -t local -- --metadata meta.tar.xz --fstree rootfs.tar.xz`
|
||||
- `cd lxc && ./start`
|
||||
- Good to go!
|
||||
|
||||
|
||||
#### Installation (advanced)
|
||||
|
||||
- See `var/install.txt` for how to build the container manually
|
||||
|
||||
#### CLI Usage
|
||||
- `cli/execute [language] [file path] [args]`
|
||||
<br>
|
||||
|
||||
# Usage
|
||||
|
||||
### CLI
|
||||
|
||||
```sh
|
||||
lxc/execute [language] [file path] [args]
|
||||
```
|
||||
|
||||
### API
|
||||
To use the API, it must first be started. Please note that if root is required to access
|
||||
LXC then the API must also be running as root. To start the API, run the following:
|
||||
|
||||
```
|
||||
cd api
|
||||
./start
|
||||
```
|
||||
|
||||
For your own local installation, the API is available at:
|
||||
|
||||
```
|
||||
http://127.0.0.1:2000
|
||||
```
|
||||
|
||||
#### Versions Endpoint
|
||||
`GET /versions`
|
||||
This endpoint will return the supported languages along with the current version and aliases. To execute
|
||||
code for a particular language using the `/execute` endpoint, either the name or one of the aliases must
|
||||
be provided.
|
||||
```json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
[
|
||||
{
|
||||
"name": "awk",
|
||||
"aliases": ["awk"],
|
||||
"version": "1.3.3"
|
||||
},
|
||||
{
|
||||
"name": "bash",
|
||||
"aliases": ["bash"],
|
||||
"version": "4.4.20"
|
||||
},
|
||||
{
|
||||
"name": "c",
|
||||
"aliases": ["c"],
|
||||
"version": "7.5.0"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
#### Execute Endpoint
|
||||
`POST /execute`
|
||||
This endpoint requests execution of some arbitrary code.
|
||||
- `language` (**required**) The language to use for execution, must be a string and supported by Piston (see list below).
|
||||
- `source` (**required**) The source code to execute, must be a string.
|
||||
- `stdin` (*optional*) The text to pass as stdin to the program. Must be a string or left out of the request.
|
||||
- `args` (*optional*) The arguments to pass to the program. Must be an array or left out of the request.
|
||||
```json
|
||||
{
|
||||
"language": "js",
|
||||
"source": "console.log(process.argv)",
|
||||
"stdin": "",
|
||||
"args": [
|
||||
"1",
|
||||
"2",
|
||||
"3"
|
||||
]
|
||||
}
|
||||
```
|
||||
A typical response upon successful execution will contain the `language`, `version`, `output` which
|
||||
is a combination of both `stdout` and `stderr` but in chronological order according to program output,
|
||||
as well as separate `stdout` and `stderr`.
|
||||
```json
|
||||
HTTP/1.1 200 OK
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"ran": true,
|
||||
"language": "js",
|
||||
"version": "12.13.0",
|
||||
"output": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
|
||||
"stdout": "[ '/usr/bin/node',\n '/tmp/code.code',\n '1',\n '2',\n '3' ]",
|
||||
"stderr": ""
|
||||
}
|
||||
```
|
||||
If a problem exists with the request, a `400` status code is returned and the reason in the `message` key.
|
||||
```json
|
||||
HTTP/1.1 400 Bad Request
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"message": "Supplied language is not supported by Piston"
|
||||
}
|
||||
```
|
||||
|
||||
<br>
|
||||
|
||||
# Supported Languages
|
||||
`awk`,
|
||||
`bash`,
|
||||
`brainfuck`,
|
||||
`c`,
|
||||
`cpp`,
|
||||
`crystal`,
|
||||
`csharp`,
|
||||
`d`,
|
||||
`dash`,
|
||||
`deno`,
|
||||
`elixir`,
|
||||
`emacs`,
|
||||
`elisp`,
|
||||
`go`,
|
||||
`haskell`,
|
||||
`java`,
|
||||
`jelly`,
|
||||
`julia`,
|
||||
`kotlin`,
|
||||
`lisp`,
|
||||
`lua`,
|
||||
`nasm`,
|
||||
`nasm64`,
|
||||
`nim`,
|
||||
`node`,
|
||||
`osabie`,
|
||||
`paradoc`,
|
||||
`perl`,
|
||||
`php`,
|
||||
`python2`,
|
||||
`python3`,
|
||||
`ruby`,
|
||||
`rust`,
|
||||
`scala`,
|
||||
`swift`,
|
||||
`typescript`,
|
||||
`zig`,
|
||||
|
||||
<br>
|
||||
|
||||
# Principle of Operation
|
||||
Piston utilizes LXC as the primary mechanism for sandboxing. There is a small API written in Node which takes
|
||||
in execution requests and executes them in the container. High level, the API writes
|
||||
a temporary source and args file to `/tmp` and that gets mounted read-only along with the execution scripts into the container.
|
||||
The source file is either ran or compiled and ran (in the case of languages like c, c++, c#, go, etc.).
|
||||
|
||||
<br>
|
||||
|
||||
# Security
|
||||
LXC provides a great deal of security out of the box in that it's separate from the system.
|
||||
Piston takes additional steps to make it resistant to
|
||||
various privilege escalation, denial-of-service, and resource saturation threats. These steps include:
|
||||
- Disabling outgoing network interaction
|
||||
- Capping max processes at 64 (resists `:(){ :|: &}:;`, `while True: os.fork()`, etc.)
|
||||
- Capping max files at 2048 (resists various file based attacks)
|
||||
- Mounting all resources read-only (resists `sudo rm -rf --no-preserve-root /`)
|
||||
- Cleaning up all temp space after each execution (resists out of drive space attacks)
|
||||
- Running as a variety of unprivileged users
|
||||
- Capping runtime execution at 3 seconds
|
||||
- Capping stdout to 65536 characters (resists yes/no bombs and runaway output)
|
||||
- SIGKILLing misbehaving code
|
||||
|
||||
<br>
|
||||
|
||||
# License
|
||||
Piston is licensed under the MIT license.
|
|
@ -1,12 +0,0 @@
|
|||
ab -c 30 -n 1000 \
|
||||
https://emkc.org/api/v1/piston/versions
|
||||
|
||||
ab -c 30 -n 1000 \
|
||||
-p benchmark_payload.txt \
|
||||
-T 'application/json' \
|
||||
https://emkc.org/api/v1/piston/execute
|
||||
|
||||
|
||||
time for i in {1..100}; do
|
||||
timeout -s KILL 3 lxc-attach --clear-env -n piston -- /bin/bash -l -c "runuser runner1 /bin/bash -c 'ls -l '"
|
||||
done
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"language": "python",
|
||||
"source": "print('test')",
|
||||
"stdin": "",
|
||||
"args": []
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue