diff --git a/app/modules/enduser_setup.c b/app/modules/enduser_setup.c index a03a87b0ee..addef5f436 100644 --- a/app/modules/enduser_setup.c +++ b/app/modules/enduser_setup.c @@ -93,6 +93,7 @@ static const char http_html_filename[] = "enduser_setup.html"; static const char http_header_200[] = "HTTP/1.1 200 OK\r\nCache-control:no-cache\r\nConnection:close\r\nContent-Type:text/html\r\n"; /* Note single \r\n here! */ static const char http_header_204[] = "HTTP/1.1 204 No Content\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_302[] = "HTTP/1.1 302 Moved\r\nLocation: /\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; +static const char http_header_302_trying[] = "HTTP/1.1 302 Moved\r\nLocation: /?trying=true\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_400[] = "HTTP/1.1 400 Bad request\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_404[] = "HTTP/1.1 404 Not found\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; static const char http_header_405[] = "HTTP/1.1 405 Method Not Allowed\r\nContent-Length:0\r\nConnection:close\r\n\r\n"; @@ -101,8 +102,8 @@ static const char http_header_500[] = "HTTP/1.1 500 Internal Error\r\nContent-Le static const char http_header_content_len_fmt[] = "Content-length:%5d\r\n\r\n"; static const char http_html_gzip_contentencoding[] = "Content-Encoding: gzip\r\n"; -/* Externally defined: static const char http_html_backup[] = ... */ -#include "eus/http_html_backup.def" +/* Externally defined: static const char enduser_setup_html_default[] = ... */ +#include "enduser_setup/enduser_setup.html.gz.def.h" typedef struct scan_listener { @@ -398,9 +399,9 @@ static err_t close_once_sent (void *arg, struct tcp_pcb *pcb, u16_t len) /** * Search String * - * Search string for first occurance of any char in srch_str. + * Search string for first occurence of any char in srch_str. * - * @return -1 iff no occurance of char was found. + * @return -1 if no occurence of char was found. */ static int enduser_setup_srch_str(const char *str, const char *srch_str) { @@ -418,9 +419,9 @@ static int enduser_setup_srch_str(const char *str, const char *srch_str) /** * Load HTTP Payload * - * @return - 0 iff payload loaded successfully - * 1 iff backup html was loaded - * 2 iff out of memory + * @return - 0 if payload loaded successfully + * 1 if default html was loaded + * 2 if out of memory */ static int enduser_setup_http_load_payload(void) { @@ -466,16 +467,16 @@ static int enduser_setup_http_load_payload(void) if (!f || err == VFS_RES_ERR || err2 == VFS_RES_ERR) { - ENDUSER_SETUP_DEBUG("Unable to load file enduser_setup.html, loading backup HTML..."); + ENDUSER_SETUP_DEBUG("Unable to load file enduser_setup.html, loading default HTML..."); - c_sprintf(cl_hdr, http_header_content_len_fmt, sizeof(http_html_backup)); + c_sprintf(cl_hdr, http_header_content_len_fmt, sizeof(enduser_setup_html_default)); cl_len = c_strlen(cl_hdr); - int html_len = LITLEN(http_html_backup); + int html_len = LITLEN(enduser_setup_html_default); - if (http_html_backup[0] == 0x1f && http_html_backup[1] == 0x8b) + if (enduser_setup_html_default[0] == 0x1f && enduser_setup_html_default[1] == 0x8b) { ce_len = c_strlen(http_html_gzip_contentencoding); - html_len = http_html_backup_len; /* Defined in eus/http_html_backup.def by xxd -i */ + html_len = enduser_setup_html_default_len; /* Defined in enduser_setup/enduser_setup.html.gz.def.h by xxd -i */ ENDUSER_SETUP_DEBUG("Content is gzipped"); } @@ -499,7 +500,7 @@ static int enduser_setup_http_load_payload(void) c_memcpy(&(state->http_payload_data[offset]), &(cl_hdr), cl_len); offset += cl_len; - c_memcpy(&(state->http_payload_data[offset]), &(http_html_backup), sizeof(http_html_backup)); + c_memcpy(&(state->http_payload_data[offset]), &(enduser_setup_html_default), sizeof(enduser_setup_html_default)); return 1; } @@ -548,7 +549,7 @@ static int enduser_setup_http_load_payload(void) * * Parse escaped and form encoded data of request. * - * @return - return 0 iff the HTTP parameter is decoded into a valid string. + * @return - return 0 if the HTTP parameter is decoded into a valid string. */ static int enduser_setup_http_urldecode(char *dst, const char *src, int src_len, int dst_len) { @@ -631,13 +632,167 @@ static void do_station_cfg (task_param_t param, uint8_t prio) luaM_free(lua_getstate(), cnf); } +/** + * Count the number of occurences of a character in a string + * + * return the number of times the character was encountered in the string + */ +static int count_char_occurence(const char *input, const char char_to_count) { + const char *current = input; + int occur = 0; + while (*current != 0) { + if (*current == char_to_count) occur++; + current++; + } + return occur; +} + +/* structure used to store the key/value pairs that we find in a HTTP POST body */ +struct keypairs_t { + char **keypairs; + int keypairs_nb; +}; + +static void enduser_setup_free_keypairs(struct keypairs_t *kp) { + if (kp == NULL) return; + + if (kp->keypairs != NULL) { + for (int i = 0; i < kp->keypairs_nb * 2; i++) { + os_free(kp->keypairs[i]); + } + } + os_free(kp->keypairs); + os_free(kp); +} + +static struct keypairs_t * enduser_setup_alloc_keypairs(int kp_number ){ + struct keypairs_t *kp = os_malloc(sizeof(struct keypairs_t)); + os_memset(kp, 0, sizeof(struct keypairs_t)); + + kp->keypairs = os_malloc(kp_number * 2 * sizeof(char *)); + kp->keypairs_nb = kp_number; + return kp; +} + +/** + * Parses a form-urlencoded body into a struct keypairs_t, which contains an array of key,values strings and the size of the array. + */ +static struct keypairs_t *enduser_setup_get_keypairs_from_form(char *form_body, int form_length) { + int keypair_nb = count_char_occurence(form_body, '&') + 1; + int equal_nb = count_char_occurence(form_body, '='); + + if (keypair_nb == 1 && equal_nb == 0) { + ENDUSER_SETUP_DEBUG("No keypair in form body"); + return NULL; + } + + struct keypairs_t *kp = enduser_setup_alloc_keypairs(keypair_nb); + + int current_idx = 0; + int err; + + char *body_copy = os_malloc(form_length+1); + os_bzero(body_copy, form_length+1); + os_memcpy(body_copy, form_body, form_length); + char *tok = strtok(body_copy, "="); + + char last_tok = '='; + while (tok) { + size_t len = strlen(tok); + kp->keypairs[current_idx] = os_malloc(len + 1); + err = enduser_setup_http_urldecode(kp->keypairs[current_idx], tok, len, len + 1); + if (err) { + ENDUSER_SETUP_DEBUG("Unable to decode parameter"); + enduser_setup_free_keypairs(kp); + os_free(body_copy); + return NULL; + } + + current_idx++; + if (current_idx > keypair_nb*2) { + ENDUSER_SETUP_DEBUG("Too many keypairs!"); + enduser_setup_free_keypairs(kp); + os_free(body_copy); + return NULL; + } + + if (last_tok == '=') { + tok = strtok(NULL, "&"); // now search for the '&' + last_tok='&'; + } else { + tok = strtok(NULL, "="); // search for the next '=' + last_tok='='; + } + } + os_free(body_copy); + return kp; +} + + +/** + * This function saves the form data received when the configuration is sent to the ESP into a eus_params.lua file + */ +static int enduser_setup_write_file_with_extra_configuration_data(char *form_body, int form_length) { + ENDUSER_SETUP_DEBUG("enduser: write data from posted form"); + ENDUSER_SETUP_DEBUG(form_body); + + // We will save the form data into a file in the LUA format: KEY="VALUE", so that configuration data is available for load in the lua code. + // As input, we have a string as such: "key1=value1&key2=value2&key3=value%203" (urlencoded), the number of '&' tells us how many keypairs there are (the count + 1) + + struct keypairs_t *kp = enduser_setup_get_keypairs_from_form(form_body, form_length); + if (kp == NULL || kp->keypairs_nb == 0) { + ENDUSER_SETUP_DEBUG("enduser: No extra configuration."); + if (kp != NULL) enduser_setup_free_keypairs(kp); + return 1; + } + + // Now that we have the keys and the values, let's save them in a lua file + int p_file = vfs_open("eus_params.lua", "w"); + if (p_file == 0) + { + ENDUSER_SETUP_DEBUG("Can't open file in write mode!"); + enduser_setup_free_keypairs(kp); + return 1; + } + + // write all key pairs as KEY="VALUE"\n into a Lua table, example: + // local p = {} + // p.wifi_ssid="ssid" + // p.wifi_password="password" + // p.device_name="foo-node" + // return p + vfs_write(p_file, "local p={}\n", 11); + int idx = 0; + for( idx = 0; idx < kp->keypairs_nb*2; idx=idx+2){ + char* to_write = kp->keypairs[idx]; + size_t length = c_strlen(to_write); + + vfs_write(p_file, "p.", 2); + + vfs_write(p_file, to_write, length); + + vfs_write(p_file, "=\"", 2); + + to_write = kp->keypairs[idx+1]; + length = c_strlen(to_write); + vfs_write(p_file, to_write, length); + + vfs_write(p_file, "\"\n", 2); + } + vfs_write(p_file, "return p\n", 9); + + vfs_close(p_file); + enduser_setup_free_keypairs(kp); + // TODO: we could call back in the LUA with an associative table setup, but this is MVP2... + return 0; +} /** * Handle HTTP Credentials * - * @return - return 0 iff credentials are found and handled successfully - * return 1 iff credentials aren't found - * return 2 iff an error occured + * @return - return 0 if credentials are found and handled successfully + * return 1 if credentials aren't found + * return 2 if an error occured */ static int enduser_setup_http_handle_credentials(char *data, unsigned short data_len) { @@ -682,7 +837,6 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data return 1; } - ENDUSER_SETUP_DEBUG(""); ENDUSER_SETUP_DEBUG("WiFi Credentials Stored"); ENDUSER_SETUP_DEBUG("-----------------------"); @@ -702,7 +856,7 @@ static int enduser_setup_http_handle_credentials(char *data, unsigned short data /** * Serve HTML * - * @return - return 0 iff html was served successfully + * @return - return 0 if html was served successfully */ static int enduser_setup_http_serve_header(struct tcp_pcb *http_client, const char *header, uint32_t header_len) { @@ -763,7 +917,7 @@ static err_t streamout_sent (void *arg, struct tcp_pcb *pcb, u16_t len) /** * Serve HTML * - * @return - return 0 iff html was served successfully + * @return - return 0 if html was served successfully */ static int enduser_setup_http_serve_html(struct tcp_pcb *http_client) { @@ -957,6 +1111,37 @@ static void enduser_setup_handle_OPTIONS (struct tcp_pcb *http_client, char *dat } +static err_t enduser_setup_handle_POST(struct tcp_pcb *http_client, char* data, size_t data_len) +{ + ENDUSER_SETUP_DEBUG("Handling POST"); + if (c_strncmp(data + 5, "/setwifi ", 9) == 0) // User clicked the submit button + { + switch (enduser_setup_http_handle_credentials(data, data_len)) + { + case 0: { + // all went fine, extract all the form data into a file + char* body=strstr(data, "\r\n\r\n"); + char *content_length_str = strstr(data, "Content-Length: "); + if( body != NULL && content_length_str != NULL){ + int bodylength = c_atoi(content_length_str + 16); + body += 4; // length of the double CRLF found above + enduser_setup_write_file_with_extra_configuration_data(body, bodylength); + } + // redirect user to the base page with the trying flag + enduser_setup_http_serve_header(http_client, http_header_302_trying, LITLEN(http_header_302_trying)); + break; + } + case 1: + enduser_setup_http_serve_header(http_client, http_header_400, LITLEN(http_header_400)); + break; + default: + ENDUSER_SETUP_ERROR("http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); + break; + } + } +} + + /* --- WiFi AP scanning support -------------------------------------------- */ static void free_scan_listeners (void) @@ -1165,7 +1350,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s if (c_strncmp(data, "GET ", 4) == 0) { - if (c_strncmp(data + 4, "/ ", 2) == 0) + if (c_strncmp(data + 4, "/ ", 2) == 0 || c_strncmp(data + 4, "/?", 2) == 0) { if (enduser_setup_http_serve_html(http_client) != 0) { @@ -1237,21 +1422,6 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s break; } } - else if (c_strncmp(data + 4, "/setwifi?", 9) == 0) - { - switch (enduser_setup_http_handle_credentials(data, data_len)) - { - case 0: - enduser_setup_serve_status_as_json(http_client); - break; - case 1: - enduser_setup_http_serve_header(http_client, http_header_400, LITLEN(http_header_400)); - break; - default: - ENDUSER_SETUP_ERROR("http_recvcb failed. Failed to handle wifi credentials.", ENDUSER_SETUP_ERR_UNKOWN_ERROR, ENDUSER_SETUP_ERR_NONFATAL); - break; - } - } else if (c_strncmp(data + 4, "/generate_204", 13) == 0) { /* Convince Android devices that they have internet access to avoid pesky dialogues. */ @@ -1267,6 +1437,10 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s { enduser_setup_handle_OPTIONS(http_client, data, data_len); } + else if (c_strncmp(data, "POST ", 5) == 0) + { + enduser_setup_handle_POST(http_client, data, data_len); + } else /* not GET or OPTIONS */ { enduser_setup_http_serve_header(http_client, http_header_405, LITLEN(http_header_405)); @@ -1279,6 +1453,7 @@ static err_t enduser_setup_http_recvcb(void *arg, struct tcp_pcb *http_client, s return ret; } + static err_t enduser_setup_http_connectcb(void *arg, struct tcp_pcb *pcb, err_t err) { ENDUSER_SETUP_DEBUG("enduser_setup_http_connectcb"); @@ -1332,7 +1507,7 @@ static int enduser_setup_http_start(void) int err = enduser_setup_http_load_payload(); if (err == 1) { - ENDUSER_SETUP_DEBUG("enduser_setup_http_start info. Loaded backup HTML."); + ENDUSER_SETUP_DEBUG("enduser_setup_http_start info. Loaded default HTML."); } else if (err == 2) { diff --git a/app/modules/enduser_setup/.gitattributes b/app/modules/enduser_setup/.gitattributes new file mode 100644 index 0000000000..4a8a437832 --- /dev/null +++ b/app/modules/enduser_setup/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf diff --git a/app/modules/enduser_setup/.gitignore b/app/modules/enduser_setup/.gitignore new file mode 100644 index 0000000000..f72d8a38d1 --- /dev/null +++ b/app/modules/enduser_setup/.gitignore @@ -0,0 +1 @@ +enduser_setup.html.gz diff --git a/app/modules/eus/enduser_setup.html b/app/modules/enduser_setup/enduser_setup.html similarity index 83% rename from app/modules/eus/enduser_setup.html rename to app/modules/enduser_setup/enduser_setup.html index 8a25e16057..551795f408 100644 --- a/app/modules/eus/enduser_setup.html +++ b/app/modules/enduser_setup/enduser_setup.html @@ -153,14 +153,17 @@

Connect device to your Wi-Fi

- - - - - +
+ + + + + + +

Success!

@@ -180,6 +183,11 @@

Updating Status...

var ab = $('#networks'), ap = $('#aplist'); var stopAll = false, ra, rs, submitted = false; + $.urlParam = function (name) { + var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href); + if (results == null) { return null;} + else { return decodeURI(results[1]) || 0;} + } function show(f, y) { if (y == null) y = f; $(f).style.display = y == f ? 'block' : 'none'; @@ -240,13 +248,6 @@

Updating Status...

} } } - function submit() { - submitted = true; - var url = '/setwifi?wifi_ssid=' + encodeURIComponent($('#ssid').value) + '&wifi_password=' + encodeURIComponent($('#wifi_password').value); - clearTimeout(rs); - fetch(url, 'GET', newSt, 2); - cur('#f3'); - } function fetch(url, method, callback, time_out) { var xhr = new XMLHttpRequest(); xhr.onloadend = function () { @@ -305,18 +306,19 @@

Updating Status...

fetch('/aplist?n=' + Math.random(), 'GET', gotAp, 10); } window.onload = function() { - ab.innerText = 'Scan for Networks'; - ab.onclick = refrAp; - $('#aplist').onchange = function () { - $('#ssid').value = $('#aplist').value; - }; - $('#submit').onclick = submit; - $('#bk2').onclick = function () { - cur('#f1') - } - rs = to(refr, 0.5); + let trying = $.urlParam('trying'); + ab.innerText = 'Scan for Networks'; + ab.onclick = refrAp; + $('#aplist').onchange = function () { + $('#ssid').value = $('#aplist').value; + }; + $('#bk2').onclick = function () { + cur('#f1') + } + rs = to(refr, 0.5); + if( trying ) cur("#f3"); } - \ No newline at end of file + diff --git a/app/modules/enduser_setup/enduser_setup.html.gz.def.h b/app/modules/enduser_setup/enduser_setup.html.gz.def.h new file mode 100644 index 0000000000..d829ee0d22 --- /dev/null +++ b/app/modules/enduser_setup/enduser_setup.html.gz.def.h @@ -0,0 +1,218 @@ +static const char enduser_setup_html_default[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x9d, 0x59, + 0xfb, 0x73, 0xdb, 0xc6, 0xf1, 0xff, 0x59, 0xf9, 0x2b, 0x56, 0x92, 0xbf, + 0x06, 0x64, 0x93, 0x10, 0xa9, 0x87, 0xe3, 0x91, 0x48, 0x66, 0xfc, 0x4d, + 0x9c, 0x47, 0x27, 0x76, 0x3c, 0x96, 0x32, 0x69, 0xc6, 0x55, 0x33, 0x47, + 0xe0, 0x40, 0x5c, 0x04, 0xe2, 0xd0, 0xbb, 0x83, 0x28, 0x36, 0xf1, 0xff, + 0xde, 0x5d, 0x2c, 0x8e, 0x20, 0x08, 0x95, 0xd3, 0x76, 0x62, 0x89, 0xb8, + 0xc3, 0xbe, 0xf7, 0xb3, 0x0f, 0x2a, 0x93, 0xc3, 0x6f, 0x7e, 0xfa, 0xfa, + 0xf6, 0xd7, 0x0f, 0x6f, 0x21, 0x73, 0xcb, 0x7c, 0xf6, 0xc5, 0x84, 0x3f, + 0xf0, 0x53, 0x8a, 0x64, 0xf6, 0xc5, 0xc1, 0x64, 0x29, 0x9d, 0x80, 0x42, + 0x2c, 0xe5, 0x34, 0x78, 0x50, 0x72, 0x55, 0x6a, 0xe3, 0x02, 0x88, 0x75, + 0xe1, 0x64, 0xe1, 0xa6, 0xc1, 0x4a, 0x25, 0x2e, 0x9b, 0x26, 0xf2, 0x41, + 0xc5, 0x72, 0x58, 0x1f, 0x06, 0xa0, 0x0a, 0xe5, 0x94, 0xc8, 0x87, 0x36, + 0x16, 0xb9, 0x9c, 0x8e, 0xa3, 0x51, 0x40, 0x72, 0x9c, 0x72, 0xb9, 0x9c, + 0xfd, 0xa2, 0xbe, 0x55, 0xf0, 0xa3, 0x5e, 0xa8, 0x62, 0x72, 0xca, 0x37, + 0xf8, 0xca, 0xba, 0x75, 0x2e, 0xc1, 0xad, 0x4b, 0x39, 0x75, 0xf2, 0xd1, + 0x9d, 0xc6, 0xd6, 0xe2, 0xf5, 0xc1, 0x0b, 0xf8, 0x03, 0x7f, 0x1f, 0x2c, + 0x85, 0x41, 0xf2, 0x2b, 0x18, 0x5d, 0xd3, 0xa9, 0x14, 0x49, 0xa2, 0x8a, + 0x45, 0x73, 0xfc, 0x8c, 0x3f, 0xf8, 0x8f, 0x6c, 0x1e, 0xe0, 0xe7, 0x5c, + 0x27, 0x6b, 0x66, 0xca, 0xa4, 0x5a, 0x64, 0xee, 0x0a, 0xc6, 0xa3, 0xd1, + 0xff, 0xd5, 0x7c, 0x29, 0x5a, 0x3c, 0x4c, 0xc5, 0x52, 0xe5, 0xeb, 0x2b, + 0xb0, 0xa2, 0xb0, 0x43, 0x2b, 0x8d, 0x4a, 0xeb, 0x77, 0xa4, 0x74, 0x28, + 0x72, 0xb5, 0x40, 0x2d, 0xb1, 0x44, 0xcf, 0x4c, 0x7d, 0x3d, 0x17, 0xf1, + 0xfd, 0xc2, 0xe8, 0xaa, 0x48, 0xae, 0xe0, 0xf8, 0xe2, 0xe2, 0x22, 0xb9, + 0xb8, 0xd8, 0xd2, 0x79, 0xdc, 0xc4, 0x80, 0xf5, 0x95, 0xda, 0xa2, 0xd3, + 0x1a, 0x05, 0x88, 0xb9, 0xd5, 0x79, 0xe5, 0x24, 0x4b, 0xd6, 0xa5, 0x37, + 0xdc, 0xb0, 0x41, 0x7c, 0x98, 0x6b, 0xe7, 0xf4, 0xd2, 0x9f, 0x72, 0x99, + 0x6e, 0xde, 0xd4, 0x31, 0xbc, 0x82, 0xf3, 0xb3, 0x51, 0xf9, 0x78, 0xbd, + 0xed, 0xc9, 0xc5, 0x6b, 0x7f, 0xe3, 0x03, 0x22, 0x2a, 0xa7, 0xb7, 0x0c, + 0x52, 0x45, 0x59, 0xb9, 0x3a, 0x0a, 0x15, 0x0a, 0x2f, 0xe8, 0xc9, 0xca, + 0x5c, 0xc6, 0x8d, 0x85, 0xc3, 0x95, 0x9c, 0xdf, 0x2b, 0xf4, 0xb3, 0x2c, + 0xa5, 0x30, 0xa2, 0x88, 0xe5, 0x15, 0x14, 0xba, 0x90, 0x8d, 0x3d, 0x26, + 0x91, 0x66, 0x68, 0x44, 0xa2, 0x2a, 0xdb, 0x8d, 0x6d, 0xaa, 0x64, 0x9e, + 0x58, 0xc9, 0x52, 0x1a, 0xc2, 0xd6, 0x8d, 0xc7, 0xa1, 0xcd, 0x44, 0xa2, + 0x57, 0x78, 0x83, 0xff, 0x8d, 0x2f, 0xcb, 0x47, 0x18, 0xe3, 0x8f, 0x59, + 0xcc, 0x45, 0x38, 0x1a, 0x00, 0xff, 0x8b, 0x2e, 0x4e, 0x5a, 0x72, 0xf5, + 0xcf, 0x3a, 0x7d, 0x8d, 0x46, 0xbc, 0xea, 0xa6, 0x95, 0xfc, 0x86, 0x73, + 0xfc, 0xd5, 0x4f, 0x41, 0x9a, 0xa6, 0xec, 0xbf, 0x2a, 0x86, 0x1c, 0x15, + 0x8e, 0x53, 0x37, 0x2a, 0x43, 0xd4, 0xbf, 0x1b, 0x95, 0xae, 0xed, 0x64, + 0x20, 0xe6, 0x48, 0x25, 0x70, 0x1c, 0xc7, 0xf1, 0x16, 0xf3, 0xd0, 0xa7, + 0x65, 0xcc, 0x42, 0x7d, 0x36, 0x3c, 0x8a, 0xf6, 0x7a, 0x10, 0xeb, 0x5c, + 0x1b, 0xb4, 0xf2, 0xec, 0xec, 0x6c, 0x03, 0x38, 0xe4, 0x7c, 0x85, 0xca, + 0x96, 0xba, 0xd0, 0xb6, 0x14, 0xb1, 0xec, 0xb8, 0x8a, 0xd1, 0xea, 0x58, + 0xea, 0x93, 0xb5, 0x97, 0xb9, 0x0d, 0xc8, 0xb0, 0x51, 0xe8, 0x30, 0x97, + 0xf8, 0xde, 0x20, 0x14, 0xf7, 0x8a, 0x67, 0x54, 0xb0, 0x78, 0x66, 0xf5, + 0x11, 0xed, 0x64, 0xb5, 0x0f, 0x86, 0xf3, 0xb2, 0x71, 0xb0, 0x32, 0x96, + 0xb8, 0x4a, 0xad, 0x36, 0x25, 0x92, 0x28, 0x5b, 0xe6, 0x62, 0x8d, 0xc1, + 0xc8, 0x75, 0x7c, 0xbf, 0xeb, 0xf7, 0x53, 0x65, 0x96, 0xc8, 0x58, 0x1b, + 0xc1, 0xa5, 0xc2, 0xf0, 0xeb, 0xd8, 0x4c, 0xd9, 0xbf, 0x7c, 0x2a, 0xf9, + 0xe7, 0xe3, 0xf9, 0xc5, 0xe5, 0x97, 0xfd, 0xa4, 0xec, 0xf8, 0x77, 0x95, + 0xea, 0xb8, 0xb2, 0x83, 0xf6, 0x9c, 0xe9, 0x07, 0x69, 0xc8, 0xeb, 0x3e, + 0x5a, 0x47, 0x70, 0x86, 0xda, 0x28, 0x08, 0x03, 0x3e, 0x93, 0xab, 0x5e, + 0xd3, 0x76, 0x77, 0x39, 0x6f, 0x93, 0x42, 0xd9, 0x97, 0xec, 0x5e, 0x27, + 0xeb, 0xaf, 0x5e, 0xbd, 0xea, 0x03, 0x89, 0xd1, 0xbc, 0x2d, 0xe9, 0xa2, + 0x1b, 0x7f, 0x82, 0x5f, 0xd7, 0xff, 0x2e, 0x7d, 0x54, 0x39, 0x95, 0x2b, + 0xb7, 0x6e, 0xf4, 0xe7, 0x5a, 0x60, 0x68, 0xeb, 0x46, 0xc2, 0xca, 0x73, + 0x29, 0x50, 0x0c, 0x2a, 0xcb, 0x1a, 0xe5, 0x8f, 0xc3, 0x26, 0x38, 0x5f, + 0x5e, 0x52, 0x6c, 0xba, 0x36, 0x73, 0x22, 0xfb, 0x48, 0x65, 0x9b, 0x59, + 0xf9, 0x6e, 0x97, 0xad, 0x0b, 0xba, 0x5f, 0x8d, 0xde, 0xf6, 0x9e, 0xa5, + 0x6d, 0xfc, 0xfd, 0xcd, 0xff, 0x90, 0x81, 0xae, 0xe8, 0xe3, 0xc4, 0xe8, + 0x12, 0x59, 0x8a, 0x01, 0x1d, 0xd2, 0x33, 0xfe, 0x38, 0xaf, 0x3f, 0xe6, + 0xf7, 0x67, 0x2c, 0xd9, 0x03, 0xd1, 0x63, 0xaa, 0xc7, 0xbc, 0xdb, 0xa6, + 0x8d, 0xcc, 0x11, 0x85, 0x0f, 0xf2, 0xc9, 0x32, 0x27, 0x8b, 0x31, 0xda, + 0x2b, 0xee, 0xb1, 0x9d, 0x36, 0x7c, 0x89, 0xdd, 0x63, 0x5f, 0xcb, 0xf0, + 0x7a, 0x45, 0x99, 0x2b, 0xbb, 0x77, 0x38, 0xf4, 0xb4, 0xf6, 0x66, 0x96, + 0x9f, 0x1e, 0x7e, 0x44, 0xf4, 0x86, 0xc7, 0x9e, 0xae, 0xd6, 0x9b, 0x79, + 0xbd, 0x26, 0xd4, 0xab, 0xb8, 0xd6, 0x76, 0x63, 0xf4, 0xaa, 0x8b, 0xd4, + 0xd7, 0xaf, 0x5f, 0x5f, 0xef, 0x71, 0xa5, 0x19, 0x6e, 0xaf, 0x59, 0x0e, + 0x1b, 0x3e, 0xde, 0x91, 0xaa, 0x58, 0x62, 0x7f, 0xd8, 0x36, 0x44, 0x93, + 0xd3, 0x7a, 0x0f, 0xc0, 0x15, 0xe4, 0x94, 0x77, 0x8f, 0x2f, 0x26, 0x34, + 0xcf, 0x69, 0x41, 0x48, 0xd4, 0x03, 0xa8, 0x64, 0xda, 0x4c, 0x5c, 0xda, + 0x0d, 0x26, 0x7e, 0x2c, 0xd1, 0xc1, 0x13, 0x34, 0x7b, 0xc8, 0x0f, 0xc9, + 0x6c, 0x72, 0x8a, 0x37, 0x9d, 0x57, 0xe9, 0x18, 0x8f, 0x74, 0xce, 0xce, + 0x67, 0x5f, 0xeb, 0xa2, 0xa0, 0x56, 0xcb, 0xe4, 0xe0, 0x34, 0xac, 0x75, + 0x65, 0xe0, 0x17, 0x35, 0xfc, 0x56, 0xa1, 0xf2, 0xf3, 0x86, 0x32, 0xd5, + 0x66, 0x09, 0x22, 0x26, 0x77, 0xa7, 0x47, 0xa7, 0xa8, 0x6b, 0xa5, 0x52, + 0x75, 0x04, 0x4b, 0xe9, 0x32, 0x9d, 0x4c, 0x8f, 0x3e, 0xfc, 0x74, 0x73, + 0x7b, 0x44, 0xa4, 0x44, 0xcb, 0xdd, 0x86, 0x14, 0x15, 0x48, 0xa7, 0xcd, + 0xbd, 0xe5, 0x7d, 0xa6, 0xb9, 0x8f, 0x73, 0x61, 0xed, 0xb4, 0xa9, 0x08, + 0xb4, 0x8e, 0xaf, 0x3d, 0xb3, 0xb7, 0x9e, 0xa1, 0x4a, 0xd7, 0x7c, 0x8f, + 0xe9, 0xaa, 0x45, 0xd6, 0xf9, 0x98, 0x3d, 0x3f, 0x7e, 0x3c, 0xbb, 0x9c, + 0xc7, 0xd7, 0x18, 0xa7, 0x52, 0xb4, 0x44, 0x3c, 0x36, 0x88, 0x8c, 0x21, + 0xc7, 0xbb, 0x1a, 0x3f, 0xa3, 0x26, 0x7e, 0xed, 0x35, 0x71, 0x58, 0xf8, + 0x99, 0x27, 0x23, 0xf2, 0x59, 0xab, 0x12, 0xe6, 0x22, 0x07, 0x7f, 0xa3, + 0x63, 0xbb, 0x8c, 0xd5, 0x15, 0x10, 0x6b, 0x63, 0x50, 0xca, 0x54, 0xa7, + 0x29, 0x9f, 0x45, 0xa9, 0x9c, 0xc8, 0xb1, 0xad, 0x4c, 0xa9, 0xde, 0xa0, + 0xcc, 0x11, 0x57, 0x99, 0xce, 0x11, 0x88, 0xd3, 0xa0, 0x0e, 0x23, 0xbc, + 0x47, 0x79, 0x01, 0x9c, 0x76, 0x95, 0xb5, 0x4a, 0x4a, 0x8c, 0x07, 0x86, + 0xe9, 0xbf, 0x55, 0xc4, 0x34, 0xcb, 0x32, 0x97, 0x4e, 0x12, 0x51, 0x47, + 0xf3, 0x87, 0x46, 0x66, 0xab, 0xf5, 0x70, 0x38, 0x84, 0x5f, 0x75, 0x05, + 0x31, 0xc6, 0x11, 0x01, 0x0f, 0xb5, 0x15, 0x16, 0x32, 0x69, 0x50, 0x54, + 0x91, 0x40, 0x26, 0x1e, 0x24, 0xb8, 0x4c, 0x2e, 0xa1, 0xd4, 0x25, 0x54, + 0x25, 0x12, 0x30, 0x14, 0xf2, 0x4a, 0x40, 0xac, 0x13, 0x7a, 0x69, 0x74, + 0xb5, 0xc8, 0x88, 0x08, 0x52, 0x95, 0x4b, 0x90, 0x95, 0x45, 0xe3, 0x8d, + 0x58, 0xda, 0x88, 0x88, 0x86, 0xc3, 0x8e, 0x87, 0xec, 0xce, 0x91, 0xad, + 0xe6, 0x4b, 0xe5, 0x8e, 0xe0, 0x41, 0xe4, 0x15, 0x1e, 0x6f, 0x50, 0xcd, + 0x11, 0x1a, 0xc5, 0x29, 0x20, 0x58, 0x31, 0x34, 0xfb, 0x20, 0x3d, 0xf3, + 0x20, 0x1d, 0xcf, 0x6e, 0xaa, 0x38, 0x96, 0xd6, 0x1e, 0x22, 0x20, 0x3d, + 0x74, 0x1b, 0x2a, 0x85, 0x47, 0x0f, 0x65, 0xf4, 0xce, 0x78, 0x1c, 0x67, + 0xc2, 0x82, 0x65, 0xae, 0xb4, 0xca, 0xf3, 0x35, 0xc4, 0x8c, 0x73, 0x99, + 0x10, 0xc4, 0xc9, 0x03, 0x4e, 0x4d, 0x83, 0xd0, 0x68, 0x32, 0x37, 0x18, + 0x2a, 0xfc, 0x7d, 0x4a, 0x62, 0x60, 0x29, 0xd6, 0x50, 0x60, 0xdd, 0xc7, + 0xb9, 0xb6, 0xe4, 0xb8, 0xb2, 0x80, 0x2b, 0x23, 0x94, 0x62, 0x21, 0x23, + 0x5f, 0x15, 0x1d, 0xa3, 0xfb, 0xe6, 0x7b, 0x9a, 0xec, 0x6c, 0x76, 0x6b, + 0xd6, 0xd8, 0x5f, 0xa2, 0x88, 0x58, 0xc9, 0xab, 0x6e, 0x91, 0x50, 0xdf, + 0xee, 0xd7, 0x47, 0xd0, 0x14, 0x48, 0x30, 0xfb, 0x4e, 0xc3, 0xff, 0xe3, + 0xb0, 0x21, 0xbb, 0xd9, 0xe6, 0x1b, 0xe9, 0xaa, 0xd2, 0xd7, 0x4d, 0x47, + 0x3d, 0x3e, 0xb4, 0xbd, 0x80, 0x74, 0x5f, 0x90, 0x82, 0xc0, 0xba, 0x60, + 0xf6, 0x73, 0x99, 0x08, 0x87, 0x56, 0xc0, 0x8d, 0x13, 0xae, 0xb2, 0x6c, + 0xcc, 0x05, 0x52, 0x79, 0xde, 0x89, 0x8d, 0x8d, 0x2a, 0x6b, 0xbe, 0x07, + 0x61, 0xe0, 0x19, 0x4c, 0x21, 0xad, 0x8a, 0xba, 0xe2, 0x21, 0xe4, 0xca, + 0xd1, 0xe6, 0x04, 0xfe, 0x00, 0x83, 0xea, 0x4d, 0x01, 0x09, 0x0e, 0xb7, + 0xa5, 0x2c, 0x5c, 0xf4, 0x8f, 0x4a, 0x9a, 0xf5, 0x4d, 0x43, 0xd0, 0x52, + 0x5e, 0xc3, 0xe7, 0xeb, 0x46, 0x96, 0x98, 0xa3, 0xb0, 0x67, 0x61, 0x70, + 0xec, 0xfb, 0x41, 0x70, 0x32, 0x00, 0x51, 0x36, 0x97, 0x5c, 0x9e, 0xc1, + 0x89, 0xa7, 0xb6, 0x4e, 0x97, 0x6f, 0xf2, 0x9c, 0xf4, 0x8b, 0xdc, 0xca, + 0x01, 0x18, 0x81, 0x3f, 0x76, 0x00, 0x8c, 0x24, 0x4a, 0x21, 0xbf, 0xc2, + 0x76, 0x8b, 0x2c, 0xcf, 0xa2, 0xca, 0xe4, 0x1f, 0x08, 0x85, 0x1d, 0x8b, + 0xa9, 0xbc, 0x4e, 0xb8, 0xcb, 0x92, 0x50, 0x23, 0x6d, 0x95, 0x3b, 0x8b, + 0x24, 0x85, 0x5c, 0xc1, 0x47, 0xb9, 0x78, 0xfb, 0x58, 0x86, 0xc1, 0xa7, + 0xbf, 0x7d, 0xf5, 0xfc, 0x2e, 0x80, 0x97, 0x40, 0xd4, 0xf8, 0x11, 0x4c, + 0xc3, 0x4f, 0x7f, 0x7f, 0x7e, 0x7c, 0xf7, 0xe2, 0x24, 0x38, 0x89, 0xe4, + 0xa3, 0x8c, 0xc3, 0x95, 0x2a, 0xb0, 0x0d, 0x45, 0xb9, 0x8e, 0x05, 0xc9, + 0x8d, 0x32, 0x23, 0x53, 0x5e, 0xe0, 0x55, 0x0a, 0xe1, 0x46, 0x2a, 0x8a, + 0x45, 0x94, 0x6d, 0x45, 0x87, 0x8e, 0xd7, 0x9f, 0x89, 0x4e, 0xa2, 0xa1, + 0x5b, 0x51, 0x93, 0x54, 0x4a, 0x3f, 0x7f, 0xfc, 0xc1, 0xf3, 0x7e, 0x1a, + 0xdf, 0x9d, 0xc0, 0x9f, 0x7f, 0xc2, 0xa8, 0xa6, 0xa6, 0x9f, 0x8d, 0x0f, + 0x36, 0xd3, 0xab, 0x30, 0x1d, 0xc0, 0x1a, 0xe5, 0x7a, 0x8d, 0xeb, 0x56, + 0x17, 0x3e, 0x02, 0x2f, 0x93, 0xcf, 0xc2, 0xf4, 0x24, 0xaa, 0x07, 0x46, + 0xc4, 0xb3, 0x9f, 0x5e, 0xd5, 0x94, 0x29, 0x7c, 0x05, 0x41, 0xbd, 0x8f, + 0x06, 0x70, 0x05, 0x01, 0xf5, 0x8d, 0xe0, 0x7a, 0x57, 0x4f, 0xa6, 0x12, + 0x89, 0x12, 0x48, 0xc9, 0xd3, 0xb2, 0xfe, 0x1d, 0xa3, 0xd3, 0x61, 0x3c, + 0x1f, 0xc0, 0x63, 0xc3, 0xda, 0xb8, 0x68, 0xa5, 0xbb, 0x55, 0x4b, 0xa9, + 0x2b, 0x47, 0x6f, 0x69, 0x82, 0x8f, 0xe0, 0x05, 0x12, 0xf5, 0xd8, 0x31, + 0x94, 0x26, 0xdc, 0xf2, 0xed, 0xb0, 0xc9, 0xfc, 0x09, 0x5e, 0x20, 0x99, + 0x74, 0x71, 0x16, 0x06, 0xa7, 0x96, 0xf1, 0xfa, 0xbb, 0xd5, 0xc5, 0x57, + 0xc5, 0x94, 0x92, 0xf5, 0x4e, 0xb8, 0x2c, 0x32, 0x02, 0x13, 0xb3, 0x0c, + 0x11, 0x48, 0xc1, 0x77, 0x6f, 0x6f, 0x83, 0x01, 0xe5, 0xf5, 0xc6, 0x0d, + 0xe0, 0xac, 0xaf, 0x27, 0xae, 0xcc, 0xc6, 0x3d, 0x8a, 0x29, 0x62, 0x2e, + 0x1d, 0x23, 0x47, 0x93, 0x48, 0x7f, 0x75, 0xd6, 0xbf, 0x3a, 0xa7, 0xab, + 0x9e, 0x40, 0x56, 0x15, 0x22, 0x22, 0x13, 0x96, 0xca, 0xcb, 0xa7, 0x77, + 0xda, 0x58, 0x16, 0x62, 0x10, 0x17, 0x14, 0x22, 0x72, 0x73, 0x00, 0xe7, + 0x78, 0xe9, 0x1d, 0xb5, 0x70, 0x38, 0xc5, 0x75, 0x78, 0xd4, 0x70, 0x1f, + 0x50, 0x15, 0x50, 0x05, 0x44, 0xaa, 0x28, 0xa4, 0xb9, 0xc5, 0x01, 0x40, + 0x31, 0x7f, 0xb3, 0x12, 0x6a, 0xab, 0x62, 0x21, 0x24, 0xdf, 0x2d, 0xa1, + 0xf4, 0x84, 0x52, 0x81, 0x36, 0x01, 0x63, 0x0b, 0x9f, 0x59, 0x2e, 0x75, + 0x11, 0x9d, 0x42, 0x82, 0x99, 0x47, 0x7e, 0xeb, 0x0c, 0x72, 0x07, 0x5e, + 0xc9, 0x01, 0x5e, 0xc3, 0x5f, 0x6e, 0x7e, 0x7a, 0x1f, 0x95, 0xc2, 0x58, + 0x19, 0x26, 0x6c, 0x25, 0x7a, 0xb6, 0xb1, 0xc1, 0xaf, 0x0c, 0x3b, 0x96, + 0x1c, 0x7d, 0x53, 0xdf, 0x5f, 0xc1, 0x11, 0x2a, 0x4f, 0x22, 0xa6, 0x52, + 0x09, 0xf9, 0xd3, 0x54, 0x57, 0x8c, 0x54, 0x09, 0xca, 0x55, 0xa4, 0x71, + 0xeb, 0xde, 0x12, 0xfb, 0x27, 0x56, 0x1f, 0xfc, 0x90, 0xe4, 0x32, 0x18, + 0x34, 0x87, 0x66, 0xed, 0xe0, 0xb6, 0xb8, 0xb9, 0xfd, 0x56, 0xa8, 0x5c, + 0x26, 0x30, 0x84, 0x95, 0xd1, 0xe8, 0xb8, 0x1f, 0x8c, 0xbd, 0xf7, 0xbe, + 0x6d, 0x43, 0xa1, 0x1d, 0xa4, 0xba, 0x2a, 0x76, 0x48, 0xda, 0x23, 0x77, + 0xcc, 0xa7, 0x27, 0xc1, 0x61, 0x50, 0x13, 0xdd, 0x7d, 0x4a, 0x22, 0x06, + 0xd9, 0x1d, 0x9b, 0xce, 0x39, 0x72, 0x9b, 0x4a, 0x63, 0x51, 0xb6, 0x0e, + 0xc5, 0xd1, 0x16, 0xc9, 0x61, 0xdb, 0x90, 0x9e, 0x3f, 0x07, 0x2f, 0x04, + 0x66, 0x30, 0xee, 0x9c, 0x27, 0x70, 0xd9, 0x11, 0xf1, 0x5e, 0x22, 0x83, + 0xa0, 0x79, 0xa8, 0x12, 0x78, 0xdf, 0x38, 0x42, 0x13, 0xd8, 0xcf, 0x6c, + 0xaf, 0xe3, 0x49, 0x58, 0x58, 0xb7, 0x65, 0x81, 0xd7, 0x41, 0x09, 0x47, + 0x2d, 0x3e, 0xd3, 0x08, 0x78, 0x06, 0x74, 0x93, 0xe2, 0x83, 0xb6, 0xa5, + 0x3a, 0x53, 0x49, 0xba, 0xec, 0x81, 0x56, 0x30, 0xad, 0x07, 0x95, 0x97, + 0xee, 0x3d, 0xda, 0x95, 0x3d, 0x0e, 0x3c, 0x3d, 0xfd, 0xee, 0xb5, 0x2e, + 0x2e, 0x5e, 0x6c, 0xcc, 0x83, 0x66, 0x45, 0x1c, 0x40, 0x2c, 0xf2, 0x9c, + 0xbe, 0x34, 0x0d, 0xc0, 0xa1, 0xce, 0xdf, 0x50, 0xe9, 0x56, 0x7b, 0x7e, + 0xcc, 0x4c, 0xd3, 0x9a, 0xff, 0xfa, 0xee, 0xc7, 0xef, 0x9d, 0x2b, 0x3f, + 0x4a, 0x1c, 0x2b, 0xd6, 0x85, 0xac, 0x05, 0x5f, 0x47, 0xba, 0xc8, 0xb5, + 0x48, 0x64, 0x91, 0x74, 0xda, 0xbc, 0xb7, 0xcb, 0x4b, 0x0f, 0x89, 0x94, + 0xcd, 0x1e, 0x00, 0x3d, 0x1b, 0x69, 0x4b, 0x5d, 0x58, 0x49, 0xe1, 0x63, + 0x61, 0x9f, 0x5b, 0x89, 0x8e, 0xbd, 0xdf, 0x2f, 0x71, 0x38, 0x1e, 0x30, + 0x0e, 0x76, 0xb8, 0x4b, 0x59, 0x84, 0xde, 0xb9, 0xda, 0x53, 0x8a, 0x6d, + 0x6b, 0xaf, 0x95, 0xae, 0x71, 0xe2, 0x7b, 0x89, 0x76, 0x63, 0xd4, 0xde, + 0x20, 0x08, 0x4b, 0x87, 0x2d, 0x25, 0x10, 0x65, 0x99, 0x2b, 0x9e, 0x28, + 0xa7, 0xd4, 0xd8, 0x82, 0x96, 0xad, 0x35, 0x29, 0xf4, 0x71, 0xa2, 0xf1, + 0x30, 0xc6, 0x66, 0xf1, 0xa2, 0xee, 0xa5, 0x5b, 0x0a, 0x8a, 0x24, 0xec, + 0x37, 0xa7, 0x85, 0x76, 0x6f, 0x4a, 0x6a, 0x4e, 0x24, 0x78, 0x2b, 0xc4, + 0x34, 0x64, 0x37, 0x83, 0x8b, 0x11, 0x83, 0x2d, 0x88, 0x90, 0x4a, 0x84, + 0x70, 0xd8, 0x80, 0xbd, 0xdf, 0x4e, 0xe8, 0x75, 0xa7, 0xa3, 0x78, 0x9e, + 0x28, 0x97, 0xc5, 0xc2, 0x65, 0x08, 0x8f, 0xd1, 0x06, 0x1e, 0xa4, 0xa5, + 0xdb, 0x67, 0x88, 0xb2, 0x87, 0xad, 0xbe, 0x6c, 0x3d, 0xff, 0x5d, 0xc6, + 0x2e, 0xd8, 0x15, 0x44, 0x04, 0x9d, 0x3e, 0x45, 0xf7, 0x91, 0xd5, 0xc6, + 0x85, 0x6d, 0xca, 0xc4, 0x00, 0xe6, 0x9e, 0xd1, 0x4f, 0xa1, 0x79, 0x64, + 0xac, 0x55, 0x30, 0x04, 0x51, 0x3f, 0x34, 0x32, 0xc8, 0x90, 0x26, 0x1e, + 0xba, 0xb4, 0x80, 0x7a, 0x27, 0xba, 0x24, 0x21, 0x33, 0x5e, 0x60, 0x40, + 0xf8, 0x8a, 0xac, 0x17, 0xa4, 0xe6, 0x5d, 0xc0, 0x5c, 0xa9, 0x36, 0x10, + 0x12, 0xab, 0x42, 0xc6, 0xd1, 0x35, 0x7e, 0x4c, 0xea, 0xa8, 0x36, 0x71, + 0xb8, 0x86, 0x97, 0x2f, 0xd5, 0xc6, 0x0c, 0x12, 0xff, 0x72, 0x4b, 0x3e, + 0x35, 0x6f, 0x22, 0xfe, 0xa4, 0xee, 0x22, 0xb4, 0x27, 0xc1, 0x63, 0xd0, + 0x51, 0xe0, 0xb1, 0x75, 0x20, 0x4a, 0x2e, 0xf8, 0xef, 0x6f, 0xdf, 0xfd, + 0x88, 0x8a, 0x50, 0x10, 0xbf, 0x15, 0x73, 0x9a, 0xc8, 0x62, 0x9e, 0xb7, + 0x0b, 0x10, 0xbf, 0x70, 0x7a, 0x81, 0x19, 0xa7, 0xec, 0x79, 0x0c, 0x7a, + 0x7a, 0x5d, 0xc4, 0x88, 0xb3, 0x7b, 0x24, 0xaf, 0x69, 0x7a, 0x53, 0x03, + 0x69, 0xba, 0x33, 0xe7, 0xbd, 0xf6, 0xad, 0xd5, 0x72, 0x5f, 0xed, 0x4f, + 0x9d, 0x03, 0x23, 0xda, 0xb9, 0xf6, 0xa6, 0x1c, 0xc0, 0x25, 0xeb, 0xeb, + 0xf5, 0x00, 0x36, 0x4b, 0x3e, 0x0c, 0x50, 0x92, 0x89, 0xe5, 0xf6, 0xa0, + 0xaf, 0x2f, 0x08, 0xd6, 0xa2, 0xdc, 0xdd, 0x35, 0xa6, 0x7e, 0x5f, 0xf1, + 0x91, 0xac, 0xb7, 0x93, 0xc0, 0xff, 0xed, 0xc2, 0x97, 0x8a, 0x1f, 0xd1, + 0x14, 0x4a, 0xbe, 0xea, 0x3b, 0x73, 0x13, 0x8b, 0x82, 0x74, 0xfb, 0x94, + 0xda, 0xe0, 0x89, 0xc0, 0x90, 0x17, 0xfd, 0xc8, 0xb0, 0xfc, 0xbe, 0x5a, + 0xb6, 0x66, 0xbf, 0xda, 0x77, 0xa2, 0xa8, 0x44, 0x0e, 0x6f, 0x0b, 0x67, + 0xd6, 0xc1, 0xd3, 0xa1, 0x61, 0xa5, 0xbe, 0xd5, 0xf4, 0xec, 0x96, 0xc2, + 0xc4, 0x19, 0x4d, 0x7e, 0x32, 0xde, 0xe7, 0x03, 0x01, 0x89, 0xd2, 0x7a, + 0x38, 0xe0, 0x86, 0xde, 0x87, 0x8d, 0x07, 0x1e, 0x78, 0xda, 0x19, 0x85, + 0xa3, 0x40, 0xa9, 0x3d, 0x64, 0xef, 0x59, 0xbe, 0x78, 0x37, 0xdf, 0xb7, + 0x77, 0x71, 0xbf, 0xa1, 0x35, 0x6f, 0xd3, 0x8a, 0x78, 0x67, 0xe6, 0x86, + 0xbd, 0xdd, 0xad, 0xbd, 0xbf, 0xb9, 0x74, 0x80, 0xb1, 0x21, 0x07, 0xa7, + 0xd0, 0xae, 0xef, 0x61, 0xc0, 0x97, 0x14, 0xd7, 0xff, 0x30, 0x9b, 0x7b, + 0x92, 0xb9, 0xfd, 0xcd, 0x82, 0x28, 0x32, 0x51, 0x2c, 0x64, 0xbf, 0xd1, + 0x33, 0x65, 0x93, 0xcf, 0xa8, 0xfe, 0x8e, 0xda, 0xf9, 0x5a, 0xe2, 0x2f, + 0x39, 0x8f, 0x1b, 0xc9, 0xf3, 0x7b, 0x1c, 0xae, 0x5e, 0x71, 0x4f, 0x6a, + 0x77, 0x4e, 0xd6, 0x9c, 0xfd, 0x85, 0x70, 0x14, 0x35, 0x85, 0xa3, 0xd2, + 0xd0, 0x87, 0xe3, 0x04, 0x88, 0xed, 0x08, 0x17, 0xcf, 0xa3, 0x26, 0x9a, + 0x00, 0x93, 0x53, 0xff, 0xc5, 0x6c, 0x72, 0xca, 0x7f, 0x03, 0xc2, 0x07, + 0xfe, 0x1f, 0x53, 0xff, 0x02, 0x2a, 0x13, 0x18, 0xb6, 0xb0, 0x1a, 0x00, + 0x00 +}; +unsigned int enduser_setup_html_default_len = 2569; diff --git a/app/modules/eus/prepare.sh b/app/modules/enduser_setup/prepare.sh similarity index 65% rename from app/modules/eus/prepare.sh rename to app/modules/enduser_setup/prepare.sh index 133ea9bb68..063a287eab 100644 --- a/app/modules/eus/prepare.sh +++ b/app/modules/enduser_setup/prepare.sh @@ -3,5 +3,5 @@ # Uses zopfli for better gzip compression # sudo apt-get install zopfli zopfli --gzip ./enduser_setup.html -xxd -i ./enduser_setup.html.gz | sed 's/unsigned char/static const char/; s/__enduser_setup_html_gz/http_html_backup/' > http_html_backup.def +xxd -i ./enduser_setup.html.gz | sed 's/unsigned char/static const char/; s/__enduser_setup_html_gz/enduser_setup_html_default/' > enduser_setup.html.gz.def.h diff --git a/app/modules/eus/enduser_setup.html.gz b/app/modules/eus/enduser_setup.html.gz deleted file mode 100644 index a8897cd693..0000000000 Binary files a/app/modules/eus/enduser_setup.html.gz and /dev/null differ diff --git a/app/modules/eus/http_html_backup.def b/app/modules/eus/http_html_backup.def deleted file mode 100644 index 97e5592a7a..0000000000 --- a/app/modules/eus/http_html_backup.def +++ /dev/null @@ -1,205 +0,0 @@ -static const char http_html_backup[] = { - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x03, 0x95, 0x59, - 0x7b, 0x73, 0xdb, 0x36, 0x12, 0xff, 0xdb, 0xf9, 0x14, 0xeb, 0xba, 0x17, - 0xca, 0x8d, 0xde, 0xb2, 0xd3, 0x8c, 0xf5, 0xe8, 0xe4, 0xfa, 0xbe, 0x49, - 0xd2, 0x4e, 0xed, 0x4e, 0xaf, 0x93, 0xc9, 0x74, 0x20, 0x12, 0xb4, 0x50, - 0x53, 0x00, 0x0f, 0x00, 0x2d, 0xeb, 0xda, 0x7c, 0xf7, 0xdb, 0xe5, 0x12, - 0xa2, 0x28, 0xaa, 0x9a, 0xeb, 0x34, 0x7a, 0x10, 0xd8, 0xc7, 0xee, 0x6f, - 0x1f, 0xbb, 0x72, 0x67, 0xe7, 0x5f, 0xfd, 0xf0, 0xe5, 0xdd, 0xaf, 0x3f, - 0x7e, 0x0d, 0x2b, 0xbf, 0xce, 0x16, 0xcf, 0x66, 0xfc, 0x81, 0x9f, 0x52, - 0x24, 0x8b, 0x67, 0x67, 0xb3, 0xb5, 0xf4, 0x02, 0xb4, 0x58, 0xcb, 0x79, - 0xf4, 0xa8, 0xe4, 0x26, 0x37, 0xd6, 0x47, 0x10, 0x1b, 0xed, 0xa5, 0xf6, - 0xf3, 0x68, 0xa3, 0x12, 0xbf, 0x9a, 0x27, 0xf2, 0x51, 0xc5, 0xb2, 0x57, - 0x3e, 0x74, 0x41, 0x69, 0xe5, 0x95, 0xc8, 0x7a, 0x2e, 0x16, 0x99, 0x9c, - 0x8f, 0xfa, 0xc3, 0x88, 0xe4, 0x78, 0xe5, 0x33, 0xb9, 0xf8, 0x45, 0x7d, - 0xa3, 0xe0, 0x8d, 0xb9, 0x57, 0x7a, 0x36, 0xe0, 0x13, 0xbc, 0x72, 0x7e, - 0x9b, 0x49, 0xf0, 0xdb, 0x5c, 0xce, 0xbd, 0x7c, 0xf2, 0x83, 0xd8, 0x39, - 0x3c, 0x3e, 0xfb, 0x0c, 0xfe, 0xc0, 0xf7, 0xb3, 0xb5, 0xb0, 0x48, 0x7e, - 0x03, 0xc3, 0x29, 0x3d, 0xe5, 0x22, 0x49, 0x94, 0xbe, 0xaf, 0x1e, 0x3f, - 0xe2, 0x0b, 0xff, 0x91, 0xcd, 0x5d, 0xfc, 0x5c, 0x9a, 0x64, 0xcb, 0x4c, - 0x2b, 0xa9, 0xee, 0x57, 0xfe, 0x06, 0x46, 0xc3, 0xe1, 0x3f, 0x4a, 0xbe, - 0x14, 0x2d, 0xee, 0xa5, 0x62, 0xad, 0xb2, 0xed, 0x0d, 0x38, 0xa1, 0x5d, - 0xcf, 0x49, 0xab, 0xd2, 0xf2, 0x8e, 0x94, 0xf6, 0x44, 0xa6, 0xee, 0x51, - 0x4b, 0x2c, 0xd1, 0x33, 0x5b, 0x1e, 0x2f, 0x45, 0xfc, 0x70, 0x6f, 0x4d, - 0xa1, 0x93, 0x1b, 0xb8, 0xb8, 0xba, 0xba, 0x4a, 0xae, 0xae, 0xf6, 0x74, - 0x5e, 0x54, 0x18, 0xb0, 0xbe, 0xdc, 0x38, 0x74, 0xda, 0xa0, 0x00, 0xb1, - 0x74, 0x26, 0x2b, 0xbc, 0x64, 0xc9, 0x26, 0x0f, 0x86, 0x5b, 0x36, 0x88, - 0x1f, 0x96, 0xc6, 0x7b, 0xb3, 0x0e, 0x4f, 0x99, 0x4c, 0x77, 0x37, 0x25, - 0x86, 0x37, 0x30, 0x19, 0x0f, 0xf3, 0xa7, 0xe9, 0xbe, 0x27, 0x57, 0xaf, - 0xc2, 0x49, 0x00, 0x44, 0x14, 0xde, 0xec, 0x19, 0xa4, 0x74, 0x5e, 0xf8, - 0x12, 0x85, 0x02, 0x85, 0x6b, 0xfa, 0xe6, 0x64, 0x26, 0xe3, 0xca, 0xc2, - 0xde, 0x46, 0x2e, 0x1f, 0x14, 0xfa, 0x99, 0xe7, 0x52, 0x58, 0xa1, 0x63, - 0x79, 0x03, 0xda, 0x68, 0x59, 0xd9, 0x63, 0x13, 0x69, 0x7b, 0x56, 0x24, - 0xaa, 0x70, 0x4d, 0x6c, 0x53, 0x25, 0xb3, 0xc4, 0x49, 0x96, 0x52, 0x11, - 0xd6, 0x6e, 0x3c, 0xf5, 0xdc, 0x4a, 0x24, 0x66, 0x83, 0x27, 0xf8, 0xdf, - 0xe8, 0x3a, 0x7f, 0x82, 0x11, 0xbe, 0xec, 0xfd, 0x52, 0x74, 0x86, 0x5d, - 0xe0, 0x7f, 0xfd, 0xab, 0xcb, 0x9a, 0x5c, 0xfd, 0xb7, 0x0c, 0x5f, 0xa5, - 0x11, 0x8f, 0x9a, 0x61, 0x25, 0xbf, 0x61, 0x82, 0x6f, 0xed, 0x10, 0xa4, - 0x69, 0xca, 0xfe, 0x2b, 0xdd, 0x63, 0x54, 0x18, 0xa7, 0x26, 0x2a, 0x3d, - 0xd4, 0x7f, 0x88, 0x4a, 0xd3, 0x76, 0x32, 0x10, 0x63, 0xa4, 0x12, 0xb8, - 0x88, 0xe3, 0x78, 0x8f, 0xb9, 0x17, 0xc2, 0x32, 0x0a, 0x42, 0x39, 0x1a, - 0x21, 0x8b, 0x4e, 0x7a, 0x10, 0x9b, 0xcc, 0x58, 0xb4, 0x72, 0x3c, 0x1e, - 0xef, 0x12, 0x0e, 0x39, 0x5f, 0xa2, 0xb2, 0xb5, 0xd1, 0xc6, 0xe5, 0x22, - 0x96, 0x0d, 0x57, 0x11, 0xad, 0x86, 0xa5, 0x21, 0x58, 0x27, 0x99, 0x6b, - 0x40, 0x7a, 0x95, 0x42, 0x8f, 0xb1, 0xc4, 0x7b, 0x2b, 0xb5, 0x3f, 0x29, - 0x9e, 0xb3, 0x82, 0xc5, 0x33, 0x6b, 0x40, 0xb4, 0x1d, 0xd5, 0x46, 0x32, - 0x4c, 0xf2, 0xca, 0xc1, 0xc2, 0x3a, 0xe2, 0xca, 0x8d, 0xda, 0x95, 0x48, - 0xa2, 0x5c, 0x9e, 0x89, 0x2d, 0x82, 0x91, 0x99, 0xf8, 0xe1, 0xc0, 0xef, - 0xa3, 0x65, 0x96, 0xc8, 0xd8, 0x58, 0xc1, 0xa5, 0xc2, 0xe9, 0xd7, 0xb0, - 0x99, 0xa2, 0x7f, 0x7d, 0x2c, 0xf8, 0x93, 0xd1, 0xf2, 0xea, 0xfa, 0xf3, - 0xc3, 0xa0, 0xb4, 0xfc, 0xbb, 0x49, 0x4d, 0x5c, 0xb8, 0x6e, 0xfd, 0xbc, - 0x32, 0x8f, 0xd2, 0x92, 0xd7, 0xed, 0x6c, 0x1d, 0xc2, 0x18, 0xb5, 0x11, - 0x08, 0x5d, 0x7e, 0x26, 0x57, 0xf7, 0x35, 0x85, 0xee, 0x32, 0xa9, 0x83, - 0x42, 0xd1, 0x97, 0xec, 0x5e, 0x23, 0xea, 0x2f, 0x5f, 0xbe, 0x3c, 0x96, - 0x48, 0x21, 0x3b, 0x83, 0xa4, 0xab, 0x06, 0xfe, 0x9c, 0x7e, 0x4d, 0xff, - 0x1b, 0xf4, 0xfd, 0xc2, 0xab, 0x4c, 0xf9, 0x6d, 0xa5, 0x3f, 0x33, 0x02, - 0xa1, 0x2d, 0x1b, 0x09, 0x2b, 0xcf, 0xa4, 0x40, 0x31, 0xa8, 0x6c, 0x55, - 0x29, 0x7f, 0xea, 0x55, 0xe0, 0x7c, 0x7e, 0x4d, 0xd8, 0x34, 0x6d, 0x9e, - 0xe4, 0xc7, 0x33, 0x95, 0x6d, 0x66, 0xe5, 0x87, 0x5d, 0xb6, 0x2c, 0xe8, - 0x76, 0x35, 0x06, 0xdb, 0x5b, 0x96, 0x06, 0xfc, 0xf7, 0x4e, 0xfe, 0x7e, - 0x04, 0x9a, 0xa2, 0x2f, 0x12, 0x6b, 0x72, 0x64, 0xd1, 0x5d, 0x7a, 0x48, - 0xc7, 0xfc, 0x31, 0x29, 0x3f, 0x96, 0x0f, 0x63, 0x96, 0x1c, 0x12, 0x31, - 0xe4, 0x54, 0x8b, 0xf9, 0xb0, 0x4d, 0x5b, 0x99, 0x61, 0x16, 0x3e, 0xca, - 0xa3, 0x65, 0x4e, 0x16, 0x23, 0xda, 0x1b, 0xee, 0xb1, 0x8d, 0x36, 0x7c, - 0x8d, 0xdd, 0xe3, 0x54, 0xcb, 0x08, 0x7a, 0x45, 0x9e, 0x29, 0x77, 0x7a, - 0x38, 0x34, 0xb5, 0xb6, 0x67, 0x56, 0x98, 0x1e, 0x61, 0x44, 0xb4, 0x87, - 0xc7, 0xe9, 0xae, 0xd6, 0x9c, 0x79, 0xa1, 0x8f, 0x1c, 0xaf, 0xb8, 0xa6, - 0xed, 0xd6, 0x9a, 0x4d, 0x33, 0x53, 0x5f, 0xbd, 0x7a, 0x35, 0x3d, 0xe1, - 0x4a, 0x35, 0xdc, 0x5e, 0xb1, 0x1c, 0x36, 0x7c, 0x74, 0x20, 0x55, 0xa1, - 0xc4, 0xe3, 0xc3, 0x96, 0x89, 0x66, 0x83, 0x72, 0x0f, 0xc0, 0x15, 0x64, - 0xc0, 0xbb, 0xc7, 0xb3, 0x19, 0xcd, 0x73, 0x5a, 0x10, 0x12, 0xf5, 0x08, - 0x2a, 0x99, 0x57, 0x13, 0x17, 0x4f, 0xce, 0x66, 0x61, 0x2c, 0xd1, 0x43, - 0x20, 0xa8, 0xf6, 0x90, 0xef, 0x93, 0xc5, 0x6c, 0x80, 0x27, 0x8d, 0xab, - 0x74, 0x84, 0x8f, 0xf4, 0xbc, 0x9a, 0x2c, 0xbe, 0x34, 0x5a, 0x53, 0xab, - 0x65, 0x72, 0xf0, 0x06, 0xb6, 0xa6, 0xb0, 0xf0, 0x8b, 0xea, 0x7d, 0xa3, - 0x50, 0xf9, 0xa4, 0xa2, 0xe4, 0x0e, 0x42, 0xcc, 0x5a, 0xfa, 0x8d, 0xb1, - 0x0f, 0x8e, 0x77, 0x94, 0xea, 0x3c, 0xce, 0x84, 0x73, 0xf3, 0x2a, 0xcb, - 0x51, 0x23, 0x1f, 0x33, 0x6f, 0xd0, 0x5a, 0x65, 0x1f, 0x9f, 0xe2, 0x31, - 0x06, 0xa0, 0x14, 0x58, 0x22, 0xbc, 0x78, 0x7e, 0xf1, 0x34, 0xbe, 0x5e, - 0xc6, 0x53, 0xf4, 0x1c, 0xcf, 0x03, 0x0d, 0xcf, 0x01, 0xa2, 0xe2, 0x1c, - 0xe2, 0xe5, 0x8b, 0xbf, 0xa3, 0x1a, 0xbe, 0x66, 0x62, 0x76, 0x93, 0xbf, - 0xf2, 0xa0, 0x43, 0x2e, 0xe7, 0x54, 0x52, 0x2f, 0x53, 0x65, 0x06, 0xc7, - 0xc6, 0x5a, 0x64, 0x9a, 0x9b, 0x34, 0xe5, 0x67, 0x91, 0x2b, 0x2f, 0x32, - 0x6c, 0x0b, 0x73, 0xaa, 0x17, 0xc0, 0xd2, 0x89, 0xe5, 0xca, 0x64, 0x98, - 0x48, 0xf3, 0xa8, 0x84, 0x01, 0xde, 0xa1, 0xd2, 0x08, 0x06, 0x87, 0xc2, - 0x37, 0x2a, 0x55, 0xbf, 0xe5, 0xe8, 0x38, 0xe2, 0xf1, 0x77, 0xb5, 0x30, - 0xcd, 0x3a, 0xcf, 0xa4, 0x97, 0x44, 0xd4, 0x50, 0xfb, 0x63, 0x90, 0x39, - 0x68, 0xa1, 0xef, 0x8a, 0xe5, 0x5a, 0xf9, 0x7d, 0xec, 0x17, 0xb7, 0xe2, - 0x51, 0x36, 0x10, 0x3f, 0x12, 0xf0, 0x71, 0x08, 0xf8, 0x68, 0x71, 0x5b, - 0xc4, 0xb1, 0x74, 0xee, 0x1c, 0x83, 0x3b, 0x6a, 0x06, 0x48, 0xe1, 0x63, - 0x48, 0x8b, 0x5f, 0x31, 0x09, 0x42, 0x4e, 0xac, 0x84, 0x03, 0xc7, 0x5c, - 0x69, 0x91, 0x65, 0x5b, 0x88, 0x39, 0x67, 0x64, 0x42, 0xe9, 0xe2, 0x57, - 0x12, 0x18, 0xa6, 0x2a, 0x33, 0xfa, 0xb3, 0xa5, 0x45, 0xcb, 0xf1, 0x7d, - 0x40, 0x62, 0x60, 0x2d, 0xb6, 0xa0, 0xb1, 0x86, 0xe2, 0xcc, 0x38, 0x89, - 0xe4, 0xca, 0x01, 0xae, 0x5f, 0x90, 0x8b, 0x7b, 0xd9, 0x0f, 0x19, 0xd6, - 0x30, 0xba, 0x6d, 0x7e, 0xa0, 0x59, 0x8d, 0x17, 0x77, 0x76, 0x8b, 0xb5, - 0xda, 0xef, 0x13, 0xeb, 0xb8, 0x05, 0x0f, 0xf5, 0xc0, 0x76, 0x5e, 0x46, - 0x55, 0x62, 0x46, 0x8b, 0x6f, 0x0d, 0xfc, 0x13, 0x1b, 0x37, 0xd9, 0xcd, - 0x36, 0xdf, 0x4a, 0x5f, 0xe4, 0x47, 0xd1, 0xc3, 0x2f, 0x75, 0x5d, 0x91, - 0xee, 0x2b, 0x52, 0x10, 0x39, 0x1f, 0x2d, 0x7e, 0xce, 0x13, 0xe1, 0xd1, - 0x0a, 0xb8, 0xf5, 0xc2, 0x17, 0x8e, 0x8d, 0xb9, 0x42, 0xaa, 0xc0, 0x3b, - 0x73, 0xb1, 0x55, 0x79, 0xc9, 0xf7, 0x28, 0x2c, 0x7c, 0x0a, 0x73, 0x48, - 0x0b, 0x1d, 0x53, 0xb3, 0x80, 0x0e, 0x27, 0xad, 0xb1, 0x97, 0xf0, 0x07, - 0x58, 0x54, 0x6f, 0x35, 0x24, 0x38, 0x28, 0xd6, 0x52, 0xfb, 0xfe, 0x7f, - 0x0a, 0x69, 0xb7, 0xb7, 0x15, 0x41, 0x4d, 0x39, 0x85, 0x8f, 0xd3, 0x4a, - 0x96, 0x58, 0xa2, 0xb0, 0x4f, 0x3b, 0xd1, 0x45, 0xa8, 0xc3, 0xe8, 0xb2, - 0x0b, 0x22, 0xaf, 0x0e, 0xb9, 0x32, 0xa2, 0xcb, 0x40, 0xed, 0xbc, 0xc9, - 0x5f, 0x67, 0x19, 0xe9, 0x17, 0x99, 0x93, 0x5d, 0xb0, 0x02, 0x5f, 0xae, - 0x0b, 0x9c, 0x47, 0x18, 0xc2, 0x70, 0x35, 0x7d, 0x86, 0x2c, 0x3b, 0x23, - 0xdd, 0xca, 0x6c, 0x3a, 0x38, 0x88, 0xb6, 0x97, 0xdc, 0xa8, 0x54, 0x0a, - 0x9d, 0x2d, 0xcc, 0xe7, 0xa0, 0x31, 0x01, 0x2e, 0x01, 0xbf, 0x02, 0xef, - 0x31, 0x9f, 0x76, 0xd2, 0xcb, 0x7e, 0xd9, 0xab, 0xfa, 0x3c, 0x76, 0xe8, - 0xaa, 0xa4, 0x4c, 0xe1, 0x0b, 0x88, 0xca, 0x55, 0x28, 0x82, 0x1b, 0x88, - 0x28, 0xeb, 0xa3, 0xd0, 0x02, 0x77, 0x7a, 0x56, 0x2a, 0x91, 0x28, 0x81, - 0x95, 0x1c, 0x95, 0xf5, 0x17, 0x8c, 0xde, 0x74, 0xe2, 0x65, 0x17, 0x9e, - 0x2a, 0xd6, 0x0a, 0x47, 0x8c, 0xd5, 0x9d, 0x5a, 0x4b, 0x53, 0x78, 0xba, - 0xa5, 0xe1, 0x31, 0x84, 0xcf, 0x90, 0xa8, 0xc5, 0x6e, 0x65, 0x6a, 0x3b, - 0x7b, 0xbe, 0x9d, 0x57, 0x40, 0x5d, 0xe2, 0x01, 0x92, 0x49, 0x1f, 0xaf, - 0x3a, 0xd1, 0xc0, 0x71, 0x78, 0x7f, 0x77, 0x46, 0x7f, 0xa1, 0xe7, 0x11, - 0xbc, 0x80, 0xb7, 0xc2, 0xaf, 0xfa, 0x56, 0xe8, 0xc4, 0xac, 0x3b, 0x88, - 0x7b, 0xf4, 0xed, 0xd7, 0x77, 0x51, 0x17, 0xb4, 0xdc, 0xdc, 0xfa, 0x2e, - 0x8c, 0xdb, 0x7a, 0xe2, 0xc2, 0xee, 0xdc, 0x23, 0x4c, 0x31, 0x44, 0xe9, - 0x08, 0x39, 0x52, 0x22, 0xad, 0x8f, 0xc6, 0xed, 0xa3, 0x49, 0x38, 0x6a, - 0x08, 0x64, 0x55, 0x1d, 0x0c, 0x60, 0xc2, 0x52, 0x79, 0xef, 0x09, 0x4e, - 0x5b, 0xc7, 0x42, 0xac, 0x83, 0x39, 0x41, 0x44, 0x6e, 0x76, 0x61, 0x82, - 0x87, 0xc1, 0x51, 0x07, 0xe7, 0x73, 0xdc, 0xc4, 0x86, 0x15, 0xf7, 0x19, - 0x25, 0x0d, 0x25, 0x4c, 0x5f, 0x69, 0x2d, 0xed, 0x1d, 0xb6, 0x2f, 0xc2, - 0xfc, 0xf5, 0x46, 0xa8, 0xbd, 0x04, 0x87, 0x0e, 0xf9, 0xee, 0xf0, 0x15, - 0x5d, 0x52, 0x28, 0xd0, 0x26, 0x90, 0x98, 0x33, 0x24, 0xa3, 0x92, 0x4b, - 0x45, 0x67, 0x52, 0x48, 0x30, 0xf2, 0xc8, 0xef, 0xbc, 0x45, 0xee, 0x28, - 0x28, 0x39, 0xc3, 0x63, 0xf8, 0xd7, 0xed, 0x0f, 0xef, 0xfa, 0xb9, 0xb0, - 0x4e, 0x76, 0x12, 0xb6, 0x12, 0x3d, 0xdb, 0xd9, 0x10, 0xa6, 0xd5, 0x81, - 0x25, 0x9f, 0x7c, 0x55, 0x9e, 0xdf, 0xc0, 0x27, 0xa8, 0x3c, 0xe9, 0x33, - 0x95, 0x4a, 0x4a, 0x7f, 0x38, 0xc3, 0x63, 0xa4, 0x4a, 0x50, 0xae, 0x22, - 0x8d, 0x7b, 0xe7, 0x8e, 0xd8, 0xdf, 0xb3, 0xfa, 0xe8, 0xfb, 0x24, 0x93, - 0x51, 0xb7, 0x7a, 0xa8, 0x26, 0x1e, 0x77, 0x91, 0xdd, 0xe9, 0x37, 0x42, - 0x65, 0x32, 0x81, 0x1e, 0x6c, 0xac, 0x41, 0xc7, 0x43, 0x5b, 0x6f, 0xdf, - 0x57, 0x75, 0x07, 0xda, 0x78, 0x48, 0x4d, 0xa1, 0x0f, 0x49, 0xc2, 0x63, - 0x35, 0x3b, 0x8e, 0x37, 0xce, 0xf3, 0xa8, 0x24, 0xfa, 0xf0, 0x3e, 0xe9, - 0x73, 0x92, 0x7d, 0x60, 0xd3, 0x39, 0x46, 0x7e, 0x57, 0x69, 0x2c, 0xca, - 0x95, 0x50, 0x7c, 0xb2, 0x47, 0x72, 0x5e, 0xd7, 0xef, 0xf3, 0xe7, 0x10, - 0x84, 0xc0, 0x02, 0x46, 0x8d, 0xe7, 0x19, 0x5c, 0x37, 0x44, 0xbc, 0x93, - 0xc8, 0x20, 0xe0, 0x51, 0xd0, 0x6a, 0xf4, 0xae, 0x72, 0x04, 0xb3, 0x19, - 0xc2, 0xc4, 0x09, 0x3a, 0x8e, 0xa6, 0x85, 0xf3, 0x7b, 0x16, 0x04, 0x1d, - 0x65, 0xc0, 0xaf, 0x77, 0x91, 0xc6, 0x84, 0xe7, 0x84, 0xae, 0x42, 0x7c, - 0x56, 0x77, 0x20, 0x6f, 0x0b, 0x49, 0x87, 0xad, 0xa4, 0x15, 0x4c, 0x1b, - 0x92, 0x2a, 0x48, 0x0f, 0x1e, 0x1d, 0xca, 0x1e, 0x45, 0xbb, 0xf4, 0xe1, - 0xb7, 0x66, 0x85, 0x30, 0x32, 0xa1, 0xb8, 0x6b, 0x9c, 0x82, 0x01, 0x55, - 0x7e, 0x14, 0x96, 0x6c, 0xc2, 0x1a, 0x97, 0x9e, 0xe6, 0xf8, 0x17, 0xe5, - 0x30, 0xa7, 0x75, 0xa1, 0xac, 0x73, 0xa9, 0x63, 0x93, 0xc8, 0x9f, 0x7f, - 0xfa, 0xfe, 0x4b, 0x9c, 0xd1, 0x46, 0x4b, 0xed, 0x3b, 0x04, 0x09, 0xdd, - 0x23, 0x28, 0x88, 0x5f, 0x21, 0x2f, 0xa9, 0x1c, 0x9e, 0x37, 0x76, 0x80, - 0x53, 0xac, 0x0d, 0xc2, 0x9d, 0x8c, 0xe9, 0xf1, 0x12, 0xde, 0xf5, 0x20, - 0xb4, 0xf2, 0x78, 0x97, 0x09, 0x60, 0x4c, 0xa2, 0x76, 0x8f, 0xd8, 0x63, - 0x5d, 0x4b, 0xbf, 0x32, 0x49, 0x17, 0x62, 0x91, 0x65, 0xf4, 0x8b, 0xa5, - 0x0b, 0x1e, 0xf5, 0xfc, 0x86, 0x8a, 0x10, 0x9f, 0x00, 0xc5, 0xd3, 0xca, - 0xc2, 0x9c, 0xc4, 0xc3, 0xbf, 0xdf, 0xbe, 0xf9, 0xce, 0xfb, 0xfc, 0x27, - 0x89, 0x73, 0xc8, 0xf9, 0x0e, 0x6b, 0xc2, 0xeb, 0xbe, 0xd1, 0x99, 0x11, - 0x89, 0xd4, 0x49, 0x63, 0x92, 0x85, 0xc8, 0x04, 0xe9, 0x1d, 0x22, 0xe5, - 0xc0, 0x75, 0x81, 0xbe, 0x5b, 0xe9, 0x10, 0x02, 0x27, 0x29, 0x81, 0x58, - 0xd8, 0xc7, 0x5a, 0xa2, 0x67, 0x8f, 0x4f, 0x4b, 0xec, 0x8d, 0xba, 0x5c, - 0x09, 0x07, 0xdc, 0xb9, 0xd4, 0x9d, 0xe0, 0x5c, 0xe9, 0x29, 0x05, 0xb7, - 0xb6, 0x17, 0xa3, 0x5a, 0x39, 0xf1, 0x9d, 0x44, 0xbb, 0x11, 0xaa, 0xd7, - 0x58, 0x86, 0xb9, 0x8f, 0x10, 0x4d, 0x91, 0xe3, 0x90, 0x8c, 0x05, 0x29, - 0x1c, 0x50, 0x6b, 0x8f, 0x6a, 0xb6, 0xda, 0xa4, 0x4e, 0xc0, 0x09, 0xfe, - 0xfc, 0x13, 0x46, 0xd8, 0x2e, 0x3f, 0x2b, 0xa7, 0xc9, 0x9e, 0x02, 0x9d, - 0x74, 0xda, 0xd0, 0xdf, 0x1b, 0xff, 0x3a, 0xa7, 0xf6, 0x4c, 0x82, 0xf7, - 0x20, 0xa6, 0xa9, 0x3c, 0x0d, 0x3d, 0x98, 0x6b, 0x06, 0x9b, 0x30, 0xd5, - 0x2a, 0x11, 0xc2, 0x79, 0x55, 0xee, 0xed, 0x86, 0x4a, 0xd7, 0x8d, 0x9e, - 0x1a, 0x78, 0xfa, 0x99, 0xd4, 0xf7, 0x7e, 0x05, 0x0b, 0x18, 0xee, 0x0a, - 0x84, 0xb4, 0x34, 0x3b, 0x2d, 0x51, 0xb6, 0xab, 0xab, 0x25, 0xdb, 0x2c, - 0x7f, 0x97, 0xb1, 0x8f, 0x0e, 0x05, 0x11, 0x41, 0xa3, 0x53, 0xd3, 0x79, - 0xdf, 0x19, 0xeb, 0x3b, 0x75, 0xc8, 0x44, 0x17, 0x96, 0x81, 0x31, 0xcc, - 0xe1, 0x65, 0xdf, 0x62, 0xa9, 0x40, 0x0f, 0x44, 0xf9, 0xa5, 0x92, 0x41, - 0x86, 0x54, 0x78, 0x98, 0xdc, 0x51, 0xf5, 0xcd, 0x4c, 0x4e, 0x42, 0x16, - 0xbc, 0xf1, 0x80, 0x08, 0x3d, 0xa9, 0xdc, 0xa8, 0xaa, 0xbb, 0x88, 0xb9, - 0x52, 0x63, 0xa1, 0x43, 0xac, 0x0a, 0x19, 0x87, 0x53, 0xfc, 0x98, 0x95, - 0xa8, 0x56, 0x38, 0x4c, 0xe1, 0xc5, 0x0b, 0xb5, 0x33, 0x83, 0xc4, 0xbf, - 0xd8, 0x93, 0x4f, 0x75, 0x49, 0xc4, 0xef, 0xd5, 0x87, 0x3e, 0xd5, 0x30, - 0x95, 0x6e, 0x43, 0x41, 0xc8, 0xad, 0x33, 0x91, 0x73, 0xcb, 0xfb, 0xee, - 0xee, 0xed, 0x1b, 0x54, 0x84, 0x82, 0xf8, 0x56, 0x2c, 0x69, 0x27, 0x11, - 0xcb, 0xac, 0xde, 0x98, 0xf8, 0xc2, 0x9b, 0x7b, 0x8c, 0x38, 0x45, 0x2f, - 0xe4, 0x60, 0xa0, 0x37, 0x3a, 0xc6, 0x3c, 0x7b, 0x40, 0xf2, 0x92, 0xa6, - 0x35, 0x37, 0x91, 0xa6, 0x39, 0x75, 0xdf, 0x99, 0x30, 0x5c, 0x1c, 0x4f, - 0x96, 0xf6, 0xdc, 0x3d, 0xb3, 0xa2, 0x9e, 0xec, 0xaf, 0xf3, 0x2e, 0x5c, - 0xb3, 0xbe, 0x56, 0x17, 0x64, 0xb3, 0xe4, 0x63, 0x17, 0x25, 0xd9, 0x58, - 0xee, 0xaf, 0x3a, 0xe5, 0x01, 0xa5, 0xb5, 0xc8, 0x0f, 0xb7, 0xad, 0x79, - 0xd8, 0xd8, 0x02, 0x92, 0xe5, 0x7e, 0x16, 0x85, 0x3f, 0x1c, 0x84, 0x52, - 0x09, 0x4b, 0x0a, 0xb7, 0xc3, 0xe9, 0x51, 0x67, 0x6e, 0x63, 0xa1, 0x49, - 0x77, 0x08, 0xa9, 0x8b, 0x8e, 0x00, 0xc3, 0x5e, 0xb4, 0x91, 0x61, 0xf9, - 0x4d, 0xb5, 0xc1, 0x9a, 0xd3, 0x6a, 0xdf, 0x0a, 0x5d, 0x88, 0x0c, 0xbe, - 0xd6, 0xde, 0x6e, 0xa3, 0xe3, 0xd0, 0xb0, 0xd2, 0xd0, 0x6a, 0x5a, 0x76, - 0x4b, 0x61, 0xe3, 0x15, 0x56, 0x5a, 0x69, 0x7c, 0x88, 0x07, 0x26, 0x24, - 0x4a, 0x6b, 0xe5, 0x01, 0x4f, 0x94, 0x76, 0xda, 0x84, 0xc4, 0x83, 0x40, - 0xbb, 0x20, 0x38, 0x34, 0x4a, 0x6d, 0x66, 0xf6, 0xe9, 0xf5, 0x93, 0x97, - 0xf9, 0x53, 0x9b, 0x27, 0xf7, 0x1b, 0x5a, 0x74, 0x77, 0xad, 0x68, 0xa3, - 0x90, 0x64, 0xc3, 0x0d, 0x7b, 0xbf, 0x5b, 0x57, 0xfe, 0x02, 0xfc, 0x7f, - 0x81, 0x02, 0xf8, 0x8b, 0x40, 0x41, 0xe3, 0x77, 0x06, 0x91, 0xac, 0x84, - 0xbe, 0x97, 0xc7, 0xba, 0x38, 0xc0, 0xe1, 0xcc, 0x6c, 0xfc, 0x4a, 0x09, - 0x87, 0x2c, 0xf5, 0x63, 0x2d, 0x9c, 0x67, 0x36, 0x5e, 0xd7, 0xfa, 0xf9, - 0xa8, 0x26, 0xc1, 0xdf, 0x79, 0xf5, 0xfd, 0x71, 0xdd, 0xf5, 0xb6, 0xc0, - 0xf2, 0xcb, 0xf7, 0xe6, 0x62, 0x3c, 0xec, 0x5f, 0x57, 0xb8, 0x01, 0xcc, - 0x06, 0xe1, 0x37, 0xdb, 0x6c, 0xc0, 0x7f, 0x6a, 0xc1, 0x2f, 0xe5, 0xff, - 0xff, 0xf9, 0x1f, 0xa1, 0xc6, 0xa0, 0x64, 0x16, 0x1a, 0x00, 0x00 -}; -unsigned int http_html_backup_len = 2423; diff --git a/docs/img/enduser-setup-captive-portal.png b/docs/img/enduser-setup-captive-portal.png new file mode 100644 index 0000000000..92f52050e0 Binary files /dev/null and b/docs/img/enduser-setup-captive-portal.png differ diff --git a/docs/img/enduser-setup.jpg b/docs/img/enduser-setup.jpg deleted file mode 100644 index 341cb711c2..0000000000 Binary files a/docs/img/enduser-setup.jpg and /dev/null differ diff --git a/docs/modules/enduser-setup.md b/docs/modules/enduser-setup.md index 9eb367b0b1..86060d7a73 100644 --- a/docs/modules/enduser-setup.md +++ b/docs/modules/enduser-setup.md @@ -3,49 +3,107 @@ | :----- | :-------------------- | :---------- | :------ | | 2015-09-02 | [Robert Foss](https://github.com/robertfoss) | [Robert Foss](https://github.com/robertfoss) | [enduser_setup.c](../../app/modules/enduser_setup.c)| -This module provides a simple way of configuring ESP8266 chips without using a serial interface or pre-programming WiFi credentials onto the chip. +This module provides a simple way of configuring ESP8266 chips without using a +serial interface or pre-programming WiFi credentials onto the chip. + +After running [`enduser_setup.start()`](#enduser_setupstart), a wireless +network named "SetupGadget_XXXXXX" will starting. This prefix can be overridden +in `user_config.h` by defining `ENDUSER_SETUP_AP_SSID`. Connect to that SSID +and then navigate to the root of any website or to 192.168.4.1. +`http://example.com/` will work, but do not use `.local` domains because it +will fail on iOS. A web page similar to the one depicted below will load, +allowing the end user to provide their Wi-Fi credentials. + +![enduser setup config dialog](../img/enduser-setup-captive-portal.png "enduser setup config dialog") + +After an IP address has been successfully obtained, then this module will stop +as if [`enduser_setup.stop()`](#enduser_setupstop) had been called. There is a +10-second delay before teardown to allow connected clients to obtain a last +status message while the SoftAP is still active. + +Alternative HTML can be served by placing a file called `enduser_setup.html` on +the filesystem. Everything needed by the web page must be included in this one +file. This file will be kept in RAM, so keep it as small as possible. The file +can be gzip'd ahead of time to reduce the size (i.e., using `gzip -n` or +`zopfli`), and when served, the End User Setup module will add the appropriate +`Content-Encoding` header to the response. + +*Note: If gzipped, the file can also be named `enduser_setup.html.gz` for +semantic purposes. GZIP encoding is determined by the file's contents, not the +filename.* + +### Additional configuration parameters + +You can also add some additional inputs in the `enduser_setup.html` (as long as +you keep those needed for the WiFi setup). The additional data will be written +in a `eus_params.lua` file in the root filesystem of the ESP8266, which you can +then load in your own code. In this case, the data will be saved as a set of +variables with the name being the input name, and the value being a string +representing what you put in the form. + +For instance, if your HTML contains two additional inputs: + +```html + + +``` + +Then the `eus_params.lua` file will contain the following: -![enduser setup config dialog](../img/enduser-setup.jpg "enduser setup config dialog") +```lua +-- those wifi_* are the base parameters that are saved anyway +local p = {} +p.wifi_ssid="ssid" +p.wifi_password="password" +-- your own parameters: +p.timeout_delay="xxx" +p.device_name="yyy" +return p +``` -After running [`enduser_setup.start()`](#enduser_setupstart), a wireless network named "SetupGadget_XXXXXX" will start (this prefix can be overridden in `user_config.h` by defining -`ENDUSER_SETUP_AP_SSID`). Connect to that SSID and then navigate to the root -of any website (e.g., `http://example.com/` will work, but do not use `.local` domains because it will fail on iOS). A web page similar to the picture above will load, allowing the -end user to provide their Wi-Fi information. +### How to use the eus_params.lua file -After an IP address has been successfully obtained, then this module will stop as if [`enduser_setup.stop()`](#enduser_setupstop) had been called. There is a 10-second delay before -teardown to allow connected clients to obtain a last status message while the SoftAP is still active. +Simply include the file by using the `dofile` function: +```lua +p = dofile('eus_params.lua') +-- now use the parameters in the Lua table +print("Wifi device_name: " .. p.device_name) +``` -Alternative HTML can be served by placing a file called `enduser_setup.html` on the filesystem. Everything needed by the web page must be included in this one file. This file will be kept -in RAM, so keep it as small as possible. The file can be gzip'd ahead of time to reduce the size (i.e., using `gzip -n` or `zopfli`), and when served, the End User Setup module will add -the appropriate `Content-Encoding` header to the response. +### HTTP endpoints: -*Note: If gzipped, the file can also be named `enduser_setup.html.gz` for semantic purposes. Gzip encoding is determined by the file's contents, not the filename.* +|Path|Method|Description| +|----|------|-----------| +|/|GET|Returns HTML for the web page. Will return the contents of `enduser_setup.html` if it exists on the filesystem, otherwise will return a page embedded into the firmware image.| +|/aplist|GET|Forces the ESP8266 to perform a site survey across all channels, reporting access points that it can find. Return payload is a JSON array: `[{"ssid":"foobar","rssi":-36,"chan":3}]`| +|/generate_204|GET|Returns a HTTP 204 status (expected by certain Android clients during Wi-Fi connectivity checks)| +|/status|GET|Returns plaintext status description, used by the web page| +|/status.json|GET|Returns a JSON payload containing the ESP8266's chip id in hexadecimal format and the status code: 0=Idle, 1=Connecting, 2=Wrong Password, 3=Network not Found, 4=Failed, 5=Success| +|/setwifi|POST|HTML form post for setting the WiFi credentials. Expects HTTP content type `application/x-www-form-urlencoded`. Supports sending and storing additinal configuration parameters (as input fields). Returns the same payload as `/status.json` instead of redirecting to `/`. See also: `/update`.| +|/update|GET|Data submission target. Example: `http://example.com/update?wifi_ssid=foobar&wifi_password=CorrectHorseBatteryStaple`. Will redirect to `/` when complete. Note that will NOT update the `eus_params.lua` file i.e. it does NOT support sending arbitrary parameters. See also: `/setwifi`. | -The following HTTP endpoints exist: +Module functions are described below. -|Endpoint|Description| -|--------|-----------| -|/|Returns HTML for the web page. Will return the contents of `enduser_setup.html` if it exists on the filesystem, otherwise will return a page embedded into the firmware image.| -|/aplist|Forces the ESP8266 to perform a site survey across all channels, reporting access points that it can find. Return payload is a JSON array: `[{"ssid":"foobar","rssi":-36,"chan":3}]`| -|/generate_204|Returns a HTTP 204 status (expected by certain Android clients during Wi-Fi connectivity checks)| -|/status|Returns plaintext status description, used by the web page| -|/status.json|Returns a JSON payload containing the ESP8266's chip id in hexadecimal format and the status code: 0=Idle, 1=Connecting, 2=Wrong Password, 3=Network not Found, 4=Failed, 5=Success| -|/setwifi|Endpoint intended for services to use for setting the wifi credentials. Identical to `/update` except returns the same payload as `/status.json` instead of redirecting to `/`.| -|/update|Form submission target. Example: `http://example.com/update?wifi_ssid=foobar&wifi_password=CorrectHorseBatteryStaple`. Must be a GET request. Will redirect to `/` when complete. | ## enduser_setup.manual() Controls whether manual AP configuration is used. -By default the `enduser_setup` module automatically configures an open access point when starting, and stops it when the device has been successfully joined to a WiFi network. If manual mode has been enabled, neither of this is done. The device must be manually configured for `wifi.SOFTAP` mode prior to calling `enduser_setup.start()`. Additionally, the portal is not stopped after the device has successfully joined to a WiFi network. +By default the `enduser_setup` module automatically configures an open access +point when starting, and stops it when the device has been successfully joined +to a WiFi network. If manual mode has been enabled, neither of this is done. +The device must be manually configured for `wifi.SOFTAP` mode prior to calling +`enduser_setup.start()`. Additionally, the portal is not stopped after the +device has successfully joined to a WiFi network. #### Syntax `enduser_setup.manual([on_off])` #### Parameters - - `on_off` a boolean value indicating whether to use manual mode; if not given, the function only returns the current setting. + - `on_off` a boolean value indicating whether to use manual mode; if not + given, the function only returns the current setting. #### Returns The current setting, true if manual mode is enabled, false if it is not. @@ -57,12 +115,12 @@ wifi.ap.config({ssid="MyPersonalSSID", auth=wifi.OPEN}) enduser_setup.manual(true) enduser_setup.start( function() - print("Connected to wifi as:" .. wifi.sta.getip()) + print("Connected to WiFi as:" .. wifi.sta.getip()) end, function(err, str) print("enduser_setup: Err #" .. err .. ": " .. str) end -); +) ``` ## enduser_setup.start() @@ -86,13 +144,13 @@ Starts the captive portal. ```lua enduser_setup.start( function() - print("Connected to wifi as:" .. wifi.sta.getip()) + print("Connected to WiFi as:" .. wifi.sta.getip()) end, function(err, str) print("enduser_setup: Err #" .. err .. ": " .. str) end, print -- Lua print function can serve as the debug callback -); +) ``` ## enduser_setup.stop()