-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.min.js
2 lines (2 loc) · 34.2 KB
/
index.min.js
1
2
// COPYRIGHT (c) JOHNODON.COM. ALL RIGHTS RESERVED.
const express=require("express"),app=express(),session=require("express-session"),fetch=require("node-fetch"),fs=require("fs"),bodyParser=require("body-parser"),timeago=require("epoch-timeago").default,sessionSecret="KZTC$@eBn+9ug75VhF!twY#sW'X3/]v%Epxz<(]j&fcL)a?q6Q",mysql=require("mysql"),{serverName:serverName,serverHost:serverHost,port:port}=require("./config.json");let version="1.0.1";fetch("https://www.johnodon.com/advancedban-web/latest.json").then((e=>e.json())).then((e=>e.version!=version?console.log("Your current version of AdvancedBan Web Panel is out of date! Please download a new version at https://www.spigotmc.org/resources/advancedban-web-panel.85875/"):console.log("Your current version of AdvanedBan Web Panel is up to date.")));const completed=require("./config.json").completedDontTouchThis,allowedArgs=["--log","--help","-h"],startupArgs=process.argv.splice(2);(startupArgs.includes("-h")||startupArgs.includes("--help"))&&(console.log("Allowed arguments:\n--help (alias: -h): Lists this help menu\n--log: Logs the IP address of any incoming request"),process.exit(0));let invalidArgs=0;startupArgs.forEach((e=>{allowedArgs.includes(e)||(console.log(`INVALID ARGUMENT: ${e}`),invalidArgs++)})),invalidArgs>0&&console.log("Running with invalid arguments is allowed, but is not recommended. Next time you start the script, please run with allowed arguments.");const{database_USER:database_USER,database_NAME:database_NAME,database_HOST:database_HOST,database_PASS:database_PASS}=require("./db_info.json"),http=require("http").createServer(app),db_config={host:database_HOST,user:database_USER,password:database_PASS,database:database_NAME};let con;function handleDisconnect(){con=mysql.createConnection(db_config),con.connect((function(e){e&&(console.log("error when connecting to db:",e),console.log("reconnecting, this is normal"),setTimeout(handleDisconnect,2e3))})),con.on("error",(function(e){if(console.log("db error",e),"PROTOCOL_CONNECTION_LOST"!==e.code)throw e;handleDisconnect()}))}function millisToSeconds(e){return(e/1e3).toFixed(0)}function secondsToDhms(e){e=Number(e);var t=Math.floor(e/86400),s=Math.floor(e%86400/3600),n=Math.floor(e%3600/60),r=Math.floor(e%60);return[t>0?t+(1==t?" day":" days"):"",s>0?s+(1==s?" hour":" hours"):"",n>0?n+(1==n?" minute":" minutes"):"",r>0?r+(1==r?" second":" seconds"):""]}function do404(e,t,s){t.type("text/html").status(404).sendFile(__dirname+"/errors/404.html")}function do500(e,t,s,n){"error is not defined"!=e.message&&console.log(e.stack),s.type("text/html").status(500).sendFile(__dirname+"/errors/500.html")}""==database_USER||""==database_NAME||""==database_HOST||handleDisconnect();const logger=(e,t,s)=>{if(startupArgs.includes("--log")){const t=e.headers["x-forwarded-for"]||e.connection.remoteAddress;console.log(`REQUEST FROM: ${t}\n-----------------------------------`)}s()};app.use(logger),app.use(express.static("public")),app.use(bodyParser.json({extended:!1})),app.use(bodyParser.urlencoded({extended:!1})),app.use(session({secret:sessionSecret,store:new session.MemoryStore,expires:new Date(Date.now()+604800),resave:!1,saveUninitialized:!1})),app.get("/api/punishments",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");let s=[];con.query("SELECT * FROM `Punishments` ORDER BY start DESC",(async(e,n)=>{n.length<1?s[0]="There are no active punishments.":n.forEach((async e=>{millisToSeconds(e.end),Math.round(Date.now()/1e3);let t={id:e.id,user:e.name,admin:e.operator,type:e.type,reason:e.reason,start:e.start,ends:e.end};s.push(t)}));let r=s;t.status(200).json(r)}))})),app.get("/api/punishments/:id",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");if(isNaN(e.params.id))return do404(e,t);let s=`SELECT * FROM \`Punishments\` WHERE id=${e.params.id}`;con.query(s,(async(s,n)=>{if(s)throw s;let r=[];if(n.length<1)return do404(e,t);n.forEach((async e=>{let t={id:e.id,user:e.name,admin:e.operator,type:e.type,reason:e.reason,start:e.start,ends:e.end};r.push(t)}));let a=r;t.status(200).json(a)}))})),app.get("/api/punishments/history",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");let s=[];con.query("SELECT * FROM `PunishmentHistory` ORDER BY start DESC",(async(e,n)=>{n.length<1?s[0]="There are no active punishments.":n.forEach((async e=>{millisToSeconds(e.end),Math.round(Date.now()/1e3);let t={id:e.id,user:e.name,admin:e.operator,type:e.type,reason:e.reason,start:e.start,ends:e.end};s.push(t)}));let r=s;t.status(200).json(r)}))})),app.get("/api/punishments/history/:id",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");if(isNaN(e.params.id))return do404(e,t);let s=`SELECT * FROM \`PunishmentHistory\` WHERE id=${e.params.id}`;con.query(s,(async(s,n)=>{if(s)throw s;let r=[];if(n.length<1)return do404(e,t);n.forEach((async e=>{let t={id:e.id,user:e.name,admin:e.operator,type:e.type,reason:e.reason,start:e.start,ends:e.end};r.push(t)}));let a=r;t.status(200).json(a)}))})),app.get("/",(async(e,t)=>""!=database_USER&&""!=database_NAME&&""!=database_HOST&&completed?t.redirect("/punishments"):t.redirect("/admin/setup"))),app.get("/admin/setup",(async(e,t)=>""==database_USER||""==database_NAME||""==database_HOST?t.redirect("/admin/setup/database"):t.redirect("/admin/setup/config"))),app.get("/admin/setup/database",(async(e,t)=>{let s="";if(""!=database_USER&&""!=database_NAME&&""!=database_HOST)return t.redirect("/admin/setup/config");e.session.error&&(s=`<div class="bg-red-600 py-4 px-4 rounded">${e.session.error}</div>`,e.session.error=void 0);let n=`\n <!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Setup</title>\n</head>\n<body>\n<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.js" defer><\/script>\n<div class="container max-w-full mx-auto py-24 px-6">\n <div class="max-w-sm mx-auto px-6">\n <div class="relative flex flex-wrap">\n <div class="w-full relative">\n <div class="md:mt-6">\n <div class="text-center font-semibold text-black">\n Database Setup\n </div>\n <form action="" method="POST" class="mt-8">\n ${s}\n <div class="mx-auto max-w-lg ">\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Host<span class="text-sm text-red-700"><b>*</b></span></span>\n <input placeholder="" name="host" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Database<span class="text-sm text-red-700"><b>*</b></span></span>\n <input placeholder="" name="database" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Username<span class="text-sm text-red-700"><b>*</b></span></span>\n <input placeholder="" name="user" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Password<span class="text-sm text-red-700"><b>*</b></span></span>\n <input placeholder="" name="password" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <button class="mt-3 text-lg font-semibold\n bg-gray-800 w-full text-white rounded-lg\n px-6 py-3 block shadow-xl hover:text-white hover:bg-black">\n Connect\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n</div>\n</body>\n</html>`;t.send(n)})),app.post("/admin/setup/database",(async(e,t)=>{if(""!=database_USER&&""!=database_NAME&&""!=database_HOST&&!completed)return t.redirect("/admin/setup/config");let s=e.body,n=mysql.createConnection(s);n.connect((async s=>{if(s)"ETIMEDOUT"==s.code?(e.session.error="MySQL Error: Invalid Host",t.redirect("/admin/setup/database")):(e.session.error=`MySQL Error: ${s.sqlMessage}`,t.redirect("/admin/setup/database")),n.end();else{let s=`{\n "database_HOST": "${e.body.host}",\n "database_USER": "${e.body.user}",\n "database_PASS": "${e.body.password}",\n "database_NAME": "${e.body.database}"\n }`;fs.writeFileSync("db_info.json",s,{encoding:"utf-8"}),t.redirect("/admin/setup/config"),n.end()}}))})),app.get("/admin/setup/config",(async(e,t)=>{if(completed)return t.redirect("/punishments");let s="";if(""!=serverName)return t.redirect("/");e.session.error&&(s=`<div class="bg-red-600 py-4 px-4 rounded">${e.session.error}</div>`,e.session.error=void 0);let n=`\n <!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Setup</title>\n \n</head>\n<body>\n<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.js" defer><\/script>\n<div class="container max-w-full mx-auto py-24 px-6">\n <div class="max-w-sm mx-auto px-6">\n <div class="relative flex flex-wrap">\n <div class="w-full relative">\n <div class="md:mt-6">\n <div class="text-center font-semibold text-black">\n Configuration Setup\n </div>\n <form action="" method="POST" class="mt-8">\n ${s}\n <div class="mx-auto max-w-lg ">\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Server Name</span>\n <input placeholder="" name="serverName" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Hostname</span>\n <input placeholder="" name="hostName" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <div class="py-1">\n <span class="px-1 text-sm text-gray-600">Port (to host the webserver on, default 3000)<span class="text-sm text-red-700"><b>*</b></span></span>\n <input placeholder="" value="3000" onkeypress="return isNumberKey(event)" id="port" name="port" type="text"\n class="text-md block px-3 py-2 rounded-lg w-full\n bg-white border-2 border-gray-300 placeholder-gray-600 shadow-md focus:placeholder-gray-500 focus:bg-white focus:border-gray-600 focus:outline-none">\n </div>\n <button class="mt-3 text-lg font-semibold\n bg-gray-800 w-full text-white rounded-lg\n px-6 py-3 block shadow-xl hover:text-white hover:bg-black">\n Continue\n </button>\n </div>\n </form>\n </div>\n </div>\n </div>\n </div>\n</div>\n<script>function isNumberKey(evt){\n var charCode = (evt.which) ? evt.which : evt.keyCode\n console.log(evt)\n if (charCode > 31 && (charCode < 48 || charCode > 57))\n return false;\n \n if(Number(evt.value) < 65535) return false;\n return true;\n}\n<\/script>\n</body>\n</html>`;t.send(n)})),app.post("/admin/setup/config",(async(e,t)=>{if(completed)return t.redirect("/punishments");let s=`{\n "serverName": "${e.body.serverName}",\n "serverHost": "${e.body.hostName}",\n "port": ${e.body.port},\n "completedDontTouchThis": true\n }`;fs.writeFileSync("config.json",s,{encoding:"utf-8"}),t.redirect("/admin/setup/done")})),app.get("/admin/setup/done",(async(e,t)=>{if(completed)return t.redirect("/");await t.send('\n <!DOCTYPE html>\n<html lang="en">\n<head>\n <meta charset="UTF-8">\n <meta name="viewport" content="width=device-width, initial-scale=1.0">\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Setup</title>\n \n</head>\n<body>\n<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.js" defer><\/script>\n<div class="container max-w-full pt-24 px-6">\n <div class="max-w-sm mx-auto px-1/2">\n <div class="relative flex flex-wrap">\n <div class="w-full relative">\n <div class="md:mt-6">\n <p class="text-xl">Setup is complete. Please restart the script for changes to take effect.</p>\n </div>\n </div>\n </div>\n </div>\n</div>\n<script>function isNumberKey(evt){\n var charCode = (evt.which) ? evt.which : evt.keyCode\n console.log(evt)\n if (charCode > 31 && (charCode < 48 || charCode > 57))\n return false;\n \n if(Number(evt.value) < 65535) return false;\n return true;\n}\n<\/script>\n</body>\n</html>'),process.exit(0)})),app.get("/punishments",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");let s=[];con.query("SELECT * FROM `Punishments` ORDER BY start DESC",(async(e,n)=>{n.length<1?s[0]="There are no active punishments.":n.forEach((async e=>{let t="",n=millisToSeconds(e.end)-Math.round(Date.now()/1e3);if("-1"==e.end)t="KICK"==e.punishmentType?'<td class="border px-4 py-2"><span class="text-green-700"><b>Ended</b></span></td>':'<td class="border px-4 py-2 text-red-700"><b>Permanent</b></td>';else{let e,s=secondsToDhms(n);e=""!==s[0]&&""!==s[1]?`${s[0]}, ${s[1]}`:""!==s[0]?s[0]:""!==s[1]?s[1]:""!==s[2]?s[2]:""!==s[3]?s[3]:'<span class="text-green-700"><b>Ended</b></span>',t=`<td class="border px-4 py-2">${e}</td>`}let r="";r="IP_BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-800"><b>IP Ban</b></td>':"BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Ban</b></td>':"TEMP_BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-600"><b>Temp-Ban</b></td>':"WARNING"==e.punishmentType?'<td class="border px-4 py-2 text-orange-700"><b>Warning</b></td>':"TEMP_WARNING"==e.punishmentType?'<td class="border px-4 py-2 text-orange-600"><b>Temp-Warning</b></td>':"KICK"==e.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Kick</b></td>':"TEMP_MUTE"==e.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Temp-Mute</b></td>':"MUTE"==e.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Mute</b></td>':`<td class="border px-4 py-2 text-yellow-600"><b>${e.punishmentType}</b></td>`,s.push(`\n <tr>\n <td class="border px-4 py-2"><a href="/punishments/${e.id}">${e.name}</a></td>\n <td class="border px-4 py-2">${e.operator}</td>\n ${r}\n <td class="border px-4 py-2">${e.reason}</td>\n <td class="border px-4 py-2">${timeago(e.start)}</td>\n ${t}\n </tr>`)})),s=s.join("");let r="",a="";""!=serverName&&(r=` - ${serverName}`),""!=serverHost&&""!=serverName?a=` - ${serverHost}`:""!=serverHost&&""==servername&&(a=serverHost);let d=`\n <!DOCTYPE html>\n <html>\n <head>\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Punishments${r}</title>\n </head>\n <body class="overflow-x-hidden">\n <div class="flex">\n <div class="overflow-hidden shadow-md border-t-4 bg-white mb-4 rounded-b-lg rounded-t border-red-light w-full md:w-1/4">\n <div class="px-6 py-4 mb-2 mt-4 mb-8">\n <div class="uppercase tracking-wide text-c2 mb-4">${serverName}${a}</div>\n <div onclick="window.location.href='/punishments'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest border-b-0" style="border-left: 4px solid #e2624b !important;">\n <img width="18" height="18" src="/svg/sledgehammer.svg" />\n <div class="pl-2">Punishments</div>\n </div>\n <div onclick="window.location.href='/punishments/history'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest">\n <svg width="18" height="18" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg">\n <path d="M640 896v512h-256v-512h256zm384-512v1024h-256v-1024h256zm1024 1152v128h-2048v-1536h128v1408h1920zm-640-896v768h-256v-768h256zm384-384v1152h-256v-1152h256z"\n />\n </svg>\n <div class="pl-2">History</div>\n</div>\n <input type="search" id="search" onkeyup="search()" class="flex text-lg w-full bg-purple-white shadow rounded border-0 px-6 py-4 mb-2 mt-4 mb-8" placeholder="Search">\n \n </div>\n </div>\n <table id="results" class="table-fixed w-full align-end">\n <thead>\n <tr>\n <th class="w-1/2 px-4 py-2">Player</th>\n <th class="w-1/4 px-4 py-2">Operator</th>\n <th class="w-1/4 px-4 py-2">Type</th>\n <th class="w-1/4 px-4 py-2">Reason</th>\n <th class="w-1/4 px-4 py-2">Created</th>\n <th class="w-1/4 px-4 py-2">Ends</th>\n </tr>\n </thead>\n <tbody>\n ${s}\n </tbody>\n </table>\n <script>\nfunction search() {\n var input, filter, table, tr, td, i, txtValue;\n input = document.getElementById("search");\n filter = input.value.toUpperCase();\n table = document.getElementById("results");\n tr = table.getElementsByTagName("tr");\n for (i = 0; i < tr.length; i++) {\n td = tr[i].getElementsByTagName("td")[0];\n if (td) {\n txtValue = td.textContent || td.innerText;\n if (txtValue.toUpperCase().indexOf(filter) > -1) {\n tr[i].style.display = "";\n } else {\n tr[i].style.display = "none";\n }\n } \n }\n}\n<\/script>\n </body>\n </div>\n </html>\n `;t.send(d)}))})),app.get("/punishments/history",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");let s=[];con.query("SELECT * FROM `PunishmentHistory` ORDER BY start DESC",(async(e,n)=>{n.length<1?s[0]="There are no active punishments.":n.forEach((async e=>{let t="",n=millisToSeconds(e.end)-Math.round(Date.now()/1e3);if("-1"==e.end)t="KICK"==e.punishmentType?'<td class="border px-4 py-2"><span class="text-green-700"><b>Ended</b></span></td>':'<td class="border px-4 py-2 text-red-700"><b>Permanent</b></td>';else{let e,s=secondsToDhms(n);e=""!==s[0]&&""!==s[1]?`${s[0]}, ${s[1]}`:""!==s[0]?s[0]:""!==s[1]?s[1]:""!==s[2]?s[2]:""!==s[3]?s[3]:'<span class="text-green-700"><b>Ended</b></span>',t=`<td class="border px-4 py-2">${e}</td>`}let r="";r="IP_BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-800"><b>IP Ban</b></td>':"BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Ban</b></td>':"TEMP_BAN"==e.punishmentType?'<td class="border px-4 py-2 text-red-600"><b>Temp-Ban</b></td>':"WARNING"==e.punishmentType?'<td class="border px-4 py-2 text-orange-700"><b>Warning</b></td>':"TEMP_WARNING"==e.punishmentType?'<td class="border px-4 py-2 text-orange-600"><b>Temp-Warning</b></td>':"KICK"==e.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Kick</b></td>':"TEMP_MUTE"==e.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Temp-Mute</b></td>':"MUTE"==e.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Mute</b></td>':`<td class="border px-4 py-2 text-yellow-600"><b>${e.punishmentType}</b></td>`,s.push(`\n <tr>\n <td class="border px-4 py-2"><a href="/punishments/history/${e.id}">${e.name}</a></td>\n <td class="border px-4 py-2">${e.operator}</td>\n ${r}\n <td class="border px-4 py-2">${e.reason}</td>\n <td class="border px-4 py-2">${timeago(e.start)}</td>\n ${t}\n </tr>`)})),s=s.join("");let r="",a="";""!=serverName&&(r=` - ${serverName}`),""!=serverHost&&""!=serverName?a=` - ${serverHost}`:""!=serverHost&&""==servername&&(a=serverHost);let d=`\n <!DOCTYPE html>\n <html>\n <head>\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Punishments${r}</title>\n </head>\n <body class="overflow-x-hidden">\n <div class="flex">\n <div class="overflow-hidden shadow-md border-t-4 bg-white mb-4 rounded-b-lg rounded-t border-red-light w-full md:w-1/4">\n <div class="px-6 py-4 mb-2 mt-4 mb-8">\n <div class="uppercase tracking-wide text-c2 mb-4">${serverName}${a}</div>\n <div onclick="window.location.href='/punishments'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest border-b-0">\n <img width="18" height="18" src="/svg/sledgehammer.svg" />\n <div class="pl-2">Punishments</div>\n </div>\n <div onclick="window.location.href='/punishments/history'" style="border-left: 4px solid #e2624b !important;" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest">\n <svg width="18" height="18" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg">\n <path d="M640 896v512h-256v-512h256zm384-512v1024h-256v-1024h256zm1024 1152v128h-2048v-1536h128v1408h1920zm-640-896v768h-256v-768h256zm384-384v1152h-256v-1152h256z"\n />\n </svg>\n <div class="pl-2">History</div>\n </div>\n <input type="search" id="search" onkeyup="search()" class="flex text-lg w-full bg-purple-white shadow rounded border-0 px-6 py-4 mb-2 mt-4 mb-8" placeholder="Search">\n \n </div>\n </div>\n <table id="results" class="table-fixed w-full align-end">\n <thead>\n <tr>\n <th class="w-1/2 px-4 py-2">Player</th>\n <th class="w-1/4 px-4 py-2">Operator</th>\n <th class="w-1/4 px-4 py-2">Type</th>\n <th class="w-1/4 px-4 py-2">Reason</th>\n <th class="w-1/4 px-4 py-2">Created</th>\n <th class="w-1/4 px-4 py-2">Ends</th>\n </tr>\n </thead>\n <tbody>\n ${s}\n </tbody>\n </table>\n </div>\n \n<script>\nfunction search() {\n var input, filter, table, tr, td, i, txtValue;\n input = document.getElementById("search");\n filter = input.value.toUpperCase();\n table = document.getElementById("results");\n tr = table.getElementsByTagName("tr");\n for (i = 0; i < tr.length; i++) {\n td = tr[i].getElementsByTagName("td")[0];\n if (td) {\n txtValue = td.textContent || td.innerText;\n if (txtValue.toUpperCase().indexOf(filter) > -1) {\n tr[i].style.display = "";\n } else {\n tr[i].style.display = "none";\n }\n } \n }\n}\n<\/script>\n </body>\n </div>\n </html>\n `;t.send(d)}))})),app.get("/punishments/:id",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");if(isNaN(e.params.id))return do404(e,t);let s=`SELECT * FROM \`Punishments\` WHERE id=${e.params.id}`;con.query(s,(async(s,n)=>{if(s)throw s;if(n.length<1)return do404(e,t);{let e=[];n.forEach((async t=>{let s="",n=millisToSeconds(t.end)-Math.round(Date.now()/1e3);if("-1"==t.end)s="KICK"==t.punishmentType?'<td class="border px-4 py-2"><span class="text-green-700"><b>Ended</b></span></td>':'<td class="border px-4 py-2 text-red-700"><b>Permanent</b></td>';else{let e,t=secondsToDhms(n);e=""!==t[0]&&""!==t[1]?`${t[0]}, ${t[1]}`:""!==t[0]?t[0]:""!==t[1]?t[1]:""!==t[2]?t[2]:""!==t[3]?t[3]:'<span class="text-green-700"><b>Ended</b></span>',s=`<td class="border px-4 py-2">${e}</td>`}let r="";r="IP_BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-800"><b>IP Ban</b></td>':"BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Ban</b></td>':"TEMP_BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-600"><b>Temp-Ban</b></td>':"WARNING"==t.punishmentType?'<td class="border px-4 py-2 text-orange-700"><b>Warning</b></td>':"TEMP_WARNING"==t.punishmentType?'<td class="border px-4 py-2 text-orange-600"><b>Temp-Warning</b></td>':"KICK"==t.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Kick</b></td>':`<td class="border px-4 py-2 text-yellow-600"><b>${t.punishmentType}</b></td>`,e.push(`\n <tr>\n <td class="border px-4 py-2"><a href="/punishments/${t.id}">${t.name}</a></td>\n <td class="border px-4 py-2">${t.operator}</td>\n ${r}\n <td class="border px-4 py-2">${t.reason}</td>\n <td class="border px-4 py-2">${timeago(t.start)}</td>\n ${s}\n </tr>`)})),e.join("");let s="",r="";""!=serverName&&(s=` - ${serverName}`),""!=serverHost&&""!=serverName?r=` - ${serverHost}`:""!=serverHost&&""==servername&&(r=serverHost);let a=`\n <!DOCTYPE html>\n <html>\n <head>\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Punishment${s}</title>\n </head>\n <body class="overflow-x-hidden">\n <div class="flex">\n <div class="overflow-hidden shadow-md border-t-4 bg-white mb-4 rounded-b-lg rounded-t border-red-light w-full md:w-1/4">\n <div class="px-6 py-4 mb-2 mt-4 mb-8">\n <div class="uppercase tracking-wide text-c2 mb-4">${serverName}${r}</div>\n <div onclick="window.location.href='/punishments'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest border-b-0">\n <img width="18" height="18" src="/svg/sledgehammer.svg" />\n <div class="pl-2">Punishments</div>\n </div>\n <div onclick="window.location.href='/punishments/history'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest">\n <svg width="18" height="18" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg">\n <path d="M640 896v512h-256v-512h256zm384-512v1024h-256v-1024h256zm1024 1152v128h-2048v-1536h128v1408h1920zm-640-896v768h-256v-768h256zm384-384v1152h-256v-1152h256z"\n />\n </svg>\n <div class="pl-2">History</div>\n </div>\n </div>\n </div>\n \n <table id="results" class="table-fixed w-full align-end">\n <thead>\n <tr>\n <th class="w-1/2 px-4 py-2">Player</th>\n <th class="w-1/4 px-4 py-2">Operator</th>\n <th class="w-1/4 px-4 py-2">Type</th>\n <th class="w-1/4 px-4 py-2">Reason</th>\n <th class="w-1/4 px-4 py-2">Created</th>\n <th class="w-1/4 px-4 py-2">Ends</th>\n </tr>\n </thead>\n <tbody>\n ${e}\n </tbody>\n </table>\n </div>\n </body>\n </div>\n </html>`;t.send(a)}}))})),app.get("/punishments/history/:id",(async(e,t)=>{if(""==database_USER||""==database_NAME||""==database_HOST||!completed)return t.redirect("/admin/setup");if(isNaN(e.params.id))return do404(e,t);let s=`SELECT * FROM \`PunishmentHistory\` WHERE id=${e.params.id}`;con.query(s,(async(s,n)=>{if(s)throw s;if(n.length<1)return do404(e,t);{let e=[];n.forEach((async t=>{let s="",n=millisToSeconds(t.end)-Math.round(Date.now()/1e3);if("-1"==t.end)s="KICK"==t.punishmentType?'<td class="border px-4 py-2"><span class="text-green-700"><b>Ended</b></span></td>':'<td class="border px-4 py-2 text-red-700"><b>Permanent</b></td>';else{let e,t=secondsToDhms(n);e=""!==t[0]&&""!==t[1]?`${t[0]}, ${t[1]}`:""!==t[0]?t[0]:""!==t[1]?t[1]:""!==t[2]?t[2]:""!==t[3]?t[3]:'<span class="text-green-700"><b>Ended</b></span>',s=`<td class="border px-4 py-2">${e}</td>`}let r="";r="IP_BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-800"><b>IP Ban</b></td>':"BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-700"><b>Ban</b></td>':"TEMP_BAN"==t.punishmentType?'<td class="border px-4 py-2 text-red-600"><b>Temp-Ban</b></td>':"WARNING"==t.punishmentType?'<td class="border px-4 py-2 text-orange-700"><b>Warning</b></td>':"TEMP_WARNING"==t.punishmentType?'<td class="border px-4 py-2 text-orange-600"><b>Temp-Warning</b></td>':"KICK"==t.punishmentType?'<td class="border px-4 py-2 text-yellow-600"><b>Kick</b></td>':`<td class="border px-4 py-2 text-yellow-600"><b>${t.punishmentType}</b></td>`,e.push(`\n <tr>\n <td class="border px-4 py-2"><a href="/punishments/history/${t.id}">${t.name}</a></td>\n <td class="border px-4 py-2">${t.operator}</td>\n ${r}\n <td class="border px-4 py-2">${t.reason}</td>\n <td class="border px-4 py-2">${timeago(t.start)}</td>\n ${s}\n </tr>`)})),e.join("");let s="",r="";""!=serverName&&(s=` - ${serverName}`),""!=serverHost&&""!=serverName?r=` - ${serverHost}`:""!=serverHost&&""==servername&&(r=serverHost);let a=`\n <!DOCTYPE html>\n <html>\n <head>\n <link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">\n <title>Punishment${s}</title>\n </head>\n <body class="overflow-x-hidden">\n <div class="flex">\n <div class="overflow-hidden shadow-md border-t-4 bg-white mb-4 rounded-b-lg rounded-t border-red-light w-full md:w-1/4">\n <div class="px-6 py-4 mb-2 mt-4 mb-8">\n <div class="uppercase tracking-wide text-c2 mb-4">${serverName}${r}</div>\n <div onclick="window.location.href='/punishments'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest border-b-0">\n <img width="18" height="18" src="/svg/sledgehammer.svg" />\n <div class="pl-2">Punishments</div>\n </div>\n <div onclick="window.location.href='/punishments/history'" class="flex cursor-pointer border px-4 py-2 text-lg text-grey-darkest">\n <svg width="18" height="18" viewBox="0 0 2048 1792" xmlns="http://www.w3.org/2000/svg">\n <path d="M640 896v512h-256v-512h256zm384-512v1024h-256v-1024h256zm1024 1152v128h-2048v-1536h128v1408h1920zm-640-896v768h-256v-768h256zm384-384v1152h-256v-1152h256z"\n />\n </svg>\n <div class="pl-2">History</div>\n </div>\n </div>\n </div>\n \n <table id="results" class="table-fixed w-full align-end">\n <thead>\n <tr>\n <th class="w-1/2 px-4 py-2">Player</th>\n <th class="w-1/4 px-4 py-2">Operator</th>\n <th class="w-1/4 px-4 py-2">Type</th>\n <th class="w-1/4 px-4 py-2">Reason</th>\n <th class="w-1/4 px-4 py-2">Created</th>\n <th class="w-1/4 px-4 py-2">Ends</th>\n </tr>\n </thead>\n <tbody>\n ${e}\n </tbody>\n </table>\n </div>\n </body>\n </div>\n </html>`;t.send(a)}}))})),app.get("/error/500",((e,t)=>t.send(error()))),app.use((async(e,t,s,n)=>do500(e,t,s,n))),app.use((async(e,t,s)=>do404(e,t,s))),http.listen(port);