mirror of
https://github.com/SpacehuhnTech/esp8266_deauther.git
synced 2025-12-22 22:49:58 +01:00
Add files via upload
added the HTML files from the webinterface. To convert it into bytecode use minifier.html.
This commit is contained in:
101
htmlfiles/attack.html
Normal file
101
htmlfiles/attack.html
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<style>
|
||||||
|
nav a:nth-child(3){
|
||||||
|
background: #000;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="functions.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="index.html">APs</a>
|
||||||
|
<a href="clients.html">Clients</a>
|
||||||
|
<a href="attack.html">Attack</a>
|
||||||
|
</nav>
|
||||||
|
<div id="content">
|
||||||
|
<h1>Attack</h1>
|
||||||
|
|
||||||
|
<p class="block bold">Selected AP:</p>
|
||||||
|
<ul id="selectedAPs">
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<p class="block bold">Selected Clients:</p>
|
||||||
|
<ul id="selectedClients">
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p class="small">
|
||||||
|
<br>
|
||||||
|
<b>deauth selected:</b><br>
|
||||||
|
sends deauthentication frames and dissociation frames to the selected client(s) in the selected WiFi network.
|
||||||
|
<br><br>
|
||||||
|
<b>deauth all:</b><br>
|
||||||
|
sends deauthentication frames and dissociation frames as broadcast to all clients in the selected WiFi network.
|
||||||
|
<br><br>
|
||||||
|
<b>beacon spam:</b><br>
|
||||||
|
sends beacon frames with the same SSID as the selected WiFi access point.
|
||||||
|
<br><br>
|
||||||
|
<b>random beacon spam:</b><br>
|
||||||
|
sends beacon frames with a random SSID .
|
||||||
|
<br>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var selectedAPs = document.getElementById("selectedAPs");
|
||||||
|
var selectedClients = document.getElementById("selectedClients");
|
||||||
|
var table = document.getElementsByTagName("table")[0];
|
||||||
|
|
||||||
|
function getResults(){
|
||||||
|
getResponse("attackInfo.json",function(responseText){
|
||||||
|
var res = JSON.parse(responseText);
|
||||||
|
var aps = "";
|
||||||
|
var clients = "";
|
||||||
|
var tr = "<tr><th>Attack</th><th>Status</th><th>Start/Stop</th></tr>";
|
||||||
|
for(var i=0;i<res.aps.length;i++) aps += "<li>"+res.aps[i]+"</li>";
|
||||||
|
for(var i=0;i<res.clients.length;i++) clients += "<li>"+res.clients[i]+"</li>";
|
||||||
|
|
||||||
|
selectedAPs.innerHTML = aps;
|
||||||
|
selectedClients.innerHTML = clients;
|
||||||
|
|
||||||
|
for(var i=0;i<res.attacks.length;i++){
|
||||||
|
if(res.attacks[i].running) tr += "<tr class='selected'>";
|
||||||
|
else tr += "<tr>";
|
||||||
|
|
||||||
|
tr += "<td>"+res.attacks[i].name+"</td>";
|
||||||
|
if(res.attacks[i].status == "ready") tr += "<td style='color:#1ecb1e'>"+res.attacks[i].status+"</td>";
|
||||||
|
else tr += "<td style='color:#f00'>"+res.attacks[i].status+"</td>";
|
||||||
|
if(res.attacks[i].running) tr += "<td><button class='marginNull selectedBtn' onclick='startStop("+i+")'>stop</button></td>";
|
||||||
|
else tr += "<td><button class='marginNull' onclick='startStop("+i+")'>start</button></td>";
|
||||||
|
|
||||||
|
tr += "</tr>";
|
||||||
|
}
|
||||||
|
table.innerHTML = tr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function startStop(num){
|
||||||
|
getResponse("attackStart.json?num="+num,function(responseText){
|
||||||
|
if(responseText == "true") {
|
||||||
|
getResults();
|
||||||
|
setTimeout(getResults,3000);
|
||||||
|
}
|
||||||
|
else alert("error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getResults();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
140
htmlfiles/clients.html
Normal file
140
htmlfiles/clients.html
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<style>
|
||||||
|
#clientScanStatus{
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
nav a:nth-child(2){
|
||||||
|
background: #000;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
#clientScanStart{
|
||||||
|
margin-left: 30px;
|
||||||
|
}
|
||||||
|
#clientScanTime{
|
||||||
|
width: 60px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="functions.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="index.html">APs</a>
|
||||||
|
<a href="clients.html">Clients</a>
|
||||||
|
<a href="attack.html">Attack</a>
|
||||||
|
</nav>
|
||||||
|
<div id="content">
|
||||||
|
<h1>Scan for client devices</h1>
|
||||||
|
|
||||||
|
<label for="clientScanTime">Scan time:</label>
|
||||||
|
<input type="number" id="scanTime" value="10">s
|
||||||
|
|
||||||
|
<button onclick="scan()" id="startScan">start</button>
|
||||||
|
<a id="clientScanStatus">ready!</a>
|
||||||
|
<br />
|
||||||
|
<p class="warn" id="status">AP will be off while scanning!<p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<p class="block bold" id="clientsFound">Client devices found: 0</p>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var table = document.getElementsByTagName('table')[0];
|
||||||
|
var scanBtn = document.getElementById("startScan");
|
||||||
|
var scanTime = document.getElementById("scanTime");
|
||||||
|
var clientsFound = document.getElementById("clientsFound");
|
||||||
|
var scanStatus = document.getElementById("clientScanStatus");
|
||||||
|
|
||||||
|
var res;
|
||||||
|
|
||||||
|
function compare(a,b) {
|
||||||
|
if (a.packets > b.packets) return -1;
|
||||||
|
if (a.packets < b.packets) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function toggleBtn(onoff){
|
||||||
|
if(onoff){
|
||||||
|
scanBtn.style.visibility = 'visible';
|
||||||
|
}else{
|
||||||
|
scanBtn.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResults(reload = false){
|
||||||
|
getResponse("ClientScanResults.json",function(responseText){
|
||||||
|
res = JSON.parse(responseText);
|
||||||
|
res.clients = res.clients.sort(compare);
|
||||||
|
|
||||||
|
clientsFound.innerHTML = "Client devices found: "+res.clients.length;
|
||||||
|
|
||||||
|
var tr = '';
|
||||||
|
if(res.clients.length > 0) tr += '<tr><th>Pkts</th><th>Vendor</th><th>Name</th><th>MAC</th><th>Select</th></tr>';
|
||||||
|
|
||||||
|
for(var i=0;i<res.clients.length;i++){
|
||||||
|
|
||||||
|
if(res.clients[i].selected) tr += '<tr class="selected">';
|
||||||
|
else tr += '<tr>';
|
||||||
|
tr += '<td>'+res.clients[i].packets+'</td>';
|
||||||
|
tr += '<td>'+res.clients[i].vendor+'</td>';
|
||||||
|
tr += '<td>'+res.clients[i].name+' <a class="blue" onclick="changeName('+res.clients[i].id+')">edit</a></td>';
|
||||||
|
tr += '<td>'+res.clients[i].mac+'</td>';
|
||||||
|
|
||||||
|
if(res.clients[i].selected) tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.clients[i].id+')">deselect</button></td>';
|
||||||
|
else tr += '<td><button class="marginNull" onclick="select('+res.clients[i].id+')">select</button></td>';
|
||||||
|
|
||||||
|
tr += '</tr>';
|
||||||
|
}
|
||||||
|
table.innerHTML = tr;
|
||||||
|
toggleBtn(true);
|
||||||
|
scanStatus.innerHTML = "";
|
||||||
|
|
||||||
|
if(reload == true) location.reload();
|
||||||
|
|
||||||
|
},function(){
|
||||||
|
location.reload();
|
||||||
|
},6000);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function scan(){
|
||||||
|
getResponse("ClientScan.json?time="+scanTime.value,function(responseText){
|
||||||
|
if(responseText == "true"){
|
||||||
|
scanStatus.innerHTML = "scanning...";
|
||||||
|
toggleBtn(false);
|
||||||
|
setTimeout(function(){
|
||||||
|
scanStatus.innerHTML = "reconnecting...";
|
||||||
|
getResults(true);
|
||||||
|
},scanTime.value*1000);
|
||||||
|
}
|
||||||
|
else alert("error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(num){
|
||||||
|
getResponse("clientSelect.json?num="+num,function(responseText){
|
||||||
|
if(responseText == "true") getResults();
|
||||||
|
else alert("error :/");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function changeName(id){
|
||||||
|
var newName = prompt("Name for "+res.clients[id].mac);
|
||||||
|
|
||||||
|
getResponse("setName.json?id="+id+"&name="+newName,function(responseText){
|
||||||
|
if(responseText == "true") getResults();
|
||||||
|
else alert("error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getResults();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
13
htmlfiles/functions.js
Normal file
13
htmlfiles/functions.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
function getResponse(adr, callback, timeoutCallback = function(){alert("timeout error. Please reload the site");}, timeout = 3000){
|
||||||
|
var xmlhttp = new XMLHttpRequest();
|
||||||
|
xmlhttp.onreadystatechange = function() {
|
||||||
|
if(xmlhttp.readyState == 4){
|
||||||
|
if(xmlhttp.status == 200) callback(xmlhttp.responseText);
|
||||||
|
else timeoutCallback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
xmlhttp.open("GET", adr, true);
|
||||||
|
xmlhttp.send();
|
||||||
|
xmlhttp.timeout = timeout;
|
||||||
|
xmlhttp.ontimeout = timeoutCallback;
|
||||||
|
}
|
||||||
129
htmlfiles/index.html
Normal file
129
htmlfiles/index.html
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
<style>
|
||||||
|
#apScanStatus{
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
nav a:first-child{
|
||||||
|
background: #000;
|
||||||
|
color:#fff;
|
||||||
|
}
|
||||||
|
#rssiBar{
|
||||||
|
width: 100px;
|
||||||
|
height: 15px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
#rssiBar > div{
|
||||||
|
width: 52px;
|
||||||
|
height: 15px;
|
||||||
|
background: #c20000;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script src="functions.js"></script>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=0.8">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<nav>
|
||||||
|
<a href="index.html">APs</a>
|
||||||
|
<a href="clients.html">Clients</a>
|
||||||
|
<a href="attack.html">Attack</a>
|
||||||
|
</nav>
|
||||||
|
<div id="content">
|
||||||
|
<h1>Scan for WiFi access points</h1>
|
||||||
|
|
||||||
|
<button onclick="scan()" id="apScanStart">scan</button>
|
||||||
|
<a id="scanInfo">scanning...</a>
|
||||||
|
|
||||||
|
<p class="block bold" id="networksFound">Networks found: 0</p>
|
||||||
|
<p class="small">
|
||||||
|
MAC: <span id="apMAC"></span><br />
|
||||||
|
Vendor: <span id="apVendor"></span>
|
||||||
|
</p>
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<table>
|
||||||
|
</table>
|
||||||
|
<p class="small">
|
||||||
|
<br />
|
||||||
|
WPA* = WPA/WPA2 auto mode
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
var table = document.getElementsByTagName('table')[0];
|
||||||
|
var networkInfo = document.getElementById('networksFound');
|
||||||
|
var scanBtn = document.getElementById('apScanStart');
|
||||||
|
var scanInfo = document.getElementById('scanInfo');
|
||||||
|
var apMAC = document.getElementById('apMAC');
|
||||||
|
var apVendor = document.getElementById('apVendor');
|
||||||
|
|
||||||
|
function toggleBtn(onoff){
|
||||||
|
if(onoff){
|
||||||
|
scanInfo.style.visibility = 'hidden';
|
||||||
|
scanBtn.style.visibility = 'visible';
|
||||||
|
}else{
|
||||||
|
scanInfo.style.visibility = 'visible';
|
||||||
|
scanBtn.style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function compare(a,b) {
|
||||||
|
if (a.rssi > b.rssi) return -1;
|
||||||
|
if (a.rssi < b.rssi) return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getResults(){
|
||||||
|
toggleBtn(true);
|
||||||
|
getResponse("APScanResults.json",function(responseText){
|
||||||
|
var res = JSON.parse(responseText);
|
||||||
|
res.aps = res.aps.sort(compare);
|
||||||
|
networkInfo.innerHTML = "Networks found: "+res.aps.length;
|
||||||
|
apMAC.innerHTML = "";
|
||||||
|
apVendor.innerHTML = "";
|
||||||
|
|
||||||
|
var tr = '';
|
||||||
|
if(res.aps.length > 0) tr += '<tr><th>Ch</th><th>SSID</th><th>RSSI</th><th>Encryption</th><th>Select</th></tr>';
|
||||||
|
|
||||||
|
for(var i=0;i<res.aps.length;i++){
|
||||||
|
|
||||||
|
if(res.aps[i].selected) tr += '<tr class="selected">';
|
||||||
|
else tr += '<tr>';
|
||||||
|
tr += '<td>'+res.aps[i].channel+'</td>';
|
||||||
|
tr += '<td>'+res.aps[i].ssid+'</td>';
|
||||||
|
tr += '<td>'+res.aps[i].rssi+' <meter value="'+res.aps[i].rssi+'" max="-30" min="-100" low="-80" high="-60" optimum="-50"></meter></td>';
|
||||||
|
tr += '<td>'+res.aps[i].encryption+'</td>';
|
||||||
|
|
||||||
|
if(res.aps[i].selected){
|
||||||
|
tr += '<td><button class="marginNull selectedBtn" onclick="select('+res.aps[i].id+')">deselect</button></td>';
|
||||||
|
apMAC.innerHTML = res.aps[i].mac;
|
||||||
|
apVendor.innerHTML = res.aps[i].vendor;
|
||||||
|
}
|
||||||
|
else tr += '<td><button class="marginNull" onclick="select('+res.aps[i].id+')">select</button></td>';
|
||||||
|
tr += '</tr>';
|
||||||
|
}
|
||||||
|
table.innerHTML = tr;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function scan(){
|
||||||
|
toggleBtn(false);
|
||||||
|
getResponse("APScan.json",function(responseText){
|
||||||
|
if(responseText == "true") getResults();
|
||||||
|
else alert("error");
|
||||||
|
toggleBtn(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function select(num){
|
||||||
|
getResponse("APSelect.json?num="+num,function(responseText){
|
||||||
|
if(responseText == "true") getResults();
|
||||||
|
else alert("error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getResults();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
42
htmlfiles/minifier.html
Normal file
42
htmlfiles/minifier.html
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
|
||||||
|
<script>
|
||||||
|
function miniEsc(){
|
||||||
|
var input = $('#input').val().replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' ).replace(/"/g, '\\"' );
|
||||||
|
$('#output').val(input);
|
||||||
|
$('#info1').html($('#input').val().length);
|
||||||
|
$('#info2').html(input.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
function mini(){
|
||||||
|
var input = $('#input').val().replace(/\r\n|\r|\n/g," ").replace( /\s\s+/g, ' ' );
|
||||||
|
$('#output').val(input);
|
||||||
|
$('#info1').html($('#input').val().length);
|
||||||
|
$('#info2').html(input.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
String.prototype.convertToHex = function (delim) {
|
||||||
|
return this.split("").map(function(c) {
|
||||||
|
return ("0" + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
}).join(delim || "");
|
||||||
|
};
|
||||||
|
|
||||||
|
function byte(){
|
||||||
|
var input = $('#input').val().convertToHex(",0x");
|
||||||
|
$('#output').val("0x"+input);
|
||||||
|
$('#info1').html($('#input').val().length);
|
||||||
|
$('#info2').html(input.length);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<textarea id="input" rows="50" cols="100"></textarea><br />
|
||||||
|
<p id="info1"></p>
|
||||||
|
<button onclick="mini()">minify</button>
|
||||||
|
<button onclick="miniEsc()">minify + escape</button>
|
||||||
|
<button onclick="byte()">byte-ify</button><br />
|
||||||
|
<textarea id="output" rows="50" cols="100"></textarea><br />
|
||||||
|
<p id="info2"></p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
107
htmlfiles/style.css
Normal file
107
htmlfiles/style.css
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
/* Global */
|
||||||
|
*,body{
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-family: arial;
|
||||||
|
color: #432929;
|
||||||
|
}
|
||||||
|
h1{
|
||||||
|
font-size: 22px;
|
||||||
|
margin-bottom: 0.6em;
|
||||||
|
background: #00B0FF;
|
||||||
|
color: #fff;
|
||||||
|
padding:0.2em;
|
||||||
|
border-radius:4px;
|
||||||
|
}
|
||||||
|
button{
|
||||||
|
background: #00B0FF;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid #7A7A7A;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 0.34em 1em;
|
||||||
|
margin-bottom: 0.6em;
|
||||||
|
}
|
||||||
|
button:hover{
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
input{
|
||||||
|
height: 22px;
|
||||||
|
width: 120px;
|
||||||
|
border: 1px solid #A99D9D;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 0.2em;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
input[type="checkbox"]{
|
||||||
|
height: 15px;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.warn{
|
||||||
|
color:#c20000;
|
||||||
|
}
|
||||||
|
.warnBtn{
|
||||||
|
background: #c20000;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.warnBtn:hover{
|
||||||
|
background: #f00;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.selectedBtn{
|
||||||
|
background: #fff;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
.selectedBtn:hover{
|
||||||
|
background: #00B0FF;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.right{ float: right; }
|
||||||
|
.bold{ font-weight: bold; }
|
||||||
|
.block{ display: block; }
|
||||||
|
.marginNull{ margin: 0}
|
||||||
|
.blue{ color: #00B0FF }
|
||||||
|
.small{ font-size: 14px; color: #727272 }
|
||||||
|
|
||||||
|
/* Navigation */
|
||||||
|
nav{
|
||||||
|
background: #222;
|
||||||
|
}
|
||||||
|
nav a{
|
||||||
|
background: #222;
|
||||||
|
color: #999;
|
||||||
|
padding: 0.5em;
|
||||||
|
display: inline-block;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
nav a:hover{
|
||||||
|
background: #000;
|
||||||
|
color:#f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Content */
|
||||||
|
#content{
|
||||||
|
padding: 0.34em;
|
||||||
|
}
|
||||||
|
table{
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
min-width: 420px;
|
||||||
|
border-spacing: 0;
|
||||||
|
background: #222222;
|
||||||
|
}
|
||||||
|
table th{
|
||||||
|
background: #222222;
|
||||||
|
color: #f0f0f0;
|
||||||
|
}
|
||||||
|
table td{
|
||||||
|
font-size: 14px;
|
||||||
|
background: #f0f0f0;
|
||||||
|
}
|
||||||
|
table th, table td{
|
||||||
|
border: 1px solid #000;
|
||||||
|
text-align: center;
|
||||||
|
padding: 0.1em 0.2em;
|
||||||
|
}
|
||||||
|
table .selected td{
|
||||||
|
background: #11a4cc;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user