From 7f7abfe4d1d7c51d968c0ead48b93fdb3cf2909f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A9ter=20Szil=C3=A1gyi?= Date: Tue, 17 Oct 2017 12:08:57 +0300 Subject: [PATCH] cmd/faucet: proper error handling all over --- cmd/faucet/faucet.go | 165 ++++++++++++++++++++++++++++++++--------- cmd/faucet/faucet.html | 4 +- cmd/faucet/website.go | 2 +- 3 files changed, 135 insertions(+), 36 deletions(-) diff --git a/cmd/faucet/faucet.go b/cmd/faucet/faucet.go index 6b2987315a..715f3dec94 100644 --- a/cmd/faucet/faucet.go +++ b/cmd/faucet/faucet.go @@ -302,6 +302,8 @@ func (f *faucet) webHandler(w http.ResponseWriter, r *http.Request) { // apiHandler handles requests for Ether grants and transaction statuses. func (f *faucet) apiHandler(conn *websocket.Conn) { // Start tracking the connection and drop at the end + defer conn.Close() + f.lock.Lock() f.conns = append(f.conns, conn) f.lock.Unlock() @@ -316,25 +318,50 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { } f.lock.Unlock() }() - // Send a few initial stats to the client - balance, _ := f.client.BalanceAt(context.Background(), f.account.Address, nil) - nonce, _ := f.client.NonceAt(context.Background(), f.account.Address, nil) + // Gather the initial stats from the network to report + var ( + head *types.Header + balance *big.Int + nonce uint64 + err error + ) + for { + // Attempt to retrieve the stats, may error on no faucet connectivity + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + head, err = f.client.HeaderByNumber(ctx, nil) + if err == nil { + balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number) + if err == nil { + nonce, err = f.client.NonceAt(ctx, f.account.Address, nil) + } + } + cancel() - websocket.JSON.Send(conn, map[string]interface{}{ + // If stats retrieval failed, wait a bit and retry + if err != nil { + if err = sendError(conn, errors.New("Faucet offline: "+err.Error())); err != nil { + log.Warn("Failed to send faucet error to client", "err", err) + return + } + time.Sleep(3 * time.Second) + continue + } + // Initial stats reported successfully, proceed with user interaction + break + } + // Send over the initial stats and the latest header + if err = send(conn, map[string]interface{}{ "funds": balance.Div(balance, ether), "funded": nonce, "peers": f.stack.Server().PeerCount(), "requests": f.reqs, - }) - // Send the initial block to the client - ctx, cancel := context.WithTimeout(context.Background(), time.Second) - header, err := f.client.HeaderByNumber(ctx, nil) - cancel() - - if err != nil { - log.Error("Failed to retrieve latest header", "err", err) - } else { - websocket.JSON.Send(conn, header) + }, 3*time.Second); err != nil { + log.Warn("Failed to send initial stats to client", "err", err) + return + } + if err = send(conn, head, 3*time.Second); err != nil { + log.Warn("Failed to send initial header to client", "err", err) + return } // Keep reading requests from the websocket until the connection breaks for { @@ -344,16 +371,22 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { Tier uint `json:"tier"` Captcha string `json:"captcha"` } - if err := websocket.JSON.Receive(conn, &msg); err != nil { + if err = websocket.JSON.Receive(conn, &msg); err != nil { return } if !strings.HasPrefix(msg.URL, "https://gist.github.com/") && !strings.HasPrefix(msg.URL, "https://twitter.com/") && !strings.HasPrefix(msg.URL, "https://plus.google.com/") && !strings.HasPrefix(msg.URL, "https://www.facebook.com/") { - websocket.JSON.Send(conn, map[string]string{"error": "URL doesn't link to supported services"}) + if err = sendError(conn, errors.New("URL doesn't link to supported services")); err != nil { + log.Warn("Failed to send URL error to client", "err", err) + return + } continue } if msg.Tier >= uint(*tiersFlag) { - websocket.JSON.Send(conn, map[string]string{"error": "Invalid funding tier requested"}) + if err = sendError(conn, errors.New("Invalid funding tier requested")); err != nil { + log.Warn("Failed to send tier error to client", "err", err) + return + } continue } log.Info("Faucet funds requested", "url", msg.URL, "tier", msg.Tier) @@ -366,7 +399,10 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { res, err := http.PostForm("https://www.google.com/recaptcha/api/siteverify", form) if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha post error to client", "err", err) + return + } continue } var result struct { @@ -376,12 +412,18 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { err = json.NewDecoder(res.Body).Decode(&result) res.Body.Close() if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send captcha decode error to client", "err", err) + return + } continue } if !result.Success { log.Warn("Captcha verification failed", "err", string(result.Errors)) - websocket.JSON.Send(conn, map[string]string{"error": "Beep-bop, you're a robot!"}) + if err = sendError(conn, errors.New("Beep-bop, you're a robot!")); err != nil { + log.Warn("Failed to send captcha failure to client", "err", err) + return + } continue } } @@ -404,7 +446,10 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum/go-ethereum/issues") } if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send prefix error to client", "err", err) + return + } continue } log.Info("Faucet request valid", "url", msg.URL, "tier", msg.Tier, "user", username, "address", address) @@ -424,14 +469,20 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { tx := types.NewTransaction(f.nonce+uint64(len(f.reqs)), address, amount, big.NewInt(21000), f.price, nil) signed, err := f.keystore.SignTx(f.account, tx, f.config.ChainId) if err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction creation error to client", "err", err) + return + } continue } // Submit the transaction and mark as funded if successful if err := f.client.SendTransaction(context.Background(), signed); err != nil { - websocket.JSON.Send(conn, map[string]string{"error": err.Error()}) f.lock.Unlock() + if err = sendError(conn, err); err != nil { + log.Warn("Failed to send transaction transmission error to client", "err", err) + return + } continue } f.reqs = append(f.reqs, &request{ @@ -447,10 +498,16 @@ func (f *faucet) apiHandler(conn *websocket.Conn) { // Send an error if too frequent funding, othewise a success if !fund { - websocket.JSON.Send(conn, map[string]string{"error": fmt.Sprintf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))}) + if err = sendError(conn, fmt.Errorf("%s left until next allowance", common.PrettyDuration(timeout.Sub(time.Now())))); err != nil { + log.Warn("Failed to send funding error to client", "err", err) + return + } continue } - websocket.JSON.Send(conn, map[string]string{"success": fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())}) + if err = sendSuccess(conn, fmt.Sprintf("Funding request accepted for %s into %s", username, address.Hex())); err != nil { + log.Warn("Failed to send funding success to client", "err", err) + return + } select { case f.update <- struct{}{}: default: @@ -473,11 +530,31 @@ func (f *faucet) loop() { select { case head := <-heads: // New chain head arrived, query the current stats and stream to clients - balance, _ := f.client.BalanceAt(context.Background(), f.account.Address, nil) - balance = new(big.Int).Div(balance, ether) + var ( + balance *big.Int + nonce uint64 + price *big.Int + err error + ) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + balance, err = f.client.BalanceAt(ctx, f.account.Address, head.Number) + if err == nil { + nonce, err = f.client.NonceAt(ctx, f.account.Address, nil) + if err == nil { + price, err = f.client.SuggestGasPrice(ctx) + } + } + cancel() - price, _ := f.client.SuggestGasPrice(context.Background()) - nonce, _ := f.client.NonceAt(context.Background(), f.account.Address, nil) + // If querying the data failed, try for the next block + if err != nil { + log.Warn("Failed to update faucet state", "block", head.Number, "hash", head.Hash(), "err", err) + continue + } else { + log.Info("Updated faucet state", "block", head.Number, "hash", head.Hash(), "balance", balance, "nonce", nonce, "price", price) + } + // Faucet state retrieved, update locally and send to clients + balance = new(big.Int).Div(balance, ether) f.lock.Lock() f.price, f.nonce = price, nonce @@ -488,17 +565,17 @@ func (f *faucet) loop() { f.lock.RLock() for _, conn := range f.conns { - if err := websocket.JSON.Send(conn, map[string]interface{}{ + if err := send(conn, map[string]interface{}{ "funds": balance, "funded": f.nonce, "peers": f.stack.Server().PeerCount(), "requests": f.reqs, - }); err != nil { + }, time.Second); err != nil { log.Warn("Failed to send stats to client", "err", err) conn.Close() continue } - if err := websocket.JSON.Send(conn, head); err != nil { + if err := send(conn, head, time.Second); err != nil { log.Warn("Failed to send header to client", "err", err) conn.Close() } @@ -509,7 +586,7 @@ func (f *faucet) loop() { // Pending requests updated, stream to clients f.lock.RLock() for _, conn := range f.conns { - if err := websocket.JSON.Send(conn, map[string]interface{}{"requests": f.reqs}); err != nil { + if err := send(conn, map[string]interface{}{"requests": f.reqs}, time.Second); err != nil { log.Warn("Failed to send requests to client", "err", err) conn.Close() } @@ -519,6 +596,28 @@ func (f *faucet) loop() { } } +// sends transmits a data packet to the remote end of the websocket, but also +// setting a write deadline to prevent waiting forever on the node. +func send(conn *websocket.Conn, value interface{}, timeout time.Duration) error { + if timeout == 0 { + timeout = 60 * time.Second + } + conn.SetWriteDeadline(time.Now().Add(timeout)) + return websocket.JSON.Send(conn, value) +} + +// sendError transmits an error to the remote end of the websocket, also setting +// the write deadline to 1 second to prevent waiting forever. +func sendError(conn *websocket.Conn, err error) error { + return send(conn, map[string]string{"error": err.Error()}, time.Second) +} + +// sendSuccess transmits a success message to the remote end of the websocket, also +// setting the write deadline to 1 second to prevent waiting forever. +func sendSuccess(conn *websocket.Conn, msg string) error { + return send(conn, map[string]string{"success": msg}, time.Second) +} + // authGitHub tries to authenticate a faucet request using GitHub gists, returning // the username, avatar URL and Ethereum address to fund on success. func authGitHub(url string) (string, string, common.Address, error) { diff --git a/cmd/faucet/faucet.html b/cmd/faucet/faucet.html index 3b928d6367..75dad0bdfe 100644 --- a/cmd/faucet/faucet.html +++ b/cmd/faucet/faucet.html @@ -140,10 +140,10 @@ $("#block").text(parseInt(msg.number, 16)); } if (msg.error !== undefined) { - noty({layout: 'topCenter', text: msg.error, type: 'error'}); + noty({layout: 'topCenter', text: msg.error, type: 'error', timeout: 5000, progressBar: true}); } if (msg.success !== undefined) { - noty({layout: 'topCenter', text: msg.success, type: 'success'}); + noty({layout: 'topCenter', text: msg.success, type: 'success', timeout: 15000, progressBar: true}); } if (msg.requests !== undefined && msg.requests !== null) { var content = ""; diff --git a/cmd/faucet/website.go b/cmd/faucet/website.go index 5a80cb0a79..f99c69abfd 100644 --- a/cmd/faucet/website.go +++ b/cmd/faucet/website.go @@ -68,7 +68,7 @@ func (fi bindataFileInfo) Sys() interface{} { return nil } -var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\x7f\x73\xe3\xb6\xb1\x7f\xfb\x3e\xc5\x86\xef\x5c\x4b\x63\x93\x94\xe5\xcb\xd5\x4f\x26\x95\xb9\xb9\xa6\x69\xde\xbc\x69\x6f\x92\xeb\xbc\xd7\x69\x3b\x6f\x40\x72\x45\xe2\x0c\x02\x0c\xb0\x94\xac\x78\xf4\xdd\xdf\x00\x20\x29\x4a\xb6\xef\x9c\xbb\x4c\x9b\xfb\xc3\x21\x80\xfd\xbd\x8b\xdd\xc5\x2a\xc9\x57\x7f\xf8\xcb\xdb\xf7\x7f\x7b\xf7\x2d\x54\x54\x8b\xe5\x8b\xc4\xfe\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\x7f\x50\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x6f\xf8\xd7\x37\xe1\x5b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xfd\xb7\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x8b\x0b\xe0\x92\x13\x67\x22\x34\x39\x13\x98\x5e\x06\xcb\x17\x96\x0e\x71\x12\xb8\xbc\xbf\x8f\xfe\x8c\xb4\x51\xfa\x76\xb7\x5b\xc0\x9b\x96\x2a\x94\xc4\x73\x46\x58\xc0\x1f\x59\x9b\x23\x25\xb1\x87\x74\x48\x82\xcb\x5b\xa8\x34\xae\xd2\xc0\x8a\x6e\x16\x71\x9c\x17\xf2\x83\x89\x72\xa1\xda\x62\x25\x98\xc6\x28\x57\x75\xcc\x3e\xb0\xbb\x58\xf0\xcc\xc4\xb4\xe1\x44\xa8\xc3\x4c\x29\x32\xa4\x59\x13\x5f\x45\x57\xd1\xef\xe3\xdc\x98\x78\xd8\x8b\x6a\x2e\xa3\xdc\x98\x00\x34\x8a\x34\x30\xb4\x15\x68\x2a\x44\x0a\x20\x5e\x7e\x1e\xdf\x95\x92\x14\xb2\x0d\x1a\x55\x63\xfc\x2a\xfa\x7d\x34\x73\x2c\xc7\xdb\x1f\xe7\x6a\xd9\x9a\x5c\xf3\x86\xc0\xe8\xfc\xd9\x7c\x3f\xfc\xd4\xa2\xde\xc6\x57\xd1\x65\x74\xd9\x2d\x1c\x9f\x0f\x26\x58\x26\xb1\x27\xb8\xfc\x22\xda\xa1\x54\xb4\x8d\xe7\xd1\xab\xe8\x32\x6e\x58\x7e\xcb\x4a\x2c\x7a\x4e\xf6\x28\xea\x37\x7f\x35\xbe\x4f\xf9\xf0\xc3\xb1\x0b\x7f\x0d\x66\xb5\xaa\x51\x52\xf4\xc1\xc4\xf3\xe8\xf2\x3a\x9a\xf5\x1b\x0f\xe9\x3b\x06\xd6\x69\x96\xd5\x49\xb4\x46\x6d\x23\x57\x84\x39\x4a\x42\x0d\xf7\x76\xf7\xa4\xe6\x32\xac\x90\x97\x15\x2d\xe0\x72\x36\x3b\xbd\x79\x6c\x77\x5d\xf9\xed\x82\x9b\x46\xb0\xed\x02\x56\x02\xef\xfc\x16\x13\xbc\x94\x21\x27\xac\xcd\x02\x3c\x65\x77\xb0\x73\x3c\x1b\xad\x4a\x8d\xc6\x74\xcc\x1a\x65\x38\x71\x25\x17\x36\xa2\x18\xf1\x35\x3e\x06\x6b\x1a\x26\x1f\x20\xb0\xcc\x28\xd1\x12\x1e\x09\x92\x09\x95\xdf\xfa\x3d\x77\x9b\xc7\x4a\xe4\x4a\x28\xbd\x80\x4d\xc5\x3b\x34\x70\x8c\xa0\xd1\xd8\x91\x87\x86\x15\x05\x97\xe5\x02\x5e\x37\x9d\x3e\x50\x33\x5d\x72\xb9\x80\xd9\x1e\x25\x89\x7b\x33\x26\xb1\x4f\x5c\x2f\x4e\x92\x4c\x15\x5b\xe7\xc3\x82\xaf\x21\x17\xcc\x98\x34\x38\x32\xb1\x4b\x48\x07\x00\x36\x0f\x31\x2e\xfb\xa3\x83\x33\xad\x36\x01\x38\x46\x69\xe0\x85\x08\x33\x45\xa4\xea\x05\x5c\x5a\xf1\x3a\x94\x23\x7a\x22\x14\x65\x78\x39\xef\x0f\x4f\x92\xea\xb2\x27\x42\x78\x47\xa1\xf3\xcf\xe0\x99\x60\x99\xf0\x1e\x77\xc5\x60\xc5\xc2\x8c\x51\x15\x00\xd3\x9c\x85\x15\x2f\x0a\x94\x69\x40\xba\x45\x1b\x47\x7c\x09\xe3\xf4\xf7\x44\xf6\xab\x2e\x7b\xb9\xe2\x82\xaf\x3b\xb5\x46\x9f\x47\x1a\x3e\xad\xc4\x35\x74\x1f\x6a\xb5\x32\x48\xe1\x48\xa7\x11\x30\x97\x4d\x4b\x61\xa9\x55\xdb\x0c\xe7\x27\x89\xdb\x05\x5e\xa4\x41\xc9\x0d\x05\x40\xdb\xa6\x33\x40\x30\xa8\xab\x74\x1d\x5a\xfb\x6b\x25\x02\x68\x04\xcb\xb1\x52\xa2\x40\x9d\x06\x3f\xaa\x9c\x33\x01\xd2\x6b\x0a\x7f\xfd\xe1\xbf\xa1\x73\x14\x97\x25\x6c\x55\xab\xe1\x5b\xaa\x50\x63\x5b\x03\x2b\x0a\x1b\xa4\x51\x14\x8d\xd8\xbb\x88\x7d\x28\x60\x98\x91\xdc\x43\x9d\x24\x59\x4b\xa4\x06\xc0\x8c\x24\x64\x24\xc3\x02\x57\xac\x15\x04\x85\x56\x4d\xa1\x36\x32\x24\x55\x96\xb6\xbe\x79\x25\x3c\x52\x00\x05\x23\xd6\x1d\xa5\x41\x0f\xdb\x7b\x8e\x99\x46\x35\x6d\xd3\xf9\xce\x6f\xe2\x5d\xc3\x64\x81\x85\xf5\xb4\x30\x18\x2c\xbf\xe3\x6b\x84\x1a\xbd\x2e\x27\xc7\x81\x90\x33\x8d\x14\x8e\x89\x3e\x08\x87\x24\xf6\xc2\x78\x95\xa0\xfb\x97\xb4\xa2\xa7\x34\xa8\x50\xa3\x6c\xe1\x60\x15\x6a\x9b\x4d\x82\xe5\xfd\xbd\x66\xb2\x44\x78\xc9\x8b\xbb\x0b\x78\xc9\x6a\xd5\x4a\x82\x45\x0a\xd1\x1b\xf7\x69\x76\xbb\x03\xea\x00\x89\xe0\xcb\x84\x7d\x2c\xa8\x41\xc9\x5c\xf0\xfc\x36\x0d\x88\xa3\x4e\xef\xef\x2d\xf1\xdd\xee\x06\xee\xef\xf9\x0a\x5e\x46\x3f\x60\xce\x1a\xca\x2b\xb6\xdb\x95\xba\xff\x8e\xf0\x0e\xf3\x96\x70\x32\xbd\xbf\x47\x61\x70\xb7\x33\x6d\x56\x73\x9a\xf4\xe8\x76\x5f\x16\xbb\x9d\x95\xb9\x93\x73\xb7\x83\xd8\x12\x95\x05\xde\xc1\xcb\xe8\x1d\x6a\xae\x0a\x03\x1e\x3e\x89\xd9\x32\x89\x05\x5f\x76\x78\x87\x46\x8a\x5b\xb1\x8f\x97\xd8\x06\xcc\x10\xdd\xee\xb2\x38\x51\xc7\x92\x3e\x12\xfb\x65\x38\x48\xdf\xc5\x83\xe1\x84\xb7\xb8\x4d\x83\xfb\xfb\x31\x6e\x77\x9a\x33\x21\x32\x66\xed\xe2\x55\x1b\x90\x7e\x46\x1b\xa7\x6b\x6e\x5c\x23\xb5\xec\x25\xd8\x8b\xfd\xcc\xcb\x7c\x94\xae\x48\x35\x0b\xb8\x9a\x8f\x72\xd5\x63\xf7\xfc\xf5\xd1\x3d\xbf\x7a\x14\xb8\x61\x12\x05\xb8\xbf\xa1\xa9\x99\xe8\xbf\xbb\xdb\x32\xba\x7c\xc7\x48\xa1\xcd\xcc\x83\x68\x43\x86\x9f\xdd\x80\x5a\xa3\x5e\x09\xb5\x59\x00\x6b\x49\xdd\x40\xcd\xee\x86\x2a\x77\x35\x9b\x8d\xe5\xb6\x0d\x20\xcb\x04\xba\x9c\xa2\xf1\xa7\x16\x0d\x99\x21\x97\xf8\x23\xf7\xd7\xa6\x94\x02\xa5\xc1\xe2\xc8\x1a\x96\xa3\x35\xad\x83\x1a\xb9\x7e\x30\xe6\xa3\xb2\xaf\x94\x1a\x0a\xc7\x58\x8c\x8e\xf4\xa8\xc6\x05\xcb\x84\xf4\x1e\xee\x24\xa1\xe2\x17\x25\x7e\x6d\x1b\xbb\xa7\xf2\xbe\xcf\x68\x56\xf7\x06\x51\xfb\xae\xc2\x86\x2c\xb8\x65\x12\x53\xf1\x05\x9c\x6d\x10\x66\xcc\xe0\x73\xd8\xbb\xfa\xbe\x67\xef\x96\x5f\xca\xbf\x42\xa6\x29\x43\x46\xcf\x11\x60\xd5\xca\x62\xa4\xbf\xcb\x9d\x5f\x2a\x40\x2b\xf9\x1a\xb5\xe1\xb4\x7d\xae\x04\x58\xec\x45\xf0\xeb\x43\x11\x92\x98\xf4\xc7\x63\x6d\xbc\xf8\x95\x2e\xf7\xa7\x1a\x91\xab\xe5\x9f\xd4\x06\x0a\x85\x06\xa8\xe2\x06\x6c\x71\xfd\x26\x89\xab\xab\x01\xa4\x59\xbe\xb7\x07\xce\xa8\xb0\x72\x0d\x05\x70\x03\xba\x95\xae\xf2\x2a\x09\x54\xe1\x61\x13\xd2\x15\xe9\x08\xde\x2b\xdb\xc8\xad\x51\x12\xd4\x4c\xf0\x9c\xab\xd6\x00\xcb\x49\x69\x03\x2b\xad\x6a\xc0\xbb\x8a\xb5\x86\x2c\x21\x9b\x3e\xd8\x9a\x71\xe1\xee\x92\x73\x29\x28\x0d\x2c\xcf\xdb\xba\xb5\x8d\xa8\x2c\x01\xa5\x6a\xcb\xaa\x93\x85\x14\xf8\xc2\x24\x94\x2c\x07\x79\x4c\xc3\x6a\x60\x44\x2c\xbf\x35\x17\xd0\x67\x05\x60\x1a\x81\x38\x16\x16\x2b\x47\x6d\xfb\x06\xc8\x55\x5d\x2b\x09\x57\xba\x80\x86\x69\xda\x5a\x5e\xae\xbc\x45\xf0\x46\x6e\x95\x44\xa8\xd8\xda\x89\x06\xdf\x71\xfa\x53\x9b\x5d\xc0\x7b\xff\x8a\xb8\x80\xef\x94\x2a\x05\x9e\x5b\x09\xff\xc8\x72\xcc\x94\xba\xed\xd1\xa1\x66\xdb\x9e\x71\xa7\xc7\x86\x53\xc5\xbd\xa1\x1a\xd4\xb5\xa5\x51\x80\xe0\x35\x27\x13\x25\x71\xb3\xcf\xad\xfb\x2a\x2d\xc2\x4a\x69\xfe\xb3\x6d\x71\xc4\xe0\x2f\x80\xa4\xa0\xa3\x3c\xd3\xa7\x49\x17\x00\x02\x57\xb4\x80\x57\x3e\x4d\x1e\x87\x74\xc9\xa9\x6a\xb3\x90\x89\x47\x2f\x55\x4f\xd6\xbd\x2e\x6d\xf9\x59\xc0\x95\x6f\x69\x7d\x5b\x51\xd0\x28\x25\x16\x47\x81\xe7\xf9\x5e\x5f\x37\x77\x83\x28\x43\x5f\x3c\x1b\x88\xd8\x78\x38\x34\xcc\x9a\xef\x6d\x9b\x6b\x64\x84\xc0\x20\x61\x47\xcf\x64\xdb\x2f\x46\x5e\x7a\xf7\xd0\x0a\x80\x98\x2e\x91\xd2\xe0\xff\x58\xa6\x5a\x5a\x64\x82\xc9\xdb\x60\x69\xe1\x6c\x85\x77\xf6\x7e\xbc\x27\x04\xac\x33\x2c\x0a\x2c\x80\x4b\x52\xce\x23\xdd\xdc\x01\x26\x76\xb1\xe2\x02\xdd\x64\xc2\xdd\x09\x79\x66\xbd\x69\x3d\x3e\x8d\x92\x4c\xc7\xcb\xb7\xaa\xd9\x86\x0d\x33\x84\x0e\xd5\x32\x34\xae\x17\x1d\xa8\xb1\x4c\xad\x11\x7c\xaf\x9b\xa9\x3b\x60\xb2\x80\x15\xd7\x08\x6c\xc3\xb6\x5f\x25\x71\xe1\x5e\x26\xbd\x1d\x3f\xdf\x99\xdd\x7b\xf6\x37\xe5\xc9\xe1\x76\xd4\xec\xf6\x51\x47\x76\x42\x3b\x27\x72\x67\xf5\x98\x36\x88\xf4\x8d\x4d\xc9\xe9\x0f\x9e\x20\x97\xe5\xe9\x7c\xe6\x33\x8d\xfd\xb0\xe4\x4f\xe7\x33\x6b\xe1\xd3\xf9\x6c\x76\x37\x7b\xe6\xbf\xd3\xf9\x4c\xc9\xd3\xf9\x8c\x2a\x3c\x9d\xcf\x4e\xe7\x57\xe3\x1c\xe5\x77\xfa\xe8\xb0\x50\x68\x2c\xb7\x3e\x75\x3d\x15\x62\x4e\xdc\x4f\xc5\x98\x0b\x90\x87\x11\x66\x60\x62\x5a\xad\x55\x2b\x6d\xb7\x03\x56\xe7\x67\x45\xd9\x03\x33\x9a\xb6\x69\x94\xa6\x68\x6c\x4e\x66\x5f\xb5\x02\x4d\x7c\x3d\xfb\xfa\xfa\xf5\x47\xc5\x77\x11\xeb\x74\xf8\x97\x47\x6d\xe9\xd2\x66\xd8\x88\xd6\xd8\xd6\x92\xdb\x37\xdd\x6f\x2a\x84\x7d\x5e\x87\x77\xa2\x35\x17\xd0\xb4\x99\xe0\xa6\x02\x06\x12\x37\x90\x18\xd2\x4a\x96\x4b\xb7\x9b\x27\x71\xb7\x84\x46\x19\xfa\xcc\x8c\xf3\x59\xe1\x60\xf9\xfd\x9b\x92\xce\xaa\x2b\x75\xbf\x29\x97\xf5\xf5\xf7\x17\xf9\x4b\xc9\x7f\xa5\xcb\x1e\xdc\xe0\xcd\x66\x13\xf5\xc6\x74\xd7\xb7\x42\xd1\xc4\xb6\x21\x69\x25\xa7\x6d\xec\x13\xa1\x92\xf1\x37\xbc\x48\xe7\xd7\xf3\xd7\xaf\xe7\xaf\xfe\xf3\xfa\xeb\xaf\xe7\xd7\xaf\xbe\x7e\xea\x6e\x0f\x71\xf1\xcb\xaf\xf6\xd0\x7e\x8a\x51\xdb\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xbb\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\x6b\xb5\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x8e\x0a\xed\xc1\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x90\xe1\x41\x43\xf4\xe0\xc1\x9d\x60\xbd\x7c\x6f\xcb\xf4\x83\x3e\x74\x78\x2a\x83\xc6\xb7\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x96\x0b\xeb\x67\x3c\xa5\x87\xaf\xee\x63\x3f\x0c\x76\xc7\x71\x0c\xdf\x09\x95\x31\x01\x6b\x7b\x1b\x32\x61\x7b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xae\x97\xdc\xe2\xaf\x99\xb6\x8d\x2a\xd6\x0d\x41\xda\x8d\x32\xed\x9e\x41\xbd\xee\x06\xb4\x76\x49\x1c\xb5\x3f\xef\x98\xfe\x01\x57\x5c\xfa\xb8\x5a\xb5\xd2\xab\x47\x15\x23\xf0\x03\x04\x03\xcc\xf5\x25\xd0\x6a\x01\x5d\x0c\x78\x92\x03\x03\x07\x07\xe9\x80\x3e\x79\x60\xe7\xee\xa3\xb3\xd1\xb4\x1b\xc5\x7a\x32\x91\x41\x59\x4c\xfe\xeb\xc7\xbf\xfc\x39\x32\xa4\xb9\x2c\xf9\x6a\x3b\xb9\x6f\xb5\x58\xc0\xcb\x49\xf0\x1f\x6e\xb8\x37\xfd\xfb\xec\x9f\xd1\x9a\x89\x16\x2f\x9c\x02\x0b\xf7\xf7\x01\x9b\x0b\xe8\x3e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6d\x19\x0d\x87\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x59\x67\x19\x48\x5d\xe2\xf9\x1f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xdb\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\x4d\x3f\xe7\x10\xc4\xac\xe1\xc1\xd4\x0f\xb4\x77\x80\xc2\xe0\xa7\x89\x3d\x8b\x96\x1f\xf9\x7b\x49\xcf\xcf\x7d\xd8\xf4\xae\x53\xb2\x46\x63\x58\x89\x63\x0d\xdd\x03\x6d\x50\xc5\x1a\xa2\x36\x25\xa4\xe0\x5c\xdc\x30\x6d\xd0\x83\x44\x05\x23\xd6\x71\x71\xe6\x70\x60\x69\x0a\xb2\x15\x62\xc0\x3f\xd1\x68\x2f\x73\x07\xb6\x7b\x71\x00\x1e\xf9\xb4\xfd\x55\x9a\x82\x7d\x21\x5b\x1f\x15\x7b\x4c\x1b\x3e\xfe\x2d\x3f\x8d\x6c\x6e\xdd\x63\x4c\x07\x72\x0f\xa8\x61\xf1\x29\x72\x58\x1c\xd3\xc3\xe2\x09\x82\x6e\x74\xf2\x31\x7a\x7e\xd4\x32\x22\xe7\x36\x9e\xa0\x26\xdb\x3a\x43\xfd\x31\x72\x7e\x74\xd2\x91\x73\xa6\xfe\x5e\xd2\x08\xf7\x02\x2e\x5f\x4f\x9f\xa0\x8e\x5a\xab\x27\x89\x4b\x45\xdb\xc9\xbd\x60\x5b\x5b\x20\xe0\x8c\x54\xf3\xd6\x4d\x3a\xce\x2e\x5c\xd5\x5a\xc0\x40\xe1\xc2\xcd\xb0\x17\x70\xe6\x56\x67\xbb\x27\xb8\x99\x36\xcf\x6d\x69\xfc\x12\x7e\x1d\x8d\x81\x63\xb7\x7e\x92\xe7\x50\x5f\x0e\x98\xc2\xef\x7e\x07\x0f\x4e\x0f\x43\xd0\xc6\x70\x5f\xb1\x53\x08\x82\x8e\xfc\xc9\x4a\x69\x98\xd8\x43\x9e\xce\x6e\x80\x27\x63\x32\x91\x40\x59\x52\x75\x03\xfc\xfc\x7c\x4f\xe9\xa4\x27\x73\x9e\x42\x90\x90\x5e\x26\x54\x2c\xdd\x50\xc5\x37\x30\xff\x08\x32\x96\xdf\x96\xae\x25\x58\xd8\x94\x3b\x39\xb3\x37\x74\x4c\xf8\xef\xfc\x9f\x11\x5b\x33\x62\xda\x5e\xd5\xb3\xe9\x0d\xec\x51\xba\x46\x29\x57\x36\xe3\x83\xef\xc7\xdc\xfc\x06\x86\x99\xa7\x5b\x65\x4a\x17\xa8\x43\xcd\x0a\xde\x9a\x05\xbc\x6a\xee\x6e\xfe\xd1\xcf\x84\xdd\x94\xc9\x89\xd5\x68\x5c\x3e\xca\xbd\x1b\x4c\x9c\x43\x90\xc4\x16\xa8\x47\x19\x94\x18\xff\x2e\x07\x8f\xcc\xc7\x60\xf8\xd5\xac\xdb\xaf\x79\x51\x08\xb4\x42\x38\x86\xfe\xe7\xcd\xa2\xd5\x2e\x2f\x4d\xfc\x7a\x72\x2c\x07\xf1\x1a\xa7\x51\x2b\xf9\xdd\x64\x1a\x76\x30\xfd\xfa\x02\xce\x8c\x4d\xbf\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\xed\x2c\xa7\x5e\x6e\x2b\x71\x4c\x7a\x39\x38\x73\x37\xba\x47\xc3\xf4\x77\x1a\x55\x54\x8b\x49\x90\x90\xfb\xed\xcf\x0a\x37\x78\xd0\x51\xf1\xdb\x87\x01\xb7\x3b\x4c\x91\xb9\x50\x06\x8f\x4a\x00\x18\xa4\xf7\xbc\x46\xd5\xd2\x64\x28\x13\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\xff\x44\x1a\xc7\xf0\xad\x21\xd6\x37\xa2\x1b\xcc\x8c\x4b\xdf\xd0\xe1\xb8\x6a\xed\xab\xf2\x9b\x77\xdf\x8f\x2a\xf3\x40\x75\xe2\x84\x1b\x7e\x22\x7e\xac\x0c\x3e\xfa\x9b\xb4\xed\x29\xfd\xfb\xca\x75\x94\x43\x9d\xb4\xc5\x21\xfa\x60\x02\x60\x66\x2b\x73\x28\x70\x85\x7a\x39\x22\xdf\x15\xcf\x24\xf6\xbf\x96\x26\xb1\xff\x1f\x42\xfe\x3f\x00\x00\xff\xff\x1f\xb2\x73\x97\x21\x22\x00\x00") +var _faucetHtml = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xcc\x3a\xed\x72\xdb\x38\x92\xbf\x9d\xa7\xe8\xe1\xc5\x6b\xa9\x6c\x92\xb2\x9c\x64\x7d\x32\xa9\xa9\x5c\x76\x76\x76\xae\xae\x76\xa7\x66\xb2\x75\xb7\xb5\xbb\x75\x05\x92\x2d\x12\x31\x08\x70\x80\xa6\x64\x8d\x4b\xef\x7e\x05\x80\xa4\x28\xd9\xce\x78\x92\xa9\xdb\xf8\x87\x42\x02\xfd\xdd\x8d\xee\x46\x33\xc9\x57\x7f\xf8\xcb\xbb\xf7\x7f\xfb\xfe\x1b\xa8\xa8\x16\xcb\x17\x89\xfd\x07\x04\x93\x65\x1a\xa0\x0c\x96\x2f\x4e\x92\x0a\x59\xb1\x7c\x71\x72\x92\xd4\x48\x0c\xf2\x8a\x69\x83\x94\x06\x2d\xad\xc2\xeb\x60\xbf\x51\x11\x35\x21\xfe\xd4\xf2\x75\x1a\xfc\x4f\xf8\xd7\xb7\xe1\x3b\x55\x37\x8c\x78\x26\x30\x80\x5c\x49\x42\x49\x69\xf0\xdd\x37\x29\x16\x25\x8e\xf0\x24\xab\x31\x0d\xd6\x1c\x37\x8d\xd2\x34\x02\xdd\xf0\x82\xaa\xb4\xc0\x35\xcf\x31\x74\x2f\x17\xc0\x25\x27\xce\x44\x68\x72\x26\x30\xbd\x0c\x96\x2f\x2c\x1d\xe2\x24\x70\x79\x7f\x1f\xfd\x19\x69\xa3\xf4\xed\x6e\xb7\x80\xb7\x2d\x55\x28\x89\xe7\x8c\xb0\x80\x3f\xb2\x36\x47\x4a\x62\x0f\xe9\x90\x04\x97\xb7\x50\x69\x5c\xa5\x81\x15\xdd\x2c\xe2\x38\x2f\xe4\x07\x13\xe5\x42\xb5\xc5\x4a\x30\x8d\x51\xae\xea\x98\x7d\x60\x77\xb1\xe0\x99\x89\x69\xc3\x89\x50\x87\x99\x52\x64\x48\xb3\x26\xbe\x8a\xae\xa2\xdf\xc7\xb9\x31\xf1\xb0\x16\xd5\x5c\x46\xb9\x31\x01\x68\x14\x69\x60\x68\x2b\xd0\x54\x88\x14\x40\xbc\xfc\x34\xbe\x2b\x25\x29\x64\x1b\x34\xaa\xc6\xf8\x55\xf4\xfb\x68\xe6\x58\x8e\x97\x3f\xce\xd5\xb2\x35\xb9\xe6\x0d\x81\xd1\xf9\xb3\xf9\x7e\xf8\xa9\x45\xbd\x8d\xaf\xa2\xcb\xe8\xb2\x7b\x71\x7c\x3e\x98\x60\x99\xc4\x9e\xe0\xf2\xb3\x68\x87\x52\xd1\x36\x9e\x47\xaf\xa2\xcb\xb8\x61\xf9\x2d\x2b\xb1\xe8\x39\xd9\xad\xa8\x5f\xfc\xcd\xf8\x3e\xe5\xc3\x0f\xc7\x2e\xfc\x2d\x98\xd5\xaa\x46\x49\xd1\x07\x13\xcf\xa3\xcb\xeb\x68\xd6\x2f\x3c\xa4\xef\x18\x58\xa7\x59\x56\x27\xd1\x1a\xb5\x8d\x5c\x11\xe6\x28\x09\x35\xdc\xdb\xd5\x93\x9a\xcb\xb0\x42\x5e\x56\xb4\x80\xcb\xd9\xec\xf4\xe6\xb1\xd5\x75\xe5\x97\x0b\x6e\x1a\xc1\xb6\x0b\x58\x09\xbc\xf3\x4b\x4c\xf0\x52\x86\x9c\xb0\x36\x0b\xf0\x94\xdd\xc6\xce\xf1\x6c\xb4\x2a\x35\x1a\xd3\x31\x6b\x94\xe1\xc4\x95\x5c\xd8\x88\x62\xc4\xd7\xf8\x18\xac\x69\x98\x7c\x80\xc0\x32\xa3\x44\x4b\x78\x24\x48\x26\x54\x7e\xeb\xd7\xdc\x69\x1e\x2b\x91\x2b\xa1\xf4\x02\x36\x15\xef\xd0\xc0\x31\x82\x46\x63\x47\x1e\x1a\x56\x14\x5c\x96\x0b\x78\xd3\x74\xfa\x40\xcd\x74\xc9\xe5\x02\x66\x7b\x94\x24\xee\xcd\x98\xc4\x3e\x71\xbd\x38\x49\x32\x55\x6c\x9d\x0f\x0b\xbe\x86\x5c\x30\x63\xd2\xe0\xc8\xc4\x2e\x21\x1d\x00\xd8\x3c\xc4\xb8\xec\xb7\x0e\xf6\xb4\xda\x04\xe0\x18\xa5\x81\x17\x22\xcc\x14\x91\xaa\x17\x70\x69\xc5\xeb\x50\x8e\xe8\x89\x50\x94\xe1\xe5\xbc\xdf\x3c\x49\xaa\xcb\x9e\x08\xe1\x1d\x85\xce\x3f\x83\x67\x82\x65\xc2\x7b\xdc\x15\x83\x15\x0b\x33\x46\x55\x00\x4c\x73\x16\x56\xbc\x28\x50\xa6\x01\xe9\x16\x6d\x1c\xf1\x25\x8c\xd3\xdf\x13\xd9\xaf\xba\xec\xe5\x8a\x0b\xbe\xee\xd4\x1a\x3d\x1e\x69\xf8\xb4\x12\xd7\xd0\x3d\xa8\xd5\xca\x20\x85\x23\x9d\x46\xc0\x5c\x36\x2d\x85\xa5\x56\x6d\x33\xec\x9f\x24\x6e\x15\x78\x91\x06\x25\x37\x14\x00\x6d\x9b\xce\x00\xc1\xa0\xae\xd2\x75\x68\xed\xaf\x95\x08\xa0\x11\x2c\xc7\x4a\x89\x02\x75\x1a\xfc\xa8\x72\xce\x04\x48\xaf\x29\xfc\xf5\x87\xff\x82\xce\x51\x5c\x96\xb0\x55\xad\x86\x6f\xa8\x42\x8d\x6d\x0d\xac\x28\x6c\x90\x46\x51\x34\x62\xef\x22\xf6\xa1\x80\x61\x46\x72\x0f\x75\x92\x64\x2d\x91\x1a\x00\x33\x92\x90\x91\x0c\x0b\x5c\xb1\x56\x10\x14\x5a\x35\x85\xda\xc8\x90\x54\x59\xda\xfa\xe6\x95\xf0\x48\x01\x14\x8c\x58\xb7\x95\x06\x3d\x6c\xef\x39\x66\x1a\xd5\xb4\x4d\xe7\x3b\xbf\x88\x77\x0d\x93\x05\x16\xd6\xd3\xc2\x60\xb0\xfc\x96\xaf\x11\x6a\xf4\xba\x9c\x1c\x07\x42\xce\x34\x52\x38\x26\xfa\x20\x1c\x92\xd8\x0b\xe3\x55\x82\xee\x2f\x69\x45\x4f\x69\x50\xa1\x46\xd9\xc2\xc1\x5b\xa8\x6d\x36\x09\x96\xf7\xf7\x9a\xc9\x12\xe1\x25\x2f\xee\x2e\xe0\x25\xab\x55\x2b\x09\x16\x29\x44\x6f\xdd\xa3\xd9\xed\x0e\xa8\x03\x24\x82\x2f\x13\xf6\xb1\xa0\x06\x25\x73\xc1\xf3\xdb\x34\x20\x8e\x3a\xbd\xbf\xb7\xc4\x77\xbb\x1b\xb8\xbf\xe7\x2b\x78\x19\xfd\x80\x39\x6b\x28\xaf\xd8\x6e\x57\xea\xfe\x39\xc2\x3b\xcc\x5b\xc2\xc9\xf4\xfe\x1e\x85\xc1\xdd\xce\xb4\x59\xcd\x69\xd2\xa3\xdb\x75\x59\xec\x76\x56\xe6\x4e\xce\xdd\x0e\x62\x4b\x54\x16\x78\x07\x2f\xa3\xef\x51\x73\x55\x18\xf0\xf0\x49\xcc\x96\x49\x2c\xf8\xb2\xc3\x3b\x34\x52\xdc\x8a\x7d\xbc\xc4\x36\x60\x86\xe8\x76\x87\xc5\x89\x3a\x96\xf4\x91\xd8\x2f\xc3\x41\xfa\x2e\x1e\x0c\x27\xbc\xc5\x6d\x1a\xdc\xdf\x8f\x71\xbb\xdd\x9c\x09\x91\x31\x6b\x17\xaf\xda\x80\xf4\x33\xda\x38\x5d\x73\xe3\x1a\xa9\x65\x2f\xc1\x5e\xec\x67\x1e\xe6\xa3\x74\x45\xaa\x59\xc0\xd5\x7c\x94\xab\x1e\x3b\xe7\x6f\x8e\xce\xf9\xd5\xa3\xc0\x0d\x93\x28\xc0\xfd\x86\xa6\x66\xa2\x7f\xee\x4e\xcb\xe8\xf0\x1d\x23\x85\x36\x33\x0f\xa2\x0d\x19\x7e\x76\x03\x6a\x8d\x7a\x25\xd4\x66\x01\xac\x25\x75\x03\x35\xbb\x1b\xaa\xdc\xd5\x6c\x36\x96\xdb\x36\x80\x2c\x13\xe8\x72\x8a\xc6\x9f\x5a\x34\x64\x86\x5c\xe2\xb7\xdc\xaf\x4d\x29\x05\x4a\x83\xc5\x91\x35\x2c\x47\x6b\x5a\x07\x35\x72\xfd\x60\xcc\x47\x65\x5f\x29\x35\x14\x8e\xb1\x18\x1d\xe9\x51\x8d\x0b\x96\x09\xe9\x3d\xdc\x49\x42\xc5\xaf\x4a\xfc\xda\x36\x76\x4f\xe5\x7d\x9f\xd1\xac\xee\x0d\xa2\xf6\x5d\x85\x0d\x59\x70\xaf\x49\x4c\xc5\x67\x70\xb6\x41\x98\x31\x83\xcf\x61\xef\xea\xfb\x9e\xbd\x7b\xfd\x5c\xfe\x15\x32\x4d\x19\x32\x7a\x8e\x00\xab\x56\x16\x23\xfd\x5d\xee\xfc\x5c\x01\x5a\xc9\xd7\xa8\x0d\xa7\xed\x73\x25\xc0\x62\x2f\x82\x7f\x3f\x14\x21\x89\x49\x7f\x3c\xd6\xc6\x2f\xbf\xd1\xe1\xfe\xa5\x46\xe4\x6a\xf9\x27\xb5\x81\x42\xa1\x01\xaa\xb8\x01\x5b\x5c\xbf\x4e\xe2\xea\x6a\x00\x69\x96\xef\xed\x86\x33\x2a\xac\x5c\x43\x01\xdc\x80\x6e\xa5\xab\xbc\x4a\x02\x55\x78\xd8\x84\x74\x45\x3a\x82\xf7\xca\x36\x72\x6b\x94\x04\x35\x13\x3c\xe7\xaa\x35\xc0\x72\x52\xda\xc0\x4a\xab\x1a\xf0\xae\x62\xad\x21\x4b\xc8\xa6\x0f\xb6\x66\x5c\xb8\xb3\xe4\x5c\x0a\x4a\x03\xcb\xf3\xb6\x6e\x6d\x23\x2a\x4b\x40\xa9\xda\xb2\xea\x64\x21\x05\xbe\x30\x09\x25\xcb\x41\x1e\xd3\xb0\x1a\x18\x11\xcb\x6f\xcd\x05\xf4\x59\x01\x98\x46\x20\x8e\x85\xc5\xca\x51\xdb\xbe\x01\x72\x55\xd7\x4a\xc2\x95\x2e\xa0\x61\x9a\xb6\x96\x97\x2b\x6f\x11\xbc\x95\x5b\x25\x11\x2a\xb6\x76\xa2\xc1\xb7\x9c\xfe\xd4\x66\x17\xf0\xde\xdf\x22\x2e\xe0\x5b\xa5\x4a\x81\xe7\x56\xc2\x3f\xb2\x1c\x33\xa5\x6e\x7b\x74\xa8\xd9\xb6\x67\xdc\xe9\xb1\xe1\x54\x71\x6f\xa8\x06\x75\x6d\x69\x14\x20\x78\xcd\xc9\x44\x49\xdc\xec\x73\xeb\xbe\x4a\x8b\xb0\x52\x9a\xff\x6c\x5b\x1c\x31\xf8\x0b\x20\x29\xe8\x28\xcf\xf4\x69\xd2\x05\x80\xc0\x15\x2d\xe0\x95\x4f\x93\xc7\x21\x5d\x72\xaa\xda\x2c\x64\xe2\xd1\x43\xd5\x93\x75\xb7\x4b\x5b\x7e\x16\x70\xe5\x5b\x5a\xdf\x56\x14\x34\x4a\x89\xc5\x51\xe0\x79\xbe\xd7\xd7\xcd\xdd\x20\xca\xd0\x17\xcf\x06\x22\x36\x1e\x0e\x0d\xb3\xe6\x7b\xdb\xe6\x1a\x19\x21\x30\x48\xd8\xd1\x35\xd9\xf6\x8b\x91\x97\xde\x5d\xb4\x02\x20\xa6\x4b\xa4\x34\xf8\x5f\x96\xa9\x96\x16\x99\x60\xf2\x36\x58\x5a\x38\x5b\xe1\x9d\xbd\x1f\xef\x09\x01\xeb\x0c\x8b\x02\x0b\xe0\x92\x94\xf3\x48\x37\x77\x80\x89\x7d\x59\x71\x81\x6e\x32\xe1\xce\x84\x3c\xb3\xde\xb4\x1e\x9f\x46\x49\xa6\xe3\xe5\x3b\xd5\x6c\xc3\x86\x19\x42\x87\x6a\x19\x1a\xd7\x8b\x0e\xd4\x58\xa6\xd6\x08\xbe\xd7\xcd\xd4\x1d\x30\x59\xc0\x8a\x6b\x04\xb6\x61\xdb\xaf\x92\xb8\x70\x37\x93\xde\x8e\x9f\xee\xcc\xee\x3e\xfb\x45\x79\x72\x38\x1d\x35\xbb\x7d\xd4\x91\x9d\xd0\xce\x89\xdc\x59\x3d\xa6\x0d\x22\x7d\x6d\x53\x72\xfa\x83\x27\xc8\x65\x79\x3a\x9f\xf9\x4c\x63\x1f\x2c\xf9\xd3\xf9\xcc\x5a\xf8\x74\x3e\x9b\xdd\xcd\x9e\xf9\x77\x3a\x9f\x29\x79\x3a\x9f\x51\x85\xa7\xf3\xd9\xe9\xfc\x6a\x9c\xa3\xfc\x4a\x1f\x1d\x16\x0a\x8d\xe5\xd6\xa7\xae\xa7\x42\xcc\x89\xfb\x4b\x31\xe6\x02\xe4\x61\x84\x19\x98\x98\x56\x6b\xd5\x4a\xdb\xed\x80\xd5\xf9\x59\x51\xf6\xc0\x8c\xa6\x6d\x1a\xa5\x29\x1a\x9b\x93\xd9\x5b\xad\x40\x13\x5f\xcf\x5e\x5f\xbf\xf9\xa8\xf8\x2e\x62\x9d\x0e\xff\xef\x51\x5b\xba\xb4\x19\x36\xa2\x35\xb6\xb5\xe4\xf6\x4e\xf7\x45\x85\xb0\xcf\xeb\xf0\xbd\x68\xcd\x05\x34\x6d\x26\xb8\xa9\x80\x81\xc4\x0d\x24\x86\xb4\x92\xe5\xd2\xad\xe6\x49\xdc\xbd\x42\xa3\x0c\x7d\x62\xc6\xf9\xa4\x70\xb0\xfc\xfe\x45\x49\x67\xd5\x95\xba\x2f\xca\x65\x7d\xfd\xfd\x52\xfd\xf5\xe0\xf8\x6e\x36\x9b\xa8\xb7\xa4\x3b\xbb\x15\x8a\x26\xb6\xdd\x48\x2b\x39\x6d\x63\x9f\x05\x95\x8c\xbf\xe6\x45\x3a\xbf\x9e\xbf\x79\x33\x7f\xf5\xef\xd7\xaf\x5f\xcf\xaf\x5f\xbd\x7e\xea\x60\x0f\x41\xf1\xeb\xcf\xf5\xd0\x7b\x8a\x51\xcf\xf7\x37\xd5\x42\xce\x24\x90\x66\xf9\xad\x37\x42\xab\xb5\x35\x42\x83\x5e\xff\xa1\xb5\xca\x50\xa8\x8d\x03\xf1\x7c\x56\x1c\x85\xeb\xb3\x0c\x22\x54\x6a\x03\x75\x9b\x3b\x5b\xdb\x76\x0a\xed\xc6\x86\x71\x82\x56\x12\x17\xde\x05\xd4\x6a\xd7\x8d\xe1\x41\x37\xf4\xe0\xb6\x9d\x60\xbd\x7c\x6f\x6b\xf4\x83\x26\x74\xb8\x27\x83\xc6\x77\x1e\x1c\x1a\xad\x08\x73\x6b\x47\x60\x25\xe3\xd2\x58\x0b\xb8\x7e\x0b\xeb\x67\xdc\xa3\x87\xa7\xee\x61\x3f\x09\x76\xdb\x71\x0c\xdf\x0a\x95\x31\x01\x6b\x7b\x14\x32\x61\x1b\x68\x05\x95\xb2\xaa\x8f\xac\x65\x88\x51\x6b\x40\xad\xdc\xaa\x97\xdc\xe2\xaf\x99\xb6\x5d\x2a\xd6\x0d\x41\xda\xcd\x31\xed\x9a\x41\xbd\xee\xa6\xb3\xf6\x95\x38\x6a\xbf\xdf\x31\xfd\x03\xae\xb8\xf4\x71\xb5\x6a\xa5\x57\x8f\x2a\x46\xe0\xa7\x07\x06\x98\x6b\x4a\xa0\xd5\x02\xba\x18\xf0\x24\x07\x06\x0e\x0e\xd2\x01\x7d\xf2\xc0\xce\xdd\x43\x67\xa3\x69\x37\x87\xf5\x64\x22\x83\xb2\x98\xfc\xe7\x8f\x7f\xf9\x73\x64\x48\x73\x59\xf2\xd5\x76\x72\xdf\x6a\xb1\x80\x97\x93\xe0\xdf\xdc\x64\x6f\xfa\xf7\xd9\x3f\xa3\x35\x13\x2d\x5e\x38\x05\x16\xee\xf7\x01\x9b\x0b\xe8\x1e\x17\x70\xc8\x71\x37\x9d\xde\x3c\x3e\x6a\x19\x4d\x86\x34\x1a\xa4\x89\x05\x1c\x3c\xb9\xbb\x39\x34\x12\x83\x1a\xa9\x52\x2e\x16\x35\xe6\x4a\x4a\xcc\x09\xda\x46\xc9\xce\x26\x20\x94\x31\xbd\x61\xf6\x10\x23\xdb\xf4\xca\xf3\x15\x4c\x7a\x77\x9d\xc2\x1c\xd2\x14\x66\xfd\x5e\x67\x19\x48\x5d\xd6\xf9\x6f\xcc\x7e\x54\xf9\x2d\xd2\x24\xd8\x18\x7b\xda\x03\x38\x07\xa1\x72\x66\xe9\x45\x95\xcd\x3d\xe7\x10\xc4\xac\xe1\xc1\xd4\x4f\xb3\x77\x80\xc2\xe0\x2f\x13\x7b\x16\x2d\x3f\xef\xf7\x92\x9e\x9f\xfb\xb0\xe9\x5d\xa7\x64\x8d\xc6\xb0\x12\xc7\x1a\xba\xdb\xd9\xa0\x8a\x35\x44\x6d\x4a\x48\xc1\xb9\xb8\x61\xda\xa0\x07\x89\x0a\x46\xac\xe3\xe2\xcc\xe1\xc0\xd2\x14\x64\x2b\xc4\x80\x7f\xa2\xd1\x1e\xe6\x0e\x6c\xf7\xe2\x00\x3c\xf2\x39\xfb\xab\x34\x05\x7b\x3d\xb6\x3e\x2a\xf6\x98\x36\x7c\xfc\x45\x7e\x1a\xd9\xdc\xba\xc7\x98\x0e\xe4\x1e\x50\xc3\xe2\x97\xc8\x61\x71\x4c\x0f\x8b\x27\x08\xba\xb9\xc9\xc7\xe8\xf9\x39\xcb\x88\x9c\x5b\x78\x82\x9a\x6c\xeb\x0c\xf5\xc7\xc8\xf9\xb9\x49\x47\xce\x99\xfa\x3b\x49\x23\xdc\x0b\xb8\x7c\x33\x7d\x82\x3a\x6a\xad\x9e\x24\x2e\x15\x6d\x27\xf7\x82\x6d\x6d\x81\x80\x33\x52\xcd\x3b\x37\xe6\x38\xbb\x70\x55\x6b\x01\x03\x85\x0b\x37\xc0\x5e\xc0\x99\x7b\xb3\xfb\xbc\x46\x87\xf5\x7a\x36\x9b\x5d\x40\xff\xbd\xe7\x3f\x98\x3d\xc5\xba\xc5\xdd\x13\xf2\x98\x36\xcf\x6d\xf1\xfc\x1c\x89\x3a\x1a\x83\x4c\xdd\xfb\x58\xaa\xcb\x5f\x29\xd6\x50\xa4\x0e\xe4\x82\xdf\xfd\x0e\x1e\xec\x1e\xc6\xb1\x3d\x08\x7d\xd9\x4f\x21\x08\x3a\xf2\x27\x2b\xa5\x61\x62\x37\x79\x3a\xbb\x01\x9e\x8c\xc9\x44\x02\x65\x49\xd5\x0d\xf0\xf3\xf3\x3d\xa5\x93\x9e\xcc\x79\x0a\x41\x42\x7a\x99\x50\xb1\x74\x63\x19\xdf\x02\xfd\x23\xc8\x58\x7e\x5b\xba\xbe\x62\x61\xf3\xf6\xe4\xcc\x1e\xf3\x31\xe1\xbf\xf3\x7f\x46\x6c\xcd\x88\x69\x7b\xde\xcf\xa6\x37\xb0\x47\xe9\x5a\xad\x5c\xd9\xb2\x01\xbe\xa3\x73\x13\x20\x18\xa6\xa6\xee\x2d\x53\xba\x40\x1d\x6a\x56\xf0\xd6\x2c\xe0\x55\x73\x77\xf3\x8f\x7e\xaa\xec\xe6\x54\x4e\xac\x46\xe3\xf2\x51\xee\xdd\x68\xe3\x1c\x82\x24\xb6\x40\x3d\xca\xa0\xc4\xf8\xcb\x1e\x3c\x32\x61\x83\xe1\xbb\x5b\xb7\x5e\xf3\xa2\x10\x68\x85\x70\x0c\xfd\x07\xd2\xa2\xd5\x2e\xb9\x4d\xfc\xfb\xe4\x58\x0e\x1b\x08\xd3\xa8\x95\xfc\x6e\x32\x0d\x3b\x98\xfe\xfd\x02\xce\x8c\xcd\xe1\x85\x39\x9b\x46\x55\x5b\x33\xc9\x7f\xc6\x89\x8d\x8e\xa9\x97\xdb\x4a\x1c\x93\x5e\x0e\xce\xdc\x8d\x0e\xe3\x30\x3f\x9e\x46\x15\xd5\x62\x12\x24\xe4\xbe\x1e\x5a\xe1\x06\x0f\x3a\x2a\x7e\xf9\x30\xe0\x76\x87\x79\x36\x17\xca\xe0\x51\x1d\x01\x83\xf4\xde\xc7\xf1\x64\xa8\x35\x17\x70\x35\x9b\xcd\xa6\x37\xb0\xdb\x7f\x64\x8d\x63\xf8\xc6\x10\xeb\x5b\xd9\x0d\x66\xc6\xd5\x00\xe8\x70\x5c\xc9\xf7\xa5\xfd\xed\xf7\xdf\x8d\xca\xfb\x40\x75\xe2\x84\x1b\x3e\x32\x3f\x56\x4b\x1f\xfd\xaa\x6d\x1b\x53\x7f\x43\x73\x6d\xe9\x50\x6c\x6d\x85\x89\x3e\x98\x00\x98\xd9\xca\x1c\x0a\x5c\xa1\x5e\x8e\xc8\x77\x15\x38\x89\xfd\xf7\xd6\x24\xf6\xff\xa5\xe4\xff\x02\x00\x00\xff\xff\x06\xe6\xbb\xe1\x63\x22\x00\x00") func faucetHtmlBytes() ([]byte, error) { return bindataRead(