github.com/JFJun/bsc@v1.0.0/cmd/faucet/faucet.html (about) 1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="utf-8"> 5 <meta http-equiv="X-UA-Compatible" content="IE=edge"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 8 <title>{{.Network}}: Faucet</title> 9 10 <link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" /> 11 <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" /> 12 13 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> 14 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-noty/2.4.1/packaged/jquery.noty.packaged.min.js"></script> 15 <script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.7/js/bootstrap.min.js"></script> 16 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.0/moment.min.js"></script> 17 18 <style> 19 .vertical-center { 20 min-height: 100%; 21 min-height: 100vh; 22 display: flex; 23 align-items: center; 24 } 25 .progress { 26 position: relative; 27 } 28 .progress span { 29 position: absolute; 30 display: block; 31 width: 100%; 32 color: white; 33 } 34 pre { 35 padding: 6px; 36 margin: 0; 37 } 38 </style> 39 </head> 40 41 <body> 42 <div class="vertical-center"> 43 <div class="container"> 44 <div class="row" style="margin-bottom: 16px;"> 45 <div class="col-lg-12"> 46 <h1 style="text-align: center;"><i class="fa fa-bath" aria-hidden="true"></i> {{.Network}} Faucet</h1> 47 </div> 48 </div> 49 <div class="row"> 50 <div class="col-lg-8 col-lg-offset-2"> 51 <div class="input-group"> 52 <input id="url" name="url" type="text" class="form-control" placeholder="Input your Binance Smart Chain address..."> 53 <span class="input-group-btn"> 54 <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Give me BNB <i class="fa fa-caret-down" aria-hidden="true"></i></button> 55 <ul class="dropdown-menu dropdown-menu-right">{{range $idx, $amount := .Amounts}} 56 <li><a style="text-align: center;" onclick="tier={{$idx}};symbol='BNB'; {{if $.Recaptcha}}grecaptcha.execute(){{else}}submit({{$idx}}){{end}}">{{$amount}}</a></li>{{end}} 57 </ul> 58 </span> 59 <span class="input-group-btn"> 60 <button class="btn btn-default dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Peggy tokens<i class="fa fa-caret-down" aria-hidden="true"></i></button> 61 <ul class="dropdown-menu dropdown-menu-right"> {{range $symbol, $bep2eInfo := .Bep2eInfos}} 62 <li><a style="text-align: center;" onclick="symbol={{$symbol}}; {{if $.Recaptcha}}grecaptcha.execute(){{else}}submitBep2e({{$symbol}}){{end}}">{{$bep2eInfo.AmountStr}} {{$symbol}}</a></li>{{end}} 63 </ul> 64 </span> 65 </div>{{if .Recaptcha}} 66 <div class="g-recaptcha" data-sitekey="{{.Recaptcha}}" data-callback="submit" data-size="invisible"></div>{{end}} 67 </div> 68 </div> 69 <div class="row" style="margin-top: 32px;"> 70 <div class="col-lg-6 col-lg-offset-3"> 71 <div class="panel panel-small panel-default"> 72 <div class="panel-body" style="padding: 0; overflow: auto; max-height: 300px;"> 73 <table id="requests" class="table table-condensed" style="margin: 0;"></table> 74 </div> 75 <div class="panel-footer"> 76 <table style="width: 100%"><tr> 77 <td style="text-align: center;"><i class="fa fa-rss" aria-hidden="true"></i> <span id="peers"></span> peers</td> 78 <td style="text-align: center;"><i class="fa fa-database" aria-hidden="true"></i> <span id="block"></span> blocks</td> 79 <td style="text-align: center;"><i class="fa fa-heartbeat" aria-hidden="true"></i> <span id="funds"></span> BNBs</td> 80 <td style="text-align: center;"><i class="fa fa-university" aria-hidden="true"></i> <span id="funded"></span> funded</td> 81 </tr></table> 82 </div> 83 </div> 84 </div> 85 </div> 86 </div> 87 </div> 88 89 <script> 90 // Global variables to hold the current status of the faucet 91 var attempt = 0; 92 var server; 93 var tier = 0; 94 var symbol=""; 95 var requests = []; 96 97 // Define a function that creates closures to drop old requests 98 var dropper = function(hash) { 99 return function() { 100 for (var i=0; i<requests.length; i++) { 101 if (requests[i].tx.hash == hash) { 102 requests.splice(i, 1); 103 break; 104 } 105 } 106 } 107 }; 108 // Define the function that submits a gist url to the server 109 var submit = function({{if .Recaptcha}}captcha{{end}}) { 110 server.send(JSON.stringify({url: $("#url")[0].value, symbol: symbol, tier: tier{{if .Recaptcha}}, captcha: captcha{{end}}}));{{if .Recaptcha}} 111 grecaptcha.reset();{{end}} 112 }; 113 // Define a method to reconnect upon server loss 114 var reconnect = function() { 115 server = new WebSocket(((window.location.protocol === "https:") ? "wss://" : "ws://") + window.location.host + "/faucet-smart/api"); 116 117 server.onmessage = function(event) { 118 var msg = JSON.parse(event.data); 119 if (msg === null) { 120 return; 121 } 122 123 if (msg.funds !== undefined) { 124 $("#funds").text(msg.funds); 125 } 126 if (msg.funded !== undefined) { 127 $("#funded").text(msg.funded); 128 } 129 if (msg.peers !== undefined) { 130 $("#peers").text(msg.peers); 131 } 132 if (msg.number !== undefined) { 133 $("#block").text(parseInt(msg.number, 16)); 134 } 135 if (msg.error !== undefined) { 136 noty({layout: 'topCenter', text: msg.error, type: 'error', timeout: 5000, progressBar: true}); 137 } 138 if (msg.success !== undefined) { 139 noty({layout: 'topCenter', text: msg.success, type: 'success', timeout: 5000, progressBar: true}); 140 } 141 if (msg.requests !== undefined && msg.requests !== null) { 142 // Mark all previous requests missing as done 143 for (var i=0; i<requests.length; i++) { 144 if (msg.requests.length > 0 && msg.requests[0].tx.hash == requests[i].tx.hash) { 145 break; 146 } 147 if (requests[i].time != "") { 148 requests[i].time = ""; 149 setTimeout(dropper(requests[i].tx.hash), 3000); 150 } 151 } 152 // Append any new requests into our local collection 153 var common = -1; 154 if (requests.length > 0) { 155 for (var i=0; i<msg.requests.length; i++) { 156 if (requests[requests.length-1].tx.hash == msg.requests[i].tx.hash) { 157 common = i; 158 break; 159 } 160 } 161 } 162 for (var i=common+1; i<msg.requests.length; i++) { 163 requests.push(msg.requests[i]); 164 } 165 // Iterate over our entire local collection and re-render the funding table 166 var content = ""; 167 for (var i=0; i<requests.length; i++) { 168 var done = requests[i].time == ""; 169 var elapsed = moment().unix()-moment(requests[i].time).unix(); 170 171 content += "<tr id='" + requests[i].tx.hash + "'>"; 172 content += " <td><div style=\"background: url('" + requests[i].avatar + "'); background-size: cover; width:32px; height: 32px; border-radius: 4px;\"></div></td>"; 173 content += " <td><pre>" + requests[i].account + "</pre></td>"; 174 content += " <td style=\"width: 100%; text-align: center; vertical-align: middle;\">"; 175 if (done) { 176 content += " funded"; 177 } else { 178 content += " <span id='time-" + i + "' class='timer'>" + moment.duration(-elapsed, 'seconds').humanize(true) + "</span>"; 179 } 180 content += " <div class='progress' style='height: 4px; margin: 0;'>"; 181 if (done) { 182 content += " <div class='progress-bar progress-bar-success' role='progressbar' aria-valuenow='30' style='width:100%;'></div>"; 183 } else if (elapsed > 30) { 184 content += " <div class='progress-bar progress-bar-danger progress-bar-striped active' role='progressbar' aria-valuenow='30' style='width:100%;'></div>"; 185 } else { 186 content += " <div class='progress-bar progress-bar-striped active' role='progressbar' aria-valuenow='" + elapsed + "' style='width:" + (elapsed * 100 / 30) + "%;'></div>"; 187 } 188 content += " </div>"; 189 content += " </td>"; 190 content += "</tr>"; 191 } 192 $("#requests").html("<tbody>" + content + "</tbody>"); 193 } 194 } 195 server.onclose = function() { setTimeout(reconnect, 3000); }; 196 } 197 // Start a UI updater to push the progress bars forward until they are done 198 setInterval(function() { 199 $('.progress-bar').each(function() { 200 var progress = Number($(this).attr('aria-valuenow')) + 1; 201 if (progress < 30) { 202 $(this).attr('aria-valuenow', progress); 203 $(this).css('width', (progress * 100 / 30) + '%'); 204 } else if (progress == 30) { 205 $(this).css('width', '100%'); 206 $(this).addClass("progress-bar-danger"); 207 } 208 }) 209 $('.timer').each(function() { 210 var index = Number($(this).attr('id').substring(5)); 211 $(this).html(moment.duration(moment(requests[index].time).unix()-moment().unix(), 'seconds').humanize(true)); 212 }) 213 }, 1000); 214 215 // Establish a websocket connection to the API server 216 reconnect(); 217 </script>{{if .Recaptcha}} 218 <script src="https://www.google.com/recaptcha/api.js" async defer></script>{{end}} 219 </body> 220 </html>