Site icon Renzo Mischianti

Aggiornamenti OTA su ESP32 tramite browser web: interfaccia web personalizzata – 3

Aggiornamento ESP32 OTA con browser web: interfaccia web personalizzata

Aggiornamento ESP32 OTA con browser web: interfaccia web personalizzata

Spread the love

ESP32 è un potente microcontrollore che può essere utilizzato per un’ampia gamma di applicazioni Internet of Things (IoT). Una delle caratteristiche principali dell’ESP32 è la sua capacità di ricevere aggiornamenti Over-The-Air (OTA). Gli aggiornamenti OTA ti consentono di aggiornare da remoto il firmware ESP32 senza doverlo collegare fisicamente a un computer o a un cavo USB.

In questo tutorial, esploreremo come implementare gli aggiornamenti OTA su un ESP32 utilizzando un browser Web con un’interfaccia personalizzata. Ciò significa che saremo in grado di caricare gli aggiornamenti del firmware sull’ESP32 tramite una pagina Web ospitata sul dispositivo stesso.

ESP32 OTA update with Web Browser: custom web interface

Inizieremo impostando le librerie necessarie e configurando l’ESP32 per connettersi a una rete locale. Creeremo quindi un’interfaccia web personalizzata utilizzando HTML e JavaScript, che ci consentirà di cercare e caricare i file del firmware su ESP32.

Here some common devices ESP32 Dev Kit v1 - TTGO T-Display 1.14 ESP32 - NodeMCU V3 V2 ESP8266 Lolin32 - NodeMCU ESP-32S - WeMos Lolin32 - WeMos Lolin32 mini - ESP32-CAM programmer - ESP32-CAM bundle - ESP32-WROOM-32 - ESP32-S

OTA (Over the Air) update is the process of uploading firmware to an ESP32 module using a Wi-Fi connection rather than a serial port. Such functionality becomes extremely useful in case of limited or no physical access to the module.

Gli aggiornamenti OTA possono essere effettuati utilizzando:

Prima di tutto, controlla il tutorial “ESP32: flash del firmware binario compilato (.bin)“.

Interfaccia web personalizzata

Custom Arduino OTA page

Ho già spiegato come gestire pagine web e come fare una chiamata REST, ora andremo a gestire l’endpoint esistente di ArduinoOTA con una WebPage personalizzata.

Prima di tutto analizzeremo la pagina web originale.

Descrizione della pagina ArduinoOTA originale

HTTPUpdateServer wrappa l’WebServer e aggiunge un endpoint in GET con una semplice pagina in response

static const char serverIndex[] PROGMEM =
  R"(<!DOCTYPE html>
     <html lang='en'>
     <head>
         <meta charset='utf-8'>
         <meta name='viewport' content='width=device-width,initial-scale=1'/>
     </head>
     <body>
     <form method='POST' action='' enctype='multipart/form-data'>
         Firmware:<br>
         <input type='file' accept='.bin,.bin.gz' name='firmware'>
         <input type='submit' value='Update Firmware'>
     </form>
     <form method='POST' action='' enctype='multipart/form-data'>
         FileSystem:<br>
         <input type='file' accept='.bin,.bin.gz' name='filesystem'>
         <input type='submit' value='Update FileSystem'>
     </form>
     </body>
     </html>)";
static const char successResponse[] PROGMEM = 
  "<META http-equiv=\"refresh\" content=\"15;URL=/\">Update Success! Rebooting...";

Qui l’handle

    // handler for the /update form page
    _server->on(path.c_str(), HTTP_GET, [&](){
      if(_username != emptyString && _password != emptyString && !_server->authenticate(_username.c_str(), _password.c_str()))
        return _server->requestAuthentication();
      _server->send_P(200, PSTR("text/html"), serverIndex);
    });

Descrizione degli endpoint ArduinoOTA originali

In POST controlla il nome dell’input (firmware o filesystem) per capire se il file è per FLASH o FileSystem, quindi carica il file e il servizio di aggiornamento fa il suo lavoro, qui il codice della POST.

    // handler for the /update form POST (once file upload finishes)
    _server->on(path.c_str(), HTTP_POST, [&](){
      if(!_authenticated)
        return _server->requestAuthentication();
      if (Update.hasError()) {
        _server->send(200, F("text/html"), String(F("Update error: ")) + _updaterError);
      } else {
        _server->client().setNoDelay(true);
        _server->send_P(200, PSTR("text/html"), successResponse);
        delay(100);
        _server->client().stop();
        ESP.restart();
      }
    },[&](){
      // handler for the file upload, gets the sketch bytes, and writes
      // them through the Update object
      HTTPUpload& upload = _server->upload();

      if(upload.status == UPLOAD_FILE_START){
        _updaterError.clear();
        if (_serial_output)
          Serial.setDebugOutput(true);

        _authenticated = (_username == emptyString || _password == emptyString || _server->authenticate(_username.c_str(), _password.c_str()));
        if(!_authenticated){
          if (_serial_output)
            Serial.printf("Unauthenticated Update\n");
          return;
        }

        WiFiUDP::stopAll();
        if (_serial_output)
          Serial.printf("Update: %s\n", upload.filename.c_str());
        if (upload.name == "filesystem") {
          size_t fsSize = ((size_t) &_FS_end - (size_t) &_FS_start);
          close_all_fs();
          if (!Update.begin(fsSize, U_FS)){//start with max available size
            if (_serial_output) Update.printError(Serial);
          }
        } else {
          uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
          if (!Update.begin(maxSketchSpace, U_FLASH)){//start with max available size
            _setUpdaterError();
          }
        }
      } else if(_authenticated && upload.status == UPLOAD_FILE_WRITE && !_updaterError.length()){
        if (_serial_output) Serial.printf(".");
        if(Update.write(upload.buf, upload.currentSize) != upload.currentSize){
          _setUpdaterError();
        }
      } else if(_authenticated && upload.status == UPLOAD_FILE_END && !_updaterError.length()){
        if(Update.end(true)){ //true to set the size to the current progress
          if (_serial_output) Serial.printf("Update Success: %u\nRebooting...\n", upload.totalSize);
        } else {
          _setUpdaterError();
        }
        if (_serial_output) Serial.setDebugOutput(false);
      } else if(_authenticated && upload.status == UPLOAD_FILE_ABORTED){
        Update.end();
        if (_serial_output) Serial.println("Update was aborted");
      }
      delay(0);
    });

La pagina esegue un invio senza action

     <form method='POST' action='' enctype='multipart/form-data'>

quindi se l’url della pagina è http://esp32-webupdate.local/update il post punta allo stesso url, la differenza è che la pagina è arrivata in GET l’invio dei dati è in POST.

Quindi _server->on(path.c_str(), HTTP_GET, [&](){ serve la pagina web e _server->on(path.c_str(), HTTP_POST, [&](){ gestisci l’invio dei dati del modulo.

Il POST gestisce sia firmware che filesystem binari,

        if (upload.name == "filesystem") {
          size_t fsSize = ((size_t) &_FS_end - (size_t) &_FS_start);
          close_all_fs();
          if (!Update.begin(fsSize, U_FS)){//start with max available size
            if (_serial_output) Update.printError(Serial);
          }
        } else {
          uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000;
          if (!Update.begin(maxSketchSpace, U_FLASH)){//start with max available size
            _setUpdaterError();
          }
        }

e usa il nome del file di input

<input type='file' accept='.bin,.bin.gz' name='firmware'>

nome uguale firmware per salvare lo sketch compilato binario

<input type='file' accept='.bin,.bin.gz' name='filesystem'>

nome uguale filesytem per salvare il file system binario. Il caricamento è gestito tramite standard multipart/form-data.

Pagine web

Per questo test creo 2 pagine web tutte in vanilla js e CSS.

Puoi trovare un semplice progetto con queste pagine qui su GitHub .

Scarica il progetto con il relativo link o tramite client GitHub.

Nella directory principale del progetto lancia questi comandi

npm i
npm run dist 

Ora puoi trovare nella directory minimizzata questi file:

Il risultato di queste 2 semplici pagine è questo.

Versione a colori

ArduinoOTA custom color web page

Qui la pagina

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload OTA data</title>
    <style type="text/css">
        * {
            box-sizing: border-box;
        }

        body {
        @import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700");
            font-family: Roboto, sans-serif;

            text-align: center;
            min-width: 360px;
        }

        .button-send {
            width: 100%;
            display: inline-block;
            padding: 5px 55px;
            font-size: 16px;
            cursor: pointer;
            text-align: center;
            text-decoration: none;
            outline: none;
            color: #fff;
            background-color: #337ab7;
            border: none;
            border-radius: 15px;
            box-shadow: 2px 2px #999;
        }

        .button-send:hover {
            background-color: #2e6da4
        }

        .button-send:active {
            background-color: #337ab7;
            box-shadow: 1px 1px #666;
            transform: translateY(4px);
        }
        .button-send:disabled {
            background-color: #9c9c9c;
            box-shadow: 1px 1px #666;
            transform: translateY(4px);
        }

        .container {
            padding-top: 80px;
            display: flex;
            justify-content: center;
        }

        .form-container {
            min-width: 380px;
        }

        .progress {
            width: 100%;
            height: 8px;
            background: #e1e4e8;
            border-radius: 4px;
            overflow: hidden;
        }

        .progress .progress-bar {
            display: block;
            height: 100%;
            background: linear-gradient(90deg, #ffd33d, #ea4aaa 17%, #b34bff 34%, #01feff 51%, #ffd33d 68%, #ea4aaa 85%, #b34bff);
            background-size: 300% 100%;
            -webkit-animation: progress-animation 2s linear infinite;
            animation: progress-animation 2s linear infinite;
        }

        .input-file {
            width: 100%;
            border: 0px transparent;
            padding: 4px 4px 4px 4px;
            margin-top: 20px;
            margin-bottom: 20px;
            border-radius: 7px;
            background-color: rgba(51, 122, 183, 0.3);
        }

        .additional-info {
            height: 67px;
        }

        @-webkit-keyframes progress-animation {
            0% {
                background-position: 100%;
            }
            100% {
                background-position: 0;
            }
        }

        @keyframes progress-animation {
            0% {
                background-position: 100%;
            }
            100% {
                background-position: 0;
            }
        }

        .tile-container {
            display: flex;
            justify-content: center;
        }

        .title-image {
            background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAch3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarZpZtiM3dkX/MQoPAf0FhoN2Lc/Aw/c+IDNLbZUkW0+ZfEkGI4DbnAaAO//z39f9F//V3prLxVrttXr+yz33OPil+c9//f0dfH5/v/9+fMS/f/W++/lB5K3Ea/r808b3+sH75fc3CvPX77v2/SS2743Czxu//5KerN/3LwfJ+/HzfsjfG/Xz+YV52i+HOr83Wt8L31C+f/LPYX1e9G/3qzeMKO3Cg1KMJ4Xk39/5M4KkPyENXvv727gu8N5IKWXHS071ezMC8qvp/Xj1/pcB+lWQf/zmfhv9n7/9JvhxfN9Pv4ll/caIX/7wg1B+8376+Zj4ywennyOKv/4glDB+N53vn3t3u/d8ZjdyJaL1W1Ev2OHHbbhwEvL0vlb5Mf4Ufrf30/lpfvhFyrdffvKzQg+RrFwXcthhhBvOe11hMcQcTyQnMcZFovReI0c9rqQ8Zf2EG43s7dTI24rHKXUp/hxLeM/t73krNJ68A5fGwM2U6j/9cf/uw7/z4+5dClHw7WesGFdUXTMMZU5/cxUJCfebt/IC/OPnm37/i/qhVMlgeWFuTHD4+bnFLOFftZVenhPXFV4/LRSc7e8NCBHPLgwmJDLga0gl1OAtRguBODYSNBh5TDlOMhBKiZtBxpxSjc5ii3o237Hwro0l1qi3wSYSUVJNRm7oL5KVc6F+LDdqaJRUcimlFivNlV5GTTXXUmu1KpAblixbsWpmzbqNllpupdVmrbXeRo89gYGl12699d7HiG7woMG9BtcP3plxpplnmXXabLPPsSiflVdZddlqq6+x404bmNh1226773GCOyDFyaeceuy008+41NpNN99y67Xbbr/jZ9a+Wf3dz9/IWvhmLb5M6Tr7mTXedWY/bhEEJ0U5I2Mx073elAEKOipnvoWcozKnnPkeaYoSGWRRbtwOyhgpzCfEcsPP3P0rc38pb660v5S3+J8y55S6/4/MOVL3+7z9Qda24G69jH26UDH1ie7j89OGi22I1MZfer3FX+bYxk51rMyDaJ/LzXpwcW4CE+8o1vMFglo/pd/CeFNqQq91J7E4c95a+ryTAbZxbfq4+asYo1/rwrTr1BRNBdqt3tXJ/io3j/Run++t9ef3850pz7vX3YiGsgHSbquns9xqn/FQHLbjqFy5flwZbTO8e849TG0OfzLPinG3eXq56VCs6d4eziwOlJ21aJ6Dopmn2Y0xf788j63bOjWZy0lrZ8B42R1D1++gGRvzqbdmNzZPp9xsp0I5vFt2uyUD9rkEqZ5l25p+lWD4s1f3ny74k9dwhl1fDlWz66W+XUcWkJx5VaY3g40plrXijJQe1Xn7nidAeePuku4hI1cxoP4WbEk136O0uW2DDPl+wkjx0Ow+3z5XzvvykfnTh53cTsvctYaSCHNHyIy8dsytHt92icPcjr2R40GjEVKBHREduXUrca4yw6RQQqul3b3LLSdXY5S21mQkatMblEGX+ppGjqJp2IMaO2cuS1TPvS0Yw6UHbH0qOKa29Qqfpk/m6iz9xF0cVWaHm1Sj/cfYZC7Sa+9LXeVDEayZ9vHv9+b/5NX5/3DBn75C++llgXfIg6MFtsV7Siw280ZGlBlfIpghVQ1MXmqtTGYuTbOZas2zpjsbRcdQ556IEHdODwDGJle2yO9txdNWUU1XaazNTQJQxy9Cyjx7rOf9K+g17nyolS482p3G6hri8dxRfXFvEOq3Q//RtOvq01y+qYB865vSNxewS5jOuH5fe7nQN8iIvkG6N9os0x1U276RC6wDuuQeUP80T8821+d3idHPL//X13/diIcZak1jKn3MVyUzCGOFaox/oR3usUkHU1fQVgP/MhByALfo1DYG+dAUkx6sRB6kJ1N05ZpAVabxymnzRtpmjp4MZOB1gkmbFskZcujezaJC7JAIb/cJ3JYCg72Rof8EwU34yWAyqHf0/qRLSOyuc+9bApcHc1QMiVrRVt2feibw9qsWANuAOcpOdZNmiuTE2jfwZFzBKQ70PNf/Q1T6xav7AVNJReRLbXesClUThlamUWOx0rD0MewYsFCgxGlxMhxVUqkUvybqvNGxGS6gpseotlItPi2UQYa007xvioYOn8T/0kJ02EEGqLIjrXJQ4rNtR1Lh4p1rBacIXZVmPGFhUL1qMc1P5NZ7XWTCX73phY8MUMOoPV2ncdCeEAQtU+9ACdHB5SJK4uKZXGgkZO4OH6Xb6Oy1fTSrO41NR95k9NNxzHkdqs1EdqgCYInP5yxjXaV7XqAUAwM+ChQYUcv07tlM3iN5UDaLujp0/5HMeJU00uZWwN3aNe1Ao58zpHJaH5lvMfeCjjmwOnUtWoSPCUVJGVW7c8zSF5Tw63HUSaQFEneuVOOMBSTZ5K8D6W2vDSP6Ja+VsE0BzzwgiON2Y0T0xVgbYC9pTN9m07NXyXGsTuUjfEC8NkgmGEYKwC5iTIvdE0en2/x0G/q5a7aHR7n09MqAKTbkU0Gl+V3jaDxrd6Vgh0jqyAaNsM8CRa5XDpyaqNCkF2cAunERgpEWXZG4IOvweZMUkaRDRHpbAXaieWds50BjUGgGxINbBB9c2CkcTxkgic6xV4SVRhvUBuU3BspkDZp1+05FxjMmyChVOFOl+Q+q9qsUvDGRfywE2nRQLuW/DDwHK6h9C/VBBYoALVQA3IFQGx6yno2MnymxO+tWL1IIu+aLEndUxZ5wu6DisarRVPV63iAISFJoNod4llQbVwZkEEmmgj1whOetiW7e3nUEL1q815LCmDaQxSA+UUQoEB3gDzmJP5sUdxCTrD2sI/ORI0i2YRG9SCW6Yz4lrszpYIQZeByTIJ8mpdAoq0ATkXOwr6004CGGACFB9f56o2yvJHl2Bbybs9MSsfV8YKhQ8vQ3olGEueHQOhiPk7Edc3VMQJbuoK5xK1QEoeT+xSFImdia/B+4rAo4sTP0xgRS0FTBuDtlz7wnUyui+jNzfF9EthSweezjOlyAXhoZXRZrYZABvIHuM80COx1KmnKyPcmO+hol2loxPkYVVRyDhFPmRswrdCJF9dfR18H04mxosUFcd8dKwfEHx4HGNsIJwnULMEFdIe1LlasmikP2Jv6VjQbrJLKXirrEJUBiNDwEB/AcAgZpwOSBj4wuxzYxnosMh847otrVhrjjGig/gEPU+G1SbH2jaHYAXRKlRdgIXyFQAyn+g/qBy/aDqN3fp3qmXEpLsWP9MX9i+wJCBumsijNDrJ4tmc8kaZqWzYL6YViVuNULjDvbgoqPNZQuZV9pBfQh6sD5DnkHWkdgR7zAQyIysAMYqVg8VUBaqM/oj1HMfRUbqZVFDMlFoLwTigkrCidgBak7yg1o29mvVXgg2HFxkEXN5ZFumVzUQ+VMUJGR4GAnfrVR9AI4V+Rl2qgx1CfCQ8fg6U0GV1DNN1LrE6d1TA0/5UN/pj0n3kSSxbrd7p56on2aMdiS0qKJmaUMX5RfP4h0BNNhdHEvzF2lkwq3OS+U6CpaCmDzG4dAD8GR3aNVD3RvVDtoZeFAASNNwUzZS0WMP4dZQQP8yu1YengP+YPQGnzzgLJnI9BrTZ3PcKxPp5+021+V3e4PPuirMe3kqUK0MP3pN17QQmdOJBOrTfuh2DHImGBmRozMMcINt21yj93DQjTUBMWugb+iUSIH32OEqRq6kqjHg50C0+oQ31+KtLqu9WXaq+2xmIlSD2qZsI8U0yvgzSB7fDNN2h7d3Al7spzakkL20B715LZWGyiS2sci/clQOwiKAp2SYRkEZArRhY9hiUTTonS7dZ/mfsVSMa0xTxdIe+olMTVkGjnpFDVsilbM8unUYS0AVkJCQL7UZz447gYJa7WjgQieQVRXEdNUfjSoG8lCwg8tGIGWMM8ICXhOAfhBOYlGm7BLZQFNdwRNxR92g+2hbCEWwEdAKnSldZaDsOt+DQpnWy/AClxPSqiTo+VDzCMzt0D3DCZGCcflbHyBGkJAw/xTI5EcnbyRQb6BMPCtHzsBBUEVQY1TkrJe43hhqComU7urARXCdXS/GWppr+TwswgS1Du9WjPoGRb2KUKfXm2GGiO33UuWhryGlFhO1M0rG+xcpCITegReY9qMoShGqruUMlIIqduilLXBUg0qitJKAbBNAVbbJB59RXnwbyijHfcEw/k4NTAMTocKyXMQONPI4ABoMqnAbrHfvbjBpVNQWvxaJ1S5Qs/BwaaoAR6yBugRKiVDWXoEA+wAwxEI5jEH7g9airSVjBRz8JgnNEKFPEkYU1vU4JpaJV9WPQTeDzA0Da1IY2mtr8c0Vaow6rMNwpQSUAKhQ5uUrglqqWvQCZ2CJQDp0dsDBYLwQrk1PAR4fUQ7oPVYYatoYZFkUtU7SQFkBs+INgO4D75rUsXmgnBH/6GQtH5yZaTLAWkXcpmmZnpUyOKva6iVUvbAvZzhkhbhXkX+E80HSYGqpNDcxXpYAQoYuGlMuH5DcwpskFMlow2PyqI2+fwGEyUoQeun8PLWZxVovm7OiqzjR0ajP+KsgkhMfKuhJVIImwRQPYJ3+QId+EdoE+nAREBkJDrKwNVnn7TFQclTt1WY8CISpqcO+Kdu7mUgMLM1IUIwugWZRhlS4LeT/GjuAWZHInTNHeGKlwsNpUGToMmHdCF6kjoAbfYCQhiWjEinEYagL67pB90PrAN3WhxGAma1LIaBuqMEFyWNisSGN3gKycSMQ4xYMHkowAiNh8ujYS7BlrzKHczGVhWiEiNGyoNCQwuiA11Pr158Z+YCKqtQr2dC6IcmIV9MX5PF1CSonFYuFC+WFnG3kOeeh1ZijBCpA4/RX4E38Uy+UZqCMkanA7UoVVygQyNT4ZKJaNm0sG8vDB4F+Ff9w1svcF6LTUzhTO2iANZI09vnsxHqeNh44poKiu9UABAoFt3bxEMB2sA5Io9xObyaev8mH28uCBTwBgn1MffgWQiyR8h1nlem3ko4EfnsiFJHgMnHIHgd9Dc+a1nBnhYFVfsAGCVlbj3oWlJmNWetkID14CPToadj3+m5ZExGqhBkeGsKJP2BG8atom+uLObJiDRACR+B+t+eQpiQHjZpUqhkGq0OXvO0uR2B3kWwTzGhH4BpeSQZSL5ZtUSMSsfGYK4AOYowl0WfqOiQSmmY4n0TMBLoPEQmwh8AtsMXq7zGHhHoU/6BDHhWngkRmCXUi6GaPdZHa080UMchaMdPngF2QUQzn/AmCMfOiPuF++hTSqq+TCOtsVotbXF5B+a00w3Z8uqIHhzcCASjpGdGQjVrvUlgCtYkipM+yw2vRIdAPaKhIesM/3dco7j+SLFBupDFWrQKKcEnkV2teVxGI82fX7h82aZl2bV8RxJ0Pmqm1oUr5ZYcMhgTSkzaDMq1llMWclBQAQkTKtQ6X4FPYKjR8IelN9DOeLThtudk6DbdY1jsJR7T6ooWEr7wNgywpqzlDzR51QwETpPYZRwKgEL7BwptwufAxHYHLYXmRXE0bKVWD9Yjo8aYDuAB9V6dDgBY0UWLlGZMrc4P4IapMfhARJNw2Vv7IwnWBIcwE7kgSbhRRVIVnQFAxwMtcocg91hUvFLD/wYzUoNdKxDTIQzfDJDJiCjaPyd0HrQ9Hr/gTv9MFkOXCMsWGSnSw4H4p+GtrcvXaOkTw4eRB7xP73inLQyC5irVTn/w9IVVJ8vFa604z6lFd6wovE7LIAZAjEmbU58drwkV2KatqP8mPkCEDiLAozb/2FoFL/hWPOaBE/Z1HVumzS7UCzDjRfu3ItVDy2+JWfti4IYnzDOIXlCA2EsUZdJ9oQStWqXhYKuKmKZYt6HEAJNE224ztFGk3ZlojZLbyzBfCfVx0Na4nrsg6KSZ93l2dgQjiMwn8xbVq1XmWyUZtCFNFoLGT6HidNFObzERa0nJem38wzOM6ExHP9RC01ILDFVCqmppufBIdFZAgUm3pMh7N5Looc0AWPmBR5HhvgFyuw7WKatjQKfcCqFKnu4F16oRCfTOs6U0PmC7i/YTBk69tjV5KjWpbR/as7qYzsXYZe4LPjdR+QIHGV9cElR4UQTuSJ8Fc63bwqE+kmftDgBRARMzdnQydpBl0c5Somcyc0N1UJrqwotxXVkaDrW6cBFTBTRJDEVR92pJSNYyeISQnp+Vg60lCS43FR25p05TozqUxK7Niphq9UxZHADVyKpTxlcGdCK0mGBkdveAEDh/QWhEpWK1opRoB6aOpJy9LWOSTIoRhsjHS8Twa0hJPIjL2qNcUuITYHuLiWgAFf2uDznRWngMWKvTjHORJvyR4PnMJCUlPvJaP2poVgEgTT5QEVgsrYQWeBVfRruhxjC2lvZMPmPTO3+QWrDCq0woeICk0ZErXDnAVaeQECcnf8AAt4RQ0PERHABtrdU90cLky7QONbZaqFosoLEDTIuVauArnEQ+ATd1DqBzwYMeEiYVTH7noUyHKXgi4AQ5aseWCb4qJVpeuxD4gXEwvOeMog0PyzOCAO0tLDKrfBOEikjAaRytIaI7qQxBYsYudIEEXmRp91R9n7RQmRbFDCFmLZXy5dORQkHLAXUwES13APk0dtCpAf4kwA3oxBxbGVqxHnLZZjKzdZ9K7+FIj3S8lyHvGjaYjmIBmZCNgC2x17rO9lruxvcTybcphu5qt+LxsLQgdU3cE902QDJYMZ2sReaFmtnQClXiJc+zXz6KMx0svH+3l9u1xEoRZK3J00Flx8go6STthCn5eEV5uI1KzBExuN1bxwXHQAPomDHh1mj5NrQ4SM8fz6dFcTeQWG6Prov++8R5kuAGkkWwAzUINRQTbp7koke5K6nijon5q2Xnxb7wLRAEwMallycNaxXxS8a06w66l7sSVuy5b8ANthBiDAi0rtD6A8iTRy1lEGHkDaquUGBWr3Yxk1aXYREunOSi7nGw2JcoYpHpEvpqqh+hJzhe7gLuaBoKPw1ZQcnn3Pvyx2bHQkwtEYAdbaMAUFz1kP9GxLQfDXAxWqj+aJKVeJq6Jk/MZQyUt9bRAXd/8zPHny6yoRWdq22jpV0gdJ2EG/16IzlffHBNmqINUQHBRjejrrX3TR01mBDDG3pTevGUMp90Ih6eWGfhncn643zhCHvbF1TgxbZhWRt8mRdynKmZSBbEA/CnWgMMjzOgkbV0Jr04wMgFAM/aY0aHNwrzaAtISJwSBcCouoOrUmQcPEzpHwlwR7NbHx9rUI3mH7JnCCJYmI6eWtsQH8ue1GML23Fcs04kszBEHVCYi3oCLzERaM+waz9GEcPCyGyB5kAdMcJA4iGswuR3Oegc7YzZyjVRcG8VDi1xtUg5tC2ITZQVpRDyrXAvUgNeHAX8wV3Mqc3R1RHsBBnDsrUZtzB/XUdOUDPQP7RAqVAIe1G6x+NayBSaAUzjqV6yDjRZb0PBidB0GuSaph9yBr4yao6a0OYXsnb7Z5hb9DhmtCYyFYqT1JTGCCRKSw+uBIl87SdhHng1AL7VqE2gI4xI7YDAjIsAUjiksRzQHLUy/KqRAscOIrHcudx84qG91kihGkwymAWoPULQyjNw2L0KhBuA9kFmivhboNOTTlRcHa0ynRXRqYqaG2gCFyw6j9FhQVCgVBNgo8UBepbsDK+zqFp80z6DzP3JSFfDikKZO40ataGBlsBcIZUjwyY+qNg2k/AcjOvcph+8O9DNHUaDRv1bCTMG7XIUMpdBLTJjGUWDKAMoEoXpmYJLyIGS4tKmCc5NOhdTY/ASSFuTFxkch0aSkgsi0XgRxwPxXrSbEtWlC/VES5Jy7fY3DNbUQjcxWjvlBdTyKAQ8mI2jw43824NV6kGsP/6R8s4eCOuXhsgLrbtXWtxsuaOTbfIqA9X67kfMPEWg3EytpiJpCRx+iQrdGzm9podx8QlwNc7garvi6txIQ+Bws6h9NuQPoV9X5nXKACEUl1YYMUGMomlPDUWsoyAwCZCKVdjaSgf8GSJNih5ETSHW0W2vYWzWIBWWdJIE2s0tatFtavVD3qG38fHaOExS68CtrIOuYx3tJeKCg9zYoR2QLgeXlsB6LOK6JMF0Gqhd+n0Qmi/tePBiOyaEHgZIB0iL9mqS3dqoFZxoZXwTt47cRX+2LonCIwBfHcJGCILuTUolOp2e2V5Hl3A5fSZAPR8tTL/VAEaE2j4PpMU29VytcUbtBwhvYLamvX9raEjUO53Ua9kaC6WGT4XHDxJE6gC/j4BVZwKQb7+Yh+BPjumUOWSJegfDXcxhxFEQ2BAA/o8ITSyeFrIJI8AUKWivzUOEe/8jjpAI7dNJVyIDddxuARBoIepLFga40TGooU1WuB/lmogdFaFjBNpBJNcS6MhNPt8O74id3jrfIFpAx2kvul0ta9EhOus5ULbUGGY3am8QcYFcgUyrzs1it1FxdTvIu8oSB5R0xMajg6+p2jJQ4QEq7RdQbKBwoO9EiqFQZyL8+M5fIMyfYjshXApLCNG3To6dnWBiYNlAAOgJmiOFuC2qhZpqRUcUmkjmgBKIzQqXMbVLOuYsMQqXNv3wXenB3TTMq4EExABkQJl3KKgbsSd8HckygKmi1Xr8mvYvRLXXk56UtaQchCeABRpGzbHgRvoGF0+r19DwSyCWFh9P/6jEfXRiHFnDvRs2YKMbj0qAgRF/6QUY0jD2V4dKV9Ju3aZ4eCQMiN3SGSPD25FCrCiuFfdRkApLCyKBbI58NE99x3o8VDjvai98UfjAfRKISjHvmIF8UDC7t/lQ/C5wI14VLqRiB9yJhck1xs+ewKDkEuz82fDW7gAWmlrk38RTi0Nu9H94UMhQTg3NH7WtF6orWkOlUqXSi/Y8Eb9X4jdF+XDGIh7ITcWE/npVC+QUrgBq+G4UZO/ltHj5tunw9cCUNl+JFuw7l/aMKD8dKaTXNzI5o44aKMm9/Vf6as9d2xgOqJ5DKASaoy2UpQw2A3BVx0TkgUgxzTcmzcBUaDOte2tZT4sdJ9LRXA2LbG1X9S1pD7sA5Vp+gHbaW2SUidRBF7XJhEAQJloc0fGh1Ki7TfGjGUDIwNcLxYmWKloeQ08nqXQ4DsMOCaG10AA8hX6GmHRgF99VB0HQ+zhF2rY6hQ3xI4kgivNPakUUiVbF8sYICCvAVSZ+pPikf+Gim5MgEweGBEPlO7D4SGkfnRAOWgqjFL/kAPfEjmq4QlGp4vGB34YtkxMZdWiD1a5v2c0XraJTUFow7LtJXcLWWGZYFTJqOlOmBTGkhI4vS1lR+p0q7khLTzhIuYNndGbnuVEGQNnHz2k6NAEarL28yUTk1rlep+lSG2S5nHf6TqIUOl8ONejPMxFRNz6+xnrzfYvsxPRHIT8xg4dA/RRpna5l1vGgSjvoozhKQrIWrlMX8VEerzFB+/R3zm67v3zI+3St/ICxWm4hk8jhhe2mONZ5pzQw+kgT4iPR1lRGtPpAkw+04zaGq5NK0rwUaU3qHZNR8TqRo9MGNB9eyOERqN7py1uFJdoFXASId9T5ziDVX6VDAOelRUwpEC19rlJRwbvrkOrbhTCB7+jvsFWnV7T2Y1aogJhrUU1VoJheA1KJJDL1QPL9jLeyfOBmvJ2aFneTtffpi1oEW7xRCmtq8wio0toAqXsbfQANph2FriOgyM7Uok0d0WAEYLbWR9vATud3Jq1C6x0vphMVAEFrcCbdiHbSBiCWQXDWUCSKrT7VRrzOazhAHKYUzr8llr9+VP936b8XpUKw/hfxeNzp+7nKeAAAAYVpQ0NQSUNDIHByb2ZpbGUAAHicfZE9SMNAHMVfU7UqFQc7iIhkqJ0siIo4ShWLYKG0FVp1MLn0Q2jSkKS4OAquBQc/FqsOLs66OrgKguAHiJubk6KLlPi/pNAixoPjfry797h7Bwj1MlPNjnFA1SwjFY+J2dyKGHhFD7oQxAgiEjP1RHohA8/xdQ8fX++iPMv73J+jT8mbDPCJxLNMNyzideLpTUvnvE8cYiVJIT4nHjPogsSPXJddfuNcdFjgmSEjk5ojDhGLxTaW25iVDJV4ijisqBrlC1mXFc5bnNVylTXvyV8YzGvLaa7THEYci0ggCREyqthAGRaitGqkmEjRfszDP+T4k+SSybUBRo55VKBCcvzgf/C7W7MwOeEmBWNA54ttf4wCgV2gUbPt72PbbpwA/mfgSmv5K3Vg5pP0WksLHwH928DFdUuT94DLHWDwSZcMyZH8NIVCAXg/o2/KAQO3QO+q21tzH6cPQIa6WroBDg6BSJGy1zze3d3e279nmv39AHnycqpvRjX0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QkHCiIwlmaJAwAAIABJREFUeNrtfXl0HNWZ7+9WVe+traWW1C0Jy7awje2ADU4Am8XhDE7MljCEmUkyMDxCMsMbsgxwgDfJ43FyHkwIw0kwyzgkjAk2xCYQm8XPC2AbYwxeZONdmyVrl1rdrd679vv+6KpSdau12AgjO7rnlLu7+nar+n6/+/t+33e/WyY4T9rst/bCVnvR9i/676ip2EdHr6x69HwZN+68+SFFpbMYu3vpF/13qMAXAjhvAMCcLz+ELSj0gX7xf4cqihPnUTtvGECVJA8D4IsGAVWp+3wCwHnDAFQQLjobDEBYZgoAkxIAsjob5GwAgHNOAWBSigDmrBiGWG1WYrVNaYDJ1q4osjqtLk0PUICQjB7QvYKqM4XpkdL851WaLSWo6fMMx+G4qxCyODAFgMnUglHgu7WAohlQ1Y2sG5Rkn9efqxoQFO25cT7nUdH6hLpCUM4f3jx/XMCppKru6M/8IJLvoKZHmn0eefrkbfEk6lvDIJI4BYDJFwcq8t5BoCPxxUSCFlXGJ0d6QRgC8MKUBph8YYCqsgRY3wP86wwKJ0cNF6D7cApAJUO+n4IMuQEMuQTV5C5UknnvkyO9SEoqQCnU84gBzhsAUAoZAGQKNPSmUaby2eKO6oKOZjMEHQKJ3i+bQShsDEFzIAULS0CpqoKqUwCYhAhQDV9OAELIkKm1qIACIHqygGbAYOQOdKuTzClq9CEZZBGDaM4f659XAACRDTlAAVWb8vq/QwxgNi6GsYTR39RHpSSLaqYAMIkZYCjGp6DQWEALA4cZPet1NkjMgFDNRqdTDDA557+mAaDF7KoBghwNkKsFRjC6+bVqtj+l8hQAJiMAQBNmBjCyeTQ3+0dHoH1zf2rqnwFUPqaZAsBk8gAsE9VUnqYB8vv/0YxOc6ICOsQuUy5g0jMAw0QNEQhANRl+GLXniL1cgZj1OQxlDbXPTbmASdkYJjakAShUlQ6b6Wb6pzQTL2adM4yvg4cMhYoqBVgAU2HgpGUAITcMzJ7dZLgrUNVhgi8bDBSmFIB+cooBJikDxA0G0GL3bL9Os2d4PoGYAwJoICJ6dihzdgoAk5IBCCPqlsvk+odcQN5wMJ/BTX2ztYD2RZmiwykATFIfIJqZWlFN4ZzZ6HkzgNkLR1nMQM0ugMCccZwCwOSiANEIA2FKBWcldmheBsgOCYczADHDZSoPMEntb8rXU1MeYLjKp5q6z9YDI+cGSHYakUwxwOQEgCil4TIDgOaf5ZQYGYDhopBkAUWHjnktgBAyxQCTsSlUFjlTIkjRFoOQRwQOf65FDAZoqAkMVCsV01NCmALAZGyqKqV0/pYp0VxAbno327DDw74h2jczAzGnBskUACZlo/JQnZZCqbGAMyy/n8UGdGj2w5wVzBaQ5hIhQqc0wCQFgCwZbEABhaqav6dDj4ZRaR7Vn5s61tki4wKMeJCZ0gCTs8lSGiYNkMnYU9OsHyH7l7NqOPQeMdjC7AIksOcVA5DJcBHF//gT+O/5XwOUAqCEAWEYmGeeHtep+nMVoCpACacv/sdArCUVNVYbJZhGkihORXQJl50KHqYJRssJ6CKQojGYAEMI2oJB2TfYyVOWBQijFyCqmUN7zbAAwwAMB7AcwFpAGQ4gLMBxIBwnJw5+5O1Y8eMpBgAAz1U3gPNUlhnbdLKmZw4AVFU7qOmRgpUkBBigRtZ3AQ358+HUfiaJIGBAZUFAOdZmc4NoRiYkA4RMjKgdLMCyQwCwWAHWAnBW7bUN9tqLplyAcREllabqC5JTm52nbNc4R7IEWpIQpEnGgIopj09z9wjS/Gng/GEiRUpSoAIIKypsqqJ1UDNfxujlxsSsFDX05NShARprMFCV1BQADBOJ6ZxCPLPx9elKhnkuatRwU2NLVz8LzFJIVlVwNqlkZwYxrFBkKErgZRV9KRkOliCgMkOuxywjKQEhdLhHNdiAybgElgM4S+aRYcG5y8sBBKYAAICtKKvNzrCPxAK5r4lhBN3X84QgTgC7CgMceUXfCOd1lxFIy0hIKggIZIYiohKwVAVRVQNEoCrAAFTfkciQIWNrvh8WK8DZMs9ZSwYEDAu22HsJgPemAACAsbgXZlMCTPu7tUd9t4ax80PvQ4zNHDokUoSaFoPoEFuYKT/PHgAASCsU/SkZqko1VqcQDUDqDJBN50NG1wyc+8hZtcNigEOJhv9mCgB64iadvoktGiFGMftXs5UZzS0wJLsvAAUECqUgIKYcAB0l5AMkhSLEK0jLapY7HwKlCqhK5tCpnWUzhrVYAdZqEns61XPDgaG5ADicc6Y0gNZcbmcla9qnPETTBGD1F8TM+FqBBmNs4reorLZYN1QWTnKTPzTfpg9gUJARF1XDbQ+l/c0+QgUUGawqw2a3AxY7YM0clLUBHDdkYJbNhH0MO3RogKDaa6a4xDMFAF0DHNhyIxYskQTvTI7kev084o/kpGdBgSI4EEkAvGZYhVKjnDuv4ANFQlQxKCjDRHyWDkFmnyFUFVRMo7CkHHJxWcb4loxvJ/qsZjR3oKcyDFelMRaT6SINnAR/aOfVU4kgU3POvxbTvncHdX77TsiqJYvSkWvw3HOaVYkKnEwDs5gU/AP9RkQ51EWr61YpgrwCUaXDB8CgEWqoeY4jOBGKoUROwVtaATjcGQbQqV6P+3XXQLTwUP9y/a4VrIyBja8g8MbLRD720VQmcBgTXHKdo+SC2tQF/3o/5Jp5ORsyRosjh2wnS4BNTMM/0DsMAACQkDKznuiGNqf9crSEGQAn+wZQ6y0H3MWZ2c9atWQPYwr5MPzQACD0NqDzxV8jfapxoXp892dTqeARQfD1a4nVueOC5Teg+O9/AJHYRmWALJehvS5Op+Hs6clsETdVBg0KJpFHxzEyWh+OBRKMA9bSCsBiAVhmSHwyeUbSdFEMRATWr8LA5r8AkvBz5ciHT0ytBYwFgoXLfgmr7X97yrxY+j9/DsJZjCk+agJHm+4KpZDkoWSNpGSEnqLmoZMRwTD0BscwcFjZ7L7jABFVFTT88deI9nYCVF6jHNx2x2Qb60kJAABgL/vmnwjH/YPHV4Mr735Q2+qdmyykeVO3MO0JiJ7OrJ/g1r5uBZI9raCy+K7StO9mpBOTb5wnKwBoLPgm8VR+LZ1MXhjtbEXlJZcPK99W6VD1jprznqioCGtCb/x/lOZMCXNMSIciAzL8fUJhuuUYi863XkS8vRFQpF1qd9v1iAUm50SbrACAxAMUrzEFJcuSsUhNMtAD79xLM4Y2Vf2q2iYQ/X4ACgXiooKYoJomvEkJkhz+pqNkm8+EMRgWvVteRazxAAhVP0M8dLna3Thph3nyAgAAEoMgRRX/Tay27ySC/eVSIobSC7+igYBm3egRAAQlI/Rk1RTX587q3En9eYw9zPgMBj56G+EDHwKgTWo0NF9t/WxSD/HkBgAAGuwEHEX/xThc/xjt7fRAkVA4fXbGHZjCv4SkZBZvcjN4ZKwwMofih31wtNfmO0sRhOu3YeDjdwHQHhodmK62Hprsw3tu3ChSbdkPkoxeaC0o6un67FP0HNwNlWaWfCVVxaAgg1doJmOXy+V0vLOb5DFuvjVqmhcUseN70b/9LwAhYZpOVCmth8+FoT137hQqHtsFRhKrOGdBpGvfhwi3HoegUER5RVv5047cm/yMiQaS/dlR/QHN+zrVfhw9m9eAEJIAnypVGvacK8M6ecPAkZrrmtvAuEuSAJwVX78NjsoLRrYRwdi3daOnMQrm7KHW+N5TaH99BSilIk3HbPKJPefUeJ5z9wpO7nwTSjToAsAHdvwFQqgvt9IjZ0aPMZPNIKEjfJbS7D7aIQR70PH6swClKuWT55zxzwkRmNuqq6tRKkUesMnppSm315I8dRyuCy4Ea3OcPvl9jps+yvEI2lc/CVUWAVlg5GMf41xs54wLqKmpgcPhWMVx3PcAWEEpkgUVCJfVgbFY4b/hTnAO98jUbfxi8rnv9qnwKbT9/v9ASsUBWZgtN+1vwjnaJj0D1NbWorKy8s92u30ty7ILCSGsbkirkAADirSlAMn2BrhnzAPDsKZVPjqBMM98lyqJaFv1fyHGQoDI/0hpOfAezuFGJrPh7Xb7Fo7jltGcGUuzb92KiGc64oV+WNxF8C2/AwzLja74xmKAvIEABaUq2lY9jnR/J4gqv6w01/8PnONt0gFg5syZsFqtn7Ase0Veg2uvaY5IG/ReiKSrDDZPOSqv/y4IYZA/z5ub+KEj6MOcwhAQtL/6FOIdTYAibaBth2+FqmAKABPQLBYLamtrYbFYjrAsOz/X6GMBgNLMWmGo4iKkHSWwl1ej8rq/G1cWiOZs/yX5QMEw6Pzzc4g2HQQUeQftbf06UlGcD+1LBYDT6URNTQ04jjvJMMyMkWh+PADQW7ByHgSrG64LZsF79S0Y6T93oDTPrh3zwOg6gmHQ8+4qhA/uBED3Ixb5Kg204nxpXwoAPB4PysvLyzmOO8QwTCXNY4R8Bh7J6FnPAQz4LoZksaOg7hKUXr4sCwRjGT5rcBgGgW1vIrDrHQBooGLqInQ14nxqZzUK8Pv9qK6uvr6oqGgfx3GPEkLG/d+wjsYIueeciQGkXWXgBwMApbBXThvqM94QkBAM7tmKvu1vAEAHTUbr0NuC862dFQBMmzYNVVVV97lcru0sy95NCHGcieFHen8YQ1AKeyKItLsMqf5usDYHrKW+PMbPFYl62MggemQ3ut/5b1BKA4RPVKGvFedj+0JdQG1tLZxO5+84jruLEGIdz+wdy8fne998/2bzeZm1IuSbDxUE3mu+Dde02fnkftZwyKkEwgc/ROCDdWAIQQkf7iISXxOJRCDL8hQAxtNmzJgBp9O5jmGY7xBCmLFmdL5zIxk136wfSS9QSiFxdoR9c0HBoPL6f4DDV5sHAARyKo5UoBvJUycQ3rkBAIVHHASnSPr39SiKUhePx9OiKE4BYBTDb+Q47obTMfZYAMinAfIBgFIKm80Gv9+PSCSCYDCYAYHVhUjFHIAQ+G66CzaPz/j1ciqBVH8XpGQMUiyE0AevA6qKYjECqyrmA1+PoihzkslkXBCEKQDobf78+fB6vTQWi0GWZa0m/+wCwGazYd68eYjFYkgkEmAYBl1dXZAkCaK9EDFvHQjLoerbPwIsNqQ1wxNCICeiCL7/J6iSiCIpBpvCD5MMOdcQUBTl0lQq1X0uM8KEiUCGYf6USqXmFxcXw+VyQZIkqKo6FE9PkOjL7VtUVARCCCRJgiRJ6OvrQyKRgM1mgyiKsFgsKC4uhpSIQk0lINoLEG86CJVwADJVREo6idAHf4Iq8nCLcdjktGn1l47kZlyEkPstFsv/tNlsmwAMKIry18sAPp/vBMMwcyilcDqd8Pv9AIBYLJYFhNEYYDxxvpkdqqurkU6noSgKLBYLenp6st4vLS0Fy7KoqKjAwMAAFFlGS1QE76kBsVjhXrAUBATB99ZATsbglJKwC3GolOa93tHASSkNq6p6jSiKx84lRpgQAFgsFni9Xmqe7ZRSFBQUwOfzQZZlxOPxUQEw2oJPPgBQSqGqKvx+P/x+Pzo7O1FSUoLjx49Dn4l6H7vdjtLSUqTTaTgdDjRERPCFFWAdbgihPkiRATjkNJxSArmzmJp2CI8HDJTSGKX0e5IkbTwXNMKEAKCsrAw2m42ORNPFxcWoqKiAIAhIJpNjL+6MEwD6exaLBXa7HRUVFSCEIBQKQVEUKIqCQCBgfMblckEQBLicTiSKqxCmNqR7TsEip1EgxTL/RZwJAPmuaSQmy31PB4Isy5MaCBMCgMrKyiqWZbvG8tdlZWXwer1IJpNIJpO5A3baeQGzf9aP6upqyLIMt9sNVVWRTCbR09MDWZaNPm63GyzDoNtaCiHUj1KaAiEE6XR6zPBzLO2ShylSlNJ7ZVl+ZTICYUJEoNvtfpFhmPmjZ1YzAxwMBmGz2VBeXg5VVSFJUt6++c6NdN7cotEoUqmULkwRjUZRXFxsMA8hBKIoIp1Owy2n4LFb4HDY4XK5wDAMZFmGoiinJV5p9u3kjc8SQsAwjIUQcivHcQ9ZrdYYx3F78/3mcxoABQUFTxBCSsfbP5lMIhwOw+FwoKysDIqiQJKkMQc9dwbm9tcHX1VVpFIpg/YppfB4PIhEIkYfSilkWQbPp8EwDBiGgaIoYwIgF4j6a83Yw56bHi0Mw9zAcdwjdrudZ1n2k8kAhM/tAiwWC8rLy8+oyI5SCo7j4PP54HK5EI1GwfP8qIIrn17IpW39tfk5AHAch/LyclRWVuLkyZOIxWLged7QFIqiDNMXuWDLNf5YzJUPQNr3ipTSlZIk/VQXyOckALxeL6xWK831gadLoVarFX6/HzabDZFIBIIgjCi48iWJRsoMmp+7XC7YbDbY7XYUFBQgEAggFAoZOQv9yP17DMNk+fh8Rj/d32y6dllV1f8WBOGfE4nEuQcAlmXhcDhoQUHBuHz0WEBwOBzw+/1gWRbhcDjvAkzuDB1NROayg/43EokECgsLM4kgRYHD4UA8Hkcymcz6DMMw8Pv9SKfTCAQCBqWfjsFzmWQEcSmrqrqW5/k7ziYjTFQi6CQhZIYe9+cO4pkAwe12w+/3Q1EURCKREcOz0Yw/1nt6CFtbW4u2tjbIsgyHw4He3l6DCfRkkq5VwuEwYrEYUqkUcvMeI/3e8UQTpnOqqqpvpFKpvz8bQJioVLAFwLJ/+qd/wooVK3DTTTchGo2iqakJDMOcNgj01G4oFIKqqqisrITFYoEgCCMOtPkx3zFSX0EQ0NnZCY/Hg5KSErAsC1EUIYoiWJZFOp1GLBYDx3Gw2WzgOA4lJSUoLS2Fy+VCLBYb8W/m/u185/TxMb1HGIaZZ7VaH3U6nZcxDLP2i8wsTlgq+O6776Z/+MMfoCgKQqEQwuEwurq68MILL2D37t3gOO6M2ECfHR6PB5WVlUgmk4hGo+NOG4+rjExjCp3elyxZAp7ncehQZnu3IAhQVRUcx8Hr9aKqqgqDg4NobW2F1Wo1ws6RftdYDDDW+oeiKJuTyeTyL4IRJoQB/v3f/x2PPfbYYzabTc8LoKioCC6XC0uXLgWlFJ999tmoCnosRuB5HgMDA4ZYBGBEDGN9Nt9MzPdcN8bAwAASiQQWL15sCEMdCIlEAsFgEOl0GoIgoLq6GvPnz4fT6YSiKOB5ftRryMcII/Ux6ZA6m832mMvluooQsnoiGWFCGGDv3r2WRYsWifqF6wOmKAoeeeQRbNq0CW1tbSgqKgLLsp9LKOr9KyoqUFpaisHBQYOGx5utG89zPSlUUVGB2bNno7W1FZFIBLpS10NYr9cLv9+PZDKJlpYWlJSUIBKJjArO0TTAWL9Dy1/sSKfTX4/FYpMDANu3b3+roqLiFp/Ph+LiYuNCn3rqKaxYsQLd3d1GX5fLhcrKSnAcl2W4M3ELLMvC5/OhqKgIoVAIyWRy3Gr8dFyDqqpgGAZ1dXUIBoMQBAGFhYXo7e01Ek+EEHz1q19FRUUFGhsb0dWVyYzr7uF0ElxjAUDXDuFwmHze0PFzbw8vLi6G0+m8RlEUdHR0oLm5GclkEp2dnXj55ZezjA8Ay5cvx9tvv41169bhzjvvNBiBnuaGTX3gu7q60NTUBJvNpm8gPe3vGuvvsCwLQgiam5tRXFwMu90Ou92OsrIyo191dTUaGxuxa9cuMAyDhQsXQhAE1NTUGEYbKZ09XsCbr0XLk/zuS9cAv/3tb3HxxRf/Sh8sWZYRDofx7rvv4r333suald/4xjewfv16eL1e2Gw2zJo1C7fccgtSqRQaGhrOiA10IEQiEcTjcZSVlcHj8UAQBKMyaSIbz/MoKipCZ2cnEokEampqcNlll4HjOEyfPh2yLCMQCEBRFMydOxdut9sIMy0Wy7DweDyGZxjGENGiKBqJK0qpIgjCH75UF1BfX++pqqoK6aGTJEmglOLpp5/GK6+8Yiz2cByHkydPZs0IVVURCoUwODiIAwcO4MEHH/xc2sCc8auqqgIABINB4xpON1oYrU95eTkuvPBCCIIAt9sNQgjC4TBcLpcRCbW3t0OSJPh8PtTU1CAUCoFSisbGxiw2GM0FsCwLhmEMQOsuSUtdx6LRaNHnsd/nvl18aWnpKqfTCYvFAo7jzAjlJUmSAbgB4Prrr0d1dXXWgg0hBF6vF++//z5++9vfIhKJwOVywWKx5BVG42WEVCqFpqYmFBYWoqqqysgp6AM4UkZulLz9sBaJRBCNRuH1eiEIApxOJ0pKSiBJEiKRCGbOnImqqiq0t7ejpaUFDMOgsLAQFRUVEEURp06dGt0wHAeGYSBJEtLptHEd5mIYAIUMw5w2q0wYAMrLy+F2u6+x2+3gOA4cx8FisaCjowOKonwKoAHAVQBmXXnlldaGhgb4fD6UlJQY+fWdO3fi8ccfR0NDg7GK53A44HQ6UVpailgslpUsOR0gxONxnDhxAiUlJaiqqkIqlUIwGDQGLF8ef7TnZlCIoogjR47AZrPhK1/5SpZxamtrcfz4cUyfPh0+nw91dXVobW1Fa2srjh07NmoameM4sCwLSZKMFU1zvUPua6vVei3P8x9+KSLw2WefRUlJSTHLsrBarbDb7XA6nTrt/hnAnwD8GcDWSy+9VFRVFZ2dnWhubjbCqaeffhqNjY1ZKHa73Vi5ciXefvttPPjggygqKsq7CjheIEQiERw9ehTxeBy1tbUoLS09o9AzXyZRFEXs378fBw8ehCAIsFgsSCaThs5Jp9OQZRl+vx/Lly9HZWXlaGsqBoOZVyl1w+caX9MH931pUcCll176NfO6t54u7erqwpYtW7oAeAAEKyoquubMmWPV3YQgCGhtbcV7772HEydOZOX5HQ4Htm7dittuuw2VlZW45ZZbsG7dOtx9992wWCxnrPAJIQgGgzh69CgEQcD06dONkHUiWiqVQn19Perr65FMJlFcXIyenh44HA7olUA7d+40ClfNAs/hcMBisSCdTiOVSkFRlBFnfS4IPB7P0l/+8pev6smxswaAtWvXwufzbcrNYqmqiuPHjwfC4fB8AEsAXPLNb35zfmFhIZxOp5FPZ1kWBw8eRDSavc/+4YcfxiWXXAJKKQoLC1FXV4fq6mrccccdWL9+PebOnXvGbKAPen9/v0HFM2bMMBhmIkLGVCqF/fv3Y8+ePXA6nfB6vWhra8OOHTsQDAaz3JnD4YDdbjcyjLqAzjfr8zEAAMTj8bIFCxZ8b8WKFcknn3zyj7W1tV+sBnA4HPjwww8xY8aMTpvN5tGpW2eCjo4OtLe3pwBcqX//NddcU2u328GyrLGooy/zDg4OJnShyDAM/uVf/iULTHpRqcViwUMPPYTm5mbwPA+73X5GItEMhJ6eHgQCAfj9ftTV1SEQCCAajX7u0FHXH5988okxNuZFMbvdbsx4nuezDG7WEvlmfG7UwPN8ptrZ6XQuWLDgzpUrV37n5MmTa5599tl/bmhomDgGsNvt2LdvH06dOnVk4cKFtKCgoFoURWOFTr/QxsZGHDp0KALAqX2/euWVVxbr+sDpdMLtdsNut6O3t7dPluW/ADgKgL/kkksQi8UwODg4bOB+/vOfY8OGDWhvb0c4HEYwGIQoikYZ1+mygt5XlmV0dHSgsbERLpcLM2fOhNPpnBBGyGf4oqJM1KZXP+Wb6aP5fDMIFEVBVVUVHA6Hcc5msznr6up+dMcdd7w1YQxw4MABVFdXH/F4PPPNFTMsy4JSCkEQwDAM+vr6sGnTpkhzc3MQAA8gXFNTE7nwwgtv0AdD1wo9PT3geX4HgHUATgFYdO21135NEISyzs5ODAwMwO/3w+1244MPPsDbb7+N3t5e45pEUURJSQmeeuopJBIJPP/882hrazujiAEAJElCa2srHA4Hqqur4fV60dfXh3Q6/bkYQd+v6HQ6IYqiUdsw0gwfyei5htcjhksuucQQn5RShMNhNDY2Bjds2PDmhAGAEHLMarXOHalWTpZl1NfXY8eOHfyrr766H8BmAE8DwJNPPnkrx3E/MadDGYZBb28vWltbjwGwA+gH0LB48eJFFosFiqJAFEW0traiqKgIGzZsGJZSnjNnDnbv3g2bzYb+/n5cdtlleP/997Fy5UqEw+HTBoF+fTzPo7m5GW63G9XV1VBVFX19fTjdkm69zE1nk1gsluXjxzJ8vtpEvWZRn0QMw2DWrFngeR6CICAQCPDvvvvup9u2bbsNQHjCUsFOp/MFi8Xydy6Xy2u1Wo20pCRJ2LdvHzZu3Khu2bKlbdWqVT+PRqM/A/CJHibedtttm+x2e7E5jGIYBtu2bcPKlSs/VRTlAgC1Vqu17IknnviqzWYjZsPxPI/nn3/eWFzRDbtp0yZMnz7d2Ptnt9vh9/tx6623oqCgAMeOHRtXpfFImUdJkjAwMABVVVFTUwOn02ko9NG+U18lLCwshM1mM/ZA6LM+3wwfy+frbk6f9frBMIzKcVyv1Wqlu3btan7hhRf+o6Wl5V8BpCdUBP7mN7/Bb37zm3kPPfTQvFtuuWXHzJkzy06ePIn9+/fj0KFDp7Zs2fL7np6erP8Na82aNVi6dGl9YWFhrZ710w9BEHD48OGYIAgXa9fAXHXVVWUVFRUMz/OwWCxGVY6WTpXN17ps2TIsWrQoa8XO7XbD7Xajv78f0WjUmLFnUqxpBmo0GkUkEkFpaSlmzpyJWCyG/v7+vFvIGIZBQUEBrFYrEomEkcEby8gj0b6qqobh9VnPsixYlgXHcZBlObZ58+ajmzdvDgNYA2DjF5oJ/PWvf33sd7/7nffxxx9f1dTUdMX69etXd3Z2Zhl+3bp1uOqqq/5cWlr6nc7OTnR2dhrlUzoQGhsb0dzcHNaEogpAXb58eaHFYgHDMLBYLMYRj8dBKd0NoBjALAD26667DuFwGCUlJVnGlWUZv/jFL7B161Z0d3eDYRgUFRXs2ItaAAANeUlEQVTBbrePa41hJLDoef5QKITy8nLMmjUL4XAYgUDA+IzL5TJYQr8vwZkaXs80KopiGFw3uvmR5/kuZP4L+hMAEgAcpzP7zygMjEajuO+++4bdIXPdunXw+Xyvejyef1AUhSGEoKCgAPF43Ki506twt23bJu/evbsHgAwgBaDjuuuuu1hf+DAnlXp6etSmpqZnAMwF8FUA8y+99NIZXV1dCAaD8Pl8KCgoAAC89tpr2Lx5s6EX9CLOoqIi/OxnP8PBgwfx6aefGi7sTJhhYGAAAwMDqKysxEUXXYSBgQHDVQWDQYMZxuvj8xlekqS8M978qAGgA4BeHmQFUPCFA2CkNmfOnHqO4y4FgEQigUQigYKCAqiqCpZlkUqlkEgksH37dqxevbohkUh0AFgJ4MNp06Zhzpw595ndhF6Q2dLS0sDzfAxABwDbtGnTuJqamhm6UGxra0NBQQEqKiqwZs2aYWKxsrISG9/fjoICN76bSuCzQ4fw/PPPo7m52chdjIcFcltvby/6+/sxd+5cnDx5clgSZzyGNws9SZKMvRDmWT+S8SmlvCiKQW0SCVouxasBIH7WAbBv377L5s2bF/J4PB7db+kLOdFoFI2NjWhqakq98847uw4fPnwTAGNf1NatW290Op1M7mxrb29Hd3d3D4BFAEoAFN9www1lekglyzJkWUYymcSWLVvyrrC9+eabWDh3NtIqEE7zWOR04vcLFmD79u1YuXKlUes/0rLvaFvEVFVFOp2GXqOXz9BjzXxFUSAIAhRFAcMw4zI+wzBIpVJdmvvkAdgAlGluYOBLAcA999wDr9db+uijj66+5ppr/s5ms1mj0ShaWlrQ0tLC79q168C2bdv+RlGUdA5wUFtb+3auUASAjo4OHDp0yA7gco3iuKuvvvoCfcnYXIPQ1taGSCSSdU233347Fi9eDEop7ITC77Ij6boA0WQC1y9fjqqqKvzbv/3bqLH+aIzAsqyh7vW+Ixk+3+wXBAGiKOY1fD7ja0AVBwcHjw4ODh7X6J/XGCAOoEfTBGffBQDAwMAAfvzjH9+xZMmSO+67774Po9HoFe++++5nW7duvVkUxawL++ijj3DhhRfuSyaTi/r7+1FWVga73Q4zEE6cOCG3tLTIAAq1j6lLlizx6Isn+uKSLMuw2WxqJBI5DqBOyy3g9ttvzyrHopTCjUzByCtvvYVn/vM/0d3dDZvNBpfLddq6QF+vN+9FHM+sFwTBqB7WjT+WzyeEIJlMdoRCoaOqqkY040cAdAJoBNCsJdTwpQFAbx9//DE+/vjja/MVK6xatQqzZs3aPmPGjKVlZWUghCAajaKtrQ0ejwcejwccx6GhoQG7du3qUxRF1X5s6rLLLuOqq6utekGoHg9rWqFFluXVmlBcwHFc7ezZs7mmpib4/X7oW9copdi3dy+eeuIJnDhxApRS8DxvbBXzer2G68pXC5APALnFGiMZXt+Wbi7sHM34+iGKYiQUCjWIohjWRLMMIAigBcAh7TF8Jrb6QgCgt1zjb968uaqmpqYLAMLhsLF3X7/LRzweR1FREVpbW/H666/zmzdvbtV+6HoAa++9997VuduxGYZBe3s74vH4pwAOa2BJfO1rX0vYbLYFuntwu93w+XxwOBxYsWIFmpqasny9oihYfsst+MXDD6O3txcvvPACPvroI3AcN6oOEEVxTPEny7KRRNI/pxt+NF+vqio/MDDQkkql+jSqT2mP7QAOake3WU9NKgDkWTPvppSKLMta9Vu4hEIhYzbFYjHs27cPhw4dSrzyyivvp9Pp75nDmptvvvlSszH0Qezu7saBAweCAOZoYjF1ww03WPVwTzeAXoiyf//+YZtO77zzTqx6+WVERQn2omI8/vjjOH78OJ577jkcP37cWPfI3dySW6eXK/DMItG8QDSaryeEyLFYrCMajXaYjK4fBwEc0Y7w57XJWQXA3/7t32Lp0qW2e++995OFCxdeoQ9eOp1Gc3MzmpubxV27du1///33/0ZV1SyxePTo0eu9Xu9cs0/XW2Njo3rkyBEPgEotuWRdvHix3+VyGUJRv/HDnj17kLuhoqKiAs8++ywIpSi2cCjy+xBJl+ArDqexte2ZZ55BMBgc9ptkWc4b2ulLvWawjMf46XS6b3BwsFVV1ViO4Ts14x/TnqcnwiZnFQAAsGPHDuzYsePKu+66C9///vfbXC5X7c6dO+VPPvnk6JYtW27leT5LyLzzzju44IILNnq93htkWQbHcVlCMR6P48iRIxFZlvVKCLWwsJBZtGhRMQBDLOo1CJIkIRgMpjSgAAB+9KMfobCwcEj1U4oSuw2FF9QgGImiu7vb2PFsDhl1es9V9qlUalgoOVaIJ8tyLBQKNYmiGMmZ9REA9Vp9ZctEzPovFQB6e/nll/Hyyy9Pv+uuu67dsGFDSyQS6c5df7jmmmtWzZ8//06e55n+/n6EQiGj7l9vhw8fxvHjxwN6ShmAePPNNxfre/X0QlWLxQKe59HT09Mny/IOAAsAzABgXbJkCWKxmJGpNJa7KcVLzz+H1atX4+TJkwCAwsJCowxcp3ld4OmLPvlqAkYyPgA+Eom0an4+ZQrtEiaqb9F8/YS3Lw0AJiBkVbReccUV+NWvfvXDkpKSFRzH2Ts6OlBRUWEoZf0+P06nE9FoFO+8805qz549+uAFAKy9/fbbf2muVdQHvKenB6lUapu2aBIAMLekpGRubW2t/9SpU1lCEQC2b9+ONWvWoKmpKSsVnkgkUFRUBKvVCkmSEI1G897sajSVzzCMmkqlOuLx+CmTwNON36yp++aJpPtJCYDcFg6HUVlZ+aLuSyVJQmdnZ5YISyQSaGxsxLZt28Q//vGPn1JK1wL4vf4dixcvfkXXCOb1hb6+Phw9erRFyxP0ArB/4xvfKCOE+DmOM4RicXExfD4f3njjjSzjmyOGcDiMwcHBvJVDI4V4+qMoioFYLNaiqmrCRPcigD7Nzzdoqe/wFz3ekw4ATU1NeOmll8jy5cs7q6urq/WZpfv9zs5ONDQ04MiRI11vvPHGf4XD4azVyIMHD6KsrKwyN25nWRZNTU3q3r177QAWarlz5/XXX19mt9uzhGI0GsXAwABaW1tH3XQxkvHzzXoNwInBwcEmSZLCOYYPa2VxTdrKXuBsjfekAwAAPPXUU3j66adrHnvssfuWL1/+HwUFBe5AIIDGxkYcO3YsuGnTpq2NjY3fzycwZ8+eLZgBox+JRAJHjhwJK4oy3/S7mSVLlpS73W4jLasDoa+vb8zdxqNRvpnuCSFiMpls1ZZveRPV8wCOa/mLZq0yKn02x3pSAkA34KOPPvrcK6+88twjjzzyVigUuurNN9/ctXfv3m/l9v3www9x0UUX7YvH44t6enrg8XhQXFyUlcHTwsyIRv8qAPXiiy+2z5gxw6pHF7pY1Gv3Dh8+3ALgAm0dYtRl4lyxp/t5URS7ksnkKW3Gm2e9HtY1aXT/pdwrbtICQG8tLS245557vpXvvRdeeAELFy58x+/336SHcdFoFIFAAJF4Au5iDzwFTqiShF27dsmaWFQ1Q4S/+93v1plnrA4Cq9WKtra2nmg0+poWLVysAYEZzd/nVOsE4/F4S554vk+L5b+QsO68A8BIbfXq1ViwYIHEsiyXSqWMdK8eq4vpFNzeMgQGY9j5wVasXbu2JZVKhQHs0eoQwjfddNPB3NSyfnu6/v7+T7UZmtZCsh4tbKzMBYDZ12fKIRItsiwHcwyfOhth3V8NAGKxGBRFSVkslkLd38fjcWPTKSEEn376KY4cOYKNGzce3b179+MA1uqff/DBB1FXVzc/VygSQtDX14f6+vo+zeAuLRnTY5rBtciUqJkrdEVBEE6JotiVY3jdzzdoM//UZBpHgnO4zZs3D/fff//GK6644pssyzL67A8EAnqkENi4ceP/a21tzSphq5k2Dfv27Nnk9Xq/mZtWppRi3bp16p133vmyJEmcljHkTAejPXoA1HEc5+Q4rkcQhFZKaWqU9G3b51m0mWKAPO3YsWP4wQ9+cOONN96IH/7wh4fmzZt38d69e3HixInYpk2bdtTX1w/TDq+//jrmzJv3ESkuvkomBBZkF33wPI/6+vqIJEl+TS9Ae5Q1VxDQQjYvgK/Islwsy7Kao+z1RM5nk4Xq/yraAw88UPXtb397fb7l22eeeQatra2/EwRBaWtro01NTbS5u5v2CxKVVZWq2nH48GG6bNmyY1q28C1ktrevAvBDZKqS87VrAVyvvV9wLo0ZOd9BsWzZMjz88MPzKioqPrVarW6PxwNFUYz7EzAsA2e5DzarBRaBx0svvcQ/8MADOyVJSiBTi/AagA/P1/HhzncA/PSnP/VUV1cf1VfrQqFQ1oqeqqpwUwXhwCA+eP999cUXXzwgSVIDgF98WbH5FAAmsNXX14cZhjlcV1d3sXn7tS7+JEnC9u3b0dDQwL/22mvbjh49euNfk9skfy0/9P7775/3rW99a4fP5yvTM4Tt7e04efKkumvXrqPr16//ViqVOoWpdv62oqIiPP3006s+++yz9Nq1a+lPfvKTdp/P98Opkfkra5dffjmuvvrqa6dGAvj/As0c7mrdeEkAAAAASUVORK5CYII=);
            background-repeat: no-repeat;
            background-position: center;
            background-size: 40px;
            width: 40px;
            margin-right: 20px;
        }

        .footer-desc {
            position: fixed;
            display: flex;
            bottom: 20px;
            right: 20px;
            align-items: center;
        }

        .footer-link {
            font-size: x-small;
            color: black;
            text-decoration: none;
            padding-left: 10px;
        }

        .button-o {
            cursor: pointer;
            height: 25px;
            font-size: 15px;
            background: none;
            outline: none;
            border: 1px solid rgba(0, 0, 0, 0.35);
            width: 50%;
            background: rgba(51, 122, 183, 0.3);
        }

        .button-o.selected {
            background-color: #337ab7;
            color: white;
        }

        .button-o.left {
            border-radius: 14px 0px 0px 14px;
            margin-right: -3px;
        }

        .button-o.right {
            border-radius: 0px 14px 14px 0px;
            margin-left: -3px;
        }

        #overlay {
            position: fixed; /* Sit on top of the page content */
            display: none; /* Hidden by default */
            width: 100%; /* Full width (cover the whole page) */
            height: 100%; /* Full height (cover the whole page) */
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.06); /* Black background with opacity */
            z-index: 2; /* Specify a stack order in case you're using a different order for other elements */
            cursor: pointer; /* Add a pointer on hover */
        }

    </style>
</head>
<body>
<div id="overlay"></div>
<div class="footer-desc"><img
        src="data:image/jpeg;base64,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"/><a
        class="footer-link" href="mischianti.org">www.mischianti.org</a></div>

<div class="tile-container">
    <div class="title-image"></div>
    <h1>OTA Update</h1>
</div>

<div class="container">

    <form enctype="multipart/form-data" class="form-container" id="upload_form" method="post">
        <div id="switch-container">
            <button class="button-o left selected" id="firmware-button" type="button">Firmware</button>
            <button class="button-o right" id="filesystem-button" type="button">FileSystem</button>
        </div>

        <input accept='.bin,.bin.gz' class="input-file" id="file1" name='firmware' type="file"><br>
        <div class="progress">
            <span class="progress-bar" id="progressBar" style="width: 0%"></span>
        </div>
        <div class="additional-info">
            <h3 id="status">Firmware upload</h3>
            <p id="loaded_n_total"></p>
        </div>
        <hr/>
        <button id="button-send" class="button-send" type="submit" disabled>Upload</button>
    </form>
    <script type="application/javascript">
        function stringToBoolean(string){
            switch(string.toLowerCase().trim()){
                case "true": case "yes": case "1": return true;
                case "false": case "no": case "0": case null: return false;
                default: return Boolean(string);
            }
        }

        const urlParams = new URLSearchParams(window.location.search);
        const onlyFirmware = urlParams.get('onlyFirmware');

        if (onlyFirmware && stringToBoolean(onlyFirmware)===true){
            _('switch-container').style.display = 'none';
        }

        function disableAll() {
            document.getElementById("overlay").style.display = "block";
        }

        function enableAll() {
            document.getElementById("overlay").style.display = "none";
        }

        function _(el) {
            return document.getElementById(el);
        }

        function uploadFile() {
            var file = _("file1").files[0];
            // alert(file.name+" | "+file.size+" | "+file.type);
            var formdata = new FormData();
            formdata.append(_("file1").name, file, file.name);
            var ajax = new XMLHttpRequest();
            ajax.upload.addEventListener("progress", progressHandler, false);
            ajax.addEventListener("load", completeHandler, false);
            ajax.addEventListener("loadstart", startHandler, false);
            ajax.addEventListener("error", errorHandler, false);
            ajax.addEventListener("abort", abortHandler, false);
            ajax.open("POST", "/update"); // http://www.developphp.com/video/JavaScript/File-Upload-Progress-Bar-Meter-Tutorial-Ajax-PHP
            //use file_upload_parser.php from above url
            ajax.setRequestHeader('Access-Control-Allow-Headers', '*');
            ajax.setRequestHeader('Access-Control-Allow-Origin', '*');

            ajax.send(formdata);
        }

        function progressHandler(event) {
            _("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
            var percent = Math.round((event.loaded / event.total) * 100);
            _("progressBar").style = 'width: ' + percent + '%';
            _("status").innerHTML = percent + "% uploaded... please wait";
        }

        function completeHandler(event) {
            enableAll();
            if (event.target.responseText.indexOf('error')>=0){
                _("status").innerHTML = event.target.responseText;
            }else {
                _("status").innerHTML = 'Upload Success!'; //event.target.responseText;
            }
            _("progressBar").value = 0; //wil clear progress bar after successful upload
        }

        function startHandler(event) {
            disableAll();
        }

        function errorHandler(event) {
            enableAll();
            _("status").innerHTML = "Upload Failed";
        }

        function abortHandler(event) {
            enableAll();
            _("status").innerHTML = "Upload Aborted";
        }


        _('upload_form').addEventListener('submit', (e) => {
            e.preventDefault();
            uploadFile();
        });

        _('firmware-button').addEventListener('click',
            function (e) {
                e.target.classList.add('selected');
                _('filesystem-button').classList.remove('selected');
                _("file1").name = 'firmware';
            }
        )
        _('filesystem-button').addEventListener('click',
            function (e) {
                e.target.classList.add('selected');
                _('firmware-button').classList.remove('selected');
                _("file1").name = 'filesystem';
            }
        )
        _('file1').addEventListener('change', function(e){
            var file = _("file1").files[0];
            if (file && file.name){
                _('button-send').disabled = false;
            }else{
                _('button-send').disabled = true;
            }
            _('status').innerHTML = "Firmware Upload!";
            _("loaded_n_total").innerHTML = "";
        });
    </script>
</div>
</body>
</html>

Pagina in bianco e nero

ArduinoOTA custom black white web page

E qui il codice

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Upload OTA data</title>
    <style type="text/css">
        * {
            box-sizing: border-box;
        }

        body {
        @import url("https://fonts.googleapis.com/css?family=Roboto:400,400i,700");
            font-family: Roboto, sans-serif;
            background: #555;

            text-align: center;
            min-width: 360px;
        }

        .button-send {
            width: 100%;
            border: 0;
            background: #FFF;
            line-height: 23px;
            font-weight: bold;
            color: #555;
            border-radius: 4px;
            box-shadow: inset 0 -2px 3px rgba(0,0,0,.4), 0 2px 5px rgba(0,0,0,0.5);
        }

        .button-send:hover {
            background-color: #dedede;
        }

        .button-send:active {
            background-color: #dedede;
            box-shadow: 1px 1px #666;
            transform: translateY(4px);
        }
        .button-send:disabled {
            background-color: #9c9c9c;
        }

        .container {
            padding-top: 80px;
            display: flex;
            justify-content: center;
        }

        .form-container {
            min-width: 380px;
        }

        progress {
            display: block; /* default: inline-block */
            width: 100%;
            margin: 2em auto;
            padding: 4px;
            border: 0 none;
            background: #444;
            border-radius: 14px;
            box-shadow: inset 0px 1px 1px rgba(0,0,0,0.5), 0px 1px 0px rgba(255,255,255,0.2);
        }
        progress::-moz-progress-bar {
            border-radius: 12px;
            background: #FFF;
            box-shadow: inset 0 -2px 4px rgba(0,0,0,0.4), 0 2px 5px 0px rgba(0,0,0,0.3);

        }
        /* webkit */
        @media screen and (-webkit-min-device-pixel-ratio:0) {
            progress {
                height: 25px;
            }
        }
        progress::-webkit-progress-bar {
            background: transparent;
        }
        progress::-webkit-progress-value {
            border-radius: 12px;
            background: #FFF;
            box-shadow: inset 0 -2px 4px rgba(0,0,0,0.4), 0 2px 5px 0px rgba(0,0,0,0.3);
        }
        /* environnement styles */

        h1 {
            color: #eee;
            font: 50px Helvetica, Arial, sans-serif;
            text-shadow: 0px 1px black;
            text-align: center;
            -webkit-font-smoothing: antialiased;
        }

        .input-file {
            width: 100%;
            border: 0px transparent;
            padding: 4px 4px 4px 4px;
            margin-top: 20px;
            margin-bottom: 0px;
            border-radius: 7px;
            background-color: rgb(255 255 255);
        }

        .additional-info {
            color: white;
            height: 67px;
        }

        @-webkit-keyframes progress-animation {
            0% {
                background-position: 100%;
            }
            100% {
                background-position: 0;
            }
        }

        @keyframes progress-animation {
            0% {
                background-position: 100%;
            }
            100% {
                background-position: 0;
            }
        }

        .tile-container {
            display: flex;
            justify-content: center;
        }

        .title-image {
            background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAACACAYAAADDPmHLAAAch3pUWHRSYXcgcHJvZmlsZSB0eXBlIGV4aWYAAHjarZpZtiM3dkX/MQoPAf0FhoN2Lc/Aw/c+IDNLbZUkW0+ZfEkGI4DbnAaAO//z39f9F//V3prLxVrttXr+yz33OPil+c9//f0dfH5/v/9+fMS/f/W++/lB5K3Ea/r808b3+sH75fc3CvPX77v2/SS2743Czxu//5KerN/3LwfJ+/HzfsjfG/Xz+YV52i+HOr83Wt8L31C+f/LPYX1e9G/3qzeMKO3Cg1KMJ4Xk39/5M4KkPyENXvv727gu8N5IKWXHS071ezMC8qvp/Xj1/pcB+lWQf/zmfhv9n7/9JvhxfN9Pv4ll/caIX/7wg1B+8376+Zj4ywennyOKv/4glDB+N53vn3t3u/d8ZjdyJaL1W1Ev2OHHbbhwEvL0vlb5Mf4Ufrf30/lpfvhFyrdffvKzQg+RrFwXcthhhBvOe11hMcQcTyQnMcZFovReI0c9rqQ8Zf2EG43s7dTI24rHKXUp/hxLeM/t73krNJ68A5fGwM2U6j/9cf/uw7/z4+5dClHw7WesGFdUXTMMZU5/cxUJCfebt/IC/OPnm37/i/qhVMlgeWFuTHD4+bnFLOFftZVenhPXFV4/LRSc7e8NCBHPLgwmJDLga0gl1OAtRguBODYSNBh5TDlOMhBKiZtBxpxSjc5ii3o237Hwro0l1qi3wSYSUVJNRm7oL5KVc6F+LDdqaJRUcimlFivNlV5GTTXXUmu1KpAblixbsWpmzbqNllpupdVmrbXeRo89gYGl12699d7HiG7woMG9BtcP3plxpplnmXXabLPPsSiflVdZddlqq6+x404bmNh1226773GCOyDFyaeceuy008+41NpNN99y67Xbbr/jZ9a+Wf3dz9/IWvhmLb5M6Tr7mTXedWY/bhEEJ0U5I2Mx073elAEKOipnvoWcozKnnPkeaYoSGWRRbtwOyhgpzCfEcsPP3P0rc38pb660v5S3+J8y55S6/4/MOVL3+7z9Qda24G69jH26UDH1ie7j89OGi22I1MZfer3FX+bYxk51rMyDaJ/LzXpwcW4CE+8o1vMFglo/pd/CeFNqQq91J7E4c95a+ryTAbZxbfq4+asYo1/rwrTr1BRNBdqt3tXJ/io3j/Run++t9ef3850pz7vX3YiGsgHSbquns9xqn/FQHLbjqFy5flwZbTO8e849TG0OfzLPinG3eXq56VCs6d4eziwOlJ21aJ6Dopmn2Y0xf788j63bOjWZy0lrZ8B42R1D1++gGRvzqbdmNzZPp9xsp0I5vFt2uyUD9rkEqZ5l25p+lWD4s1f3ny74k9dwhl1fDlWz66W+XUcWkJx5VaY3g40plrXijJQe1Xn7nidAeePuku4hI1cxoP4WbEk136O0uW2DDPl+wkjx0Ow+3z5XzvvykfnTh53cTsvctYaSCHNHyIy8dsytHt92icPcjr2R40GjEVKBHREduXUrca4yw6RQQqul3b3LLSdXY5S21mQkatMblEGX+ppGjqJp2IMaO2cuS1TPvS0Yw6UHbH0qOKa29Qqfpk/m6iz9xF0cVWaHm1Sj/cfYZC7Sa+9LXeVDEayZ9vHv9+b/5NX5/3DBn75C++llgXfIg6MFtsV7Siw280ZGlBlfIpghVQ1MXmqtTGYuTbOZas2zpjsbRcdQ556IEHdODwDGJle2yO9txdNWUU1XaazNTQJQxy9Cyjx7rOf9K+g17nyolS482p3G6hri8dxRfXFvEOq3Q//RtOvq01y+qYB865vSNxewS5jOuH5fe7nQN8iIvkG6N9os0x1U276RC6wDuuQeUP80T8821+d3idHPL//X13/diIcZak1jKn3MVyUzCGOFaox/oR3usUkHU1fQVgP/MhByALfo1DYG+dAUkx6sRB6kJ1N05ZpAVabxymnzRtpmjp4MZOB1gkmbFskZcujezaJC7JAIb/cJ3JYCg72Rof8EwU34yWAyqHf0/qRLSOyuc+9bApcHc1QMiVrRVt2feibw9qsWANuAOcpOdZNmiuTE2jfwZFzBKQ70PNf/Q1T6xav7AVNJReRLbXesClUThlamUWOx0rD0MewYsFCgxGlxMhxVUqkUvybqvNGxGS6gpseotlItPi2UQYa007xvioYOn8T/0kJ02EEGqLIjrXJQ4rNtR1Lh4p1rBacIXZVmPGFhUL1qMc1P5NZ7XWTCX73phY8MUMOoPV2ncdCeEAQtU+9ACdHB5SJK4uKZXGgkZO4OH6Xb6Oy1fTSrO41NR95k9NNxzHkdqs1EdqgCYInP5yxjXaV7XqAUAwM+ChQYUcv07tlM3iN5UDaLujp0/5HMeJU00uZWwN3aNe1Ao58zpHJaH5lvMfeCjjmwOnUtWoSPCUVJGVW7c8zSF5Tw63HUSaQFEneuVOOMBSTZ5K8D6W2vDSP6Ja+VsE0BzzwgiON2Y0T0xVgbYC9pTN9m07NXyXGsTuUjfEC8NkgmGEYKwC5iTIvdE0en2/x0G/q5a7aHR7n09MqAKTbkU0Gl+V3jaDxrd6Vgh0jqyAaNsM8CRa5XDpyaqNCkF2cAunERgpEWXZG4IOvweZMUkaRDRHpbAXaieWds50BjUGgGxINbBB9c2CkcTxkgic6xV4SVRhvUBuU3BspkDZp1+05FxjMmyChVOFOl+Q+q9qsUvDGRfywE2nRQLuW/DDwHK6h9C/VBBYoALVQA3IFQGx6yno2MnymxO+tWL1IIu+aLEndUxZ5wu6DisarRVPV63iAISFJoNod4llQbVwZkEEmmgj1whOetiW7e3nUEL1q815LCmDaQxSA+UUQoEB3gDzmJP5sUdxCTrD2sI/ORI0i2YRG9SCW6Yz4lrszpYIQZeByTIJ8mpdAoq0ATkXOwr6004CGGACFB9f56o2yvJHl2Bbybs9MSsfV8YKhQ8vQ3olGEueHQOhiPk7Edc3VMQJbuoK5xK1QEoeT+xSFImdia/B+4rAo4sTP0xgRS0FTBuDtlz7wnUyui+jNzfF9EthSweezjOlyAXhoZXRZrYZABvIHuM80COx1KmnKyPcmO+hol2loxPkYVVRyDhFPmRswrdCJF9dfR18H04mxosUFcd8dKwfEHx4HGNsIJwnULMEFdIe1LlasmikP2Jv6VjQbrJLKXirrEJUBiNDwEB/AcAgZpwOSBj4wuxzYxnosMh847otrVhrjjGig/gEPU+G1SbH2jaHYAXRKlRdgIXyFQAyn+g/qBy/aDqN3fp3qmXEpLsWP9MX9i+wJCBumsijNDrJ4tmc8kaZqWzYL6YViVuNULjDvbgoqPNZQuZV9pBfQh6sD5DnkHWkdgR7zAQyIysAMYqVg8VUBaqM/oj1HMfRUbqZVFDMlFoLwTigkrCidgBak7yg1o29mvVXgg2HFxkEXN5ZFumVzUQ+VMUJGR4GAnfrVR9AI4V+Rl2qgx1CfCQ8fg6U0GV1DNN1LrE6d1TA0/5UN/pj0n3kSSxbrd7p56on2aMdiS0qKJmaUMX5RfP4h0BNNhdHEvzF2lkwq3OS+U6CpaCmDzG4dAD8GR3aNVD3RvVDtoZeFAASNNwUzZS0WMP4dZQQP8yu1YengP+YPQGnzzgLJnI9BrTZ3PcKxPp5+021+V3e4PPuirMe3kqUK0MP3pN17QQmdOJBOrTfuh2DHImGBmRozMMcINt21yj93DQjTUBMWugb+iUSIH32OEqRq6kqjHg50C0+oQ31+KtLqu9WXaq+2xmIlSD2qZsI8U0yvgzSB7fDNN2h7d3Al7spzakkL20B715LZWGyiS2sci/clQOwiKAp2SYRkEZArRhY9hiUTTonS7dZ/mfsVSMa0xTxdIe+olMTVkGjnpFDVsilbM8unUYS0AVkJCQL7UZz447gYJa7WjgQieQVRXEdNUfjSoG8lCwg8tGIGWMM8ICXhOAfhBOYlGm7BLZQFNdwRNxR92g+2hbCEWwEdAKnSldZaDsOt+DQpnWy/AClxPSqiTo+VDzCMzt0D3DCZGCcflbHyBGkJAw/xTI5EcnbyRQb6BMPCtHzsBBUEVQY1TkrJe43hhqComU7urARXCdXS/GWppr+TwswgS1Du9WjPoGRb2KUKfXm2GGiO33UuWhryGlFhO1M0rG+xcpCITegReY9qMoShGqruUMlIIqduilLXBUg0qitJKAbBNAVbbJB59RXnwbyijHfcEw/k4NTAMTocKyXMQONPI4ABoMqnAbrHfvbjBpVNQWvxaJ1S5Qs/BwaaoAR6yBugRKiVDWXoEA+wAwxEI5jEH7g9airSVjBRz8JgnNEKFPEkYU1vU4JpaJV9WPQTeDzA0Da1IY2mtr8c0Vaow6rMNwpQSUAKhQ5uUrglqqWvQCZ2CJQDp0dsDBYLwQrk1PAR4fUQ7oPVYYatoYZFkUtU7SQFkBs+INgO4D75rUsXmgnBH/6GQtH5yZaTLAWkXcpmmZnpUyOKva6iVUvbAvZzhkhbhXkX+E80HSYGqpNDcxXpYAQoYuGlMuH5DcwpskFMlow2PyqI2+fwGEyUoQeun8PLWZxVovm7OiqzjR0ajP+KsgkhMfKuhJVIImwRQPYJ3+QId+EdoE+nAREBkJDrKwNVnn7TFQclTt1WY8CISpqcO+Kdu7mUgMLM1IUIwugWZRhlS4LeT/GjuAWZHInTNHeGKlwsNpUGToMmHdCF6kjoAbfYCQhiWjEinEYagL67pB90PrAN3WhxGAma1LIaBuqMEFyWNisSGN3gKycSMQ4xYMHkowAiNh8ujYS7BlrzKHczGVhWiEiNGyoNCQwuiA11Pr158Z+YCKqtQr2dC6IcmIV9MX5PF1CSonFYuFC+WFnG3kOeeh1ZijBCpA4/RX4E38Uy+UZqCMkanA7UoVVygQyNT4ZKJaNm0sG8vDB4F+Ff9w1svcF6LTUzhTO2iANZI09vnsxHqeNh44poKiu9UABAoFt3bxEMB2sA5Io9xObyaev8mH28uCBTwBgn1MffgWQiyR8h1nlem3ko4EfnsiFJHgMnHIHgd9Dc+a1nBnhYFVfsAGCVlbj3oWlJmNWetkID14CPToadj3+m5ZExGqhBkeGsKJP2BG8atom+uLObJiDRACR+B+t+eQpiQHjZpUqhkGq0OXvO0uR2B3kWwTzGhH4BpeSQZSL5ZtUSMSsfGYK4AOYowl0WfqOiQSmmY4n0TMBLoPEQmwh8AtsMXq7zGHhHoU/6BDHhWngkRmCXUi6GaPdZHa080UMchaMdPngF2QUQzn/AmCMfOiPuF++hTSqq+TCOtsVotbXF5B+a00w3Z8uqIHhzcCASjpGdGQjVrvUlgCtYkipM+yw2vRIdAPaKhIesM/3dco7j+SLFBupDFWrQKKcEnkV2teVxGI82fX7h82aZl2bV8RxJ0Pmqm1oUr5ZYcMhgTSkzaDMq1llMWclBQAQkTKtQ6X4FPYKjR8IelN9DOeLThtudk6DbdY1jsJR7T6ooWEr7wNgywpqzlDzR51QwETpPYZRwKgEL7BwptwufAxHYHLYXmRXE0bKVWD9Yjo8aYDuAB9V6dDgBY0UWLlGZMrc4P4IapMfhARJNw2Vv7IwnWBIcwE7kgSbhRRVIVnQFAxwMtcocg91hUvFLD/wYzUoNdKxDTIQzfDJDJiCjaPyd0HrQ9Hr/gTv9MFkOXCMsWGSnSw4H4p+GtrcvXaOkTw4eRB7xP73inLQyC5irVTn/w9IVVJ8vFa604z6lFd6wovE7LIAZAjEmbU58drwkV2KatqP8mPkCEDiLAozb/2FoFL/hWPOaBE/Z1HVumzS7UCzDjRfu3ItVDy2+JWfti4IYnzDOIXlCA2EsUZdJ9oQStWqXhYKuKmKZYt6HEAJNE224ztFGk3ZlojZLbyzBfCfVx0Na4nrsg6KSZ93l2dgQjiMwn8xbVq1XmWyUZtCFNFoLGT6HidNFObzERa0nJem38wzOM6ExHP9RC01ILDFVCqmppufBIdFZAgUm3pMh7N5Looc0AWPmBR5HhvgFyuw7WKatjQKfcCqFKnu4F16oRCfTOs6U0PmC7i/YTBk69tjV5KjWpbR/as7qYzsXYZe4LPjdR+QIHGV9cElR4UQTuSJ8Fc63bwqE+kmftDgBRARMzdnQydpBl0c5Somcyc0N1UJrqwotxXVkaDrW6cBFTBTRJDEVR92pJSNYyeISQnp+Vg60lCS43FR25p05TozqUxK7Niphq9UxZHADVyKpTxlcGdCK0mGBkdveAEDh/QWhEpWK1opRoB6aOpJy9LWOSTIoRhsjHS8Twa0hJPIjL2qNcUuITYHuLiWgAFf2uDznRWngMWKvTjHORJvyR4PnMJCUlPvJaP2poVgEgTT5QEVgsrYQWeBVfRruhxjC2lvZMPmPTO3+QWrDCq0woeICk0ZErXDnAVaeQECcnf8AAt4RQ0PERHABtrdU90cLky7QONbZaqFosoLEDTIuVauArnEQ+ATd1DqBzwYMeEiYVTH7noUyHKXgi4AQ5aseWCb4qJVpeuxD4gXEwvOeMog0PyzOCAO0tLDKrfBOEikjAaRytIaI7qQxBYsYudIEEXmRp91R9n7RQmRbFDCFmLZXy5dORQkHLAXUwES13APk0dtCpAf4kwA3oxBxbGVqxHnLZZjKzdZ9K7+FIj3S8lyHvGjaYjmIBmZCNgC2x17rO9lruxvcTybcphu5qt+LxsLQgdU3cE902QDJYMZ2sReaFmtnQClXiJc+zXz6KMx0svH+3l9u1xEoRZK3J00Flx8go6STthCn5eEV5uI1KzBExuN1bxwXHQAPomDHh1mj5NrQ4SM8fz6dFcTeQWG6Prov++8R5kuAGkkWwAzUINRQTbp7koke5K6nijon5q2Xnxb7wLRAEwMallycNaxXxS8a06w66l7sSVuy5b8ANthBiDAi0rtD6A8iTRy1lEGHkDaquUGBWr3Yxk1aXYREunOSi7nGw2JcoYpHpEvpqqh+hJzhe7gLuaBoKPw1ZQcnn3Pvyx2bHQkwtEYAdbaMAUFz1kP9GxLQfDXAxWqj+aJKVeJq6Jk/MZQyUt9bRAXd/8zPHny6yoRWdq22jpV0gdJ2EG/16IzlffHBNmqINUQHBRjejrrX3TR01mBDDG3pTevGUMp90Ih6eWGfhncn643zhCHvbF1TgxbZhWRt8mRdynKmZSBbEA/CnWgMMjzOgkbV0Jr04wMgFAM/aY0aHNwrzaAtISJwSBcCouoOrUmQcPEzpHwlwR7NbHx9rUI3mH7JnCCJYmI6eWtsQH8ue1GML23Fcs04kszBEHVCYi3oCLzERaM+waz9GEcPCyGyB5kAdMcJA4iGswuR3Oegc7YzZyjVRcG8VDi1xtUg5tC2ITZQVpRDyrXAvUgNeHAX8wV3Mqc3R1RHsBBnDsrUZtzB/XUdOUDPQP7RAqVAIe1G6x+NayBSaAUzjqV6yDjRZb0PBidB0GuSaph9yBr4yao6a0OYXsnb7Z5hb9DhmtCYyFYqT1JTGCCRKSw+uBIl87SdhHng1AL7VqE2gI4xI7YDAjIsAUjiksRzQHLUy/KqRAscOIrHcudx84qG91kihGkwymAWoPULQyjNw2L0KhBuA9kFmivhboNOTTlRcHa0ynRXRqYqaG2gCFyw6j9FhQVCgVBNgo8UBepbsDK+zqFp80z6DzP3JSFfDikKZO40ataGBlsBcIZUjwyY+qNg2k/AcjOvcph+8O9DNHUaDRv1bCTMG7XIUMpdBLTJjGUWDKAMoEoXpmYJLyIGS4tKmCc5NOhdTY/ASSFuTFxkch0aSkgsi0XgRxwPxXrSbEtWlC/VES5Jy7fY3DNbUQjcxWjvlBdTyKAQ8mI2jw43824NV6kGsP/6R8s4eCOuXhsgLrbtXWtxsuaOTbfIqA9X67kfMPEWg3EytpiJpCRx+iQrdGzm9podx8QlwNc7garvi6txIQ+Bws6h9NuQPoV9X5nXKACEUl1YYMUGMomlPDUWsoyAwCZCKVdjaSgf8GSJNih5ETSHW0W2vYWzWIBWWdJIE2s0tatFtavVD3qG38fHaOExS68CtrIOuYx3tJeKCg9zYoR2QLgeXlsB6LOK6JMF0Gqhd+n0Qmi/tePBiOyaEHgZIB0iL9mqS3dqoFZxoZXwTt47cRX+2LonCIwBfHcJGCILuTUolOp2e2V5Hl3A5fSZAPR8tTL/VAEaE2j4PpMU29VytcUbtBwhvYLamvX9raEjUO53Ua9kaC6WGT4XHDxJE6gC/j4BVZwKQb7+Yh+BPjumUOWSJegfDXcxhxFEQ2BAA/o8ITSyeFrIJI8AUKWivzUOEe/8jjpAI7dNJVyIDddxuARBoIepLFga40TGooU1WuB/lmogdFaFjBNpBJNcS6MhNPt8O74id3jrfIFpAx2kvul0ta9EhOus5ULbUGGY3am8QcYFcgUyrzs1it1FxdTvIu8oSB5R0xMajg6+p2jJQ4QEq7RdQbKBwoO9EiqFQZyL8+M5fIMyfYjshXApLCNG3To6dnWBiYNlAAOgJmiOFuC2qhZpqRUcUmkjmgBKIzQqXMbVLOuYsMQqXNv3wXenB3TTMq4EExABkQJl3KKgbsSd8HckygKmi1Xr8mvYvRLXXk56UtaQchCeABRpGzbHgRvoGF0+r19DwSyCWFh9P/6jEfXRiHFnDvRs2YKMbj0qAgRF/6QUY0jD2V4dKV9Ju3aZ4eCQMiN3SGSPD25FCrCiuFfdRkApLCyKBbI58NE99x3o8VDjvai98UfjAfRKISjHvmIF8UDC7t/lQ/C5wI14VLqRiB9yJhck1xs+ewKDkEuz82fDW7gAWmlrk38RTi0Nu9H94UMhQTg3NH7WtF6orWkOlUqXSi/Y8Eb9X4jdF+XDGIh7ITcWE/npVC+QUrgBq+G4UZO/ltHj5tunw9cCUNl+JFuw7l/aMKD8dKaTXNzI5o44aKMm9/Vf6as9d2xgOqJ5DKASaoy2UpQw2A3BVx0TkgUgxzTcmzcBUaDOte2tZT4sdJ9LRXA2LbG1X9S1pD7sA5Vp+gHbaW2SUidRBF7XJhEAQJloc0fGh1Ki7TfGjGUDIwNcLxYmWKloeQ08nqXQ4DsMOCaG10AA8hX6GmHRgF99VB0HQ+zhF2rY6hQ3xI4kgivNPakUUiVbF8sYICCvAVSZ+pPikf+Gim5MgEweGBEPlO7D4SGkfnRAOWgqjFL/kAPfEjmq4QlGp4vGB34YtkxMZdWiD1a5v2c0XraJTUFow7LtJXcLWWGZYFTJqOlOmBTGkhI4vS1lR+p0q7khLTzhIuYNndGbnuVEGQNnHz2k6NAEarL28yUTk1rlep+lSG2S5nHf6TqIUOl8ONejPMxFRNz6+xnrzfYvsxPRHIT8xg4dA/RRpna5l1vGgSjvoozhKQrIWrlMX8VEerzFB+/R3zm67v3zI+3St/ICxWm4hk8jhhe2mONZ5pzQw+kgT4iPR1lRGtPpAkw+04zaGq5NK0rwUaU3qHZNR8TqRo9MGNB9eyOERqN7py1uFJdoFXASId9T5ziDVX6VDAOelRUwpEC19rlJRwbvrkOrbhTCB7+jvsFWnV7T2Y1aogJhrUU1VoJheA1KJJDL1QPL9jLeyfOBmvJ2aFneTtffpi1oEW7xRCmtq8wio0toAqXsbfQANph2FriOgyM7Uok0d0WAEYLbWR9vATud3Jq1C6x0vphMVAEFrcCbdiHbSBiCWQXDWUCSKrT7VRrzOazhAHKYUzr8llr9+VP936b8XpUKw/hfxeNzp+7nKeAAAAYVpQ0NQSUNDIHByb2ZpbGUAAHicfZE9SMNAHMVfU7UqFQc7iIhkqJ0siIo4ShWLYKG0FVp1MLn0Q2jSkKS4OAquBQc/FqsOLs66OrgKguAHiJubk6KLlPi/pNAixoPjfry797h7Bwj1MlPNjnFA1SwjFY+J2dyKGHhFD7oQxAgiEjP1RHohA8/xdQ8fX++iPMv73J+jT8mbDPCJxLNMNyzideLpTUvnvE8cYiVJIT4nHjPogsSPXJddfuNcdFjgmSEjk5ojDhGLxTaW25iVDJV4ijisqBrlC1mXFc5bnNVylTXvyV8YzGvLaa7THEYci0ggCREyqthAGRaitGqkmEjRfszDP+T4k+SSybUBRo55VKBCcvzgf/C7W7MwOeEmBWNA54ttf4wCgV2gUbPt72PbbpwA/mfgSmv5K3Vg5pP0WksLHwH928DFdUuT94DLHWDwSZcMyZH8NIVCAXg/o2/KAQO3QO+q21tzH6cPQIa6WroBDg6BSJGy1zze3d3e279nmv39AHnycqpvRjX0AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5QkHCiIwlmaJAwAAIABJREFUeNrtfXl0HNWZ7+9WVe+traWW1C0Jy7awje2ADU4Am8XhDE7MljCEmUkyMDxCMsMbsgxwgDfJ43FyHkwIw0kwyzgkjAk2xCYQm8XPC2AbYwxeZONdmyVrl1rdrd679vv+6KpSdau12AgjO7rnlLu7+nar+n6/+/t+33e/WyY4T9rst/bCVnvR9i/676ip2EdHr6x69HwZN+68+SFFpbMYu3vpF/13qMAXAjhvAMCcLz+ELSj0gX7xf4cqihPnUTtvGECVJA8D4IsGAVWp+3wCwHnDAFQQLjobDEBYZgoAkxIAsjob5GwAgHNOAWBSigDmrBiGWG1WYrVNaYDJ1q4osjqtLk0PUICQjB7QvYKqM4XpkdL851WaLSWo6fMMx+G4qxCyODAFgMnUglHgu7WAohlQ1Y2sG5Rkn9efqxoQFO25cT7nUdH6hLpCUM4f3jx/XMCppKru6M/8IJLvoKZHmn0eefrkbfEk6lvDIJI4BYDJFwcq8t5BoCPxxUSCFlXGJ0d6QRgC8MKUBph8YYCqsgRY3wP86wwKJ0cNF6D7cApAJUO+n4IMuQEMuQTV5C5UknnvkyO9SEoqQCnU84gBzhsAUAoZAGQKNPSmUaby2eKO6oKOZjMEHQKJ3i+bQShsDEFzIAULS0CpqoKqUwCYhAhQDV9OAELIkKm1qIACIHqygGbAYOQOdKuTzClq9CEZZBGDaM4f659XAACRDTlAAVWb8vq/QwxgNi6GsYTR39RHpSSLaqYAMIkZYCjGp6DQWEALA4cZPet1NkjMgFDNRqdTDDA557+mAaDF7KoBghwNkKsFRjC6+bVqtj+l8hQAJiMAQBNmBjCyeTQ3+0dHoH1zf2rqnwFUPqaZAsBk8gAsE9VUnqYB8vv/0YxOc6ICOsQuUy5g0jMAw0QNEQhANRl+GLXniL1cgZj1OQxlDbXPTbmASdkYJjakAShUlQ6b6Wb6pzQTL2adM4yvg4cMhYoqBVgAU2HgpGUAITcMzJ7dZLgrUNVhgi8bDBSmFIB+cooBJikDxA0G0GL3bL9Os2d4PoGYAwJoICJ6dihzdgoAk5IBCCPqlsvk+odcQN5wMJ/BTX2ztYD2RZmiwykATFIfIJqZWlFN4ZzZ6HkzgNkLR1nMQM0ugMCccZwCwOSiANEIA2FKBWcldmheBsgOCYczADHDZSoPMEntb8rXU1MeYLjKp5q6z9YDI+cGSHYakUwxwOQEgCil4TIDgOaf5ZQYGYDhopBkAUWHjnktgBAyxQCTsSlUFjlTIkjRFoOQRwQOf65FDAZoqAkMVCsV01NCmALAZGyqKqV0/pYp0VxAbno327DDw74h2jczAzGnBskUACZlo/JQnZZCqbGAMyy/n8UGdGj2w5wVzBaQ5hIhQqc0wCQFgCwZbEABhaqav6dDj4ZRaR7Vn5s61tki4wKMeJCZ0gCTs8lSGiYNkMnYU9OsHyH7l7NqOPQeMdjC7AIksOcVA5DJcBHF//gT+O/5XwOUAqCEAWEYmGeeHtep+nMVoCpACacv/sdArCUVNVYbJZhGkihORXQJl50KHqYJRssJ6CKQojGYAEMI2oJB2TfYyVOWBQijFyCqmUN7zbAAwwAMB7AcwFpAGQ4gLMBxIBwnJw5+5O1Y8eMpBgAAz1U3gPNUlhnbdLKmZw4AVFU7qOmRgpUkBBigRtZ3AQ358+HUfiaJIGBAZUFAOdZmc4NoRiYkA4RMjKgdLMCyQwCwWAHWAnBW7bUN9tqLplyAcREllabqC5JTm52nbNc4R7IEWpIQpEnGgIopj09z9wjS/Gng/GEiRUpSoAIIKypsqqJ1UDNfxujlxsSsFDX05NShARprMFCV1BQADBOJ6ZxCPLPx9elKhnkuatRwU2NLVz8LzFJIVlVwNqlkZwYxrFBkKErgZRV9KRkOliCgMkOuxywjKQEhdLhHNdiAybgElgM4S+aRYcG5y8sBBKYAAICtKKvNzrCPxAK5r4lhBN3X84QgTgC7CgMceUXfCOd1lxFIy0hIKggIZIYiohKwVAVRVQNEoCrAAFTfkciQIWNrvh8WK8DZMs9ZSwYEDAu22HsJgPemAACAsbgXZlMCTPu7tUd9t4ax80PvQ4zNHDokUoSaFoPoEFuYKT/PHgAASCsU/SkZqko1VqcQDUDqDJBN50NG1wyc+8hZtcNigEOJhv9mCgB64iadvoktGiFGMftXs5UZzS0wJLsvAAUECqUgIKYcAB0l5AMkhSLEK0jLapY7HwKlCqhK5tCpnWUzhrVYAdZqEns61XPDgaG5ADicc6Y0gNZcbmcla9qnPETTBGD1F8TM+FqBBmNs4reorLZYN1QWTnKTPzTfpg9gUJARF1XDbQ+l/c0+QgUUGawqw2a3AxY7YM0clLUBHDdkYJbNhH0MO3RogKDaa6a4xDMFAF0DHNhyIxYskQTvTI7kev084o/kpGdBgSI4EEkAvGZYhVKjnDuv4ANFQlQxKCjDRHyWDkFmnyFUFVRMo7CkHHJxWcb4loxvJ/qsZjR3oKcyDFelMRaT6SINnAR/aOfVU4kgU3POvxbTvncHdX77TsiqJYvSkWvw3HOaVYkKnEwDs5gU/AP9RkQ51EWr61YpgrwCUaXDB8CgEWqoeY4jOBGKoUROwVtaATjcGQbQqV6P+3XXQLTwUP9y/a4VrIyBja8g8MbLRD720VQmcBgTXHKdo+SC2tQF/3o/5Jp5ORsyRosjh2wnS4BNTMM/0DsMAACQkDKznuiGNqf9crSEGQAn+wZQ6y0H3MWZ2c9atWQPYwr5MPzQACD0NqDzxV8jfapxoXp892dTqeARQfD1a4nVueOC5Teg+O9/AJHYRmWALJehvS5Op+Hs6clsETdVBg0KJpFHxzEyWh+OBRKMA9bSCsBiAVhmSHwyeUbSdFEMRATWr8LA5r8AkvBz5ciHT0ytBYwFgoXLfgmr7X97yrxY+j9/DsJZjCk+agJHm+4KpZDkoWSNpGSEnqLmoZMRwTD0BscwcFjZ7L7jABFVFTT88deI9nYCVF6jHNx2x2Qb60kJAABgL/vmnwjH/YPHV4Mr735Q2+qdmyykeVO3MO0JiJ7OrJ/g1r5uBZI9raCy+K7StO9mpBOTb5wnKwBoLPgm8VR+LZ1MXhjtbEXlJZcPK99W6VD1jprznqioCGtCb/x/lOZMCXNMSIciAzL8fUJhuuUYi863XkS8vRFQpF1qd9v1iAUm50SbrACAxAMUrzEFJcuSsUhNMtAD79xLM4Y2Vf2q2iYQ/X4ACgXiooKYoJomvEkJkhz+pqNkm8+EMRgWvVteRazxAAhVP0M8dLna3Thph3nyAgAAEoMgRRX/Tay27ySC/eVSIobSC7+igYBm3egRAAQlI/Rk1RTX587q3En9eYw9zPgMBj56G+EDHwKgTWo0NF9t/WxSD/HkBgAAGuwEHEX/xThc/xjt7fRAkVA4fXbGHZjCv4SkZBZvcjN4ZKwwMofih31wtNfmO0sRhOu3YeDjdwHQHhodmK62Hprsw3tu3ChSbdkPkoxeaC0o6un67FP0HNwNlWaWfCVVxaAgg1doJmOXy+V0vLOb5DFuvjVqmhcUseN70b/9LwAhYZpOVCmth8+FoT137hQqHtsFRhKrOGdBpGvfhwi3HoegUER5RVv5047cm/yMiQaS/dlR/QHN+zrVfhw9m9eAEJIAnypVGvacK8M6ecPAkZrrmtvAuEuSAJwVX78NjsoLRrYRwdi3daOnMQrm7KHW+N5TaH99BSilIk3HbPKJPefUeJ5z9wpO7nwTSjToAsAHdvwFQqgvt9IjZ0aPMZPNIKEjfJbS7D7aIQR70PH6swClKuWT55zxzwkRmNuqq6tRKkUesMnppSm315I8dRyuCy4Ea3OcPvl9jps+yvEI2lc/CVUWAVlg5GMf41xs54wLqKmpgcPhWMVx3PcAWEEpkgUVCJfVgbFY4b/hTnAO98jUbfxi8rnv9qnwKbT9/v9ASsUBWZgtN+1vwjnaJj0D1NbWorKy8s92u30ty7ILCSGsbkirkAADirSlAMn2BrhnzAPDsKZVPjqBMM98lyqJaFv1fyHGQoDI/0hpOfAezuFGJrPh7Xb7Fo7jltGcGUuzb92KiGc64oV+WNxF8C2/AwzLja74xmKAvIEABaUq2lY9jnR/J4gqv6w01/8PnONt0gFg5syZsFqtn7Ase0Veg2uvaY5IG/ReiKSrDDZPOSqv/y4IYZA/z5ub+KEj6MOcwhAQtL/6FOIdTYAibaBth2+FqmAKABPQLBYLamtrYbFYjrAsOz/X6GMBgNLMWmGo4iKkHSWwl1ej8rq/G1cWiOZs/yX5QMEw6Pzzc4g2HQQUeQftbf06UlGcD+1LBYDT6URNTQ04jjvJMMyMkWh+PADQW7ByHgSrG64LZsF79S0Y6T93oDTPrh3zwOg6gmHQ8+4qhA/uBED3Ixb5Kg204nxpXwoAPB4PysvLyzmOO8QwTCXNY4R8Bh7J6FnPAQz4LoZksaOg7hKUXr4sCwRjGT5rcBgGgW1vIrDrHQBooGLqInQ14nxqZzUK8Pv9qK6uvr6oqGgfx3GPEkLG/d+wjsYIueeciQGkXWXgBwMApbBXThvqM94QkBAM7tmKvu1vAEAHTUbr0NuC862dFQBMmzYNVVVV97lcru0sy95NCHGcieFHen8YQ1AKeyKItLsMqf5usDYHrKW+PMbPFYl62MggemQ3ut/5b1BKA4RPVKGvFedj+0JdQG1tLZxO5+84jruLEGIdz+wdy8fne998/2bzeZm1IuSbDxUE3mu+Dde02fnkftZwyKkEwgc/ROCDdWAIQQkf7iISXxOJRCDL8hQAxtNmzJgBp9O5jmGY7xBCmLFmdL5zIxk136wfSS9QSiFxdoR9c0HBoPL6f4DDV5sHAARyKo5UoBvJUycQ3rkBAIVHHASnSPr39SiKUhePx9OiKE4BYBTDb+Q47obTMfZYAMinAfIBgFIKm80Gv9+PSCSCYDCYAYHVhUjFHIAQ+G66CzaPz/j1ciqBVH8XpGQMUiyE0AevA6qKYjECqyrmA1+PoihzkslkXBCEKQDobf78+fB6vTQWi0GWZa0m/+wCwGazYd68eYjFYkgkEmAYBl1dXZAkCaK9EDFvHQjLoerbPwIsNqQ1wxNCICeiCL7/J6iSiCIpBpvCD5MMOdcQUBTl0lQq1X0uM8KEiUCGYf6USqXmFxcXw+VyQZIkqKo6FE9PkOjL7VtUVARCCCRJgiRJ6OvrQyKRgM1mgyiKsFgsKC4uhpSIQk0lINoLEG86CJVwADJVREo6idAHf4Iq8nCLcdjktGn1l47kZlyEkPstFsv/tNlsmwAMKIry18sAPp/vBMMwcyilcDqd8Pv9AIBYLJYFhNEYYDxxvpkdqqurkU6noSgKLBYLenp6st4vLS0Fy7KoqKjAwMAAFFlGS1QE76kBsVjhXrAUBATB99ZATsbglJKwC3GolOa93tHASSkNq6p6jSiKx84lRpgQAFgsFni9Xmqe7ZRSFBQUwOfzQZZlxOPxUQEw2oJPPgBQSqGqKvx+P/x+Pzo7O1FSUoLjx49Dn4l6H7vdjtLSUqTTaTgdDjRERPCFFWAdbgihPkiRATjkNJxSArmzmJp2CI8HDJTSGKX0e5IkbTwXNMKEAKCsrAw2m42ORNPFxcWoqKiAIAhIJpNjL+6MEwD6exaLBXa7HRUVFSCEIBQKQVEUKIqCQCBgfMblckEQBLicTiSKqxCmNqR7TsEip1EgxTL/RZwJAPmuaSQmy31PB4Isy5MaCBMCgMrKyiqWZbvG8tdlZWXwer1IJpNIJpO5A3baeQGzf9aP6upqyLIMt9sNVVWRTCbR09MDWZaNPm63GyzDoNtaCiHUj1KaAiEE6XR6zPBzLO2ShylSlNJ7ZVl+ZTICYUJEoNvtfpFhmPmjZ1YzAxwMBmGz2VBeXg5VVSFJUt6++c6NdN7cotEoUqmULkwRjUZRXFxsMA8hBKIoIp1Owy2n4LFb4HDY4XK5wDAMZFmGoiinJV5p9u3kjc8SQsAwjIUQcivHcQ9ZrdYYx3F78/3mcxoABQUFTxBCSsfbP5lMIhwOw+FwoKysDIqiQJKkMQc9dwbm9tcHX1VVpFIpg/YppfB4PIhEIkYfSilkWQbPp8EwDBiGgaIoYwIgF4j6a83Yw56bHi0Mw9zAcdwjdrudZ1n2k8kAhM/tAiwWC8rLy8+oyI5SCo7j4PP54HK5EI1GwfP8qIIrn17IpW39tfk5AHAch/LyclRWVuLkyZOIxWLged7QFIqiDNMXuWDLNf5YzJUPQNr3ipTSlZIk/VQXyOckALxeL6xWK831gadLoVarFX6/HzabDZFIBIIgjCi48iWJRsoMmp+7XC7YbDbY7XYUFBQgEAggFAoZOQv9yP17DMNk+fh8Rj/d32y6dllV1f8WBOGfE4nEuQcAlmXhcDhoQUHBuHz0WEBwOBzw+/1gWRbhcDjvAkzuDB1NROayg/43EokECgsLM4kgRYHD4UA8Hkcymcz6DMMw8Pv9SKfTCAQCBqWfjsFzmWQEcSmrqrqW5/k7ziYjTFQi6CQhZIYe9+cO4pkAwe12w+/3Q1EURCKREcOz0Yw/1nt6CFtbW4u2tjbIsgyHw4He3l6DCfRkkq5VwuEwYrEYUqkUcvMeI/3e8UQTpnOqqqpvpFKpvz8bQJioVLAFwLJ/+qd/wooVK3DTTTchGo2iqakJDMOcNgj01G4oFIKqqqisrITFYoEgCCMOtPkx3zFSX0EQ0NnZCY/Hg5KSErAsC1EUIYoiWJZFOp1GLBYDx3Gw2WzgOA4lJSUoLS2Fy+VCLBYb8W/m/u185/TxMb1HGIaZZ7VaH3U6nZcxDLP2i8wsTlgq+O6776Z/+MMfoCgKQqEQwuEwurq68MILL2D37t3gOO6M2ECfHR6PB5WVlUgmk4hGo+NOG4+rjExjCp3elyxZAp7ncehQZnu3IAhQVRUcx8Hr9aKqqgqDg4NobW2F1Wo1ws6RftdYDDDW+oeiKJuTyeTyL4IRJoQB/v3f/x2PPfbYYzabTc8LoKioCC6XC0uXLgWlFJ999tmoCnosRuB5HgMDA4ZYBGBEDGN9Nt9MzPdcN8bAwAASiQQWL15sCEMdCIlEAsFgEOl0GoIgoLq6GvPnz4fT6YSiKOB5ftRryMcII/Ux6ZA6m832mMvluooQsnoiGWFCGGDv3r2WRYsWifqF6wOmKAoeeeQRbNq0CW1tbSgqKgLLsp9LKOr9KyoqUFpaisHBQYOGx5utG89zPSlUUVGB2bNno7W1FZFIBLpS10NYr9cLv9+PZDKJlpYWlJSUIBKJjArO0TTAWL9Dy1/sSKfTX4/FYpMDANu3b3+roqLiFp/Ph+LiYuNCn3rqKaxYsQLd3d1GX5fLhcrKSnAcl2W4M3ELLMvC5/OhqKgIoVAIyWRy3Gr8dFyDqqpgGAZ1dXUIBoMQBAGFhYXo7e01Ek+EEHz1q19FRUUFGhsb0dWVyYzr7uF0ElxjAUDXDuFwmHze0PFzbw8vLi6G0+m8RlEUdHR0oLm5GclkEp2dnXj55ZezjA8Ay5cvx9tvv41169bhzjvvNBiBnuaGTX3gu7q60NTUBJvNpm8gPe3vGuvvsCwLQgiam5tRXFwMu90Ou92OsrIyo191dTUaGxuxa9cuMAyDhQsXQhAE1NTUGEYbKZ09XsCbr0XLk/zuS9cAv/3tb3HxxRf/Sh8sWZYRDofx7rvv4r333suald/4xjewfv16eL1e2Gw2zJo1C7fccgtSqRQaGhrOiA10IEQiEcTjcZSVlcHj8UAQBKMyaSIbz/MoKipCZ2cnEokEampqcNlll4HjOEyfPh2yLCMQCEBRFMydOxdut9sIMy0Wy7DweDyGZxjGENGiKBqJK0qpIgjCH75UF1BfX++pqqoK6aGTJEmglOLpp5/GK6+8Yiz2cByHkydPZs0IVVURCoUwODiIAwcO4MEHH/xc2sCc8auqqgIABINB4xpON1oYrU95eTkuvPBCCIIAt9sNQgjC4TBcLpcRCbW3t0OSJPh8PtTU1CAUCoFSisbGxiw2GM0FsCwLhmEMQOsuSUtdx6LRaNHnsd/nvl18aWnpKqfTCYvFAo7jzAjlJUmSAbgB4Prrr0d1dXXWgg0hBF6vF++//z5++9vfIhKJwOVywWKx5BVG42WEVCqFpqYmFBYWoqqqysgp6AM4UkZulLz9sBaJRBCNRuH1eiEIApxOJ0pKSiBJEiKRCGbOnImqqiq0t7ejpaUFDMOgsLAQFRUVEEURp06dGt0wHAeGYSBJEtLptHEd5mIYAIUMw5w2q0wYAMrLy+F2u6+x2+3gOA4cx8FisaCjowOKonwKoAHAVQBmXXnlldaGhgb4fD6UlJQY+fWdO3fi8ccfR0NDg7GK53A44HQ6UVpailgslpUsOR0gxONxnDhxAiUlJaiqqkIqlUIwGDQGLF8ef7TnZlCIoogjR47AZrPhK1/5SpZxamtrcfz4cUyfPh0+nw91dXVobW1Fa2srjh07NmoameM4sCwLSZKMFU1zvUPua6vVei3P8x9+KSLw2WefRUlJSTHLsrBarbDb7XA6nTrt/hnAnwD8GcDWSy+9VFRVFZ2dnWhubjbCqaeffhqNjY1ZKHa73Vi5ciXefvttPPjggygqKsq7CjheIEQiERw9ehTxeBy1tbUoLS09o9AzXyZRFEXs378fBw8ehCAIsFgsSCaThs5Jp9OQZRl+vx/Lly9HZWXlaGsqBoOZVyl1w+caX9MH931pUcCll176NfO6t54u7erqwpYtW7oAeAAEKyoquubMmWPV3YQgCGhtbcV7772HEydOZOX5HQ4Htm7dittuuw2VlZW45ZZbsG7dOtx9992wWCxnrPAJIQgGgzh69CgEQcD06dONkHUiWiqVQn19Perr65FMJlFcXIyenh44HA7olUA7d+40ClfNAs/hcMBisSCdTiOVSkFRlBFnfS4IPB7P0l/+8pev6smxswaAtWvXwufzbcrNYqmqiuPHjwfC4fB8AEsAXPLNb35zfmFhIZxOp5FPZ1kWBw8eRDSavc/+4YcfxiWXXAJKKQoLC1FXV4fq6mrccccdWL9+PebOnXvGbKAPen9/v0HFM2bMMBhmIkLGVCqF/fv3Y8+ePXA6nfB6vWhra8OOHTsQDAaz3JnD4YDdbjcyjLqAzjfr8zEAAMTj8bIFCxZ8b8WKFcknn3zyj7W1tV+sBnA4HPjwww8xY8aMTpvN5tGpW2eCjo4OtLe3pwBcqX//NddcU2u328GyrLGooy/zDg4OJnShyDAM/uVf/iULTHpRqcViwUMPPYTm5mbwPA+73X5GItEMhJ6eHgQCAfj9ftTV1SEQCCAajX7u0FHXH5988okxNuZFMbvdbsx4nuezDG7WEvlmfG7UwPN8ptrZ6XQuWLDgzpUrV37n5MmTa5599tl/bmhomDgGsNvt2LdvH06dOnVk4cKFtKCgoFoURWOFTr/QxsZGHDp0KALAqX2/euWVVxbr+sDpdMLtdsNut6O3t7dPluW/ADgKgL/kkksQi8UwODg4bOB+/vOfY8OGDWhvb0c4HEYwGIQoikYZ1+mygt5XlmV0dHSgsbERLpcLM2fOhNPpnBBGyGf4oqJM1KZXP+Wb6aP5fDMIFEVBVVUVHA6Hcc5msznr6up+dMcdd7w1YQxw4MABVFdXH/F4PPPNFTMsy4JSCkEQwDAM+vr6sGnTpkhzc3MQAA8gXFNTE7nwwgtv0AdD1wo9PT3geX4HgHUATgFYdO21135NEISyzs5ODAwMwO/3w+1244MPPsDbb7+N3t5e45pEUURJSQmeeuopJBIJPP/882hrazujiAEAJElCa2srHA4Hqqur4fV60dfXh3Q6/bkYQd+v6HQ6IYqiUdsw0gwfyei5htcjhksuucQQn5RShMNhNDY2Bjds2PDmhAGAEHLMarXOHalWTpZl1NfXY8eOHfyrr766H8BmAE8DwJNPPnkrx3E/MadDGYZBb28vWltbjwGwA+gH0LB48eJFFosFiqJAFEW0traiqKgIGzZsGJZSnjNnDnbv3g2bzYb+/n5cdtlleP/997Fy5UqEw+HTBoF+fTzPo7m5GW63G9XV1VBVFX19fTjdkm69zE1nk1gsluXjxzJ8vtpEvWZRn0QMw2DWrFngeR6CICAQCPDvvvvup9u2bbsNQHjCUsFOp/MFi8Xydy6Xy2u1Wo20pCRJ2LdvHzZu3Khu2bKlbdWqVT+PRqM/A/CJHibedtttm+x2e7E5jGIYBtu2bcPKlSs/VRTlAgC1Vqu17IknnviqzWYjZsPxPI/nn3/eWFzRDbtp0yZMnz7d2Ptnt9vh9/tx6623oqCgAMeOHRtXpfFImUdJkjAwMABVVVFTUwOn02ko9NG+U18lLCwshM1mM/ZA6LM+3wwfy+frbk6f9frBMIzKcVyv1Wqlu3btan7hhRf+o6Wl5V8BpCdUBP7mN7/Bb37zm3kPPfTQvFtuuWXHzJkzy06ePIn9+/fj0KFDp7Zs2fL7np6erP8Na82aNVi6dGl9YWFhrZ710w9BEHD48OGYIAgXa9fAXHXVVWUVFRUMz/OwWCxGVY6WTpXN17ps2TIsWrQoa8XO7XbD7Xajv78f0WjUmLFnUqxpBmo0GkUkEkFpaSlmzpyJWCyG/v7+vFvIGIZBQUEBrFYrEomEkcEby8gj0b6qqobh9VnPsixYlgXHcZBlObZ58+ajmzdvDgNYA2DjF5oJ/PWvf33sd7/7nffxxx9f1dTUdMX69etXd3Z2Zhl+3bp1uOqqq/5cWlr6nc7OTnR2dhrlUzoQGhsb0dzcHNaEogpAXb58eaHFYgHDMLBYLMYRj8dBKd0NoBjALAD26667DuFwGCUlJVnGlWUZv/jFL7B161Z0d3eDYRgUFRXs2ItaAAANeUlEQVTBbrePa41hJLDoef5QKITy8nLMmjUL4XAYgUDA+IzL5TJYQr8vwZkaXs80KopiGFw3uvmR5/kuZP4L+hMAEgAcpzP7zygMjEajuO+++4bdIXPdunXw+Xyvejyef1AUhSGEoKCgAPF43Ki506twt23bJu/evbsHgAwgBaDjuuuuu1hf+DAnlXp6etSmpqZnAMwF8FUA8y+99NIZXV1dCAaD8Pl8KCgoAAC89tpr2Lx5s6EX9CLOoqIi/OxnP8PBgwfx6aefGi7sTJhhYGAAAwMDqKysxEUXXYSBgQHDVQWDQYMZxuvj8xlekqS8M978qAGgA4BeHmQFUPCFA2CkNmfOnHqO4y4FgEQigUQigYKCAqiqCpZlkUqlkEgksH37dqxevbohkUh0AFgJ4MNp06Zhzpw595ndhF6Q2dLS0sDzfAxABwDbtGnTuJqamhm6UGxra0NBQQEqKiqwZs2aYWKxsrISG9/fjoICN76bSuCzQ4fw/PPPo7m52chdjIcFcltvby/6+/sxd+5cnDx5clgSZzyGNws9SZKMvRDmWT+S8SmlvCiKQW0SCVouxasBIH7WAbBv377L5s2bF/J4PB7db+kLOdFoFI2NjWhqakq98847uw4fPnwTAGNf1NatW290Op1M7mxrb29Hd3d3D4BFAEoAFN9www1lekglyzJkWUYymcSWLVvyrrC9+eabWDh3NtIqEE7zWOR04vcLFmD79u1YuXKlUes/0rLvaFvEVFVFOp2GXqOXz9BjzXxFUSAIAhRFAcMw4zI+wzBIpVJdmvvkAdgAlGluYOBLAcA999wDr9db+uijj66+5ppr/s5ms1mj0ShaWlrQ0tLC79q168C2bdv+RlGUdA5wUFtb+3auUASAjo4OHDp0yA7gco3iuKuvvvoCfcnYXIPQ1taGSCSSdU233347Fi9eDEop7ITC77Ij6boA0WQC1y9fjqqqKvzbv/3bqLH+aIzAsqyh7vW+Ixk+3+wXBAGiKOY1fD7ja0AVBwcHjw4ODh7X6J/XGCAOoEfTBGffBQDAwMAAfvzjH9+xZMmSO+67774Po9HoFe++++5nW7duvVkUxawL++ijj3DhhRfuSyaTi/r7+1FWVga73Q4zEE6cOCG3tLTIAAq1j6lLlizx6Isn+uKSLMuw2WxqJBI5DqBOyy3g9ttvzyrHopTCjUzByCtvvYVn/vM/0d3dDZvNBpfLddq6QF+vN+9FHM+sFwTBqB7WjT+WzyeEIJlMdoRCoaOqqkY040cAdAJoBNCsJdTwpQFAbx9//DE+/vjja/MVK6xatQqzZs3aPmPGjKVlZWUghCAajaKtrQ0ejwcejwccx6GhoQG7du3qUxRF1X5s6rLLLuOqq6utekGoHg9rWqFFluXVmlBcwHFc7ezZs7mmpib4/X7oW9copdi3dy+eeuIJnDhxApRS8DxvbBXzer2G68pXC5APALnFGiMZXt+Wbi7sHM34+iGKYiQUCjWIohjWRLMMIAigBcAh7TF8Jrb6QgCgt1zjb968uaqmpqYLAMLhsLF3X7/LRzweR1FREVpbW/H666/zmzdvbtV+6HoAa++9997VuduxGYZBe3s74vH4pwAOa2BJfO1rX0vYbLYFuntwu93w+XxwOBxYsWIFmpqasny9oihYfsst+MXDD6O3txcvvPACPvroI3AcN6oOEEVxTPEny7KRRNI/pxt+NF+vqio/MDDQkkql+jSqT2mP7QAOake3WU9NKgDkWTPvppSKLMta9Vu4hEIhYzbFYjHs27cPhw4dSrzyyivvp9Pp75nDmptvvvlSszH0Qezu7saBAweCAOZoYjF1ww03WPVwTzeAXoiyf//+YZtO77zzTqx6+WVERQn2omI8/vjjOH78OJ577jkcP37cWPfI3dySW6eXK/DMItG8QDSaryeEyLFYrCMajXaYjK4fBwEc0Y7w57XJWQXA3/7t32Lp0qW2e++995OFCxdeoQ9eOp1Gc3MzmpubxV27du1///33/0ZV1SyxePTo0eu9Xu9cs0/XW2Njo3rkyBEPgEotuWRdvHix3+VyGUJRv/HDnj17kLuhoqKiAs8++ywIpSi2cCjy+xBJl+ArDqexte2ZZ55BMBgc9ptkWc4b2ulLvWawjMf46XS6b3BwsFVV1ViO4Ts14x/TnqcnwiZnFQAAsGPHDuzYsePKu+66C9///vfbXC5X7c6dO+VPPvnk6JYtW27leT5LyLzzzju44IILNnq93htkWQbHcVlCMR6P48iRIxFZlvVKCLWwsJBZtGhRMQBDLOo1CJIkIRgMpjSgAAB+9KMfobCwcEj1U4oSuw2FF9QgGImiu7vb2PFsDhl1es9V9qlUalgoOVaIJ8tyLBQKNYmiGMmZ9REA9Vp9ZctEzPovFQB6e/nll/Hyyy9Pv+uuu67dsGFDSyQS6c5df7jmmmtWzZ8//06e55n+/n6EQiGj7l9vhw8fxvHjxwN6ShmAePPNNxfre/X0QlWLxQKe59HT09Mny/IOAAsAzABgXbJkCWKxmJGpNJa7KcVLzz+H1atX4+TJkwCAwsJCowxcp3ld4OmLPvlqAkYyPgA+Eom0an4+ZQrtEiaqb9F8/YS3Lw0AJiBkVbReccUV+NWvfvXDkpKSFRzH2Ts6OlBRUWEoZf0+P06nE9FoFO+8805qz549+uAFAKy9/fbbf2muVdQHvKenB6lUapu2aBIAMLekpGRubW2t/9SpU1lCEQC2b9+ONWvWoKmpKSsVnkgkUFRUBKvVCkmSEI1G897sajSVzzCMmkqlOuLx+CmTwNON36yp++aJpPtJCYDcFg6HUVlZ+aLuSyVJQmdnZ5YISyQSaGxsxLZt28Q//vGPn1JK1wL4vf4dixcvfkXXCOb1hb6+Phw9erRFyxP0ArB/4xvfKCOE+DmOM4RicXExfD4f3njjjSzjmyOGcDiMwcHBvJVDI4V4+qMoioFYLNaiqmrCRPcigD7Nzzdoqe/wFz3ekw4ATU1NeOmll8jy5cs7q6urq/WZpfv9zs5ONDQ04MiRI11vvPHGf4XD4azVyIMHD6KsrKwyN25nWRZNTU3q3r177QAWarlz5/XXX19mt9uzhGI0GsXAwABaW1tH3XQxkvHzzXoNwInBwcEmSZLCOYYPa2VxTdrKXuBsjfekAwAAPPXUU3j66adrHnvssfuWL1/+HwUFBe5AIIDGxkYcO3YsuGnTpq2NjY3fzycwZ8+eLZgBox+JRAJHjhwJK4oy3/S7mSVLlpS73W4jLasDoa+vb8zdxqNRvpnuCSFiMpls1ZZveRPV8wCOa/mLZq0yKn02x3pSAkA34KOPPvrcK6+88twjjzzyVigUuurNN9/ctXfv3m/l9v3www9x0UUX7YvH44t6enrg8XhQXFyUlcHTwsyIRv8qAPXiiy+2z5gxw6pHF7pY1Gv3Dh8+3ALgAm0dYtRl4lyxp/t5URS7ksnkKW3Gm2e9HtY1aXT/pdwrbtICQG8tLS245557vpXvvRdeeAELFy58x+/336SHcdFoFIFAAJF4Au5iDzwFTqiShF27dsmaWFQ1Q4S/+93v1plnrA4Cq9WKtra2nmg0+poWLVysAYEZzd/nVOsE4/F4S554vk+L5b+QsO68A8BIbfXq1ViwYIHEsiyXSqWMdK8eq4vpFNzeMgQGY9j5wVasXbu2JZVKhQHs0eoQwjfddNPB3NSyfnu6/v7+T7UZmtZCsh4tbKzMBYDZ12fKIRItsiwHcwyfOhth3V8NAGKxGBRFSVkslkLd38fjcWPTKSEEn376KY4cOYKNGzce3b179+MA1uqff/DBB1FXVzc/VygSQtDX14f6+vo+zeAuLRnTY5rBtciUqJkrdEVBEE6JotiVY3jdzzdoM//UZBpHgnO4zZs3D/fff//GK6644pssyzL67A8EAnqkENi4ceP/a21tzSphq5k2Dfv27Nnk9Xq/mZtWppRi3bp16p133vmyJEmcljHkTAejPXoA1HEc5+Q4rkcQhFZKaWqU9G3b51m0mWKAPO3YsWP4wQ9+cOONN96IH/7wh4fmzZt38d69e3HixInYpk2bdtTX1w/TDq+//jrmzJv3ESkuvkomBBZkF33wPI/6+vqIJEl+TS9Ae5Q1VxDQQjYvgK/Islwsy7Kao+z1RM5nk4Xq/yraAw88UPXtb397fb7l22eeeQatra2/EwRBaWtro01NTbS5u5v2CxKVVZWq2nH48GG6bNmyY1q28C1ktrevAvBDZKqS87VrAVyvvV9wLo0ZOd9BsWzZMjz88MPzKioqPrVarW6PxwNFUYz7EzAsA2e5DzarBRaBx0svvcQ/8MADOyVJSiBTi/AagA/P1/HhzncA/PSnP/VUV1cf1VfrQqFQ1oqeqqpwUwXhwCA+eP999cUXXzwgSVIDgF98WbH5FAAmsNXX14cZhjlcV1d3sXn7tS7+JEnC9u3b0dDQwL/22mvbjh49euNfk9skfy0/9P7775/3rW99a4fP5yvTM4Tt7e04efKkumvXrqPr16//ViqVOoWpdv62oqIiPP3006s+++yz9Nq1a+lPfvKTdp/P98Opkfkra5dffjmuvvrqa6dGAvj/As0c7mrdeEkAAAAASUVORK5CYII=);
            background-repeat: no-repeat;
            background-position: center;
            background-size: 40px;
            width: 40px;
            margin-right: 20px;
        }

        .footer-desc {
            position: fixed;
            display: flex;
            bottom: 20px;
            right: 20px;
            align-items: center;
        }

        .footer-link {
            font-size: x-small;
            color: black;
            text-decoration: none;
            padding-left: 10px;
        }

        .button-o {
            cursor: pointer;
            height: 25px;
            font-size: 15px;
            background: none;
            outline: none;
            border: 1px solid rgba(0, 0, 0, 0.35);
            width: 50%;
            color: white;
            background: black;
        }

        .button-o.selected {
            background-color: white;
            color: black;
        }

        .button-o.left {
            border-radius: 14px 0px 0px 14px;
            margin-right: -3px;
        }

        .button-o.right {
            border-radius: 0px 14px 14px 0px;
            margin-left: -3px;
        }

        #overlay {
            position: fixed; /* Sit on top of the page content */
            display: none; /* Hidden by default */
            width: 100%; /* Full width (cover the whole page) */
            height: 100%; /* Full height (cover the whole page) */
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-color: rgba(0, 0, 0, 0.06); /* Black background with opacity */
            z-index: 2; /* Specify a stack order in case you're using a different order for other elements */
            cursor: pointer; /* Add a pointer on hover */
        }

    </style>
</head>
<body>
<div id="overlay"></div>
<div class="footer-desc"><img
        src="data:image/png;base64,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"/><a
        class="footer-link" href="mischianti.org">www.mischianti.org</a></div>

<div class="tile-container">
    <div class="title-image"></div>
    <h1>OTA Update</h1>
</div>

<div class="container">

    <form enctype="multipart/form-data" class="form-container" id="upload_form" method="post">
        <div id="switch-container">
            <button class="button-o left selected" id="firmware-button" type="button">Firmware</button>
            <button class="button-o right" id="filesystem-button" type="button">FileSystem</button>
        </div>

        <input accept='.bin,.bin.gz' class="input-file" id="file1" name='firmware' type="file"><br>
        <progress id="progressBar" max="100" value="0"></progress>
        <div class="additional-info">
            <h3 id="status">Firmware upload</h3>
            <p id="loaded_n_total"></p>
        </div>
        <hr/>
        <button id="button-send" class="button-send" type="submit" disabled>Upload</button>
    </form>
    <script type="application/javascript">
        function stringToBoolean(string){
            switch(string.toLowerCase().trim()){
                case "true": case "yes": case "1": return true;
                case "false": case "no": case "0": case null: return false;
                default: return Boolean(string);
            }
        }

        const urlParams = new URLSearchParams(window.location.search);
        const onlyFirmware = urlParams.get('onlyFirmware');

        if (onlyFirmware && stringToBoolean(onlyFirmware)===true){
            _('switch-container').style.display = 'none';
        }

        function disableAll() {
            document.getElementById("overlay").style.display = "block";
        }

        function enableAll() {
            document.getElementById("overlay").style.display = "none";
        }

        function _(el) {
            return document.getElementById(el);
        }

        function uploadFile() {
            var file = _("file1").files[0];
            // alert(file.name+" | "+file.size+" | "+file.type);
            var formdata = new FormData();
            formdata.append(_("file1").name, file, file.name);
            var ajax = new XMLHttpRequest();
            ajax.upload.addEventListener("progress", progressHandler, false);
            ajax.addEventListener("load", completeHandler, false);
            ajax.addEventListener("loadstart", startHandler, false);
            ajax.addEventListener("error", errorHandler, false);
            ajax.addEventListener("abort", abortHandler, false);
            ajax.open("POST", "/update"); // http://www.developphp.com/video/JavaScript/File-Upload-Progress-Bar-Meter-Tutorial-Ajax-PHP
            //use file_upload_parser.php from above url
            ajax.setRequestHeader('Access-Control-Allow-Headers', '*');
            ajax.setRequestHeader('Access-Control-Allow-Origin', '*');

            ajax.send(formdata);
        }

        function progressHandler(event) {
            _("loaded_n_total").innerHTML = "Uploaded " + event.loaded + " bytes of " + event.total;
            var percent = Math.round((event.loaded / event.total) * 100);
            _("progressBar").value = percent;
            _("status").innerHTML = percent + "% uploaded... please wait";
        }

        function completeHandler(event) {
            enableAll();
            _("status").innerHTML = 'Upload Success!'; //event.target.responseText;
            _("progressBar").value = 0; //wil clear progress bar after successful upload
        }

        function startHandler(event) {
            disableAll();
        }

        function errorHandler(event) {
            enableAll();
            _("status").innerHTML = "Upload Failed";
        }

        function abortHandler(event) {
            enableAll();
            _("status").innerHTML = "Upload Aborted";
        }


        _('upload_form').addEventListener('submit', (e) => {
            e.preventDefault();
            uploadFile();
        });

        _('firmware-button').addEventListener('click',
            function (e) {
                e.target.classList.add('selected');
                _('filesystem-button').classList.remove('selected');
                _("file1").name = 'firmware';
            }
        )
        _('filesystem-button').addEventListener('click',
            function (e) {
                e.target.classList.add('selected');
                _('firmware-button').classList.remove('selected');
                _("file1").name = 'filesystem';
            }
        )
        _('file1').addEventListener('change', function(e){
            var file = _("file1").files[0];
            if (file && file.name){
                _('button-send').disabled = false;
                _("progressBar").value = 0; //wil clear progress bar after successful upload
            }else{
                _('button-send').disabled = true;
            }
            _('status').innerHTML = "Firmware Upload!";
            _("loaded_n_total").innerHTML = "";
        });
    </script>
</div>
</body>
</html>

Descrizione del codice

Il codice è abbastanza semplice, utilizzo lo standard XMLHttpRequest per eseguire il POST e cambio il target (firmware o filesystem).

La form rimane molto semplice.

    <form enctype="multipart/form-data" class="form-container" id="upload_form" method="post">
        <div id="switch-container">
            <button class="button-o left selected" id="firmware-button" type="button">Firmware</button>
            <button class="button-o right" id="filesystem-button" type="button">FileSystem</button>
        </div>

        <input accept='.bin,.bin.gz' class="input-file" id="file1" name='firmware' type="file"><br>
        <progress id="progressBar" max="100" value="0"></progress>
        <div class="additional-info">
            <h3 id="status">Firmware upload</h3>
            <p id="loaded_n_total"></p>
        </div>
        <hr/>
        <button id="button-send" class="button-send" type="submit" disabled>Upload</button>
    </form>

Puoi vedere che non c’è il nome dell’input “filesystem” questo perché lo gestisco tramite JavaScript. L’invio viene interrotto con questo listener.

        _('upload_form').addEventListener('submit', (e) => {
            e.preventDefault();
            uploadFile();
        });

Quindi viene chiamata la funzione uploadFile.

        function uploadFile() {
            var file = _("file1").files[0];
            var formdata = new FormData();
            formdata.append(_("file1").name, file, file.name);
            var ajax = new XMLHttpRequest();
            ajax.upload.addEventListener("progress", progressHandler, false);
            ajax.addEventListener("load", completeHandler, false);
            ajax.addEventListener("loadstart", startHandler, false);
            ajax.addEventListener("error", errorHandler, false);
            ajax.addEventListener("abort", abortHandler, false);
            ajax.open("POST", "/update");
            // Enable CORS for testing
            ajax.setRequestHeader('Access-Control-Allow-Headers', '*');
            ajax.setRequestHeader('Access-Control-Allow-Origin', '*');

            ajax.send(formdata);
        }

Creo nuovi FormData e aggiungo solo il file con i gestori

Gestire la pagina OTA personalizzata

Abbiamo 2 opzioni per aggiungere questa pagina allo sketch spiegato in questo articolo “Server Web con esp8266 ed esp32: array di byte, pagine gzip e SPIFFS“: puoi aggiungerlo al filesystem o come bytearray. Uso gzipped per tutti i metodi, puoi controllare la versione semplice sull’articolo collegato.

Add page to filesystem

Puoi anche caricare i dati del filesystem con il metodo classico tramite il plugin, per installare il plugin SPIFFS, LittleFS o FFat, fai riferimento al relativo tutorial:

Quindi aggiungeremo una cartella di dati allo sketch e inseriremo la pagina gzippata che vogliamo, ora, ho inserito

index_color.html.gz
index_black_white.html.gz

a scopo di test. Dopo tale operazione, puoi utilizzare il plug-in come al solito per caricare le pagine.

Arduino IDE esp32 SPIFFS Sketch Data Upload
esp32 SPIFFS LittleFS FatFS file uploader from Arduino IDE

Puoi controllare l’output della console dell’IDE per verificare cosa è successo.

Chip : esp32
Using partition scheme from Arduino IDE.
Start: 0x290000
Size : 0x170000
mkspiffs : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\tools\mkspiffs\0.2.3\mkspiffs.exe

espota : C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe

[SPIFFS] data   : D:\Projects\Arduino\sloeber-workspace-OTA\ArduinoOTAesp32_basic_arduino\data
[SPIFFS] offset : 0
[SPIFFS] start  : 2686976
[SPIFFS] size   : 1472
[SPIFFS] page   : 256
[SPIFFS] block  : 4096
->/version.txt
[SPIFFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin
[SPIFFS] IP     : 192.168.1.186
Running: C:\Users\renzo\AppData\Local\Arduino15\packages\esp32\hardware\esp32\2.0.0\tools\espota.exe -i 192.168.1.186 -p 3232 -s -f C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin

_>Sending invitation to 192.168.1.186 
_>Uploading................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................
_>09:21:38 [ERROR]: Error response from device
SPIFFS Upload failed!

La console dell’IDE restituisce un errore, ma il caricamento funziona, penso che ci sia un piccolo bug ora quando scrivo questo articolo.

IDE dà un errore ma è un bug, il caricamento funziona correttamente

È possibile recuperare il file bin del file system da questa riga

[SPIFFS] upload : C:\Users\renzo\AppData\Local\Temp\arduino_build_258074/ArduinoOTAesp32_basic_arduino.spiffs.bin

Sketch con la pagina OTA personalizzata gzip in SPIFFS

Ora cambieremo il file WebUpdater.ino.

/*
 *	Custom OTA page from SPIFFS file system
 *	on ESP32
 *
 *	Renzo Mischianti <www.mischianti.org>
 *
 *	www.mischianti.org
 */

#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <HTTPUpdateServer.h>
#include <SPIFFS.h>

#ifndef STASSID
#define STASSID "<YOUR-SSID>"
#define STAPSK  "<YOUR-PASSWD>"
#endif

const char* host = "esp32-webupdate";
const char* ssid = STASSID;
const char* password = STAPSK;

WebServer httpServer(80);
HTTPUpdateServer httpUpdater;
void handleNotFound() {
  String message = "File Not Found\n\n";
  message += "URI: ";
  message += httpServer.uri();
  message += "\nMethod: ";
  message += (httpServer.method() == HTTP_GET) ? "GET" : "POST";
  message += "\nArguments: ";
  message += httpServer.args();
  message += "\n";

  for (uint8_t i = 0; i < httpServer.args(); i++) {
    message += " " + httpServer.argName(i) + ": " + httpServer.arg(i) + "\n";
  }

  httpServer.send(404, "text/plain", message);
}

bool loadFromFS(String path, String dataType) {
  Serial.print("Requested page -> ");
  Serial.println(path);
  if (SPIFFS.exists(path)){
      File dataFile = SPIFFS.open(path, "r");
      if (!dataFile) {
          handleNotFound();
          return false;
      }

      if (httpServer.streamFile(dataFile, dataType) != dataFile.size()) {
        Serial.println("Sent less data than expected!");
      }else{
          Serial.println("Page served!");
      }

      dataFile.close();
  }else{
      handleNotFound();
      return false;
  }
  return true;
}

void handleRoot() {
//	loadFromFS("/index_color.html.gz", "text/html");
	loadFromFS("/index_black_white.html.gz", "text/html");
}

void setup(void) {

  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi failed, retrying.");
  }

  MDNS.begin(host);
  if (MDNS.begin("esp32")) {
    Serial.println("mDNS responder started");
  }

  Serial.print(F("Inizializing FS..."));
  if (SPIFFS.begin()){
    Serial.println(F("done."));
  }else{
    Serial.println(F("fail."));
  }

  // handler for the /update form page
  httpServer.on("/update", HTTP_GET, handleRoot);

  httpUpdater.setup(&httpServer, "/update", "mischianti", "passwd");
  httpServer.begin();

  MDNS.addService("http", "tcp", 80);

  IPAddress ip = WiFi.localIP();
  Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser (%u.%u.%u.%u)\n", host, ip & 0xFF, (ip>>8) & 0xFF, (ip>>16) & 0xFF, (ip>>24) & 0xFF);
}

void loop(void) {
  httpServer.handleClient();
}

Puoi vedere il codice spiegato nell’articolo collegato e con

  httpServer.on("/update", HTTP_GET, handleRoot);

Sovrascrivo la pagina standard sulla GET /update, l’handle

bool loadFromFS(String path, String dataType) {
  Serial.print("Requested page -> ");
  Serial.println(path);
  if (LittleFS.exists(path)){
      File dataFile = LittleFS.open(path, "r");
      if (!dataFile) {
          handleNotFound();
          return false;
      }

      if (httpServer.streamFile(dataFile, dataType) != dataFile.size()) {
        Serial.println("Sent less data than expected!");
      }else{
          Serial.println("Page served!");
      }

      dataFile.close();
  }else{
      handleNotFound();
      return false;
  }
  return true;
}

void handleRoot() {
//	loadFromFS("/index_color.html.gz", "text/html");
	loadFromFS("/index_black_white.html.gz", "text/html");
}

leggere la pagina selezionata in handleRoot dallo SPIFFS e restituire il flusso.

Aggiungi una pagina personalizzata come array di byte

Preparati a utilizzare la pagina

L’articolo linkato prima spiega in modo approfondito la gestione delle pagine in byte array, ora nel repository delle pagine puoi prendere la pagina con estensione HTML,

https://github.com/xreef/ArduinoOTA_reusable_custom_web_page/minified

e inseriscilo nel convertitore bytearray selezionando il file corretto (come index_color.html) e prendendo il filearray generato e compresso con gzip.

ArduinoOTA custom web page generate gzipped bytearray

Sketch con bytearray pagina OTA personalizzata con gzip

Quindi possiamo andare a modificare la risposta di WebUpdater.ino alla pagina selezionata.

/*
 *	Custom OTA page from bytearray file system
 *	on ESP32
 *
 *	Renzo Mischianti <www.mischianti.org>
 *
 *	www.mischianti.org
 */
#include <WiFi.h>
#include <WiFiClient.h>
#include <WebServer.h>
#include <ESPmDNS.h>
#include <HTTPUpdateServer.h>

#ifndef STASSID
#define STASSID "<YOUR-SSID>"
#define STAPSK  "<YOUR-PASSWD>"
#endif

const char* host = "esp32-webupdate";
const char* ssid = STASSID;
const char* password = STAPSK;

WebServer httpServer(80);
HTTPUpdateServer httpUpdater;

//File: index_color.html.gz, Size: 33264
#define index_color_html_gz_len 33264
const uint8_t index_color_html_gz[] PROGMEM = {
0x1F, 0x8B, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0xB4, 0xBB, 0xE7, 0x92, 0xF4, 0xD8,
0x75, 0x2D, 0xF8, 0x2A, 0x3D, 0x64, 0x28, 0x42, 0xBA, 0x60, 0x13, 0xDE, 0x75, 0x4B, 0x1A, 0xC1,
0xBB, 0x84, 0x37, 0x09, 0xE0, 0x1F, 0xBC, 0xF7, 0x48, 0x98, 0x64, 0xF0, 0xDD, 0x07, 0x5F, 0x93,
0xA2, 0xC8, 0x2B, 0xFD, 0xB8, 0x33, 0x11, 0x53, 0x15, 0xC8, 0x02, 0x50, 0x07, 0x67, 0x9F, 0xB3,
0xCD, 0xDA, 0x6B, 0x45, 0xA1, 0xFE, 0xF5, 0xFF, 0xCA, 0xA7, 0x6C, 0xBF, 0xE7, 0xA2, 0xDE, 0x87,
0xFE, 0xDF, 0xFF, 0xF5, 0xC7, 0xE7, 0x4F, 0x7D, 0x32, 0x56, 0xFF, 0xF6, 0xBB, 0x62, 0xFC, 0xDD,
0xBF, 0xFF, 0xEB, 0x50, 0xEC, 0xC9, 0x4F, 0x59, 0x9D, 0xAC, 0x5B, 0xB1, 0xFF, 0xDB, 0xEF, 0x7C,
0x4F, 0xFC, 0x99, 0x7A, 0xEE, 0xEE, 0xCD, 0xDE, 0x17, 0xFF, 0xEE, 0xCF, 0xFD, 0x94, 0xE4, 0x3F,

[...]

0x17, 0xF4, 0xDE, 0xE0, 0x8B, 0xFC, 0x18, 0xC7, 0xC4, 0x2D, 0x41, 0xB4, 0xFB, 0x1D, 0x92, 0xF3,
0x32, 0xD1, 0xFD, 0x68, 0x99, 0xF8, 0xB5, 0xFB, 0xF9, 0xE7, 0xEE, 0x3E, 0xC7, 0xFF, 0x02, 0xAD,
0x6F, 0xA3, 0x91, 0x4F, 0x8F, 0xAF, 0x21, 0xC8, 0x4F, 0xC8, 0x3F, 0xFE, 0x45, 0x23, 0xFC, 0x57,
0x3A, 0xFC, 0x1A, 0x2F, 0x3D, 0x29, 0xF3, 0x93, 0x6D, 0xFE, 0x2B, 0x8F, 0x05, 0x48, 0x03, 0xD1,
0xD9, 0x53, 0x34, 0xF3, 0x14, 0x41, 0xFD, 0x5F, 0xDB, 0x3E, 0xEF, 0x40, 0x55, 0xB9, 0x00, 0x00
};


void setup(void) {

  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);

  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
    WiFi.begin(ssid, password);
    Serial.println("WiFi failed, retrying.");
  }

  MDNS.begin(host);
  if (MDNS.begin("esp32")) {
    Serial.println("mDNS responder started");
  }

  const char*  username = "mischianti";
  const char*  password = "password";

  // handler for the /update form page
  httpServer.on("/update", HTTP_GET, [&](){
		httpServer.sendHeader(F("Content-Encoding"), F("gzip"));
		httpServer.send_P(200, "text/html", (const char*)index_color_html_gz, (int)index_color_html_gz_len);
  });

  httpUpdater.setup(&httpServer, "/update", username, password);
  httpServer.begin();

  MDNS.addService("http", "tcp", 80);

  IPAddress ip = WiFi.localIP();
  Serial.printf("HTTPUpdateServer ready! Open http://%s.local/update in your browser (%u.%u.%u.%u)\n", host, ip & 0xFF, (ip>>8) & 0xFF, (ip>>16) & 0xFF, (ip>>24) & 0xFF);
}

void loop(void) {
  httpServer.handleClient();
}

Devi aggiungere il bytearray completo della pagina, nel codice c’è solo una piccola parte

il codice di base è molto semplice,

  httpServer.on("/update", HTTP_GET, [&](){
	  httpServer.sendHeader(F("Content-Encoding"), F("gzip"));
	  httpServer.send_P(200, "text/html", (const char*)index_color_html_gz, (int)index_color_html_gz_len);
  });

il flusso send_P stream tutto l’array di byte con Content-Encoding gzip, è possibile utilizzare l’array di byte non gzippato, ma la dimensione aumenta.

Grazie

  1. ESP32: piedinatura, specifiche e configurazione dell’Arduino IDE
  2. ESP32: fileSystem integrato SPIFFS
  3. ESP32: gestire più seriali e logging per il debug
  4. ESP32 risparmio energetico pratico
    1. ESP32 risparmio energetico pratico: gestire WiFi e CPU
    2. ESP32 risparmio energetico pratico: modem e light sleep
    3. ESP32 risparmio energetico pratico: deep sleep e ibernazione
    4. ESP32 risparmio energetico pratico: preservare dati al riavvio, sveglia a tempo e tramite tocco
    5. ESP32 risparmio energetico pratico: sveglia esterna e da ULP
    6. ESP32 risparmio energetico pratico: sveglia da UART e GPIO
  5. ESP32: filesystem integrato LittleFS
  6. ESP32: filesystem integrato FFat (Fat/exFAT)
  7. ESP32-wroom-32
    1. ESP32-wroom-32: flash, piedinatura, specifiche e configurazione dell’Arduino IDE
  8. ESP32-CAM
    1. ESP32-CAM: piedinatura, specifiche e configurazione dell’Arduino IDE
    2. ESP32-CAM: upgrade CamerWebServer con gestione della luce flash
  9. ESP32: ethernet w5500 con chiamate standard (HTTP) e SSL (HTTPS)
  10. ESP32: ethernet enc28j60 con chiamate standard (HTTP) e SSL (HTTPS)
  11. Come usare la scheda SD con l’esp32
  12. esp32 e esp8266: file system FAT su memoria SPI flash esterna
  13. Gestione aggiornamenti firmware e OTA
    1. Gestione del firmware
      1. ESP32: flash del firmware binario compilato (.bin)
      2. ESP32: flash del firmware e filesystem (.bin) con strumenti grafici
    2. Aggiornamento OTA con Arduino IDE
      1. Aggiornamenti OTA su ESP32 con Arduino IDE: filesystem, firmware e password
    3. Aggiornamento OTA con browser web
      1. Aggiornamenti OTA su ESP32 tramite browser web: firmware, filesystem e autenticazione
      2. Aggiornamenti OTA su ESP32 tramite browser web: caricamento in HTTPS (SSL/TLS) con certificato autofirmato
      3. Aggiornamenti OTA su ESP32 tramite browser web: interfaccia web personalizzata
    4. Aggiornamenti automatici OTA da un server HTTP
      1. Aggiornamento automatico Firmware OTA dell’ESP32 dal server
      2. Aggiornamento automatico Firmware OTA dell’ESP32 dal server con controllo della versione
      3. Aggiornamento automatico Firmware OTA dell’ESP32 in HTTPS (SSL/TLS) con certificato autofirmato affidabile
    5. Aggiornamento del firmware non standard
      1. Aggiornamento firmware e filesystem ESP32 dalla scheda SD
      2. Aggiornamento firmware e filesystem ESP32 con client FTP
  14. Integrare LAN8720 con ESP32 per la connettività Ethernet con plain (HTTP) e SSL (HTTPS)
  15. Collegare l’EByte E70 (CC1310) ai dispositivi ESP32 c3/s3 ed un semplice sketch di esempio
  16. ESP32-C3: piedinatura, specifiche e configurazione dell’IDE Arduino
  17. Integrazione del modulo W5500 su ESP32 con Core 3: supporto nativo ai protocolli Ethernet con SSL e altre funzionalità
  18. Integrazione del modulo LAN8720 su ESP32 con Core 3: supporto nativo del protocollo Ethernet con SSL e altre funzionalità.

Spread the love
Exit mobile version