From 0c6cb1719f538d3ead0ca964c70829244ac15572 Mon Sep 17 00:00:00 2001 From: Dmitry Borisenko Date: Tue, 24 Dec 2019 11:53:26 +0300 Subject: [PATCH] first working version --- Cmd.ino | 505 ++++++++++++++++ Init.ino | 50 ++ Scenario.ino | 85 +++ Sensors.ino | 315 ++++++++++ Time_esp32.ino | 20 + Time_esp8266.ino | 112 ++++ Timers.ino | 184 ++++++ Web_server.ino | 222 +++++++ WiFi.ino | 188 ++++++ certificates.ino | 72 +++ data/.exclude.files | 2 + data/ace.js.gz | Bin 0 -> 98943 bytes data/config.all.json | 144 +++++ data/config.all.txt | 19 + data/config.json | 1 + data/css/build.css.gz | Bin 0 -> 15178 bytes data/edit.htm | 572 ++++++++++++++++++ data/edit.htm.gz | Bin 0 -> 5794 bytes data/favicon.ico | Bin 0 -> 1150 bytes data/index.htm | 75 +++ data/index.htm.gz | Bin 0 -> 1444 bytes data/index.json | 56 ++ data/js/build.chart.js.gz | Bin 0 -> 12758 bytes data/js/function.js.gz | Bin 0 -> 17110 bytes data/lang/lang.en.json.gz | Bin 0 -> 3364 bytes data/lang/lang.lv.json.gz | Bin 0 -> 3831 bytes data/lang/lang.ru.json.gz | Bin 0 -> 5071 bytes data/lang/lang.ua.json.gz | Bin 0 -> 4448 bytes data/mode-html.js.gz | Bin 0 -> 17037 bytes data/mqtt.json | 73 +++ data/page.htm.gz | Bin 0 -> 1457 bytes data/push.json | 92 +++ data/pushingbox.json | 46 ++ data/scenario.all.txt | 31 + data/setup.json | 154 +++++ data/soket.json | 57 ++ data/vigets/viget.alertbg.json | 12 + data/vigets/viget.alertsm.json | 12 + data/vigets/viget.button.json | 18 + data/vigets/viget.chart.json | 13 + data/vigets/viget.fillgauge.json | 23 + data/vigets/viget.gauge.json | 18 + data/vigets/viget.led.json | 16 + data/vigets/viget.range.json | 13 + data/vigets/viget.status.json | 13 + data/vigets/viget.termometr.json | 15 + data/vigets/viget.toggle.json | 11 + data/worker-html.js.gz | Bin 0 -> 50024 bytes data_new/ace.js.gz | Bin 0 -> 98943 bytes data_new/chart.json.gz | Bin 0 -> 538 bytes data_new/config.all.json | 144 +++++ data_new/config.all.txt | 19 + data_new/config.json | 1 + data_new/configclient.json | 1 + data_new/configevery.json | 1 + data_new/css/build.css.gz | Bin 0 -> 15178 bytes data_new/donate.htm.gz | Bin 0 -> 2148 bytes data_new/edit.htm.gz | Bin 0 -> 5906 bytes data_new/ext-searchbox.js.gz | Bin 0 -> 3131 bytes data_new/favicon.ico | Bin 0 -> 1150 bytes data_new/img/swatches.png | Bin 0 -> 2278 bytes data_new/img/swatches1.png | Bin 0 -> 2329 bytes data_new/index.htm | 57 ++ data_new/index.htm.gz | Bin 0 -> 1243 bytes data_new/index.json | 56 ++ data_new/js/build.chart.js.gz | Bin 0 -> 12758 bytes data_new/js/function.js.gz | Bin 0 -> 17024 bytes data_new/lang/lang.en.json.gz | Bin 0 -> 3848 bytes data_new/lang/lang.lv.json.gz | Bin 0 -> 4512 bytes data_new/lang/lang.ru.json.gz | Bin 0 -> 5071 bytes data_new/lang/lang.ua.json.gz | Bin 0 -> 5322 bytes data_new/mode-css.js.gz | Bin 0 -> 6102 bytes data_new/mode-html.js.gz | Bin 0 -> 17037 bytes data_new/mode-javascript.js.gz | Bin 0 -> 6315 bytes data_new/mqtt.json | 73 +++ data_new/page.htm.gz | Bin 0 -> 1255 bytes data_new/push.json | 92 +++ data_new/pushingbox.json | 46 ++ data_new/scenario.all.txt | 31 + data_new/setup.json | 154 +++++ data_new/soket.json | 57 ++ data_new/viget.alertbg.json | 12 + data_new/viget.alertsm.json | 12 + data_new/viget.button.json | 18 + data_new/viget.chart.json | 13 + data_new/viget.fillgauge.json | 23 + data_new/viget.gauge.json | 18 + data_new/viget.led.json | 16 + data_new/viget.range.json | 13 + data_new/viget.status.json | 13 + data_new/viget.termometr.json | 15 + data_new/viget.toggle.json | 11 + data_new/worker-html.js.gz | Bin 0 -> 50024 bytes .../WiFiClientSecure/WiFiClientSecure.cpp | 197 ++++++ .../WiFiClientSecure/WiFiClientSecure.h | 92 +++ dependencies/WiFiClientSecure/ssl_client.cpp | 261 ++++++++ dependencies/WiFiClientSecure/ssl_client.h | 37 ++ esp32_iot-manager_modules_firmware.ino | 78 +++ main.ino | 279 +++++++++ mqtt.ino | 370 +++++++++++ set.h | 118 ++++ 101 files changed, 5567 insertions(+) create mode 100644 Cmd.ino create mode 100644 Init.ino create mode 100644 Scenario.ino create mode 100644 Sensors.ino create mode 100644 Time_esp32.ino create mode 100644 Time_esp8266.ino create mode 100644 Timers.ino create mode 100644 Web_server.ino create mode 100644 WiFi.ino create mode 100644 certificates.ino create mode 100644 data/.exclude.files create mode 100644 data/ace.js.gz create mode 100644 data/config.all.json create mode 100644 data/config.all.txt create mode 100644 data/config.json create mode 100644 data/css/build.css.gz create mode 100644 data/edit.htm create mode 100644 data/edit.htm.gz create mode 100644 data/favicon.ico create mode 100644 data/index.htm create mode 100644 data/index.htm.gz create mode 100644 data/index.json create mode 100644 data/js/build.chart.js.gz create mode 100644 data/js/function.js.gz create mode 100644 data/lang/lang.en.json.gz create mode 100644 data/lang/lang.lv.json.gz create mode 100644 data/lang/lang.ru.json.gz create mode 100644 data/lang/lang.ua.json.gz create mode 100644 data/mode-html.js.gz create mode 100644 data/mqtt.json create mode 100644 data/page.htm.gz create mode 100644 data/push.json create mode 100644 data/pushingbox.json create mode 100644 data/scenario.all.txt create mode 100644 data/setup.json create mode 100644 data/soket.json create mode 100644 data/vigets/viget.alertbg.json create mode 100644 data/vigets/viget.alertsm.json create mode 100644 data/vigets/viget.button.json create mode 100644 data/vigets/viget.chart.json create mode 100644 data/vigets/viget.fillgauge.json create mode 100644 data/vigets/viget.gauge.json create mode 100644 data/vigets/viget.led.json create mode 100644 data/vigets/viget.range.json create mode 100644 data/vigets/viget.status.json create mode 100644 data/vigets/viget.termometr.json create mode 100644 data/vigets/viget.toggle.json create mode 100644 data/worker-html.js.gz create mode 100644 data_new/ace.js.gz create mode 100644 data_new/chart.json.gz create mode 100644 data_new/config.all.json create mode 100644 data_new/config.all.txt create mode 100644 data_new/config.json create mode 100644 data_new/configclient.json create mode 100644 data_new/configevery.json create mode 100644 data_new/css/build.css.gz create mode 100644 data_new/donate.htm.gz create mode 100644 data_new/edit.htm.gz create mode 100644 data_new/ext-searchbox.js.gz create mode 100644 data_new/favicon.ico create mode 100644 data_new/img/swatches.png create mode 100644 data_new/img/swatches1.png create mode 100644 data_new/index.htm create mode 100644 data_new/index.htm.gz create mode 100644 data_new/index.json create mode 100644 data_new/js/build.chart.js.gz create mode 100644 data_new/js/function.js.gz create mode 100644 data_new/lang/lang.en.json.gz create mode 100644 data_new/lang/lang.lv.json.gz create mode 100644 data_new/lang/lang.ru.json.gz create mode 100644 data_new/lang/lang.ua.json.gz create mode 100644 data_new/mode-css.js.gz create mode 100644 data_new/mode-html.js.gz create mode 100644 data_new/mode-javascript.js.gz create mode 100644 data_new/mqtt.json create mode 100644 data_new/page.htm.gz create mode 100644 data_new/push.json create mode 100644 data_new/pushingbox.json create mode 100644 data_new/scenario.all.txt create mode 100644 data_new/setup.json create mode 100644 data_new/soket.json create mode 100644 data_new/viget.alertbg.json create mode 100644 data_new/viget.alertsm.json create mode 100644 data_new/viget.button.json create mode 100644 data_new/viget.chart.json create mode 100644 data_new/viget.fillgauge.json create mode 100644 data_new/viget.gauge.json create mode 100644 data_new/viget.led.json create mode 100644 data_new/viget.range.json create mode 100644 data_new/viget.status.json create mode 100644 data_new/viget.termometr.json create mode 100644 data_new/viget.toggle.json create mode 100644 data_new/worker-html.js.gz create mode 100644 dependencies/WiFiClientSecure/WiFiClientSecure.cpp create mode 100644 dependencies/WiFiClientSecure/WiFiClientSecure.h create mode 100644 dependencies/WiFiClientSecure/ssl_client.cpp create mode 100644 dependencies/WiFiClientSecure/ssl_client.h create mode 100644 esp32_iot-manager_modules_firmware.ino create mode 100644 main.ino create mode 100644 mqtt.ino create mode 100644 set.h diff --git a/Cmd.ino b/Cmd.ino new file mode 100644 index 00000000..a62d9438 --- /dev/null +++ b/Cmd.ino @@ -0,0 +1,505 @@ +void CMD_init() { + + sCmd.addCommand("button", button); + sCmd.addCommand("buttonSet", buttonSet); + + sCmd.addCommand("pinSet", pinSet); + + sCmd.addCommand("pwm", pwm); + sCmd.addCommand("pwmSet", pwmSet); + + sCmd.addCommand("switch", switch_); + + sCmd.addCommand("analog", analog); + sCmd.addCommand("ph", ph); + sCmd.addCommand("level", level); + sCmd.addCommand("dallas", dallas); + + sCmd.addCommand("logging", logging); + + sCmd.addCommand("input", input); + sCmd.addCommand("valueUpSet", valueUpSet); + sCmd.addCommand("valueDownSet", valueDownSet); + + sCmd.addCommand("text", text); + sCmd.addCommand("textSet", textSet); + + // sCmd.addCommand("time", time); + // sCmd.addCommand("timeSet", timeSet); + + sCmd.addCommand("timerStart", timerStart); + sCmd.addCommand("timerStop", timerStop); + + sCmd.addCommand("mqtt", mqttOrderSend); + sCmd.addCommand("http", httpOrderSend); + //!sCmd.addCommand("push", pushControl); + + //handleCMD_ticker(); +} + + +//========================================================================================================== +//==========================================Модуль кнопок=================================================== +void button() { + + String button_number = sCmd.next(); + String button_param = sCmd.next(); + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String start_state = sCmd.next(); + String page_number = sCmd.next(); + + jsonWrite(optionJson, "button_param" + button_number, button_param); + jsonWrite(configJson, "buttonSet" + button_number, start_state); + + if (isDigitStr (button_param)) { + pinMode(button_param.toInt(), OUTPUT); + digitalWrite(button_param.toInt(), start_state.toInt()); + } + + if (button_param == "scenario") { + jsonWrite(configSetup, "scenario", start_state); + Scenario_init(); + saveConfig(); + } + + if (button_param.indexOf("line") != -1) { + String str = button_param; + while (str.length() != 0) { + if (str == "") return; + String tmp = selectToMarker (str, ","); //line1, + String number = deleteBeforeDelimiter(tmp, "e"); //1, + number.replace(",", ""); + Serial.println(number); + int number_int = number.toInt(); + scenario_line_status[number_int] = start_state.toInt(); + str = deleteBeforeDelimiter(str, ","); + } + } + + + createViget (viget_name, page_name, page_number, "vigets/viget.toggle.json", "buttonSet" + button_number); +} + +void buttonSet() { + + String button_number = sCmd.next(); + String button_state = sCmd.next(); + String button_param = jsonRead(optionJson, "button_param" + button_number); + + if (button_param != "na" || button_param != "scenario" || button_param.indexOf("line") != -1) { + digitalWrite(button_param.toInt(), button_state.toInt()); + } + + if (button_param == "scenario") { + jsonWrite(configSetup, "scenario", button_state); + Scenario_init(); + saveConfig(); + } + + if (button_param.indexOf("line") != -1) { + String str = button_param; + while (str.length() != 0) { + if (str == "") return; + String tmp = selectToMarker (str, ","); //line1, + String number = deleteBeforeDelimiter(tmp, "e"); //1, + number.replace(",", ""); + Serial.println(number); + int number_int = number.toInt(); + scenario_line_status[number_int] = button_state.toInt(); + str = deleteBeforeDelimiter(str, ","); + } + } + + eventGen ("buttonSet", button_number); + + jsonWrite(configJson, "buttonSet" + button_number, button_state); + sendSTATUS("buttonSet" + button_number, button_state); +} + +void pinSet() { + + String pin_number = sCmd.next(); + String pin_state = sCmd.next(); + pinMode(pin_number.toInt(), OUTPUT); + digitalWrite(pin_number.toInt(), pin_state.toInt()); + +} +//================================================================================================================== +//==========================================Модуль управления ШИМ=================================================== +void pwm() { + + static boolean flag = true; + String pwm_number = sCmd.next(); + String pwm_pin = sCmd.next(); + String viget_name = sCmd.next(); + viget_name.replace("#", " "); + String page_name = sCmd.next(); + String start_state = sCmd.next(); + String page_number = sCmd.next(); + + + uint8_t pwm_pin_int = pwm_pin.toInt(); + jsonWrite(optionJson, "pwm_pin" + pwm_number, pwm_pin); + pinMode(pwm_pin_int, INPUT); + analogWrite(pwm_pin_int, start_state.toInt()); + jsonWrite(configJson, "pwmSet" + pwm_number, start_state); + + createViget (viget_name, page_name, page_number, "vigets/viget.range.json", "pwmSet" + pwm_number); +} + +void pwmSet() { + + String pwm_number = sCmd.next(); + String pwm_state = sCmd.next(); + int pwm_state_int = pwm_state.toInt(); + + int pin = jsonReadtoInt(optionJson, "pwm_pin" + pwm_number); + analogWrite(pin, pwm_state_int); + + eventGen ("pwmSet", pwm_number); + + jsonWrite(configJson, "pwmSet" + pwm_number, pwm_state); + sendSTATUS("pwmSet" + pwm_number, pwm_state); +} +//================================================================================================================== +//==========================================Модуль физической кнопки================================================ +void switch_ () { + + String switch_number = sCmd.next(); + String switch_pin = sCmd.next(); + String switch_delay = sCmd.next(); + + buttons[switch_number.toInt()].attach(switch_pin.toInt()); + buttons[switch_number.toInt()].interval(switch_delay.toInt()); + but[switch_number.toInt()] = true; +} + +void handleButton() { + + static uint8_t switch_number = 1; + + if (but[switch_number]) { + buttons[switch_number].update(); + if (buttons[switch_number].fell()) { + + eventGen ("switchSet", String(switch_number)); + + jsonWrite(configJson, "switchSet" + String(switch_number), "1"); + } + if (buttons[switch_number].rose()) { + + eventGen ("switchSet", String(switch_number)); + + jsonWrite(configJson, "switchSet" + String(switch_number), "0"); + } + } + switch_number++; + if (switch_number == NUM_BUTTONS) switch_number = 0; +} + +//===================================================================================================================================== +//=========================================Добавление окна ввода переменной============================================================ +void input() { + + String name_ = sCmd.next(); + String number = name_.substring(5); + String start_value = sCmd.next(); + String step_ = sCmd.next(); + String value_name = sCmd.next(); + String page_name = sCmd.next(); + String page_number = sCmd.next(); + + int psn1 = start_value.indexOf("."); //ищем позицию запятой + int digits = 0; + if (psn1 != -1) { //если она есть + String last_part = deleteBeforeDelimiter(start_value, "."); + digits = last_part.length() + 1; + } + + createViget ("", page_name, page_number, "vigets/viget.button.json", "valueDownSet" + number, "title", "-"); + createViget (value_name, page_name, String(page_number.toInt() + 1), "vigets/viget.alertbg.json", name_); + createViget ("", page_name, String(page_number.toInt() + 2), "vigets/viget.button.json", "valueUpSet" + number , "title", "+"); + + //jsonWrite(valuesJson, name_, start_value); + //saveValues (); + sendSTATUS(name_, start_value); + + jsonWrite(configJson, name_ + "step", step_); + jsonWrite(configJson, name_ + "digits", digits); +} + +void valueUpSet() { + String number = sCmd.next(); + float val = jsonRead(configJson, "value" + number).toFloat(); + float step_ = jsonRead(configJson, "value" + number + "step").toFloat(); + int digits = jsonRead(configJson, "value" + number + "digits").toInt(); + val = val + step_; + String val_str = String(val); + val_str = selectToMarkerPlus (val_str, ".", digits); + jsonWrite(configJson, "value" + number, val_str); + //jsonWrite(valuesJson, "value" + number, val_str); + //saveValues (); + sendSTATUS("value" + number, val_str); +} + +void valueDownSet() { + String number = sCmd.next(); + float val = jsonRead(configJson, "value" + number).toFloat(); + float step_ = jsonRead(configJson, "value" + number + "step").toFloat(); + int digits = jsonRead(configJson, "value" + number + "digits").toInt(); + val = val - step_; + String val_str = String(val); + val_str = selectToMarkerPlus (val_str, ".", digits); + jsonWrite(configJson, "value" + number, val_str); + //jsonWrite(valuesJson, "value" + number, val_str); + //saveValues (); + sendSTATUS("value" + number, val_str); +} + +//===================================================================================================================================== +//=========================================Добавление текстового виджета============================================================ +void text() { + + String number = sCmd.next(); + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String page_number = sCmd.next(); + + createViget (viget_name, page_name, page_number, "vigets/viget.alertsm.json", "textSet" + number); +} + + +void textSet() { + + String number = sCmd.next(); + String text = sCmd.next(); + text.replace("_", " "); + + if (text.indexOf("-time") >= 0) { + text.replace("-time", ""); + String time = GetTime(); + time.replace(":", "."); + text = GetDataDigital() + " " + time + " " + text; + } + + jsonWrite(configJson, "textSet" + number, text); + sendSTATUS("textSet" + number, text); +} + +//=================================================Глобальные команды удаленного управления=========================================================== + +void mqttOrderSend() { + + String id = sCmd.next(); + String order = sCmd.next(); + + String all_line = prefix + "/" + id + "/order"; + //Serial.print(all_line); + //Serial.print("->"); + //Serial.println(order); + int send_status = client.publish (all_line.c_str(), order.c_str(), false); +} + +void httpOrderSend() { + + String ip = sCmd.next(); + String order = sCmd.next(); + order.replace("_", "%20"); + String url = "http://" + ip + "/cmd?command=" + order; + getURL(url); +} + + + +//============================================================================================================================== +//============================выполнение команд (в лупе) по очереди из строки order============================================= +void handleCMD_loop() { + + if (order_loop != "") { + + String tmp = selectToMarker(order_loop, ","); //выделяем из страки order первую команду rel 5 1, + sCmd.readStr(tmp); //выполняем первую команду + Serial.println("[ORDER] => " + order_loop); + order_loop = deleteBeforeDelimiter(order_loop, ","); //осекаем выполненную команду + } +} + +//=============================выполнение команд (через период) по очереди из строки order======================================= +/*void handleCMD_ticker() { + + ts.add(CMD, CMD_update_int, [&](void*) { + if (!busy) { + if (order_ticker != "") { + + String tmp = selectToMarker(order_ticker, ","); //выделяем из страки order первую команду pus title body + if (tmp != "no_command") sCmd.readStr(tmp); //выполняем первую команду + Serial.println("order_ticker => " + order_ticker); + order_ticker = deleteBeforeDelimiter(order_ticker, ","); //осекаем выполненную команду + } + } + }, nullptr, true); + }*/ + + + +//======================================================================================================================================= +//======================================================================================================================================= +void txtExecution(String file) { + + String command_all = readFile(file, 2048) + "\r\n"; //2048 + + command_all.replace("\r\n", "\n"); + command_all.replace("\r", "\n"); + + while (command_all.length() != 0) { + + String tmp = selectToMarker (command_all, "\n"); + //if (tmp.indexOf("//") < 0) + sCmd.readStr(tmp); + command_all = deleteBeforeDelimiter(command_all, "\n"); + } +} +void stringExecution(String str) { + + String command_all = str + "\r\n"; //"\r\n" + + command_all.replace("\r\n", "\n"); + command_all.replace("\r", "\n"); + + while (command_all.length() != 0) { + + String tmp = selectToMarker (command_all, "\n"); + //if (tmp.indexOf("//") < 0) + sCmd.readStr(tmp); + command_all = deleteBeforeDelimiter(command_all, "\n"); + } +} + +//====================================================================================================================== +//===============================================Создание виджетов======================================================= + +void createViget (String viget_name, String page_name, String page_number, String file, String topic) { + + String viget; + viget = readFile(file, 1024); + + if (viget == "Failed") return; + if (viget == "Large") return; + + viget_name.replace("#", " "); + page_name.replace("#", " "); + + jsonWrite(viget, "page", page_name); + jsonWrite(viget, "pageId", page_number); + jsonWrite(viget, "descr", viget_name); + jsonWrite(viget, "topic", prex + "/" + topic); + all_vigets += viget + "\r\n"; + viget = ""; +} +void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value) { + + String viget; + viget = readFile(file, 1024); + + if (viget == "Failed") return; + if (viget == "Large") return; + + viget_name.replace("#", " "); + page_name.replace("#", " "); + + value.replace("#", " "); + + viget = vidgetConfigWrite(viget, key, value); + + jsonWrite(viget, "page", page_name); + jsonWrite(viget, "pageId", page_number); + jsonWrite(viget, "descr", viget_name); + jsonWrite(viget, "topic", prex + "/" + topic); + + all_vigets += viget + "\r\n"; + viget = ""; +} + +void createViget (String viget_name, String page_name, String page_number, String file, String topic, String key, String value, String key2, String value2) { + + String viget; + viget = readFile(file, 1024); + + if (viget == "Failed") return; + if (viget == "Large") return; + + viget_name.replace("#", " "); + page_name.replace("#", " "); + + value.replace("#", " "); + + viget = vidgetConfigWrite(viget, key, value); + viget = vidgetConfigWrite(viget, key2, value2); + + jsonWrite(viget, "page", page_name); + jsonWrite(viget, "pageId", page_number); + jsonWrite(viget, "descr", viget_name); + jsonWrite(viget, "topic", prex + "/" + topic); + + all_vigets += viget + "\r\n"; + viget = ""; +} + +String vidgetConfigWrite(String viget, String key, String value) { + + if (viget == "") return ""; + if (viget == "{}") return ""; + int psn1 = viget.indexOf("{"); + if (psn1 != -1) { + psn1 = viget.indexOf("{", psn1 + 1); + if (psn1 != -1) { + int psn2 = viget.indexOf("}", psn1); + String WigetConfig = viget.substring(psn1, psn2) + "}"; + jsonWrite(WigetConfig, key, value); + String part1 = viget.substring(0, psn1); + viget = part1 + WigetConfig + "}"; + return viget; + + } + } +} + + + + + + + + + + + + +//============разное + +/* + void delAlert() { + + String alert_id = sCmd.next(); + delViget(alert_id); + sendAllWigets(); + } + + + void delViget(String text_in_viget) { + String viget = all_vigets; + while (viget.length() != 0) { + String tmp = selectToMarkerPlus (viget, "\r\n", 2); + if (tmp.indexOf(text_in_viget) > 0) { + + all_vigets.replace(tmp, ""); + //Serial.println(all_vigets); + + viget = deleteBeforeDelimiter(viget, "\r\n"); + } else { + viget = deleteBeforeDelimiter(viget, "\r\n"); + } + } + } +*/ diff --git a/Init.ino b/Init.ino new file mode 100644 index 00000000..dcfca754 --- /dev/null +++ b/Init.ino @@ -0,0 +1,50 @@ +void All_init() { + + server.on("/all_modules_init", HTTP_GET, [](AsyncWebServerRequest * request) { + Device_init(); + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + + + server.on("/scenario", HTTP_GET, [](AsyncWebServerRequest * request) { + if (request->hasArg("status")) { + jsonWrite(configSetup, "scenario", request->getParam("status")->value()); + } + saveConfig(); + Scenario_init(); + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + + server.on("/cleanlog", HTTP_GET, [](AsyncWebServerRequest * request) { + SPIFFS.remove("/log.analog.txt"); + SPIFFS.remove("/log.dallas.txt"); + SPIFFS.remove("/log.level.txt"); + SPIFFS.remove("/log.ph.txt"); + SPIFFS.remove("/log.txt"); + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + + Device_init(); + Scenario_init(); + Timer_countdown_init(); +} + +void Device_init() { + + ts.remove(LEVEL); + ts.remove(ANALOG_); + ts.remove(PH); + ts.remove(DALLAS); + + all_vigets = ""; + txtExecution("config.all.txt"); + //outcoming_date(); + +} +//-------------------------------сценарии----------------------------------------------------- + +void Scenario_init() { + if (jsonRead(configSetup, "scenario") == "1") { + scenario = readFile(scenarioFileNameS, 2048); + } +} diff --git a/Scenario.ino b/Scenario.ino new file mode 100644 index 00000000..8a1b5ac9 --- /dev/null +++ b/Scenario.ino @@ -0,0 +1,85 @@ +void handleScenario() { + + if (jsonRead(configSetup, "scenario") == "1") { + if ((jsonRead(optionJson, "scenario_status") != "")) { + int i = 0; + String str = scenario; //читаем переменную с сценариями (то что из файла на странице) + str += "\n"; + str.replace("\r\n", "\n"); + str.replace("\r", "\n"); + while (str.length() != 0) { + //----------------------------------------------------------------------------------------------------------------------- + String tmp = selectToMarker (str, "end"); //выделяем первый сценарий из файла вместе с командами + if (tmp == "") return; + i++; + + if (scenario_line_status[i] == 1) { + //Serial.println(i); + String condition = selectToMarker (tmp, "\n"); //выделяем первую строку самого сценария button1 = 1 (условие) + String param_name = selectFromMarkerToMarker(condition, " " , 0); //из первой страки берем имя параметра button1 и вставляем в него Set и получаем buttonSet1 + String num1 = param_name.substring(param_name.length() - 1); + String num2 = param_name.substring(param_name.length() - 2, param_name.length() - 1); + if (isDigitStr(num1) && isDigitStr(num2)) { + param_name = param_name.substring(0, param_name.length() - 2) + "Set" + num2 + num1; + } else { + if (isDigitStr(num1)) { + param_name = param_name.substring(0, param_name.length() - 1) + "Set" + num1; + } + } //преобразуем из button1 в вид buttonSet1 ,param_name = buttonSet1 + String order = jsonRead(optionJson, "scenario_status"); //читаем весь файл событий + String param = selectToMarker (order, ","); //читаем первое событие из файла событий + if (param_name == param) { //если поступившее событие равно событию заданному buttonSet1 в файле начинаем его обработку + + String sign = selectFromMarkerToMarker(condition, " " , 1); //читаем знак (=) + String value = selectFromMarkerToMarker(condition, " " , 2); //читаем значение (1) + if (value.indexOf("value") != -1) { + value = jsonRead(configJson, value); + } + boolean flag = false; //если одно из значений совпало то только тогда начинаем выполнять комнады + if (sign == "=") { + if (jsonRead(configJson, param_name) == value) flag = true; + } + if (sign == "!=") { + if (jsonRead(configJson, param_name) != value) flag = true; + } + if (sign == "<") { + if (jsonRead(configJson, param_name).toFloat() < value.toFloat()) flag = true; + } + if (sign == ">") { + if (jsonRead(configJson, param_name).toFloat() > value.toFloat()) flag = true; + } + if (sign == ">=") { + if (jsonRead(configJson, param_name).toFloat() >= value.toFloat()) flag = true; + } + if (sign == "<=") { + if (jsonRead(configJson, param_name).toFloat() <= value.toFloat()) flag = true; + } + + if (flag) { + tmp = deleteBeforeDelimiter(tmp, "\n"); //удаляем строку самого сценария оставляя только команды + stringExecution(tmp); //выполняем все команды + + Serial.println("[SCENARIO] '" + condition + "'"); + //Serial.println(" " + tmp); + } + } + } + str = deleteBeforeDelimiter(str, "end\n"); //удаляем первый сценарий + //----------------------------------------------------------------------------------------------------------------------- + } + String tmp2 = jsonRead(optionJson, "scenario_status"); //читаем файл событий + tmp2 = deleteBeforeDelimiter(tmp2, ","); //удаляем выполненное событие + jsonWrite(optionJson, "scenario_status", tmp2); //записываем обновленный файл событий + i = 0; + } + } +} + +void eventGen (String event_name, String number) { //событие выглядит как имя плюс set плюс номер: button+Set+1 + + if (jsonRead(configSetup, "scenario") == "1") { + String tmp = jsonRead(optionJson, "scenario_status") ; //генерирование события + //Serial.println(event_name); + jsonWrite(optionJson, "scenario_status", tmp + event_name + number + ","); + } +} diff --git a/Sensors.ino b/Sensors.ino new file mode 100644 index 00000000..d8c92552 --- /dev/null +++ b/Sensors.ino @@ -0,0 +1,315 @@ +//=============================================================================================================================== +//=========================================Модуль аналогового сенсора============================================================ +void analog() { + + static boolean flag = true; + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String type = sCmd.next(); + String analog_start = sCmd.next(); + String analog_end = sCmd.next(); + String analog_start_out = sCmd.next(); + String analog_end_out = sCmd.next(); + String page_number = sCmd.next(); + + jsonWrite(optionJson, "analog_start", analog_start); + jsonWrite(optionJson, "analog_end", analog_end); + jsonWrite(optionJson, "analog_start_out", analog_start_out); + jsonWrite(optionJson, "analog_end_out", analog_end_out); + + if (type == "text") createViget (viget_name, page_name, page_number, "vigets/viget.alertsm.json", "analog"); + if (type == "gauge") createViget (viget_name, page_name, page_number, "vigets/viget.fillgauge.json", "analog"); + if (type == "gauge2") createViget (viget_name, page_name, page_number, "vigets/viget.gauge.json", "analog", "maximum", analog_end_out); + if (type == "termometr") createViget (viget_name, page_name, page_number, "vigets/viget.termometr.json", "analog", "titleString", viget_name); + + ts.add(ANALOG_, analog_update_int, [&](void*) { + + static int analog_old; + + int analog_in = analogRead(35); + jsonWrite(configJson, "analog_in", analog_in); + + int analog = map(analog_in, + jsonReadtoInt(optionJson, "analog_start") , + jsonReadtoInt(optionJson, "analog_end"), + jsonReadtoInt(optionJson, "analog_start_out"), + jsonReadtoInt(optionJson, "analog_end_out")); + + jsonWrite(configJson, "analog", analog); + + // if (analog_old != analog) { + + eventGen ("analog", ""); + sendSTATUS("analog", String(analog)); + if (client.connected()) { + Serial.println("[i] sensor analog send date " + String(analog)); + } + // } + analog_old = analog; + }, nullptr, true); +} + +//=============================================================================================================================== +//=========================================Модуль аналогового сенсора============================================================ +void ph() { + + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String type = sCmd.next(); + String offset = sCmd.next(); + String page_number = sCmd.next(); + + jsonWrite(optionJson, "ph_offset", offset); + + if (type == "text") createViget (viget_name, page_name, page_number, "vigets/viget.alertsm.json", "ph"); + if (type == "gauge") createViget (viget_name, page_name, page_number, "vigets/viget.fillgauge.json", "ph"); + if (type == "gauge2") createViget (viget_name, page_name, page_number, "vigets/viget.gauge.json", "ph"); + if (type == "termometr") createViget (viget_name, page_name, page_number, "vigets/viget.termometr.json", "ph", "titleString", viget_name); + + + ts.add(PH, ph_shooting_interval, [&](void*) { + + static float pHValue_old; + static int counter; + + float offset = jsonRead(optionJson, "ph_offset").toFloat(); + + int analog = analogRead(A0); + analog = medianFilter.filtered(analog); + float voltage = analog * 3.2 / 1024; + float pHValue = 3.5 * voltage + offset; + String pHValue_str = String(pHValue); + + pHValue_str = selectToMarkerPlus(pHValue_str, "." , 2); + + counter++; + + if (counter > ph_times_to_send) { + counter = 0; + + jsonWrite(configJson, "ph", pHValue_str); + + //if (pHValue_old != pHValue) { + + eventGen ("ph", ""); + sendSTATUS("ph", pHValue_str); + if (client.connected()) { + Serial.println("[i] sensor ph send date " + pHValue_str); + Serial.println("voltage " + String(voltage)); + } + //} + pHValue_old = pHValue; + } + }, nullptr, true); +} +//=================================================================================================================================== +//=========================================Модуль измерения уровня в баке============================================================ +void level() { + + static boolean flag = true; + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String type = sCmd.next(); + String empty_level = sCmd.next(); + String full_level = sCmd.next(); + String page_number = sCmd.next(); + + jsonWrite(optionJson, "empty_level", empty_level); + jsonWrite(optionJson, "full_level", full_level); + + pinMode(14, OUTPUT); + pinMode(12, INPUT); + + if (type == "text") createViget (viget_name, page_name, page_number, "vigets/viget.alertsm.json", "level"); + if (type == "gauge") createViget (viget_name, page_name, page_number, "vigets/viget.fillgauge.json", "level"); + if (type == "gauge2") createViget (viget_name, page_name, page_number, "vigets/viget.gauge.json", "level", "maximum", "100"); + if (type == "termometr") createViget (viget_name, page_name, page_number, "vigets/viget.termometr.json", "level", "titleString", viget_name); + + ts.add(LEVEL, tank_level_shooting_interval, [&](void*) { + + long duration_; + int distance_cm; + int level; + static int level_old; //переменная static сохраняет свое значение между вызовами функции + static int counter; + + digitalWrite(14, LOW); + delayMicroseconds(2); + digitalWrite(14, HIGH); + delayMicroseconds(10); + digitalWrite(14, LOW); + duration_ = pulseIn(12, HIGH, 30000); // 3000 µs = 50cm // 30000 µs = 5 m + distance_cm = duration_ / 29 / 2; + distance_cm = medianFilter.filtered(distance_cm);//отсечение промахов медианным фильтром + + counter++; + + if (counter > tank_level_times_to_send) { + counter = 0; + jsonWrite(configJson, "level_in", distance_cm); + + level = map(distance_cm, + jsonReadtoInt(optionJson, "empty_level"), + jsonReadtoInt(optionJson, "full_level"), 0, 100); + + //jsonWrite(configJson, "level", level); + + //if (level_old != level) { + + eventGen ("level", ""); + sendSTATUS("level", String(level)); + if (client.connected()) { + Serial.println("[i] sensor tank level send date " + String(level)); + } + //} + level_old = level; + } + }, nullptr, true); +} + +//========================================================================================================================================== +//=========================================Модуль температурного сенсора ds18b20============================================================ +void dallas() { + + static boolean flag = true; + String pin = sCmd.next(); + String viget_name = sCmd.next(); + String page_name = sCmd.next(); + String type = sCmd.next(); + String page_number = sCmd.next(); + + oneWire = new OneWire((uint8_t) pin.toInt()); + sensors.setOneWire(oneWire); + sensors.begin(); + sensors.setResolution(12); + + if (type == "text") createViget (viget_name, page_name, page_number, "vigets/viget.alertsm.json", "dallas"); + if (type == "gauge") createViget (viget_name, page_name, page_number, "vigets/viget.fillgauge.json", "dallas"); + if (type == "gauge2") createViget (viget_name, page_name, page_number, "vigets/viget.gauge.json", "dallas"); + if (type == "termometr") createViget (viget_name, page_name, page_number, "vigets/viget.termometr.json", "dallas", "titleString", viget_name); + + ts.add(DALLAS, temp_update_int, [&](void*) { + + float temp = 0; + static float temp_old; + sensors.requestTemperatures(); + temp = sensors.getTempCByIndex(0); + + jsonWrite(configJson, "dallas", String(temp)); + + //if (temp_old != temp) { + + eventGen ("dallas", ""); + sendSTATUS("dallas", String(temp)); + if (client.connected()) { + Serial.println("[i] sensor dallas send date " + String(temp)); + } + //} + + temp_old = temp; + }, nullptr, true); +} + +//====================================================================================================================== +//===============================================Логирование============================================================ + +void logging() { + + static boolean flag = true; + + String sensor_name = sCmd.next(); + String period_min = sCmd.next(); + String maxCount = sCmd.next(); + String viget_name = sCmd.next(); + viget_name.replace("#", " "); + String page_name = sCmd.next(); + String page_number = sCmd.next(); + + if (sensor_name == "analog") jsonWrite(optionJson, "analog_logging_count", maxCount); + if (sensor_name == "level") jsonWrite(optionJson, "level_logging_count", maxCount); + if (sensor_name == "dallas") jsonWrite(optionJson, "dallas_logging_count", maxCount); + if (sensor_name == "ph") jsonWrite(optionJson, "ph_logging_count", maxCount); + + if (sensor_name == "analog") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loganalog", "maxCount", maxCount); + if (sensor_name == "level") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "loglevel", "maxCount", maxCount); + if (sensor_name == "dallas") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logdallas", "maxCount", maxCount); + if (sensor_name == "ph") createViget (viget_name, page_name, page_number, "vigets/viget.chart.json", "logph", "maxCount", maxCount); + + if (sensor_name == "analog") { + flagLoggingAnalog = true; + ts.remove(ANALOG_LOG); + ts.add(ANALOG_LOG, period_min.toInt() * 1000 * 60, [&](void*) { + deleteOldDate("log.analog.txt", jsonReadtoInt(optionJson, "analog_logging_count"), jsonRead(configJson, "analog"), false); + }, nullptr, true); + } + + if (sensor_name == "level") { + flagLoggingLevel = true; + ts.remove(LEVEL_LOG); + ts.add(LEVEL_LOG, period_min.toInt() * 1000 * 60, [&](void*) { + deleteOldDate("log.level.txt", jsonReadtoInt(optionJson, "level_logging_count"), jsonRead(configJson, "level"), false); + }, nullptr, true); + } + + if (sensor_name == "dallas") { + flagLoggingDallas = true; + ts.remove(DALLAS_LOG); + ts.add(DALLAS_LOG, period_min.toInt() * 1000 * 60, [&](void*) { + deleteOldDate("log.dallas.txt", jsonReadtoInt(optionJson, "dallas_logging_count"), jsonRead(configJson, "dallas"), false); + }, nullptr, true); + } + + if (sensor_name == "ph") { + flagLoggingPh = true; + ts.remove(PH_LOG); + ts.add(PH_LOG, period_min.toInt() * 1000 * 60, [&](void*) { + deleteOldDate("log.ph.txt", jsonReadtoInt(optionJson, "ph_logging_count"), jsonRead(configJson, "ph"), false); + }, nullptr, true); + } +} + +void deleteOldDate(String file, int seted_number_of_lines, String date_to_add, boolean date_time) { + + String current_time; + + if (date_time) { + current_time = GetDataDigital() + " " + GetTimeWOsec(); + current_time.replace(".", ""); + current_time.replace(":", ""); + } else { + current_time = ""; + } + + String log_date = readFile(file, 5000); + getMemoryLoad("[i] after logging procedure"); + + //предел количества строк 255 + + log_date.replace("\r\n", "\n"); + log_date.replace("\r", "\n"); + + int current_number_of_lines = count(log_date, "\n"); + Serial.println("[i] in log file " + file + " " + current_number_of_lines + " lines"); + + + if (current_number_of_lines > seted_number_of_lines + 1) { + SPIFFS.remove("/" + file); + current_number_of_lines = 0; + } + if (current_number_of_lines == 0) { + SPIFFS.remove("/" + file); + current_number_of_lines = 0; + } + if (current_number_of_lines > seted_number_of_lines) { + log_date = deleteBeforeDelimiter(log_date, "\n"); + log_date += current_time + " " + date_to_add + "\n"; + writeFile(file, log_date); + + } else { + if (date_time) { + addFile(file, current_time + " " + date_to_add); + } else { + addFile(file, date_to_add); + } + } +} diff --git a/Time_esp32.ino b/Time_esp32.ino new file mode 100644 index 00000000..d70ceb99 --- /dev/null +++ b/Time_esp32.ino @@ -0,0 +1,20 @@ +#ifdef ESP32 + +void Time_Init() { + + //init and get the time + configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); + printLocalTime(); + +} + +void printLocalTime() { + struct tm timeinfo; + if (!getLocalTime(&timeinfo)) { + Serial.println("[E] Failed to obtain time"); + return; + } + Serial.println(&timeinfo, "[V] %A, %B %d %Y %H:%M:%S"); +} + +#endif diff --git a/Time_esp8266.ino b/Time_esp8266.ino new file mode 100644 index 00000000..7b75a4d8 --- /dev/null +++ b/Time_esp8266.ino @@ -0,0 +1,112 @@ +#ifdef ESP8266 + +#include +void Time_Init() { + server.on("/Time", HTTP_GET, [](AsyncWebServerRequest * request) { + //handle_Time(); + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + server.on("/timeZone", HTTP_GET, [](AsyncWebServerRequest * request) { + //handle_time_zone(); + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + + timeSynch(jsonReadtoInt(configSetup, "timezone")); +} + + +void timeSynch(int zone) { + if (WiFi.status() == WL_CONNECTED) { + // Настройка соединения с NTP сервером + configTime(zone * 3600, 0, "pool.ntp.org", "ru.pool.ntp.org"); + // int i = 0; + // Serial.println("\nWaiting for time"); + // while (!time(nullptr) && i < 10) { + // Serial.print("."); + // i++; + // delay(1000); + // } + Serial.println(""); + Serial.println("ITime Ready!"); + delay(1000); + Serial.println(GetTime()); + Serial.println(GetDate()); + } +} +/*// Установка параметров времянной зоны по запросу вида http://192.168.0.101/timeZone?timeZone=3 +void handle_time_zone() { + if (request->hasArg("timeZone")) { + jsonWrite(configSetup, "timeZone", request->getParam("timeZone")->value()); + } + saveConfig(); + //request->send(200, "text/text", "OK"); +} + +void handle_Time() { + timeSynch(jsonReadtoInt(configSetup, "timezone")); + //request->send(200, "text/text", "OK"); +} +*/ +#endif + +// Получение текущего времени +String GetTime() { + time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + String Time = ""; // Строка для результатов времени + Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017 + int i = Time.indexOf(":"); //Ишем позицию первого символа : + Time = Time.substring(i - 2, i + 6); // Выделяем из строки 2 символа перед символом : и 6 символов после + return Time; // Возврашаем полученное время +} + +String GetTimeWOsec() { + time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + String Time = ""; // Строка для результатов времени + Time += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017 + int i = Time.indexOf(":"); //Ишем позицию первого символа : + Time = Time.substring(i - 2, i + 3); // Выделяем из строки 2 символа перед символом : и 6 символов после + return Time; // Возврашаем полученное время +} + +// Получение даты +String GetDate() { + time_t now = time(nullptr); // получаем время с помощью библиотеки time.h + String Data = ""; // Строка для результатов времени + Data += ctime(&now); // Преобразуем время в строку формата Thu Jan 19 00:55:35 2017 + Data.replace("\n", ""); + uint8_t i = Data.lastIndexOf(" "); //Ишем позицию последнего символа пробел + String Time = Data.substring(i - 8, i + 1); // Выделяем время и пробел + Data.replace(Time, ""); // Удаляем из строки 8 символов времени и пробел + return Data; // Возврашаем полученную дату +} + +String GetDataDigital() { + String date = GetDate(); + + date = deleteBeforeDelimiter(date, " "); + + date.replace("Jan", "01"); + date.replace("Feb", "02"); + date.replace("Mar", "03"); + date.replace("Apr", "04"); + date.replace("May", "05"); + date.replace("Jun", "06"); + date.replace("Jul", "07"); + date.replace("Aug", "08"); + date.replace("Sep", "09"); + date.replace("Oct", "10"); + date.replace("Nov", "11"); + date.replace("Dec", "12"); + + String month = date.substring(0, 2); + String day = date.substring(3, 5); + String year = date.substring(8, 10); + + String out = day; + out += "."; + out += month; + out += "."; + out += year; + + return out; +} diff --git a/Timers.ino b/Timers.ino new file mode 100644 index 00000000..37dc9fb9 --- /dev/null +++ b/Timers.ino @@ -0,0 +1,184 @@ +//================================================================================================================ +//=========================================Таймера================================================================= +void Timer_countdown_init() { + + ts.add(TIMER_COUNTDOWN, 1000, [&](void*) { + + String old_line = jsonRead(optionJson, "timers"); + + + if (old_line != "") { + + Serial.println(old_line); + + int i = 0; + + do { + + String timer = selectFromMarkerToMarker(old_line, "," , i); + // Serial.print("timer no " + String (i) + ": "); + // Serial.println(timer); + if (timer == "not found" || timer == "") return; + int number = selectToMarker (timer, ":").toInt(); + int time = readTimer(number); + if (time == 0) { + + delTimer (String (number)); + + jsonWrite(configJson, "timerSet" + String(number), "0"); + + eventGen ("timerSet", String(number)); + + } else { + time--; + addTimer(String (number), String (time)); + } + i++; + } while (i <= 9); + + } + }, nullptr, true); +} + + + +void timerStart() { + + String number = sCmd.next(); + String period_of_time = sCmd.next(); + String type = sCmd.next(); + + if (period_of_time.indexOf("value") != -1) { + period_of_time = jsonRead(configJson, period_of_time); + } + + if (type == "sec") period_of_time = period_of_time; + if (type == "min") period_of_time = String(period_of_time.toInt() * 60); + if (type == "hours") period_of_time = String(period_of_time.toInt() * 60 * 60); + + addTimer(number, period_of_time); + jsonWrite(configJson, "timerSet" + number, "1"); +} +void addTimer(String number, String time) { + + String tmp = jsonRead(optionJson, "timers"); //1:60,2:120, + String new_timer = number + ":" + time; + int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо заменить + + if (psn1 != -1) { //если он есть + + int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой + + String timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо заменить + ///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке) + tmp.replace(timer + ",", ""); + tmp += new_timer + ","; + + } else { //если его нет + tmp += new_timer + ","; + } + jsonWrite(optionJson, "timers", tmp); + //Serial.println("ura"); +} + + +void timerStop() { + + String number = sCmd.next(); + delTimer(number); + +} +void delTimer (String number) { + + String tmp = jsonRead(optionJson, "timers"); //1:60,2:120, + int psn1 = tmp.indexOf(number + ":"); //0 ищем позицию таймера который надо удалить + + if (psn1 != -1) { //если он есть + int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой + String timer = tmp.substring(psn1, psn2) + ","; //1:60, выделяем таймер который надо удалить + tmp.replace(timer, ""); //удаляем таймер + jsonWrite(optionJson, "timers", tmp); + } +} + +int readTimer(int number) { + + String tmp = jsonRead(optionJson, "timers"); //1:60,2:120, + + int psn1 = tmp.indexOf(String(number) + ":"); //0 ищем позицию таймера который надо прочитать + + String timer; + + if (psn1 != -1) { //если он есть + int psn2 = tmp.indexOf(",", psn1); //4 от этой позиции находим позицию запятой + timer = tmp.substring(psn1, psn2); //1:60 выделяем таймер который надо прочитать + timer = deleteBeforeDelimiter(timer, ":"); + } + return timer.toInt(); +} + +/*void timer() { + + String seted_time = sCmd.next(); + String order = sCmd.next(); + order.replace("_", " "); + if (seted_time == current_time) { + + order_loop += order + ","; + + } +}*/ + +//------------------------------таймеры------------------------------------------------------ +void time() { + + String time_number = sCmd.next(); + String time = sCmd.next(); + + String time_to_add = time_number + "-" + time; + + String replace_line = jsonRead(optionJson, "times") ; + int psn1 = replace_line.indexOf(time_number + "-") ; //ищем позицию времени которое надо заменить + + if (psn1 != -1) { //если оно есть + + int psn2 = replace_line.indexOf(",", psn1); //от этой позиции находим позицию запятой + + String timer = replace_line.substring(psn1, psn2); //выделяем таймер который надо заменить + ///tmp.replace(timer, new_timer); //заменяем таймер на новый (во всей стороке) + replace_line.replace(timer + ",", ""); + replace_line += time_to_add + ","; + + } else { //если его нет + replace_line += time_to_add + ","; + } + + + jsonWrite(optionJson, "times", replace_line); + + jsonWrite(configJson, "timeSet" + time_number, "1"); + + ts.add(TIMERS, 1000, [&](void*) { + + current_time = GetTime(); + Serial.println(current_time); + + String seted_times = jsonRead(optionJson, "times"); + + while (seted_times.length() != 0) { + String tmp = selectToMarker (seted_times, ","); + + String time_number = selectToMarker(tmp, "-"); + String seted_time = deleteBeforeDelimiter(tmp, "-"); + + Serial.println(seted_time); + + if (current_time == seted_time) { + jsonWrite(configJson, "timeSet" + time_number, "0"); + eventGen ("timeSet", time_number); + } + + seted_times = deleteBeforeDelimiter(seted_times, ","); + } + }, nullptr, true); +} diff --git a/Web_server.ino b/Web_server.ino new file mode 100644 index 00000000..0cb5a214 --- /dev/null +++ b/Web_server.ino @@ -0,0 +1,222 @@ +void Web_server_init() { + +//========================================OTA============================================ +#ifdef OTA_enable + //Send OTA events to the browser + ArduinoOTA.onStart([]() { + events.send("Update Start", "ota"); + }); + + ArduinoOTA.onEnd([]() { + events.send("Update End", "ota"); + }); + + ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { + char p[32]; + sprintf(p, "Progress: %u%%\n", (progress / (total / 100))); + events.send(p, "ota"); + }); + + ArduinoOTA.onError([](ota_error_t error) { + if (error == OTA_AUTH_ERROR) events.send("Auth Failed", "ota"); + else if (error == OTA_BEGIN_ERROR) events.send("Begin Failed", "ota"); + else if (error == OTA_CONNECT_ERROR) events.send("Connect Failed", "ota"); + else if (error == OTA_RECEIVE_ERROR) events.send("Recieve Failed", "ota"); + else if (error == OTA_END_ERROR) events.send("End Failed", "ota"); + }); + ArduinoOTA.setHostname(hostName); + + ArduinoOTA.begin(); +#endif +//========================================MDNS============================================ +#ifdef MDNS_enable + MDNS.addService("http", "tcp", 80); +#endif + + //SPIFFS.begin(); + +//========================================WS============================================ +#ifdef WS_enable + ws.onEvent(onWsEvent); + server.addHandler(&ws); + + events.onConnect([](AsyncEventSourceClient * client) { + client->send("hello!", NULL, millis(), 1000); + }); + + server.addHandler(&events); +#endif +//====================================================================================== + +#ifdef ESP32 + server.addHandler(new SPIFFSEditor(SPIFFS, http_username, http_password)); +#elif defined(ESP8266) + server.addHandler(new SPIFFSEditor(http_username, http_password)); +#endif + + server.on("/heap", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "text/plain", String(ESP.getFreeHeap())); + }); + + + server.serveStatic("/css/", SPIFFS, "/css/").setCacheControl("max-age=31536000"); + server.serveStatic("/js/", SPIFFS, "/js/").setCacheControl("max-age=31536000"); + server.serveStatic("/", SPIFFS, "/favicon.ico").setCacheControl("max-age=31536000"); + + server.serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm") + .setAuthentication(http_username, http_password); + + + server.onNotFound([](AsyncWebServerRequest * request) { + Serial.printf("NOT_FOUND: "); + if (request->method() == HTTP_GET) + Serial.printf("GET"); + else if (request->method() == HTTP_POST) + Serial.printf("POST"); + else if (request->method() == HTTP_DELETE) + Serial.printf("DELETE"); + else if (request->method() == HTTP_PUT) + Serial.printf("PUT"); + else if (request->method() == HTTP_PATCH) + Serial.printf("PATCH"); + else if (request->method() == HTTP_HEAD) + Serial.printf("HEAD"); + else if (request->method() == HTTP_OPTIONS) + Serial.printf("OPTIONS"); + else + Serial.printf("UNKNOWN"); + Serial.printf(" http://%s%s\n", request->host().c_str(), request->url().c_str()); + + if (request->contentLength()) { + Serial.printf("_CONTENT_TYPE: %s\n", request->contentType().c_str()); + Serial.printf("_CONTENT_LENGTH: %u\n", request->contentLength()); + } + + int headers = request->headers(); + int i; + for (i = 0; i < headers; i++) { + AsyncWebHeader* h = request->getHeader(i); + Serial.printf("_HEADER[%s]: %s\n", h->name().c_str(), h->value().c_str()); + } + + int params = request->params(); + for (i = 0; i < params; i++) { + AsyncWebParameter* p = request->getParam(i); + if (p->isFile()) { + Serial.printf("_FILE[%s]: %s, size: %u\n", p->name().c_str(), p->value().c_str(), p->size()); + } else if (p->isPost()) { + Serial.printf("_POST[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } else { + Serial.printf("_GET[%s]: %s\n", p->name().c_str(), p->value().c_str()); + } + } + + request->send(404); + }); + server.onFileUpload([](AsyncWebServerRequest * request, const String & filename, size_t index, uint8_t *data, size_t len, bool final) { + if (!index) + Serial.printf("UploadStart: %s\n", filename.c_str()); + Serial.printf("%s", (const char*)data); + if (final) + Serial.printf("UploadEnd: %s (%u)\n", filename.c_str(), index + len); + }); + server.onRequestBody([](AsyncWebServerRequest * request, uint8_t *data, size_t len, size_t index, size_t total) { + if (!index) + Serial.printf("BodyStart: %u\n", total); + Serial.printf("%s", (const char*)data); + if (index + len == total) + Serial.printf("BodyEnd: %u\n", total); + }); + + server.begin(); + + //=============================Устанавливаем реакции на запросы к серверу============================ + + // --------------------Выдаем данные configJson //config.live.json - динамические данные + server.on("/config.live.json", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "application/json", configJson); + }); + // --------------------Выдаем данные optionJson //config.option.json - данные не являющиеся событиями + server.on("/config.option.json", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "application/json", optionJson); + }); + // -------------------Выдаем данные configSetup //config.setup.json - для хранения постоянных данных + server.on("/config.setup.json", HTTP_GET, [](AsyncWebServerRequest * request) { + request->send(200, "application/json", configSetup); + }); +} +//========================================WS========================================================================================= +#ifdef WS_enable +void onWsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventType type, void * arg, uint8_t *data, size_t len) { + if (type == WS_EVT_CONNECT) { + Serial.printf("ws[%s][%u] connect\n", server->url(), client->id()); + client->printf(configJson.c_str(), client->id()); + client->ping(); + } else if (type == WS_EVT_DISCONNECT) { + Serial.printf("ws[%s][%u] disconnect\n", server->url(), client->id()); + } else if (type == WS_EVT_ERROR) { + Serial.printf("ws[%s][%u] error(%u): %s\n", server->url(), client->id(), *((uint16_t*)arg), (char*)data); + } else if (type == WS_EVT_PONG) { + Serial.printf("ws[%s][%u] pong[%u]: %s\n", server->url(), client->id(), len, (len) ? (char*)data : ""); + } else if (type == WS_EVT_DATA) { + AwsFrameInfo * info = (AwsFrameInfo*)arg; + String msg = ""; + if (info->final && info->index == 0 && info->len == len) { + //the whole message is in a single frame and we got all of it's data + Serial.printf("ws[%s][%u] %s-message[%llu]: ", server->url(), client->id(), (info->opcode == WS_TEXT) ? "text" : "binary", info->len); + + if (info->opcode == WS_TEXT) { + for (size_t i = 0; i < info->len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for (size_t i = 0; i < info->len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n", msg.c_str()); + + if (info->opcode == WS_TEXT) + client->text("{}"); + else + client->binary("{}"); + } else { + //message is comprised of multiple frames or the frame is split into multiple packets + if (info->index == 0) { + if (info->num == 0) + Serial.printf("ws[%s][%u] %s-message start\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary"); + Serial.printf("ws[%s][%u] frame[%u] start[%llu]\n", server->url(), client->id(), info->num, info->len); + } + + Serial.printf("ws[%s][%u] frame[%u] %s[%llu - %llu]: ", server->url(), client->id(), info->num, (info->message_opcode == WS_TEXT) ? "text" : "binary", info->index, info->index + len); + + if (info->opcode == WS_TEXT) { + for (size_t i = 0; i < len; i++) { + msg += (char) data[i]; + } + } else { + char buff[3]; + for (size_t i = 0; i < len; i++) { + sprintf(buff, "%02x ", (uint8_t) data[i]); + msg += buff ; + } + } + Serial.printf("%s\n", msg.c_str()); + + if ((info->index + len) == info->len) { + Serial.printf("ws[%s][%u] frame[%u] end[%llu]\n", server->url(), client->id(), info->num, info->len); + if (info->final) { + Serial.printf("ws[%s][%u] %s-message end\n", server->url(), client->id(), (info->message_opcode == WS_TEXT) ? "text" : "binary"); + if (info->message_opcode == WS_TEXT) + client->text("I got your text message"); + else + client->binary("I got your binary message"); + } + } + } + } +} +#endif +//=================================================================================================================================== diff --git a/WiFi.ino b/WiFi.ino new file mode 100644 index 00000000..280b0dd2 --- /dev/null +++ b/WiFi.ino @@ -0,0 +1,188 @@ +void WIFI_init() { + + // --------------------Получаем ssid password со страницы + server.on("/ssid", HTTP_GET, [](AsyncWebServerRequest * request) { + if (request->hasArg("ssid")) { + jsonWrite(configSetup, "ssid", request->getParam("ssid")->value()); + } + if (request->hasArg("password")) { + jsonWrite(configSetup, "password", request->getParam("password")->value()); + } + saveConfig(); // Функция сохранения данных во Flash + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + // --------------------Получаем ssidAP passwordAP со страницы + server.on("/ssidap", HTTP_GET, [](AsyncWebServerRequest * request) { + if (request->hasArg("ssidAP")) { + jsonWrite(configSetup, "ssidAP", request->getParam("ssidAP")->value()); + } + if (request->hasArg("passwordAP")) { + jsonWrite(configSetup, "passwordAP", request->getParam("passwordAP")->value()); + } + saveConfig(); // Функция сохранения данных во Flash + request->send(200, "text/text", "OK"); // отправляем ответ о выполнении + }); + + + // Попытка подключения к точке доступа + + WiFi.mode(WIFI_STA); + + byte tries = 20; + String _ssid = jsonRead(configSetup, "ssid"); + String _password = jsonRead(configSetup, "password"); + //WiFi.persistent(false); + + if (_ssid == "" && _password == "") { + WiFi.begin(); + } + else { + WiFi.begin(_ssid.c_str(), _password.c_str()); + } + // Делаем проверку подключения до тех пор пока счетчик tries + // не станет равен нулю или не получим подключение + while (--tries && WiFi.status() != WL_CONNECTED) + { + if (WiFi.status() == WL_CONNECT_FAILED) { + Serial.println("[E] password is not correct"); + tries = 1; + jsonWrite(optionJson, "pass_status", 1); + } + Serial.print("."); + delay(1000); + } + + if (WiFi.status() != WL_CONNECTED) + { + // Если не удалось подключиться запускаем в режиме AP + Serial.println(""); + // WiFi.disconnect(true); + StartAPMode(); + + } + else { + // Иначе удалось подключиться отправляем сообщение + // о подключении и выводим адрес IP + Serial.println(""); + Serial.println("[V] WiFi connected"); + Serial.println("[V] IP address: "); + Serial.println(WiFi.localIP()); + jsonWrite(configJson, "ip", WiFi.localIP().toString()); + + } +} + +bool StartAPMode() { + /* + Serial.println("WiFi up AP"); + IPAddress apIP(192, 168, 4, 1); + IPAddress staticGateway(192, 168, 4, 1); + IPAddress staticSubnet(255, 255, 255, 0); + WiFi.disconnect(); + WiFi.mode(WIFI_AP); + WiFi.softAPConfig(apIP, staticGateway, staticSubnet); + String _ssidAP = jsonRead(configSetup, "ssidAP"); + String _passwordAP = jsonRead(configSetup, "passwordAP"); + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + jsonWrite(configJson, "ip", apIP.toString()); + */ + Serial.println("WiFi up AP"); + WiFi.disconnect(); + + WiFi.mode(WIFI_AP); + + String _ssidAP = jsonRead(configSetup, "ssidAP"); + String _passwordAP = jsonRead(configSetup, "passwordAP"); + WiFi.softAP(_ssidAP.c_str(), _passwordAP.c_str()); + IPAddress myIP = WiFi.softAPIP(); + Serial.print("AP IP address: "); + Serial.println(myIP); + + if (jsonReadtoInt(optionJson, "pass_status") != 1) { + ts.add(ROUTER_SEARCHING, 30 * 1000, [&](void*) { + Serial.println("->try find router"); + if (RouterFind(jsonRead(configSetup, "ssid"))) { + ts.remove(ROUTER_SEARCHING); + WIFI_init(); + MQTT_init(); + } + }, nullptr, true); + } + return true; +} + + +boolean RouterFind(String ssid) { + int n = WiFi.scanComplete (); + if (n == -2) { //Сканирование не было запущено, запускаем + WiFi.scanNetworks (true, false); //async, show_hidden + return false; + } + if (n == -1) { //Сканирование все еще выполняется + return false; + } + if (n > 0) { + for (int i = 0; i <= n; i++) { + if (WiFi.SSID (i) == ssid) { + WiFi.scanDelete(); + return true; + } else { + Serial.print(i); + Serial.print(")"); + Serial.print(ssid); + Serial.print("<=>"); + Serial.println(WiFi.SSID(i)); + } + } + WiFi.scanDelete(); + return false; + } +} + + +/* + boolean RouterFind(String ssid) { + + int n = WiFi.scanComplete(); + + Serial.print("status="); + Serial.println(n); + + if (n == -2) { //Сканирование не было запущено, запускаем + Serial.println("->enter to scanning function"); + WiFi.mode(WIFI_AP); + WiFi.scanNetworks (true, false, false, 5000); //async, show_hidden + Serial.println("->out of scanning function"); + return false; + + } + if (n == -1) { //Сканирование все еще выполняется + Serial.println("->scanning in progress"); + return false; + + } + if (n > 0) { //Найдено несколько сетей + for (int i = 0; i <= n; i++) { + if (WiFi.SSID(i) == ssid) { + Serial.println("router found"); + WiFi.scanDelete(); + return true; + } else { + Serial.print(i); + Serial.print(")"); + Serial.print(ssid); + Serial.print("<=>"); + Serial.println(WiFi.SSID(i)); + } + } + WiFi.scanDelete(); + Serial.println("->scanning deleted"); + return false; + } + } + + void wifi_reset() { + WiFi.mode(WIFI_STA); + WiFi.disconnect(true, true); + } +*/ diff --git a/certificates.ino b/certificates.ino new file mode 100644 index 00000000..e3fcfeaf --- /dev/null +++ b/certificates.ino @@ -0,0 +1,72 @@ +/* +const char* local_root_ca1 = \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIFdDCCBFygAwIBAgIQJ2buVutJ846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBv\n" \ + "MQswCQYDVQQGEwJTRTEUMBIGA1UEChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFk\n" \ + "ZFRydXN0IEV4dGVybmFsIFRUUCBOZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBF\n" \ + "eHRlcm5hbCBDQSBSb290MB4XDTAwMDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFow\n" \ + "gYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO\n" \ + "BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYD\n" \ + "VQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkq\n" \ + "hkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNw\n" \ + "AHG8U9/E+ioSj0t/EFa9n3Byt2F/yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR6\n" \ + "2RRr55yzhaCCenavcZDX7P0N+pxs+t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onr\n" \ + "ayzT7Y+YHBSrfuXjbvzYqOSSJNpDa2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt\n" \ + "4Q08RWD8MpZRJ7xnw8outmvqRsfHIKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIq\n" \ + "m1y9TBsoilwie7SrmNnu4FGDwwlGTm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/\n" \ + "vOldxJuvRZnio1oktLqpVj3Pb6r/SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT\n" \ + "8dm74YlguIwoVqwUHZwK53Hrzw7dPamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IE\n" \ + "IlKVgJNp6I5MZfGRAy1wdALqi2cVKWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfO\n" \ + "KJwGRXa/ghgntNWutMtQ5mv0TIZxMOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPO\n" \ + "GHFrK+ymircxXDpqR+DDeVnWIBqv8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/\n" \ + "s1Hap0flhFMCAwEAAaOB9DCB8TAfBgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73g\n" \ + "JMtUGjAdBgNVHQ4EFgQUu69+Aj36pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQD\n" \ + "AgGGMA8GA1UdEwEB/wQFMAMBAf8wEQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9\n" \ + "MDswOaA3oDWGM2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVy\n" \ + "bmFsQ0FSb290LmNybDA1BggrBgEFBQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6\n" \ + "Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQ\n" \ + "zbihKVcN6Fr30ek+8nYEbvFScLsePP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfj\n" \ + "Jw5dhHk3QBN39bSsHNA7qxcS1u80GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLY\n" \ + "Uspzgb8c8+a4bmYRBbMelC1/kZWSWfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5\n" \ + "B5a6SE2Q8pTIqXOi6wZ7I53eovNNVZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9Hvx\n" \ + "PUsE2JOAWVrgQSQdso8VYFhH2+9uRv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vR\n" \ + "pu/xO28QOG8=\n" \ + "-----END CERTIFICATE-----\n"; + +const char* local_root_ca2 = \ + "-----BEGIN CERTIFICATE-----\n" \ + "MIIGCDCCA/CgAwIBAgIQKy5u6tl1NmwUim7bo3yMBzANBgkqhkiG9w0BAQwFADCB\n" \ + "hTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\n" \ + "A1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNV\n" \ + "BAMTIkNPTU9ETyBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQwMjEy\n" \ + "MDAwMDAwWhcNMjkwMjExMjM1OTU5WjCBkDELMAkGA1UEBhMCR0IxGzAZBgNVBAgT\n" \ + "EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR\n" \ + "Q09NT0RPIENBIExpbWl0ZWQxNjA0BgNVBAMTLUNPTU9ETyBSU0EgRG9tYWluIFZh\n" \ + "bGlkYXRpb24gU2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \ + "ADCCAQoCggEBAI7CAhnhoFmk6zg1jSz9AdDTScBkxwtiBUUWOqigwAwCfx3M28Sh\n" \ + "bXcDow+G+eMGnD4LgYqbSRutA776S9uMIO3Vzl5ljj4Nr0zCsLdFXlIvNN5IJGS0\n" \ + "Qa4Al/e+Z96e0HqnU4A7fK31llVvl0cKfIWLIpeNs4TgllfQcBhglo/uLQeTnaG6\n" \ + "ytHNe+nEKpooIZFNb5JPJaXyejXdJtxGpdCsWTWM/06RQ1A/WZMebFEh7lgUq/51\n" \ + "UHg+TLAchhP6a5i84DuUHoVS3AOTJBhuyydRReZw3iVDpA3hSqXttn7IzW3uLh0n\n" \ + "c13cRTCAquOyQQuvvUSH2rnlG51/ruWFgqUCAwEAAaOCAWUwggFhMB8GA1UdIwQY\n" \ + "MBaAFLuvfgI9+qbxPISOre44mOzZMjLUMB0GA1UdDgQWBBSQr2o6lFoL2JDqElZz\n" \ + "30O0Oija5zAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV\n" \ + "HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgG\n" \ + "BmeBDAECATBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3JsLmNvbW9kb2NhLmNv\n" \ + "bS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEFBQcB\n" \ + "AQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9E\n" \ + "T1JTQUFkZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21v\n" \ + "ZG9jYS5jb20wDQYJKoZIhvcNAQEMBQADggIBAE4rdk+SHGI2ibp3wScF9BzWRJ2p\n" \ + "mj6q1WZmAT7qSeaiNbz69t2Vjpk1mA42GHWx3d1Qcnyu3HeIzg/3kCDKo2cuH1Z/\n" \ + "e+FE6kKVxF0NAVBGFfKBiVlsit2M8RKhjTpCipj4SzR7JzsItG8kO3KdY3RYPBps\n" \ + "P0/HEZrIqPW1N+8QRcZs2eBelSaz662jue5/DJpmNXMyYE7l3YphLG5SEXdoltMY\n" \ + "dVEVABt0iN3hxzgEQyjpFv3ZBdRdRydg1vs4O2xyopT4Qhrf7W8GjEXCBgCq5Ojc\n" \ + "2bXhc3js9iPc0d1sjhqPpepUfJa3w/5Vjo1JXvxku88+vZbrac2/4EjxYoIQ5QxG\n" \ + "V/Iz2tDIY+3GH5QFlkoakdH368+PUq4NCNk+qKBR6cGHdNXJ93SrLlP7u3r7l+L4\n" \ + "HyaPs9Kg4DdbKDsx5Q5XLVq4rXmsXiBmGqW5prU5wfWYQ//u+aen/e7KJD2AFsQX\n" \ + "j4rBYKEMrltDR5FL1ZoXX/nUh8HCjLfn4g8wGTeGrODcQgPmlKidrv0PJFGUzpII\n" \ + "0fxQ8ANAe4hZ7Q7drNJ3gjTcBpUC2JD5Leo31Rpg0Gcg19hCC0Wvgmje3WYkN5Ap\n" \ + "lBlGGSW4gNfL1IYoakRwJiNiqZ+Gb7+6kHDSVneFeO/qJakXzlByjAA6quPbYzSf\n" \ + "+AZxAeKCINT+b72x\n" \ + "-----END CERTIFICATE-----\n"; +*/ diff --git a/data/.exclude.files b/data/.exclude.files new file mode 100644 index 00000000..955397fa --- /dev/null +++ b/data/.exclude.files @@ -0,0 +1,2 @@ +/*.js.gz +/.exclude.files diff --git a/data/ace.js.gz b/data/ace.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..7b175c1c92c541999766de1f36c1e7141f0f7236 GIT binary patch literal 98943 zcmV(#K;*w4iwFoQ!jM=13t?krE^2cC+&gP?+c=V+ukKGsxLXZ5f@H}~W)jhiE0fqa zuFI>E%-w9sS{E%r5+)R>1Hsr{i~s$)0T2W!D#_f=+=u-_;o042H2MLwyk(xuB~KI2 ze<+Kc)Jyz_&yncxkOfJv=do!r+wIg(_)z#1+M(zNeCc)haKV;5VY{6z4!6<#Q?z0W zUk+2jS3HU0u^hx z{=}Q7NtVWJ$b?9RM;0R8ZUIbZlP>a@b#B-^$}`r{1a)qsEcs4$qK-y3Bt9(xND&lWYKB@ z)D&+Lmp76oE^lP$@J7pPhNIMO@NQ_iZJ6BwS%zJvykIe`90t9;`Hjs1sYqptK!-B@ zpw~Z-;@FdZ2q>nh8r69&M07thsM2sc3zooGtmNT{MxiwP2=db?==XCyaH(mU=K8!W z!-}k4uM*@^9@619&(_}3FC3c979+=K>cg2B6$KSF&Xf#DJd|nVftk+_AUqRalOSHe zL9gRL-VZ_I+1=ZvN4muChT&kWaVNllY#Vc_IxKn=>FH?Z_o20~YvY+;C`j{lB%Vue z1Z*Zl!&nir63h|thgr-)_(l}441Y^`qFMtPiar$jGPqsyn7Kp^4N<)w95}<4ER--s zf>PMVD9cAzM_0qEqa&(N*w*Rau8wAX)u(%jUzFP*3!1sifI})mt_p!cVTD`Flsd@# z2W+)RKsOuN&0xtTI4e?c0`l;IFD8QKf=_TK@3yIs*(9Z*Q$&&a)MDJNo%1YfJ`h6e3G309q@@eJ^b6y7HLeG0(cWgd+&sOJmTL&$+ zQpqy8--WGo6Uq5{Vsu#5r<$n|^!;wrLDjk2?^eyI41~h3b>orepPi{Q0_Qn&l#F{$ zv|zLF=x;}>QX>dOsRqJuKJ5Z`qD)>Q2hr>Tf3jYWmnyN93C;n~NMuP}t1<(#8abzr zRh9$nwExiM@ME^<8K{mNwh<_MhHAu%LQR2!In2^r0INjFG`)~ib@~*95-0l2er6Pz zQB*#SsOxzdabe*&V5d#{Iyep(NR4eq<5^Scp2Vig+7-Uyp(6MCPM<_rpIZg0w!mEW zCfcyfFYzw{|MJw@u_a&yt$uLcbU7H$Xrc%J&rnX6VB@-(L8Xsruh*5J{tZaeWq13T z;YYK5FmUxQcoMDBepm*y^+pk3))L7-gf80c$^tmNr|?+zc#y66=69<+t8N5HLZy6e zaZys-m%81!DjMxOaORkh_jrIZkO^pt2}Reus&ddu#T*Yl_%RPf1^MSnn}Wpk83i9R zWM?cKO|UfT_3&qWWC{aS0$0~#&qli)7~=0=M{+$}#wm!6Dn>Wp1@#fhVo>dZnlx+HxMR}exe;59_D&^Ru9p! zU)S|U=Kz3AM#)^cIi&?iT)oVP5LVBmfxF@DykoHlqx1@-l4?z>(vM{a$J%%m?Sq zHm;-W?QK#Xcb~>|PS_t78O7zWzC2AZ zln#>t)50e-SnW_S9Dz47d#CdlPbYU)q|~lonr93%YiH6AFe)~Yh^7O=El{d}7vz-n zQxMFkpAAwP12GZEQ8GwXOnVwx7h)Zbg7s+(@$cG4xYK2SJyQfvBPa!BtO8&BHeS}VPyy|@RycQ8`{qTjR)z_p zS|QGeW{9~JApRr)d9U1I@If>1Qb5s)(uIHaOx+{mBD)p1QfJRvO{2L===ZbJ)JG%M z5f~IGj&mxe8K41w4ScNT`Zm$FW!2F7$FA62U1?`L?!&rWUi|KLd$LbDV6~GJum39V z!M)uI@>3q<5Dw&qFJ3my;iQ`22e^~ZXb#-5dOK_3(~`$vE7}A^b^NK^0-KS7-TiYp zwFFKrfm0YbElW;;SVCY#4X<(_V+oAv^|b!-(l7IjeP-gmg=MP!PvzL3%c>Mul>)0$ zeIJqX72^^Lq&Se*Npmn@qLzJ)1z2kt}im2u9sS_H=w0%kRS(jmcDW;!csyn2I@)KG}c zF_7-PpS~zn7glZBMrM1EWuF_UNjk#lT^-#atWp@A7{T#3aEGErVC4&k|t&P(4Wp0R14$xY( zvQa%x)MTaE*(NY%^e1+oL2F$Q=AfpfxvRPfnm2mRnl$InZuZkk9_*kA4k?Ps&HhW- zLt(u?iHC&wY$|oKguOm@WjADvJ3?sKn&M@4Zub$IdFCD%ywZM^f_O5mFq}K?>cTv9 zSEkYrSV3zXX^5$kB6T5Mil7K@JaaG8D#Ps-&y2GSo|1k!wNGZ9ZrJ%w&;O2;H?j^Z zK|-CYTZt+Uz(Wx4tVY_)|zQKGbUpyA+ zT&c&#Bgd^*b{Hm}#|S@6$9Ki+lEcf0NfAHm**tvCxuI_o{V-JK@rV@S%j&cbLG zymj5=ne5!KP6Q5NsgLLztIX=q92HhmVDv>uR_gXQ>-0LADb1rqIb}CxW|5kxo&|o3 zK1Z5{4j2^ZvO2JiuqIOVY^Z-!_q{Q?uYAF20VnF<#FxN*>!|baMOcQS2^S z*YpC+HPQ!LOZ;9h)|-GT)TgQ=(;aiu0ad?xtSt_lph_1vdm0MFW=<#%!C!jFzV?HO zm-}!qr(#yU7QpE6`E~I zDg-TWlxN9A!jPh<)8`k~7O~HuL(Vb3C4&hL%lEpz!U>*z0CurO1)*$dnW(NB?63=w z{+%W6MBVb$iH10^RPN-ewFbbdVV$8TTd#Aqi%f_KYK*s&^h0t+0(By~BlDhOvUUt7 z+><5hUI4lV`e?p_+4OlhC8g0Ml++C>F=zbk5=wO&4GlG84D~jf4b6_FCo}psd~S0y z%sF`t=j5TJLHiXx&^8VniY@Otm-yUPPcCihKUUX&>`VHOI7kk7y2d7iGg;k#vH?#C0j0u61u%aEU0gGyKD99 zfsFuC!7;i9kBBJJUn)PxWGj)sVHb3MPkj2$?a{6O4qMZTp(P<&kJAC9&6j+MnNGI$ zPNz#E85gz09R2cmScbr3_)c~}&_9FxcSxW0Nk^s~D?ZJ9fTAV&X36i;cyR;JGjKw_ zl7d6`k`(uoc)pUE2&jkUY@e!{o!XWhv`Bw{UQi98)>C9H<#uv(bbEU{ygeDFVs$ir z`t<41-CAy9P--a4FO6&YGm93reJG;`Oymzs2NZ}Ou3;n`bewD)(d?)DkI@R_B#&S( z@u#C14k@RZahR}O^I+TGLEF9EHy_Rpb$AjSFUtJM0Y4dp05F42eUW7^;wZ}+c(wZQ zAW*_iTt^>8Ro{giU1j~Fm0u-?*vw6xIEvUM7va?ZV)Q(THPH6Ntw(m!l3g1ERD?p z>AvQ;2H2rQYk}ddnoP!{(O(EH8#g@BK*?x(S2eHo(h0bMZu5eJnvCv4aucWXPo=SM z#h$`C1s*C0=hbAq=}I$>goh-$$FA1jQ(pF?hpd%@+%nV4I=- zxE#|UoLiE|k4-~^SP)BB^pf%wb7iS^Zz&fm%rgQTCu;rRWx;-bo?_< zzfC~z2ekkY*%ps_ABZ_4)kHjdU!M7^nF%WKn~+*}>Ly*>8~KNk--@|yIt~Sg*AN9z zUbu(xtZ_Ko{X;Ma2j=TPi0pO`g+Gd0d9jYvTw5gk&B~JVJ`c)_?{tXqu;;1rUGUo-nT$&V=NU%^Z(nP{2%-pxEZk!^N zu97BYDC;!g{~|1$P`YZjF}jKe+$ma;zKDR^o^J$iClr1uXF{D++{gAQaFn7vmjA`s zEk+$%XF^-_m!|*VAIJ7tx(>^hTrj|L5jT=QE&M^)Bm_hX7*LcxGDRAn2K5yNbL`|a1bwWzBy`c z2HUlL_?E!A0ieukR(+{5@U_<*^Dy@M?aRxH%k%fw|9Sq`50i)S4-@iX&A~mP;~yvF zg%mNAo=nK|7@CfcA5F+>CL>Z%7=I0uVa^-|O~y2e<>Z*A>MaBc8A6#nqD1XAnLMEz zm2nTEzHUf~#1bB>Pfb&vaYyzcFev@y&OBzAt$Feep%9FBk43(#4 zJ^q^$jjwMS*`3DzE$wWlCBgYgL|>*oo2Hgr4&SQld~ z0GNwoEC7THBw-AbFAzKK{RJY%oxebwxbYW=4mo~-n2v$oi>Fu^Bft@s6ljEfjIhTD z{E;S4`!ZwXm^Oi`p`h>HU%vVH{HIsvX3KH&I>1dp2M`|tG644&PywvRfC$KZ3`2m( z|7Gt_+Z#uYby4&=AJ4y#cxtN&6I2nLhl2QUwEMWr-KVR)?6p;LT^0pNSWN+109e&! ziU0k+k#l08RNd{h_q}Jioh2~mAu=)|GBTovCeXzm>PH8As2JVrq2uUW58X!BdMG}r zxqX!L@dsHp_=7BfqCT`u z0zJf^>upy(lbJ;Hlp{EoD3={lLcLpGkQoow&y2j;)j_`TZ`Pa!{yETG>I|(bX0Ss? zG(E(G5lB6ZBcP|la-K3bBx(ca+5$A!PjNx?BL^E^2I>ekE|k^d;Cki@A^A-b-!JYq z2~|iB44FX9SoN}V6_`H(PA6pi+vt<;-}#T@g}R+LpkL7bo}<+x2uze@H%!ow^o4H!rO-&^)>m(^R7t?O3U*V&oE zmU@&JNd5h_*?B^wZ@Rn=kZK!YednC6PB%(Ppvszynb}mBWK~`9uKg|e_~$V5jad(+ z3MEf^&FmeZN7~*2m0R2;^wglN+zC&sC^-A}M?ch1HM@>K28d%o#o_jc&9#{${DJOc zWa>}xetVb8A>(u|-UHwRBiG3y`TpGr%TxB6{nPVE%gwP5C0OsJ20k`2nXt&l--`={ z(~xiPv$K?V7~r(G@pX6;2Fbe&oEKr|LS()6{W}r_l%)W5)EtLQIz0J9ZfD{g$J-yd zj#0gHMsU%Q7)_*Men_|r81{z12=sR#P5ab9CT`eGIWc9xpz`;aoju=)UlUou;Oy*% z{yHh0jJ_wd_OtLlKo{>H9Q8huw|927!QT!q)#k14%mU4LvU}5OF^M+s?P&`q(Sgw} ziA`aU$eu1}+|3y(jxPKW+K=A&qmE2rbB>L~8t?pyK~gtS4m`2Dahnm>wUX@o4_pmJ znPXz=bfE#B8130mmVT!2WOL>>N8(QD^mK!j;X}5lBNc1YQ&ZUl*l}%0;HFM$`8IFQ zjZ_)@DFbz80gZlXNGAC5?2KQWmwUGWG-z;CZEFetWNpj zAT`T2+dGy)-VGXuyfk7U<#BAzoWmqK|L{2>@oVBIu2o6BhIMUZuDCPcV$KxC+D`0UL3Df^*&inU|HkTi=QSe7zb5l<$)n$7J-q`6AtX~|)S;`oJFF0)l* zkWZZ!V(Jcw2+6d;ZodCWT1jM#Dc@YKRy%Q;k6?B3(fk`zZ00=$@|y3nEZ0XZvm-H- zU%URe+wMYes`P?bM$(xa{F2=V(HLZRq62>L$140(^lacoLF>Q}adi#;} zV*KchTW)*YcDrNma4Dm&m<9kh2~)VDRU0d$t~1+f0lR%m_#)Y`rgUQIe8Ik=v>E|U z>-oHUu(RQFIj^x((`-Y+5SCXdEt;G4crT7*G`moqE#JNy3QYrcUcar_c6`%eb7Yi@ zb%!ZWJqmq&8`qE&oMjXZ75SZjjIKqu0dF-(L3vNuT@$-L`8yDs{Qmbtek`(bJ}Jez zJvS|_KREw<7X-V%`%RouqM>Huye6S4OZj&r<=>kjr6hi8^hqVU)ZBsNDs=5FP5s}f zii)|z#IfaJ&9Ir97RF>`C>hjHc7GY{vd!P^s~$ZvE0Z-cGv(i3XU*`R{+o zo}P^EiRgc4(frNYq)-)j$JMyl!0eAJUBB$j-%*eAhn{XhCj2{3IEe8VMvRKts&g@& zJ#?V8U+9q=|LddIfBOE%Z~y1_IQqZ)F#G$r?~E0z^W!JnQv^q0vp;)WC{cX5dL9di*5oOVgOlfrzFqylFjdG~D>2%Sc7famM&}A_%8%SA4m* zzBa?8HrU>|=si6Z68^opK>~jO^z^iKsJff8v+XX}B%}u!@3Z<1*`P_eUL^Z%SZ-ld z&cTf?x0+rjBDU#9(IBF z-5uBdbHBOfzYY`25C^)o*+CSGw zdZ`+@^6Ta=LTn9Bm?Y+Pt3)Nh-upp;Cv&so-6b6jwRm)+%h#E{J7u8$zn6}*rC`QytP1K{Kl3) z(K!zDuj`lRe`rkq@#^tVcb+caU%h|*{{5Bn`qr(zfB(v>8PzcbwBwbXQMt4Kt23OK zw$N)Lwrj>D22Z%ug9M3vDM4%bdBe`s*26_->+nRTLzM*@#r?Q^V6O%&}T zU%C8iEa#e8=#BU`x(SjbxLyEEOO~IBY$H>ID&puu*D|qhkds^j2*M&W`3#UtL_oR8 zLErVK+q-}c0iTSCZmlj@&L(t~boZGYT-iuTev8@3s1vNitWcQ#5JcBG#Z?Wp37?VO z=1XBh^vdwsEUB_FC80GX5r5dl?hlNqNN6fD!vbr_TeZvP__l~_bQUW?lX@CMdQFg< z#=`s^Sf>2!l{UxO!SLw30gS@@(f_lc^Iwyol_?;+_^wRctd*$<*w4jm8skOp!{|=p z+-ODKQ=I2oqRR>$f6a8{VQkCBv-6w_H+6>-@L;4T(_GS zP5C!$jrk4k+1VEbP<2C~@FU7v5b~dn`=1qpga?9np}jAktUS06K3TITB0Rbdk{~&M z^)n7}N}S<%nPrQ8lE#VJGS6l_ZCRDkQ6uyG6!Sbp&}*TL`b+a+v%7CzhbbwoHaGh$ZsMq^F`0Hg zGu`C?l!3!*#Y8H)je(uF+3`G^hcMgh!hZ&p+0ut#x5J{6^yAcX)YA&EN82#_;*++X zAv;lv2Odg1l6d%qUUHs?OkZ*y;1H*ynQT)gX~vYbxt{8cU;97)kD9xq_ibDHhaiwG zz02Ge5!`YMvPy@01F-p|o=9T-1^nIvev>@!_i?vRY}PhAkE1zai4p$fvuE>#Qj)PX z4>%4#;EO1Y3V)MN|fjg67J;{-l_?Ob$~vbkl5s!s?$m<8tfA=7DH-@6*}Y z$2vJvaKBV%B6GJI$*>|0vmB(*4QV12u5@esl0>04OAC(_@I^eCKp?&gK2`vz?KTf7vt0*pAf(57%H}M=Rw6CoKqjHPRzk*612s=zV9$Zvnsf^mf5tk< zM|8%7^Dc?*h0cH-A|D5j$J7Klmp>kNL4b2L!=1` z4x2Ui7Y;{%@gKbo4(0Y>>>Y}wN@Q_&fP+&pil?W)7?L?Md#iE58atWBBXY>X_7yyi!y(S(f zkr*GxX(YGPTh>peE#`hOJ0EJ>Q|yu5!x!oScgu9DEcGQt9h(VNnPU5d`AwU zeW4CwYl}qyJv%~F@(4{0>|H@MFv9CI-dl>Nv=IDz4$sAB=yXqC5C6GiaqeX}ac!g@NzmIlbG^_h~aPLU+@K@|`vJw%bWNqvG)gHg!ZX)pB ziCb2k4eS5mG9@B(!o2%kJGyRWCcWe&Vmu{hVCtL`m0h^sBtKKhKPK`1q0Unj#X~%= zqS)%rk#Yz3KXN?7X~`7*_2C*MROuW^eu5wO+8yIBEstb~+L{G~UXnA~^n9D&d0U_%d;XZ6L^5V<dGv(K}LA19rGkbki z6g=6?4DRXTG}@4;#?+v7A2IXj=Qwk(<9o)&j{_-2VIsMhseMTTBOh;)Rx#hYF^3Ay z7mA%k9%LT;oJ>*6v80f(9#3okY_dljV`kc;HQ{bdYur%BxYn?ZjWlYLT006N zHg27Jyxc?@ai$@IwhS2MIFI*C8opo(Tt9MhY(oM?%jAMligd2_B%o>3)k~hu`Nuf9 z4w9eZ2X2;wU61ULk8G0|8TTS1-4Po(w>~A1376(gGqTLLG~4c74i@;Jnbi}m1Gj6o z8#U9^3W<=E1#_(ucY_MI4$FF&+zAhU91WcM26oVA(Q(o3OQgGkbIVDbL;k|e)HWfs zBXq3IDR=MOADuF|U+iLl-H&W(|I_`eEdpUe3dZx;h3FvtvF?;G_)5L`uO%DXK%B?4 z-s`;bd47Om&cDgs)UXb|779xr?l`;sa$5)XO-%LO%}XCT z?fLAyVv2g|h}TCi0dH^}W^poMb~wcR2{D0nP>F?CI;WgF2n79BD5{Ur&BKA^oPc?SR zzEi*02Q$M^QvxCL=lsjxfVfgS>N~)mh$5B$ziq|bjFbmFF5*{@Jx9v34@1&WLuR8OsmGmc1k8CjM=LspA(OdRw`gHixwEsW|Z@0fkg(9E& zNjdosr8Hb#7ddf0wTrU|U4f(Qeeue>`bv`bfod@-Z>qYLy`ML&>Eo6m_OZz5ZldiS z`-!}Vu};NLoyM{rj2C9+oorZgqnlRT=#uiZNzdoeLy7VO-F6vlhD+9r4AXKy2#SrE zAWqZ>+{0gE1*S7fjc;W=*c3_lbK=glSg#P(}=u#Wd201Ezz*_r}g2|;NGDW9QVc)edF zLN;mub}T|e+3FBn302~{GmR|vjJ^yo37m2E^b}RY5zUeqhZ06cMN);?C*`wCcVWlU z>*B_m)6ML{U9`>=EpqEDjw32lfM&%L+0!qqB)OTj9SNmF;X z)BD!=Gu3vL-^EZBcjI` z`b?)tF~GzZolzEd`GckO;z%PL&R8?*+&3CBsfk=ubll5^Kn1|wh6%;2x z>g3v)Lve;r0madAC}!PtGX=#*5n@t`X^JSX0*V!x>>EEhrEJD%V%d(B^m0L`uZ&4@ z&C_KcJ%dt9P9ct&6Xe{afx_NjlUt2j9mhpub=)gk{*3yi^yK>D=Jso5QW^E&0<=%o ztfELR3N(fzhGU-b6(?qq($fM3gFP%I9ZQRsU@IXfXBKOTG)y+zpQXT*tb9zFa7y1` z*jtOpH)B&b8kL8oGp<{R?%ZTx^82B@5&@w#N2KQgFf`%4uBXc2g@5f-O)5IXHixp1 z7?qLF6QV#F=}4LDj6@bfqBKA5X(^V;Pn+Tz$^DwdedTjPYjdo)Wak)uAAeorX0wGk zS2Bc>8Mo%uQspS^Kvv3>lr9Krsp&pwVMM{<1ywoQZi5}8N7Z$SO{S9K6@OgJ_)-4k zm_3zKkFj~O`8ZjLi4@JQjKL5{HN^_koro|69Nr7X^c<^Zpt>;Sc}b&l{zY}*5A;YO z2(DH8GQts#`=U4PR?9Kjjak-7$-i$L7;=yUv)HjC^Brj;Gp z1!ZVQ$wZ1Wj#uRRw(4DlYBVf$wP*LNpc5@8&CZoG+8)J`6fzp)v5cKt<#UZ{g|OK`ZZb!G#e(cN1J4Sbr!YEOS^c6T;U=7CD{EGzhfc*llgDCdoU5KdAe$S z^$@4bOZkOvK|V~7#eW2+vEwBqp=fmQ!0o!pK2L7^l!;QsyW%$=lh+r_&5OVyWPl@N zJC3PZd`QFFXtM(ag_u9GHT_BA)zDIO5;r|taryd6tk4>VWc)d0#Flec-y8l@9xy<%R#K+D*K>2J%2sYMGW5 zcLx<4&D=kVn_#=grnsG0Nk8f-X`f4HsELLnZh42yEovKc1`AP8>ZCaS#y?gW0Rm&Of(vLCnyNFcDR8*R5#g5@KYC1rR7&84ptJeI? zmaS&u4zes%zLU?+nE$W6&nk`OQpXkAY20**yJw72$gB8)42=ZWQ>@CE@RZAR`^f`T zxr%`RexbAw?{oIigy9rn80n=wG8*QnOup=4z)0KHx;jNUek9VtDUAyqzxd;Ha9VN| zD4%S~qs);fD?L9F4lU{%H+I}SVNp%Eaexp?>Y;KUrQL+(J(8G?cfeGcB{>oCY*C(# zEYF$51}Vk*HvK|dt>Jq;H)H<>jqrkqqo4_jGHen-)<`dy?oHEgw;CyC$go&ojM-cQ z4Ek{35gVIK;b>aE(8zOCoLFK1e)u|TxxZSA4vhmOmtE{>q3ZcuIaOl3o@rK zz&rIc?HKu0^CS;tK z$=Ib|B$zoKCGY$s0B~2$Pfy{~Q|c6N&wY;^I*~6rc6*jnGbmiUA^ST&aewh2e;Gfx zU&hx54YIMntN#Kr|CjSG?t^>nOyY~p^c~wit6WYR?EMmL&m+pl82=-&W#fk?R~U8~cQ)R0F0J`+!0bE% zXO6F%O!L^~tlC&94PPG)V8E2N@8ht6c{}CHHr}W!i_ZRj@SN1b1ySF%^EdD+T*^wwOTkZ`0jf|;olAl4l-@E3uZp_?$n0TLG z{W1;E{F52iVnwZqc*QT%84pZE;hbEq(%V(C8^P*foaT?aN8}i z3D9!G=PgHnZ%o8@(!hvWzaBT20EnUA(VPg`K`BPjvq^qw?D@Q}KrFdAIsN>?dC54Z z&fi+leBbk~-SR&)6&!*DYQe<3#J0CNH{WA!X38?ktb*s7NqOwu+1YnQ3SlLTO5U0m zLUa_R(i<|E5N-_3U#fHf-$ zs*?O2O?ZFHJ?$o2zeWQYhxa(`U*Co|laJ_izw7?k+WqnShQ z=hYPgPgY49dw7Ces?fY4{atjX*TAvS{DNnWXyOv04utKOI2?F#{3Gsa)$) z!7#JpxSyGEAX~+OR>sh7pe|WzS@gDAFCTk`uefzp3%8)ig~9fzp&aH~7>Rg-6`S|T z=||>yhT{(Y#L_$&>!oXH+uN!j^gdK<|_e-PUR?eRP(Wk=*Fi@~LV0HETPygbc)D;a5$|QdT=x14_rP%9V8^JtVf*W?q z?Y3u1kr(+|9`2thvm@B56`<{CsraF0!jgTA&T?$k?zcRh`aNCpu?-hlq zk|-(avuc?@r6TG?sG7Q zylQ9@X`_-ocb?XSupIOiL#C6Ua=bDmPe zv-=I&-IM5|L$nRmN*IIdSC|d@noszh8f-E8^!M5|%=uD|eJENdVZ!ihhOMbh<+iV+ z9r2Pd|8yz;Ix(@|7P7a7xl8+}Cr{`RkgP4?#to(0I79cxtgsuaHRKz zcY&OH4vJUmLFtuxjkZ7ag{FzjBr&~`b2HW_-+1DB!^W#@XsNO_S+ccTMGFs;y|tMS zCA*13AAiM?$J`UqhRJ~ycAYR)MXV^J`bw_C)ZM{NPL);M6e!bpC2kj@;N{n?FHl}J zG*7vbDVyhV>)65PlfS?H?oV0vApB2EB62Ak)oXuT{Zw-UVFovj$T-Otwx_vDfNiLh zrM?q8z6*>%*GfV95M$k$>5l_@F^Eaz!g}(t9dEARZIke!yl0kv%%4y_+av1kJtta8 zSw#d@Ou7=FHIr=(iQ0)HYSIsn4o14DiI7lkZ z_f9fFDHSA*fp%P!2y9o>ZVX&z_6%4DBr)6C%CQ4;t5>4TR&7Z*4^$Ic_lh+C@q;j4 ze*Izmc;JS5>0zvtNYXcZHLLTn31zmPtvEmQFRvKaOs*;tN2n@lH`|#rNl)1m&`|pO zNXg#^HQ|#-1~E0idYslOOSwR<-+XkwFRBXJ04Ir7YtN|+2BdCCq^YCcu_oGrLvd({ zH8c)4eo_F7f&zXS?x}!i)7C@*yQn(~EKpS*woYc}`NQ1g61)d!Eh6>6d(bl0u9#O1 zHjJAaKgr!?sfg;aef`L)@Mih)8Y_^T@^M6R2@>W_M)q;GQ;t#7A}4D%C!ZOVP8}V$ zY``mi6#7ZYVTrB$VaqQ6f8{$P`?M`NPowyxRH-9oW8x;fbOQ4OE#cPt8vq1nrtheGP$3`%$DDIWOqsY`6N16 z&d04MQTAjx*7AUKAope8Kd@&9mitBF@QD1F<7er8l0*x{ z8`Nou?@Q7&41BW>nL`$;tr*5T#=MD2KbZ`H3Oy&$Q7PDEyI1vpY;R4$ZC}=2)f$8p zffX%ruhn{f3j)x-xert3Z6dfn;kiy~-!y{8H??p0K|uZmM*J1WyjGMk z-_%V27FU!?-vyZE2BFWn!_%W|TGYW1QRrf3B~oOlA{0ARKnC~!LQ4~)2HGZ1R^OYD7FERRZ*7QUPd zN!#YyqpMY&iIK)8tVZQKNYWA6l{6roXamwfwBQ5OM2-_?7cXMI4eR`a)>yZC$s@1) zgp4_}JAP*Fl%xfu?i{e`RhiDsJlyD>o+7f)&E`i4almt`?d(_L3B4UFhZ`BwMB}b~ zl3k3rg9(jJgmqc&JlQ5exQ*WYVwq-Ua?3-!Mft*EDu^vf&>2*`1yCfx(zZM3u(-S1 z;_fUkI4th&?(V*@xGpXWEbi{^?(XjHE|>G2@Bi<;5gF0%R7Z4IWMnMN@$J#Yj@n@tT6kQMe`aOKe^x)6C$Ij5%^!X^4r|w7eaHDaEOO1; z?kZuACFaFI@g9VVm&&MezV=H0xbR87+U)1V+nj9Ub1k5=p(oS9^p+heULZHy$HHNS zh?TI=JF26zr`VAE`LCv(5@Kv3@l*6dx8ya~&&PKXJw*32*Y^W>_-;jW-|_t6)SKEN z@EKG0@pa~7#N%9=KPO=B)BPB1MCm~+n$6w&wb`TNA^53Drlu2gl z!7#4(K#`xMK#)dKT$Y%nYX}C~@QGHw9*{hkXS;K5%$M?e>_4(8clYOK8gUJl+xYuQ z1`6&46TQ^Ne$)31eD)Q0;o;nxr%EKGpJb!M0%2Ib%RO&o&&uLc7YU4kH+XZ?*x+}+ zmp*+5s8-a6!bUMVvoh&ox|(se;(!$mv{(+(FC>;>1CiayQY@H^pg!2EEXU@-rJCc9 z1IjlOZ3w{pni{^qJNt5eUj8E zfI^HMD1|C)3%YP101y2h&Un|(+K^2B z0(u+giCwbMr^e3>$Ko?pPL7>Adn{BwOvs;PBAEIn#%df_QrOuy2BkkCj?q49y`DH7 z9d*jtUcBIbMZhwuOrh2Lv*UUDB<$0Gxzav#ijVl4&;Er(D(mKp#ZVdF9}2SN1E^zJ zt-t1a!=*{%6eVOs#nhG@2Wj7x$Z6PE3ivxHPiSw^4vJ$)JQy&nJSU1JqVVnllTW9x5f;WTGjF@+Gp=jF$S{epgXA?}m*Fi6Scfi)7Hs z6U9YgNc7B1e{-s~NPt3@ywWYra7l^d_RG>Nea;$89V& z3hQw+=LNXPoB7;DO%A0A6L7I{oD2&7ap}o|*p-Fg6Y}ESh#%FK$_F)RG{g@}Lv&sA zAc3s>q7v#vy7nlQF1LwMDefjXBgH{22H@*WP7r?rb#lhPFo`0Z!c=E?7kU@1RgUzVkI`Q8MC!%lx?_TSv>(zj=7AY;BkoVouPGg%*N`vL&V5yM~%k z(|9TkOSF{-zkN}^M?U?l!E&o69Um@k+>hMeuYgtYd7zMUS!vefVYnTbk+58y@q2lR zKCmHQNv3}8x!VdU+xQkh6w>B~ejCD}s<|XK))x}_?1poDX=}k4gNN#E5Yx7~(V<*N zqdVyEE?}WGu3SX}k*xOyqJG}KjbQsQNfV1Z(Nj2<@~e5(-fk-({cUwESNF|4*3yIj z2a_|Wbm8e(mq}AQFRxU-ppNZ~B>#K0Ar9Y1#Px`OjAClaRzf>%!u3<;4lP!bi&f{q8utZ)L6}rEdK4~ScZ*Pn6LXtMhxVA+y@SA|%JJBxNurutV^b1g z)c0siXniKC2D4~Zkv-V)9xj*j!H|k!Tj>w!s7d@&m3Ah-jc!K^X<)3X;~wGcU4X}( z=wfiSN&L-qpRKJ(@GBWaB>OySAg>Xqxt8!`W9nAkWjrp6L|Cb2&MZY)h*Q$_;zlrC zjHNTbmTHz)0cR!B&i3beWE|vXMLHhSc4;zB5()hJNEmZ_z-hg8lmkz+l$K&iGVd+; z_CN;mQ#%-lMJZM}5isbp62fj&qGV@$(nGZQEUbjV14r|X$lO|3kzSloDL~eQ?jyF;d zrp*Vh!l&7wX5!_Ck+b^hQmVaS#>Kns9qSe_(@x#@nWz;cy>s_ZmM{}J8ZC@NVV>@mfq|GBI?F>BX1g=gZe8i%&qSTeDp;+8JDtXhhx#fu16_rIMMN zM-!iNg5-U*Fc%uhgfBw7pY)xdn4GjCf264baKoXFfr6(YEGTnDWmBRo202ye+zfSn zjt;lrZiC19g-nt5`dQdoZ0SSiIuzaePl`NcRkG)Fsi$L_JSe~N> zLXY?LC8u_e|uQ0#}i~E%n=d637a3NXzCDAOrgfV^2*ftNs23e zP{N#(grvUEM;O1Pu;;L(O#g>9&(=^fDw0<5fCVOzzvs^O;Pqt0CT(<({5F8CGK(>@ znVyt^w1NtI>ijx*$o^S{Q&4kOiX#5)EGJ#~Ph-g3+1*^c>0o&K?GpsbGWCav+sIX! zrxzr;lj)?fQgU+=MhZ4Z1L*ofY4umbJ#3tf!{XJ1`pV4n`$6~2L+r-(8OM?4XgDzj zZ^*?KD0zP`sAuFN%yZ=-9Hwy%eQ!Q}4*~VsOds!|gF78|zlioi#uw)|W_Q7IMy%1% znzL<%BeE`MfkeaPIlchj-+~&x^1zH#hPBu)K;{}b_yNoP8p+zMPq#K67q4#Dk@ zBGsTz{!{Sj&)fAn>;MJjmm1~#DEyZ~Y$3|7oKOa<$PD}}?FC#{M!fn()r2ZX)m9!0 z-J-ReLY~U)@fw8pnYq+0^Vs>LCM-77~Z!GJXDm`Io;TeoPUJMaV zii*I;N=nK>15aI(;k`_8IZp}F1hyqpi}^S^2C0uaKhGQ-qfgHoq1A3RgL8}{AjMQh z@y{Ev;G6lB4LzwwS<`O@a4t9^nev-i3la50_x4UUHS>-G_uh3{Wu&ZBr#oZHuDvN3 zt!R!PWei0UoO>3GIqNJ+9qA2Ady>D~1Y3{cBnHGg@GrLSG3MMXc zq5(5Ba{12dU-^D=Zs+}(rgpFq<5OLtw%=f~A_F;_XNGXJQ>;R)`vZ;Abe{TEHFpb! ztTV`tVzTU-*&hbD&t6s^=ao5ZCtB8r?79K7W>%jM+!DST5Sp3tX>ijcw7;9B8YkH`J;7AKw8_;{R2nN z&ON0uexqw`WGM{x6z=*U>i7!tk>ekxvc0aFxjM|nm`%XjU7XY`jp3wQLQMwL^)?qf z3*&tyrq4eDg*KMWXL)u{sq8yq*KA^#{UX09(M%X@xea$As)|K8FJBTPA#wY3Prm<7 z(d(BmIrOgX!S^ytIek}&0XfCUIbveNBi`(b@%>yM{$}DS?DlaK@$+B8P`c~W(z;Ka z8m6I7^Mt?HDnwD;sa~DBbaiOm+AiraFUIedAa=Oz{bY@BW63pI`-;7>P&#_6rS;UJ z0|Z9OddGa7%ppc_OKBN(Vg<$X>YJi#61?N*DZVEb2{4pJIB2m=ak!*7a=&ZYS6jp< zGPM4kKO@)m8uCj_jn?kPB*{ntVpo4M59-}u8R3-dnFwtw_O>`^^cc(u3x~<^TPWS0FnbDBrdoQ8pbG)cO{VPFCBd(maBcb5!B&%iu># ztD-V$+#*qQBK-VI8g9SC=)iHn)NV95o$==WR@4>xr?wGffgSvYB(qz=p??b$hb^Jd z9dA-#cQIC>_$wiUYyjH~YQgRJgPA8{>L0WdCDPov1IXb58*%){AJP2HB7ve5zf(^l z2K+q?(%2nem2I)@#G^7*hc2FfwWMw+qTPnJ%8TP~rg=;KoO6m>ewDM$ue7CYWH*X% z?6t+lI^@fuwjWT9?Dt41l)Of%7ZQDzS@2w@R3e4vPhQ=A9KR0V(ucWCV*{lH`-&TjnvFd47&4sk)gI3%%#J+gpQ- zxU^cuCmFLk7RHI9Z#srnOjK@uKo@g+zts>-w9gMOegM59O$xggt-YYPpMOgINcQoW z55`Igl-x^xY|c=pb)7FOY)PM7G<}%Bf76Sw&2==IP`O_Owt}y!??#klle$s}9Q+;b z$i`G1s5sztYBkd+P-#!n{oX3E&(h=p#a z^k8hfbWj;vZo97-i$`}dE9E&nl2s{gJqYa0`_NSE^2{oGXPSn`Xe{rBOOqjd77Kp* z4PCU1CQLc zLsyG4N-A1pBiPK6WSHOugEm*El84eWX{lO1UN*z;AKry(wK6qg{YWC_s2vIfYWUl) z^y}{nCQ?kJH>6nw-`m!g*M3oF)l#ESz$2n}erw5y@4X40;$LsluMCnvLltOthXQ&P z0K>-z-L?e+TYl*qWbo%hDx$-aTgjVuqg>V{;?vB$3i8_s6m$P<9DK~RaM01TWkn5g z<=;>;jdC(u=rkXuQI%E@+E#&tvbfEvHRtvCfw&4t=w{6{hHfwzVZ3$tY#D5H~!GpInB;?LlFd5Z!BqXTBT9 z;+Ls#zqhp_h^4G%8@S5P9G{W$7fOs^0f=wc!mV>j_ zPbS~>hpN}hn&oxBy%8s4JJz~u5s}F|-+_y76K;Utc9NA}DFg|^s$=>;WN3xEZ3hUy zj#SOoY@b>c&-HW&6%4?Ss=55JfTZj?jvApWNxzU1OUojLF2RD1OrrNuu2=HgyQp2? z%5TyucYhyxsx^bwQ_ntJy!;KI54hn@D}kkaX1_&YA_*^1hA);Zp%Pcb$yv;+v#jtd z#7jB){!8+ha`AMNG)mD#J4O5h+nbc4oaeargFih)*)T@fJzUhb1JI)+fD!Uk>+v_) z8VLPv2g*tM<)e@-VK2C)D>U}Asv5w{557cU^wAFXs^W?DJu<9sxJxRbn5O|-EqL~* zK0V1b)Ou-;@_eWZd@w8%2dnVm$qNBs0WuAei06S*RLpVB5eu}*=ghn{Z~V*XlvX0- zDyug4kJe-Zl3``SXwKTPQa$9*%m3{M?MI<5y4E;)><};a@#jhI`SUGR-CCBGe$J8w zXPqpCZNO-O#*8AVp(8;SWK^(LxN)Bll-*1%s~CHSXZeAv5DLP5y2hgEM(|tG6^bTU zd!C*i>{V1#=;%Dln^c^~{u`n2@qSYqK3@bB3BKs{@# z^OU#Xd|^-`SB06fhm=(5*tpFNR4s#TfuiwoGI_MrPC{fYx_YUH^uQ!gbKC+o!*Shy zqp@$!eby6JllNa0!n_NLT`GQGX>ywib#fVw?cZd{%*@OxM*Qg?OsXjQHc5?f&EBIJ zm{&{pQVLZn^3|NR__bo%VY8_krUJ|q_9w|Mcd0cAPN9Y!mBqrkmA;0x_ zhIq3ocy|B1M336s`RJa=Q^qT8H8{19cVhMY&F zKR0DyV%g@>`+@!>P|$WPxE#JA$@4 zla@7~&7y?0N&V z!Jpp$%4aLtsY`6^gME3A5^xOkRl^mF&C;2idZ}4UM>#mQ0~*sqfMxvsCmLj48)8r# zHiJ1#qQo1F!$4&z#}!qdJ@g%gB})C7aEGX|)2hYp`qi{naf4kK7pt0S+Xjvqy4NTo z9oyLRwX)C+LM@bzzp|>HL!x($3b-Oc75q?RRaNAU&03wdX&x1FgZG+7i$&aW_fCVw+|lk7?bDp> z=Na6)cntRT1v|ofw?3E07E(yxMcWuZ4C7-OWiIC$Z{heDdxeE`w5_sY#WU9_q5j&} zgjL9?PZG)6#=C#UW@--#;`+q@t;#QNj`@Z|(BYs#vsyW~6kz&e6V8n8bpo1HNm72tJOZ%IHeG}@^N|!Uf4vjQchvavXDxF{z za>7eR2E^F!mGIwk_(z=NgA{UtOCF{3|8vi9i07DGRIGSuRDQ2NsS{N zI5t05PwmN_(T9uZcnl_~o9!H*!0$GLcZXVZ|NeSgIO^Bd+2Z)Y=HpjfXA2EjlEFw{DZb}sP^VY!TtOS{68rovG7bGJR$*fAjX z`g#FBg!w*z;t4I0JIY&E)F;dCl4F>zv~j4nOTe-W@g^LZX9`-~O%q0w6ShyxE{8?@0-=bTgk80;d3R8~Z#Sm7 z-%1!oWd88Rjxv6whnZa2hd;DF%#J?YjLs)|(aVh<2Ud2RW~~J|n^1+vGcO*Z)GCt8 zL40TteOrqAVM!-&qAYB{t+TH@o-?lAlGE`^ud8f+sALkQ$-Y$I@Ng4ryN7*yXCsxW zu{8_dr;iU?eC_!7etG%+*(Y{wCjCQcD$A`W^Lx@Ml-1q0zF5t9xu1Hc-5zBO>4B17 zVMKe)!f$?Hu*U^aPLIZGh&A<#vB)nmCL?CjwmP&;Y&GN-Ja z?Mz}f>$(Mt^s#4xvieVCl9_@EtHi!(%%SRPpW>UKfcR>*^Rka|$fGcNyT%@yp2G|> zb>=H!Tg3#1acEN5Ne{&;!`hzgu{Ji&kG^KT)#%5I%{s3?dw-8mCjN0>do#3xm(~$*Gy!Of~=TD34?uym`cy34&-yyhm4Ou<1qd_pmz-&S8H6syVFbj+fnunU4h zJ?YAMB)$O;ALpT4qzl*jZ`7Z)7wVIp4+r$+_ly-cL5;iFh+X*tu}b9JtJXDjWO5(z zUSG9)L@p81Ec#hh%Ylpo1nkLL*u}s?)R1Xj$pD<;v|5p$Wt32a6$!#6*vAlTEv;~iLwl2 zGhyXxgr++Lr)bZXZS9-o#UT z((aGS=z{{Tnyy_v;H!J0b?w%qq&AZs=dyeUQKVSNM6ITcK2}iDAF|%*`Q0` z%o0ER#m3%JkkO2*htA$aoMlx{kM^tbT0#O3iV%!BnF&THSN>TK?aN`3+1*$45SmlH zTi=qpTucb+r(tnHADS`hkVvQGt$ZIIcDpt^u2#IU6M`2;>a>yz=A3JIyKicBxG!ZKeIJb zGYxU@kWDgO&djGQMS`0ytXs>2I}!&BWRd#}p}21N!;+B;K)a>O8MJ*yVIDgLvryO+ zSu(!NCVlr5L?DLB1zkYhQ;>i?N_O-(NW#U>WTdPKnO@XC%cG9(m99A7YA@O`WVno? zadAXRs_E7ISjViTl{k0RkU0FAiE$b&F$<--I0VMLI!|FSqQ9;a8$=;1I%>{oa50*_ zb!RS#v4-3N**~`fKTj68RGh-4l%t6qf?S2$Xbw_|mtYP+;~5AK9GshBPQGUB{1Hf! zoS;Qn-57b|&~5occ$%ndm@=L2!^bUrh}7gZNhV88IzY$|&I3;i?nCC3_z4Gtdo(5Z zm%GVi%LE1bFxz%nf75ZIM!@7Rpa-MQ+Hgx|!KLKrNpk`xeLvbj7Ik_JyHI7f=0nNs zlIEGuG`RrCie;>O#2b|vFK~4J-(E(DckYjO7QKKq5F4D;MfUp=IU5s?SfQG9zo=+P zyk>Rx3%-Rq3S~eeGmTW%qm?BrVZg(6n$*Qd+BXnu-!%_1b3|uw??poy zCxLA50NunbakzV=`p;+tto4AS53Rf^Snjgf=c&z4##`UtB=tWK6v7$&>bH*D%oWeq z%*Usxv{KZJL>2oVz*d#oJ-(85 zYhh@r^$L6ELc-5j%aLU9jrgKmQ z2MK@nEYuz)+iQ2W^4sUGfbE0E8-1-Xk@h572C86Ev{nU96n#Wse>kcf>+tN$`@!g7 zb{;gXuChUY@nOzyP3Lpsj7u5~l>CS#wma;8M4vnieDS@2RTZZn9oGAFCsXHH`R7YT zA;y~v%|fI7jqf54^ZbU9uVEXGw>r+k`@`B+1h|atkG_V*_k}0y7BD;))zC9d z3~V)=ZQ&UWIL(-DkeAvR15`GMMp{LCUa+fZCY&2=b>bNOE zVOc|0h%(b$f4hB$b$@ty4IvgH0XuOqwkLw(U+mZEd9+qRDl3pHyeTFeKN(y489~tX z>t*W#jNOr)aDr$jq{iB^t$&*kQF~`3LE_&2N)g$lypi`XA{>a%N*6KFq-55*T^`15&^t;TBlG(pS zRKBbOa$BqZI_GhCNc9kQ%ZSc%=$RY5G2$U6{EKv|ZHJ6D{4aXAVRhET&O3DQqN8(9 zOZt8tY!~P3??o9l#d2jg)4BwRn$zbnCnwo}nGKmcC|z$9yFXv)4<5(=Ip{b6W1?j4+*oawnahS$p3wcyr2KBb1u8!k7FXMk3t$ z_x;{0nnVsOd`ByqW?FY{PEvIo?)7SDD>7Fx)IQTMU?Frrpk8-w^g0+TbekC6`-v(( zorugBNzS*qXVo_6?yRsBBh>9(<<)zrqg2BIBx)h(4B%1in1*_ZmyJHlB7@#j zhMm=&n^#EAxA}OnY*fP>>{_+$ZB6u>7@W;et5^A?@AmD=cotTpPMjyxJHi&2iC}nx z?FX_}`BU-pHgi|U>NQL5&gah`d<9!CXJ;;56;F`4j^lR$8Q>1?mrAM|<%Kn<7v+90 z$H&ENqu=B9;e@q2vUv2~yvlmYUqw}3GX19}kc865lq1A7^N`(LlXA5@jN_8tC6&#B-%ZLt%Kzz%dXu9Lik>`?>!KnJ(Ka)0OQNv zS!D3Oim6H)oW4(l7G#D;rQJlmFp6;>qXapnpd;4JeBTi~_LW+i1w4pMyD~B>$kppI zuZuO%`hwd#Yz!pOvGgM`EU)k?hAQfoFNyABgbdOq$@S(9aWjivvL&F#+5bh)A+;5I zEd|y(AZ~%2C`u9x5&{((AhI&S4|9$co_}yFT!%M%dk6{C`hRT|vs{;a853@>+CI)GW)d<&xjMAw7Lg?>e}W&jk?X{7^}TLp zUuv&hWbbRD{#@%-r`+BWs3jcAML-jLi;Q2ku*@B9#1>zHUGq2&8@ zt3&zxiRZX#DW_Ha%N=vqAiTkbaMz|NT-+#s4>FOJciHu{t~-p6H{Er$Q07BPL={NA zo(Dq28CoZZzXxC-hBB&Z78*)Ia|CY&0~dthJN6?8k$-_NNU(OEz!QdQ&gxOK9g%0@ z^d3d5obbMe6Ti+=ifu+~T(h0sr);&{7fe^IX7fnA)2EEiw*15OeAq zi}TwkBr0-<#>FaKFb^Y@@@8C=Q2)2U?pV=|Y5FhB@2JxSt~Sgc*6e7$EDF|)pwD>) zh9HPghzKm~=)5dMcH9##NX3ey3xBN2k@aNTx=942REv_9%`h?5kK^JH{GaPGKKleU zV+*%1rSUa;NJLjx<|}M&N(-w zee|~sq__xAcHq(2H|wub`|12&j^z~^fiV%Mg=7nJm^9OYr0c_%=gU%HP7oHKrdMvz z|0KZ#MEQ?k9&P+;X#_Q5&Xq&8)PG(1@&J%nOOSAPmV)gX`WRSq=}?}v*&B3B;&5rX zP|!`;%^KPLP-)t9YV>8KzZNwWPeX-324|#@=(;)g6!jewS54O~&De$EXW4QKN2BS;w!Jc-e8Kjp1fV5rRutqxno-x=vHM0#*zQX({8G_C`o^FsqmLp44%jDrKe|UYy$eV^_JRpLGQxeK6+zU5 z;q!)%W6?%=+8xXhuMLl3x71{e4I;A9|KsW=MwFsg(ux2-b3u}HVwd~jnq?RgilaD& z%uE)Z+K9YzH!X}kGdNoUt+%EzAFBe|J(BrboRD78iE1%>U=7aci?(vs zuQ9typMcD4_YvJQT4iES>h#D=LH#SYNeLd@dS0|I>PD1{Z1Glh$K}QAE?CSu;oY7U z#jB?q0D~YV@ob5)6Wqi~3z$<6tbcMua6yTU1^rt8@yZgE;WzVzQAF^5eerTN^g!G4 z#RMFy23;l8ks0a$GC))Fe4oHN2LQ{!pUJ9$uQG5-7<)R#1W!N2Kd_ijBpcr*TzfZ{ zRY-kmu;tv~<_gKMrL=)lgre6r{Qx1m!IF{ZZn{@Ii(gejbNtw7zTj9Ws{P^54c+V0 zQ6*T^oza{fquCvEZVZV}c2|bsL1?Pd7(O#xxCXJQATwMa9kpp#3PnGi+EFiVXkN(F zWt~0lF45bO{-oPfGlOVkEQ{t0ux5hF6d|KpcWMwqu{ah#g;F3YKPcnX9&3?$QD+PYxS9rfLeX@EG!878!rW?fN}=$H+^s%! zQT9yq44O0L>ah1-BiR$MT~Fc`;@`jr3kPxc7;>mjrh`@qg+jhYa3Ce`ng7`JwC!Z@ zT#x-!DnbYqU&gMH4ACiAk9Y8HB{v>eX=D|8twN&!MDzduW>i1r9-!h=O>k2n?u@h))fA zy=?M!rLR{c22;CZ;PV25_X@#g1Z_OBLyqyY$pBh}U}mh@>!%GU_V`=U4=oaxInfL! zfF>`Uxd4dqUjAFpqTCQ3ke54OULe~I=pG!4jJQ4Kj(_G=;*zXA#yPf=ixWAPAH>5; zH1z>EM*=yxXBz}qAjgL8c0&;C1^}+aj?gC{VkZ2M5{iI^u;@u@!0hlel&`uW#{aoaf;1LPDW>BG^J}Dha zY_ti~z?WB&>Z43-j38~C%c8^5vOi611(omxVJ9IfE{5_1x2_% z5?Lhj0nAX?^0B@vPs(3J)55_2D}h>n+>4^Oa{Wh{*a@n*bj}`Cv504(hMd7zbo{0N z|56m#dZho=B>KG-A`c?Yd3ur|RBj@9o0B*nZX+LVAUguZ6^vO28A(TeTL&QH7UYZ^ zqXUq|@}Gs;at^R=0mc9KSAUSdE(pZKVd)m_43Ni4u*S+W#=4sA4_k#|UxvbW!4eL_ z0f!DMK4FNBE_z#sPjIT5A%P%7{r0rFt4;m%!XMn+JF zH0Bu`$aK*(cHeHSzYR=5@FA593Lg>QAw$EEeK7zPOc~{B2DZrrYOSj0LpQ)1BJsDs zv%F+BA#&`7m?z$`Oj(#!M^DNzFt3|0z4+jgE&yl?oiXobBjY{v4YZ9HwaKu z&%>bf{5`B`&_#Q-ON)F&i>&*9t(0&^u(a|;0@&UG{@Q->pKzW^D&?OM9I3EBs04LY zFkQ_9j`eHRvKLjegSyj*iG4zyrROa}ovUE>`Rp)>QS z$HY3SQh9+jy7XT?M=3)9pQ)yy9Xo@qt?hwPJKBehs*ty@7vecu!7$Ipkhqw~J+{i* zwbm(*>!7s6phWhXWHEIt{wy=)yLT^a#-X~>jdw%t_mItqAP4e@eo_N1r8B}se89pQ}E ze?%jC0>jLU#3>oVnNep<9sf))6{pAwvW0LSLL9VEqd*>80^V0A?-XLD2LoM!V0#Yf z9pW&=;obD`U4>&+8Yr<~V`tfc@C3$3#KJ%v9)Cu7Lw`Ydrcf|w<}PAr>^?vsz=5+@ zOdQ1Xe;cs%ks;s>0l|*`0q{(*V9+dGAZY9%00hom9RJl+7?_01R38NLY#RHEcBjKY^A=q8e91TpGyo4Iwpr3FrT8BYRH2T;?3vdrC%tAG;{-Np!65(e@v#6A}CP-+|2l zeJCle?905k7WnW_38S4+(e>j=zXrfVh{)S^#-l{dZ&qlqc07{7A~}>I!=Mv!5yqU? z6eUzRcYOfTnEdoblig7LdV?)y?tmzdTmF zIRM^R-DMN|YC~t=D&~A*X!ECeafDgTc|D!>eSB z4Y9!H2w{#9zs&TT4QaOQm?E%tuA9z&i({EqidAZ{{);1jOXhQ%Kjv$SH~Z%fe(BJC;`-)7TxS_Alu?B(!z&;8A6I~ zf?EO$|3bAo+!zG-3>dFYmn_zq=zpwg7V6ADN$l%ZB*T|=K_5YZ9XsWK$8~fKPzd&c zE8~NT;i7X}0T_+MG|0zWTrDYi3=iH|Xi#%O{x>O9e>k?jW+*(AB@tmKhB+-MMGTa% z-q_$X%mz9ctvVp|DcrC3DJ=bsTm+56_ym#kz#9aBobkWf_&~}?$ny{)U=*Zu*ij*W zqx_vg32jGH;4;vs@Hb!IH$f!e(_vq8TC>Eihzfr})h(df(m1WX6)n>79nm=&6FV(n zt0d}VIJE7K=!w?6zU(aZdo)gbba zV)@mt+xbLZkdKA)kmC6NBYH8+5Co0O#3YEyxd;I+HEG+A@XuyL0>U3SH3p{iA0Wn72Y3$C$7gh)E^9YXPU zAAe^(w<8F)7Lt#;yiAaL0)WO#X2y~-lmzS^S7ag$a!$LBJ0VBrMST(h>;NBK%Sw`t zAGC#)x+U?CkS>gNbcjjGrSJZOXd)5(p99O35?fzNbz&?iagk@|$)QOs0p#6>~Y!H5jhBd@@8*?@9= zvIqF5w1^_DiOiv`xxoL+=l=zDxkO5s{}-MAL+bLFI+78DIFA2=X^#KH=&vsNpt_U# zL)gu7h890WD)a_&U>6|H@JO5zBMeSt2i76Z*y~Qo5Fa@}=H-4u-1+%`AWeOOy$FCl zt6gCv#6N*YpMZCw?5|ryK*+C%4+i5A0DVvOMl-_xVl$wg^S{<*7is11fWTA%Ho%TO zk*JPrtPRaF0rBS%@O|S~AHPjZMcfrqwyy}$7I2aEC8fN1EQ|cj>JQ>ZuD#cW=f_Rj zMY-8o4bEucMO68#-tCIp*0mOU3u+%nL2ELJx_JwM27K^a4#XM&+nZ@ninwXteBy#D zJo($u2;|ex4cp-r@$67BT59F*%8TjSTswapDAB*qs1G**=_z+iS$z1{d=>dw&-#2^fA-t_`)OzIw(-i? z!uwg-!kN6d|5@2Vlf1a6^GC_$^Y`O^=YEB^d>bvWTeNZD?>~pI(ngijB&q22u651FhB17hX+QvWQ$C zKH?Ji5bEJnJzw!xOg8Zl**C;>4zRcD$)b6(Z80RODo(w|E*?^UGHA-PfThy_DPr|5 z0b;%uC-1GgbED12WS<-XkR_c1;$1-A>yZPIG#T-4(j;Pj|C^%+IAvOMq`g7NzzYyP z1n35NE5uI>CKRUuW%gov5MUreM2ub3N_OWt2L?4QC`AUiDGFhT@g&xIvFTtAMh^&d z4H6|7r^bT@Nc#g;AWOsiLf=4;OOB*_rp{wynj&fdh9Xk{Hh57z10Xf{=c^$!el&%6 zc4s!ID1SLN6o{UiWSUa2YzQI(SXx>J7gU|1@Hm&s@{Y%r%8NT}^*&*66D^&7D9H*|+xe$sR4YjrVH_6o&k z>RYtu(F9bP#H>+cb36av#cWhBXR-LJ)C#Du73kPmV6@|0m>)809(hJ9J$^i~`?XPB zA9vM5=*WP84!-x@bT?4_S`g_wzWXa!)wTazHnbGaP12D-+Thx@Ki+hrz(mgg)93-~g!M+9EhN@Fmf%icn*8@yp&My5^NHYS7&t9!~Xzi)$USNo=R-J9@9MJVk z1M<3`0e$?CYlv#j*2J$x>xB@8VYOi5qeY9U)66k`S70qDWf)Z+>GHhlhZiCe@hxlQ{;a5o52i(!n$eT;$FkJXdHn%E;!+w?a$Yn`qVzIIkZ?(D*XV=pg5GG<2 zTuxWKTVwZ~_+|~<6XYEZL4SEp7^JQ##Z%$ra>nw*NK&0MNhJI~rLM_@(sRX2RIv(A z1DSZDOIBbYApH%1n}1QnwYn5xmPYlpP22woDZ|*bNQsJMA*&YpH}eEFBfp6JgP3%| z>@u{0iy(3D(z6jV;2R)smd#6(dU22M=g0XKYFj$ROlxul5V8)*=f62z|Y6l`moi6RIFPWEjq zF4%?_C`6y@g~{C#;>wcig|1TDqiQEvVoDr_8`PX*;aDeK3L2&3qR%zQ7VC5uT@jtd zw<4wbLAe6CyLzG@Xei+CLiPe~ATOo@A7Bt%XF+Y)#1s||6$b~?#}Md4ousK4620Fh|X1H&Z85qU2c{1h>pMR8NinWlsVIkSSOQjq=9$f zp{4}>9)+dR&KXNE|J`;VN3!p70B~L82pXDq#p?e~l5s6u>-iWI(6OGw%$2gd(32nv zh*mFn=d^2V0>yM-g=WNiC(2&(mymK>6BT)a^r6N=mEuLxLy5|djDE+khsiFI--*Ku zLnp8a&-`~e5&qj>Ec99syky}u((pVLbZT-!T^~xzNgP#42wHGocPWKz9LHabE+=}_ z5~h9u)OP@u$6tQTCJ67ZBo0WW9~A5Vx-It*7VfGE+Zlbd{|^9WK$*XD958c&rTKhBIszmP8IkZGAH5M*?i_S6v4aua;^SjD zBDKzD+XL_K4M{eFm@etecfrbcLEf~xz_$ZZE*g;15ZK=qQ95msXON;M80QXMumiH2 z_@~!tW7PNunL)PTpLM4_q?jRM<`gq0@dT}Edo=4~8u8DX5D=gZxN=BBjo}j5l*9;F zxfzWb{{VaUNKViL0If*`upX^R0}TI+03FvRczhKkJPQDb(EwntJ7TKVy*(;fceTpD z_u}d){k0Rg8`l&xk{*Wz6vOgWSL=uJbTv}CE!9q=R{3_4yJ$(T9%=KeNd`?@MQseZ z4UR%>Z~YR0{VLFufLL>XpaIcE4p&j>(Z>vdhSgq^0x|+5270ws!hMri_nv5msJ*G)Ew0HYWiy z2vVFa17sZ#JvUg=$B;f|q(V=WDGoTCQKN1T5WhlLGX;#9w-I%OI{m(xDF=D}yBh{toeXxN3LWIF#G7 z_Mkrmlz^%7Ea+nmtbrdMvUqEv$U$w- z>CTzRZbX2?Uia|bTa)aQb`wL;;By6}GXMhFEf&!0wO8H%fu2k(_(aWG=pp*lp$-mN z-+*^fRm!Rw(w1X84RDLFAUJGutvb?9>hX2Qn$vn?tr2L=7YHjXJAh`;M(Fb8U(xa- z&kA`~$g^4z6d?2v1_+?vhJXXqHyQ#$MjisvK^~1p0|FF;8H1BmyN%FA=pzvB9I_ix zFv0ACj6b6x23^h3aAX~c07a1nCQ=BAz6X8LMuN36t7pc$GYED;EQdI%k{IcR1E2*|TS zp4C$9kuCy`oFPU&#K?!(A*gROLaX36My1sjqQj&$>hM#8 zXp6PjG4zOM(BVpy^A3OAvKHVASm^W-=r7>3gRMw22QGcp1*~+jt-46-A+3kB-fB(s z9)nGqEo`)Pzk?YHX@=-pnJIJ9U(5_?lXpg>n23NiY|%H?)T4E6q0|jK=qNY6`vHV? z!0&P; z)FFe=;|ERI;Xt~~2sl_)ts%l3VTB)P43LZf_yX*$m~tWMvCOKD6FNBl%MT54SoGzA z0eA&+>f(2IM8He?%Q{7Rgqzm#IH^8L2J$#TSXG=T3;uqh-{oh>JGMdS=@@}O(P5;s z+e7GMAArOMO2b}gBY~)2Cd^n75lXv*q!-9G2mFBS1pnWnn|A!u!>L3cOVGV5dUdv% zBPL!2Td|zkfZ$;b`4loEJUlnB8~%_X1&7ju)j!8iG)w< zS&QC_&eopTrKFdFNI)LO?;(Ko9e{-(!2}6P)wixb>1`#7t#JYR_Y*5eKrIbES0RM2G>H(;l4nXWo23_Yebm z^Swl%M>Y!&VM!loen}tLUh5TotZ0>xkHk{lZks9O4rWB91BVXj1IGa=<+e#2%yh)r z3(yW}O!nJc>mty@7wiSkTal6^J&)-j3=oim5Ghcs*O`-wIX#gkjF-(X%(;H)4`V>6yf-n86MywSYJv{)uAdEmB`?5}ig=ZxhGcnv}(xUApV; zjz~>m(WmQqFWG@h?in&M5s5+|3yv}b znxHK&xBC%TH(+zlLDC~z2O~f($WrzoV%BMMu{t1nL4mIAz+*3w4@`0!>qS>XfMJ{x z>`4Ue1~k&4m2p_vSv z5KfPl6m|d1NGpN;XTa;TwZQYkUxVAf7VpWOQwi4^99N(=-!bwI2R6TW8*#lwz#kn; z{79)fMP}xyF)Tef{>7)p@e||sL+|+8T^NX+gikYepyu8}Z9 z_8A!np*tjcmA*tS5Om&>$^%OgQo=t21lm6!vw+LYGh=}LHdx{V+qE;tR_p*2J0ygD z$#K$~_Yr6#E##)fYl@!_Wz0_hbZOtkoGct%-i??Q#=Rj_pdog{`Dt_ zc~Bq>?6ZQ-2*ysWFzD6N#`ph|AtFK){JGz-wW43ZH9$=*00Nj+1Z*ebk6K{#{%3l; zh?#Xau2CiUdSG9pn!BLV#5pnR3j?yILF&`9C8lhMfXSlB&XA<382@ldj3mw$oHS%M zrq?4L4vY@qs5ivl;T#FX&eP2`uq{v@#jNnL?lsvvsy=4Cj~xI$rqu`Q*I$BZ16lz# zXaS567A=4}X(tc?&a@NOj4K&py@wt2XGpvcSf zZ|CUkoO(O&A(C|X=U|}cINRo6u;=LPoHXU1J9IehseI2LGd`9^JdGk5l$jImlFy#w$ZGo;W7F6XD3CjU}kdhl+!XN_OL!S{y8=V=U=_24i zk6vVvHak;mN3YSnCAzny?kxe%OPb(ikM3|#1YKJW*d5-mwIt>cU0b4S%h7-o-%$=k z$#RZ*<|_o0qN8((&Mir6aEZxVE>Q=lMbbNHfl@%g%;R(iRWm1L6mb0Dty@5{2pt5{ ziYKdbpnI_QSHlIuiWK0Hh^1U%1Axg#K&Bb}Mn;gOD@@O7P8u!XnK4BxOzH|9SYaks zOQc~ltw^zxG1Oh0_x&X)vXBv<1u3#1c0^Rb5@$Zbl5|+;5{L|YF?xbDED+`4ghRkl z)x~#jfPmjUB0TYXi0>i3hxi7Fw?PoJ=g2e1Z$JpQSAgHk0S*HXp^t#?-kh}7R~{X; z_y;rw-JExb*uaG0pS9N?ElF7&A8XQDUlS#>MA;tc!r(`TR9=Ww?2%lE)MWZd9(V{8 zfjS5CE94N-15Bb^zLqeC)WHl$lIZ%MlA z_#lOqQ5zo}`atufpM`(us9PZ*f*uKsP|avYSx^m79bM|v#onAQ_LiVs76|x@ZqEkz zJ6L%$dKJL6Oz2}oQma*y3qraJy3)r7P1l?hZ>WoNl4H$Djzz>by>P@v^hl`+|19X4 z7e3G|Z4CUg_Li#wY0ZGI$2zRpG?LvDdKHP^T{4z|-)Lvu!-Vu^2*`_NS`R4Dn=sJE z3xs7Cf&S9_FcQatOkVf6w1%ESw&?1U~_Lu^6tGANDhLoY*#{-Rsb88Pbk7!XBLSb8a7jr^5;{`mH3=K( zWk3%|Y(Ux~0}?%w#F3s7ESEFlD**VUKSG2YD#gK#Kmy4b!W_gM2_~rnIJRc9C1R<} zd`=?D6~da7r|3p|y&TNC^eO-!7%BdlVRgWw4rvxJ)w4E9PFHI-E>f|_P6HP@AoCY( z1bPPG(K7&0N1Y`CQoBe1^vyvy0dr!lx}@vhCGCGgp|l@RY>9PTVhKTaf=!(@Ij;&3 z<{WX4F4hJJizXLH04kB0B%y%*IbD;nSC{DM0+Rvc%(zVc$Y4!O=$cmz47Q@&C_`WP zA85^O8L^3Yc2|LepLh}c(-9P*!jjedwu>-h8<;n;9mzQbLyzx&KYz{x^a9-vsV|6S)8XPT>AGVf$Z6*!GEH?T`MOjQwvi z_J27UOYcJew6!w`cE?UM~W2guxIacG+=N|!rIg`@27n>~wHcwC7CF83*dydN@pPpzm zB`Z=^#UhSw!duZN-5#5eq_j=yIj_!f3gr%Nsf$RzR^tgDck%XTk)k5A`1W=u^OIwv z)X)3Na~_q$pU>p*M|$|l{AiNB@sml`XgI=|8*|l_p=;c0wQ%Bvy>r^aw!l9d|62?? z3bQW&?MynfM)#Q``cqFki_4FL`Nljgj6`{fV|#w<7cy`Ud+uFHN)TPU4>|Y)wEV#V z6xJI1bMBc@q-_C18q1Q1-NPYr7#D~Kj#UrIR`c6y{M{dQVq8cfWDJyjrJ3pyuYTwyZDCo z8PJCCP+IOUQm!V0$w&eyUk7tFQ{Pz6$>~SblDH{gfTAzcrgw$uKdGIarOl>WfD6ic zaKHFK&?mLB{ZZHs)WF8wIMe5#{fjex$%d%#S*Kv|;C`&|RoI$*z6*C4MYBnc?6!BC zWR?NpvGF=dqd`-b{EwSczhxsPT~w8d0JFNB^qY6lp0e^cO>c}3-v`)oC#w>1PCnPm zmoE)A3D%FM&Y47~zTfnw_2|v!?5w`=Bgc)&CoC(1n3&wfI^)%a+|h_z`D%L~h(b|K zvKm%|#yyu6ba!WG8#YXq^mdcoo!{(YY|hQ=8|M!ejW%&(*N!x;N%(eoz=Gn^07vn<;%>KD5F zeG(#Xa4kJ1Z{0iQjr{EFwLmTcMq}X$n2q4Uy%tOTOvX=seEw;(+XvcvCJhw6nq zq+b66=iO@u8(;PU%bNv%i<6&CnqC(q_tI9@w_wedn4w#Ir&bBxjo|)caGm;>SE5_Q z#gcnUMS^79!)0)p5f(BFoj>f;J4OcUlE}rtld^MM75SI7B3cBWQl!a=dC9L6;>?*R z?pRMQ)dH3=MPKh{TkZ#&sz9X=+%I-oyV4`U;gr3JFg^(XEox!u!9Qa5xC2Zzm+gdLr+;=pA@6Je0}<|H}wg`aPb7WKqW7}~cf zLTece;_%UMLd}=M$Ox+O%Gt(I7DoGEB7K9W54$j{=kjsdC}k&43X%xWf^VNbg){JD zjmT3zz6`F;HxCcHFZGysC5CbLKp8xaiXmF&j;8zZKH~D4Yk8j9t6Mls$;ml-$~&NB z7Si!~E}D>lk_r%!DCaaL5KoD+PA}stg4{>mQ}NU6uUcmA!(2Kr-yaSd)BHL3@;Oef z?d_&kW~+cx=Hty}evZ>UXJQ%`8|cdRH=8LMf`C*ekqg}z2wH$c`X-*FoL>-t6<(%S zTms@N2y&LVrdf3unFc~4*5o6G%`BR7xkkHnhq>*tN>d*}77gM1Uw?L>Jpb|pjAY&(F; zidFF=>5)B{lArfzyOH}u^zyqf&7PhvubgoqT5f!fg#WA)Dsf3(!cq|7)Fq-dnkkje z6#Azj(?E>J2~)d@im}wy-VGV6SUis&qs@IV4qQeJ;cvQ)lVIF(?}KbJu8B5kK$mj9 z!fQV#sy#U8+s$r=lm8)!vzU=tIQ8jV^LIG`FWaXdfNZnP@8|oOc#rH36vzo+AdPom z9^%`2?b`^03a?L=)Y`b_qF1@NlUgG?sG35H31dXh1@RT^>y2hlB=sW_`Hwd^k61>@ zj_P_-(Zll%`;EhclUp?^t>QSPhqwf!ZjH^5NIbdUr`gHJ;N%-#?wgZ1Ir)a?|As_~ zj44lncR-s(TiWGJp78W!RK>H%nl=&7g3`cwoThtvI%Se5$La!0dW~qa>_ZZyOrjy^ z2T{X>&7hzit=3tTs)0_p4V@u`DzD@1{$5vxGl4oWku&2PGjmGyr*{8T&q^yjxiO~d zgx8pgmWTq!dNm_P8RIAsE7=4~>bDp|VZ3_FnbhM`U(B+^OCI(dkHHBfB2WFj-8m*K z=iOs??}SC4uwu;HINJ^k7OTh(gLn_sFWxh{3Bd94^i-=&($68`RXJ)iBdSexiuu_cC$4D}{M^31na-%Qg_F za^UVAx4aRGrKCoFcCQ+~-Rgm{O%paO0T66h8xAjWN^ZnY%-1Br=x(Ov4Vw`gXDoXR zD)FY7G(5MYr#Dwt85~P_+!k%`=yvD@H&=B362}k5uiz8F^+RwUW?7KD{8mZTmOds*!vIS+{f zxo503(bJ*6tdc8LNg{1`;e*WdQ@j*dnA2oz@i`&Kra;p?GGA4-5}PX$gssPqL{5<) z&;rvuMIV?Fj6g0L$xK!JsW1CyT!k3v7x`py=m8|TR9B8p%%w5Nk{&yg0^IWjmMi9- zw&dKTWm9f$gh@0_eAbCTwSE{U{?XMSYGfjLGBz&>pA)0w6erfn73NW7i8 zIqE9PT4bGmASh}X;o422$TKZe%zf#7$Kyfm`wQQ0h;B03iCA~0Vk0vV_x7p%XEFuFP$vY56^%qp^n!ROL#cxPZZ#3Wn^aCi=mvfc*CZE($GfBXuoB{zNR0ETL8WGzd#PxHdj zB1sA0xqqWw@8^Ymf_=6?TVNP27$-?)4B!HIspCZ4{Y%&uZ5-*ODw*qqeF`Ccw%hTk z5SOf4aQ&I$fdUc`4I~I~ED>)Bxuxa77{Q)T2SpzMf16EB2>o7fUOUCLV`=3==_GjA z0e*r}xS0TetQ;0-*5v*!N-lY&D{FQOVQ$=(Qmz&4R5Qamj*d!T9+frgdF| z^ZH&KeXmG9EGx*S*`;?irjC^!3nJfJroUuf71%RwE}GH6$ zTca-4IAgJo!e4YeVuhyC*dlU_?t}M2HYr%N1|}6-%pUkmG+t9cZwxL^w-n2Qe355y zF){cRlV>-ZqvVXrMZqvFTXYFBAd}fdg1}~<@&mJDZOpR521dFJ7(Z*5Ny~SRQS3Zr z+#6CGo-t6lUyp2QzMore9?uxH@Tkg}G8tE0h!ppJED)q+jj!W`UxfuP#wz)u#cepr zlfIhvbu$0bLX}27$6#>-Ti6g7+>FEZM;;CI%%;(($<^(->}H})|I*r4x1q&JQVcLr zwKT2KM0C-08D07GkHxB6-E^dUSh5cM5I6!;Qh@k*lYqwiE6#c_wu;6vil2n($#w9M z1Y6+u>+=)Jn%xB_Jj;47An)Wp$nN56CYuX3*XK3sG*a2>9Q7L~+pq4UQM{^;Jj=6v z%w;qC$h&_8AG~B9Me(v;7Kx7sK})+Qm*0Hjo_zDol~XaPW~l)5A}G4rmEG|p_{2Z~ zZ+uViME0SlE>z3fGmci|vzz6rK&3nYClGsR_!Ou7jTb^N6i=`qvX)& zRI}-d8BuhFhL~`E|-4OX3q|l z`<&zaD)6*MXCC#oY_n`G#4&E4&(Dk^W21=FD1_W!j-r%^vWv0@CiYNs=WGd1Hf~?? z!@z30VM+9}LrGYF!e28KQIzCiM-X)GuztbzYte;hk-aX*rzE~9%Pc82zl2dgI}0va zbaE9oGN3*r8Gh5F8)tl37$%h11$_G6Po|*h$0R0CrY&ox>U$+-y79RnAaqlA?{1jN zaRqnq%tGA=sXWd34O5c)nkBm-c-vV^Qbr^dQ5&BvcA;Fc7u4~eL&pjgvo7mw4Uf=k zdFKUDbkM-Vqy~AQF>jRPrzf1*G1K7t0bEL^PypZ34i_mK!U~eHhw1A6A^TF7+Vm%Z zyeURr4Ks>a(t7tN0lx+|WIcg^HnoCNfoOziNA@Rk#!L&D{g5JfJ)`z%Z>ydKrs`RK zC78yXnz2u4@@Rd5=3=r7s=e8C@@1_$D=vezUUmLLie`~+!b}d75v`|zy1X5q#!Pc& zlLY04)(aZNTe zY{a><%}<5;?uKhD)gNChjXip;_orN2u|GEq)gQPjv%U^80H-MLt>}R| zDa1gGju=Ty4LH{q4QEqzSt ze|Ds|j3=w?!DKMe3oV4SpL2@fT+K9+jheTs`~~U~&4C1q%$5KdoMaM@7&Gz8ArfdF zX9x}~q16A?O5|uP(F@j?AE+tq1%z(i*)w5pcKMe2CG{$zh0po-Wtt|E>&pD zHKm~)6jUCal38~nQ1(==e0FuR*3(OTezhAh_UC*brFY>CsXKWk>uRXdOS-G9B{LgO zpv_thYuQ%;nzdW#N7Xu>oo#o)Cb8B|qE;Jn)YBjJjJNV;M&Cs7bvKcud0qUD#$8#9 zISqawNol(-b7J|`7Xu)9|7GT`lF7&k&4if#lGBxX#f0;N%E z`Rfa&{gKv*?TlIbuKsM8Z=kIa__8O{n=$5F4SlB)Cc9>H;$-L7$>#GrV80!^5PZ9# zGY!*xbGf5eI`6hg5JX(?5}Cll9>~ev6x+M$9os3&sE8luc2aO1W*^cZO)=2dH}UTJ z18vk7?WY%Qnf!ANPEes8kfIv^TF#_`&}O0xpqs}6Y4V>qfhECi%Gd?uvNK+oKp`sw z#w%L=QwSU)CEt!r`L;=t=}M)TiXxENOd)xr?jZh6R-|KX$qs2Zu93{|dG6F3M*dtn zDYMg4+~te{$e${@x9pBW?piT4^}C{P?1_tA+9;|B)XnuZ^}a+;cXLnYTwZJUjqcTt zTz?yt{wTF_`M1Mg|IlKsk_5Yx}i;^B^8zZ z)VDicgpHq)FF=U|5dM@-%?%_y zJw>^>b&M62c9Yl~xaNGgvHn5S6MFV<#(asF`bsFVch$qb zJ-@@__qAc2Zbpy-s~UZCJ6}wrTU@(bmtVTb8EWO{rhtMX$ulJ;8j7waL6h_P3f#F&D|eHU z7>HI}me{2l!GTw0pl5~t%<4`=xd|zH8Q9lo%sQ0Jmq^Cm3N#xN+H8!Z1N|_^zp&K< z&yv1O2Jp3PzRkmj>`jz$JL{%JNf+fLL2?PRZk6>zc@>3U#apNx-saUBwkaaIFiN#4 zyHvtL>?fD$6*1eWCRTQm_7^SNR>?+W5VnJ)-3|V5;p}X4N*~R%*&e6k%|+|!X~S{v zX*NyAi1)JDoI9t@Eaj-GqIy7hNz3Ep(ZF<^H`|P@ zb(JvC92Qr|xKL;RNy#`ejn#5!RiU&iH?shSRPZW!AY#hp>|zYiEO ztzjWH3Lil89MOyv;6oQ7mNexe1Nm|pY4MA}`pX9|msb^g*Pf&nU@hUx%66|aG3=$} zOJ&9zFyaDOxzKNhvRrCzUf@8Gfgz*+1j9-f>S~)xmW^NB%yyPx+y-GZ_-DXFnv^1rHl$}fr)-?iqSwHDvvDp9Sd!;=2WdgYsh($~4F z4SNU%GxDnXad%!-#j!5pp z(l`EIBD2k#8!dj``FoN&qr1vd-kZe2V1|{wi^SoEE-cG?$=R80c<(}4Jt)}ZJ5@aWO_J|X)$I+6zwy6Sfz_-PgJgoit8sv=`r#kf9X^Z zm45}r=@y7p>kjIrLiD{*^<>x7z7#sLWhZ32aAW+`~+&~fvOK^c$AG4nUI zZyNa#G`^{wh}b;ys&!x#$5c3x)bs>)udD6|jQfi~D-AMr#3BJ|imoXK9d$z6J18tg z?i#zY9|7x!Oy=@uSv`}?6Ikvx4{5Nt3wPH^AfGhkV%kSYzL6QdB>}0dUp>h4?B=`luO@eBMO&a1x!dO{n zvZu1@Xxwb8Q79u;G02y| zctV!HGE`euzu!s%vg8<4zFFScaC0~mZ-<{d-pHKg*Pd`y*U41}Xqms3mmh`#q22Q7 zniXvW+k$Tcjj^qq6y&Z_0B#CeNXinHNLk2ACO6JzV*~D`;gPG5fi#LWIuUmP7Bv~s zrGS}BT=iM`q|DVcippT<+oHZU zm*38_{mr%@mig{u71)yvx*T+zrpvWT2qWiW|K@0ms)33QbX7V(Lv9>(my+qRt9hU~ z3CriZAU-NMhmfYrnM^4tKhpH;$g(!53aKif7^2Lt$eI^GaaDCrjU15@DR4L@hc^xs zI!ovc|4sfN5yBOnh!a6$G-EXKFv%jmr%&m={P=ysEBV`SHW6)JG*7Pw2-I8q=qz z`qww+kYJ0PH`vw?v!<14OjyavlFyLZt9ASlyv8R49T^kmMEXX^AtiN&;1J*9H*^Vr zD6)tUzLb$9A`FodX%&W&Sh!FoRZc>lQ6>cDOqSe_8dq`u3x-qD{qjCi{{m8LSj77Z zJ@Y~@vu4ona+lSSbw@4k3+Q?}_Vpdi-Zw7V8HT*@i9dWpqu!&l(*%5Eb3bMy6>bnN zn3|_djVYD>kea6)l5{BbO5EHXHzOlQVr!M?=xW)uK?9pc9S@pDD(WsBnMZO_GO^xJ zrqkFD#yB{*)?Y>saN`nAqYxzr!KAE&Qw(c%D9>@MN;0n(V}a%J~ne>aQsQYf^=Rh%ZN6?J%l%5a7~WgSWNEa>6))n85`rNA5AjR;RW$h<;x~qC;-+=Scr1DZQTOT6U_Zadl7QXL@=twu|wg>G}OfWbv`R zM(Mw1V+DC*1BW6wr_WuH6RQwdDm&sFXUaNR^;R+t0=1ipgAg4GetFnLMK$DNMYM>= zgqeXQHc^J5l!}q+Nl-Y`FQlypf(dX|ChRmk*W73MqTK9{k`1f(6na=M#z4AA0SWD+ zn+jUT4avR}QJT|wBvj;?2~Nph$j7H-t^~6VaN`!j$s%C1zyBB{wW%x^pkSp<3&2wR zxfU`9AH-l8#wW=7C|z`hrRP0!e!-=5nUe=X%ZPpIhvKcPx`543W<7P>^jI?oMwN@w ziXsG0Bv|I^bVcdAVfk)Ksw9LV>mW}sDCd+bqa4db9tW$uOK*Ho%Nb(~|x zmmx6W=1YlD9qtP#QEJ7BDRibsPck9&8Qf^~W5bkSq@wc%uN2HkHxlf=I^KdssnxV3 zlysr%xsL6*p#Du_h~?3K!ewr6l*hllHlY=w&>=YGn;>q0tdASM)f>$Y?_Fl>+$EQF zhSBpQ6JK^J)m+JK(9o~vp1alCNKL@DGahRbmt-=Sy#I1kP zRbe=m{`mY*DnLm=V#9i8)NDHAV-0Zw7N(x096-YZBQvcZ?L~Db2m#Ca5nkeG_>xhhdKT{QM8E-P-&2=QTd%5#60VUdMF)p4)Ce<#Bv=wy~R=@SNIZ=H4Km3xoKP zdFtHTWOO0dg2mUJM%yh+jp%37?xI&MP%F7jC?QX6*S}j7G9&p)RLQ%GN_iWE3z*j{|PNagc#6!7cM&_&)Av- zpdaR5<&6LV@okA@=4z3i#OM7Y7K`zH6-wAm?OjL_QvHfvni#T5lB3e24&^y0OTL(R zN^Uo{!|BCBOn!@tf;()+EwghaA@-pvPRm^H{r9+PEN1{VG*Y_sq(x#(iy98W!qqBz@#x2UwB z(iw?4!*UJ{4IEJ^w<#h{rb41LM`LXq5ZKmlt{=*0ArFjBNqK(S1SOF#sHr%o90Ur{ z1+CR1Gn=z`QAjV;RnUB`Uh3%Ath7F*f7m4EA#D@Wc@`{>cq4!UdAG-w7B68A@^J|n zh!Q7KLfYEumL|Evc_c9|k0`^r3CFpquMlntsb(TtQkn*_75cFwoRP=o#gq^xE2a2H zMqiDSQ=y*Vaw`rjGL*P7j&v)FUAX-@H#Ky_eI4I3t4ZQn!Q)n--*LvpYJU#CxSQP$ zKet)3!!PpGNA4^sAq_w7fEiMxZg!OQp!66tBOzua5NbZBhEK4JOcm0Zcb+EO6*ojR z2|*}<%K1R6)%?r~OLwSbPa#eJvbhgP^Vay;@M|YjMj+yvqmGMwKXOx`P`tGyIoDLh z!InxZ;FW?*Y!`3edD*=BIf%S}Np? z2JuW1mC14V3djbcfUMIvPf{0p8du6rT~Cq(u~Na4YE<^42D8gXi{ z(5lZF$IQ9>hM|NKLdGMjo+YGDtluTY1@^lDt>sL(pj*?Jj2g0`t0^_bQuWL+fw{Ol zGxzbpDRdL|lcVdCF_0ojBAflEr{r8?Azs&G<{RANq$r1(W%VjoLk!Rg&>srux2G~v z8@_n{{d&V<#(D8#^I}Gs-)2RuSdnQY%t&Qs{UrEQ9^qxPKo<>k3qXs;T(WM`%n+l? z)}@^up0Ol@94F6E?7kF|J*!}Ds3bb-O{uikL}?;gc=I~Xt0p?>pIW|-ndI+eM0e~rPNRH{do$e4VQ*rFSK6!>IF%U7Q;7F-ld=%vgr+ zAA-or&}JEIjwC z@>xHPZEZ3f#F!`R7%ZF2m`^6FVQo+LIUxcr(^8`r=jBaHFwf>9oWvvv{2 z_;zcL_U9~|YhwJ!6PI*D*xo1z88SAiDLQkd? z#13PwY^=seZXcEYM2P}m$@cvJb%5GE15gGK{f>a8fJx|%i|IG)?FlG*vy(b=IUw8q zOMz@_0a?Qavb?KMF0pg69c5SE-SVW;8Fk8Rx4L(-Te*pL^0q16 zhrIYmpgBPJ12>r><)N>xgKeBJsjCqQIw8uq)l8h~>YPWP3X%6L;@fNAlk&spI_9&b zl&92E0EQn?Pdmq`yCm6LPrbzHsg7ZBuY&$pzjkOav6{R3M8+crT) za7DURhNxU&3YOEhjH4KqdsCg@O}Eo)PftB^Ku4dmhE*%GHxi_?TuvF{;)6N`l^jVN47EO^kv+@lW{{aHgr$s z8>(>(Rleb{#p61yUYEz=OVl?SwM73$qdsr9+eZKS9OFyH4f&jQJDonS4_`w*-fmaU zU$55|_2J9w%Q!JF`093K+=%zD-x+lIIQrdokI#L-*Xr^%=xZe7#Cr65UaK$Syw*_0 zwN+eO#dSm*z4p)(ah-w8*AuXTFAt|_-g7~$0sN?Y0cq$X-X6E3@hWFXgL@_jjybF6 zzdzn8+$!2KVyrzZSy~k#u?O3{Ono%18+RSWaoLCqU6lBf)j$tbn2G58ou+bXjuI-9 zLenX?W31y%#SD3)Xq1%VIw@Pc)h%-aF@+Lf5*y^kDUxpntm>3esLUztk(ohVQ|22j zy#ylnX@(yu;gjQyuWlrwMsjgMa{J&iyyBL6QYZ35^j2C%J*{VNQb)gY0s{$?f!rM)>xuq!}qh_~JoCF%g zn0GPkA^nsIB?UB`DqnFTA3N4r#z$KZo9Ru}T&8TNT|d4GBQQ0rJE9B9afaH}$CoJQ z4nrOA)n30almAAHQz@ELsYOcRoQCmJOghHSQJ4}_VN!Ks3iDA6kd$whAT#EnURWG` z=WS+l_>M909Uq+#Y#*oDgsvtZvFTGnkw+B;)vUbK4~4mAGPC8z;u&ukx$?qmM4^J& z5l!N%Do6vtUNiEB`W-b{@!f% zI}5BI35v%?D+f0TiZR#>R@9*kXI9}fbEimUr(#zOgtPg09J^ApY49$-p{yWDr=*Wb z1%3=3f=yPhoz$$#fSGXWjcfmB&Dh(zf-)m~f>*7RKt|>>&br%*3i1QjdB_l|Btim$ zlxtAVe+#oaO4QvF-96f+jOVetQz)40iYTO>t*}XsA1coUyYKR%>3>+2(ap3n;`b>? zJ|`hgD(PsCdaNRkjYk!=M^sWc*F{y((pD%fSLl({q*QenuRQ;_Cjr?~$&5)uz)m^JW%?whTq zofXD_wV9TT_sY-4IAek=C{8$C_5A9QTMP61w1Bnk25K)!!HF!(z`FsZuz0h_nJ98F4^H?pJu1(nJ|CoNyd7)mPW*p9^Gr!qIJjgeXo-iG?VeH4~f zoI47Q>Ytu2uS~RCQM{zv^~)=RpwFgo{p0)()B5{l`aW`A-va~$G;a1; zEK6sX-qpAmO&3pklz#&x62*`uXdHz4v&bDQ5r$DFHp;{rgG-2~XKJwtVlSJ0 zm5aOU$?1iw7voZ4Ad$VXY~f45xjcEFUA=Z3GqK@&s;hcu34mcwY^o%HMjlJVR9d!F zqGr}$kX2yD{uUPwml9r%=PGb=`NBnBi04o;<{yJyyfHkE9+z4dW#2+KHBWCBo}Q?F zGQQEgk*2xQ28-G6Z?BCQakE;Yx_NeH7;F$1y+Wz;*6_3K*u0hy1dFv3CvU(!SUqgA zJFcpd(A&VAy2Zrk|79*s^G)T+4Et}4XJ|ZIaz$D$5^Gysv$Jubx_X6qu;z+fhtVp& zWr`>DOVU801H)9yFkY7NQm14&K+X)WyV$eo^Bo%p#8p!YSxI3?PmZ6h;D=(FIJ%S0oh1el(SyhuGY7%R)fYhf3g>JY_xv{&|onFKk_ zZ*2jOMhsilEjpOF;MjX6V+Q-Y6Pasw=mS3i(nZtko^ivB^S zDCj`~b8+!g{7$;GC`4KB{bH^ia!yx|Z-eYEzNWr$JH(X3xS8b1CGSMJ^(>ME?&&#e z;i603JPN!^s!@`(BjDELyaAL&3BYFonwB?t&>G2o7}5QU>={qscOSZ51;|##$rr0~ zU+<8f!mcK+M4|wOFHwn(RMZDi#pMXj{A&@@#tj@V&R}AUxu@jfIt$Mvp z;@$42_`%msqu;5xQhce4_;f0S>0dT~F^r?7@g6MB#oUXDQnf%xTXeg6}N0OU}H!xFW>&B!G zdE(p6FIKTsHz!_E7%{q6#R_tsWb%DrdAN}si`K|znQ#*{tw}|uaz_MonQrv+f}gWi zobuAEE93oEU~kT1IfO`^f~ThvH3Lr{gNETYYp_Ole2w6~3xSwS6$C;4&Nx?_YR_mn zy$qLI@o&kuo=VM7m~)*Ph7rb+ohG+8%B!nwTbmozCIiG5vGcgmRumd+Y?}*zFLa8F z4K^CpO&%ihbgryD(GOmn-C@&RjsfKL4CxLTfN?43MZ)duQskj9iOInR$;ulJ+n$nL z=$IETqga6@$IEJUTer=Ku6{LZ(|u5$6=n3`pOReHeGQ<(*{vl}_iSpI(2 zMrbN17wzrcwtB3F=(&-pU&NcHyG0SJ;UP7&O{7gCH&P4sFPLYt_O5Pc49nIfb1X?G znq>Bh^w-R>M|1oyo~YDpzCsB^B&tIr-{r!q9HqjXn44=VpYWb)hi7B`tXIVy>+^%NbW^;;uhfeU5PscsK{tveI!tZEvnz-el~{ z3Y5Q6vc}Aw=?hsBHwnS%Ek=IF^hkkq>R2IJhV0VDs`oE$@40cxfpRNQj0kzWv0bi8 z%VN^4xFftt=PadJ9>kkD7v#3!>_|?|Bkp`#64ds zuK;SVvpe2rkutvtHjpvX%fpHDjGGkWP;x5lbuxQ}_Hty(zqMtVRf?8k^HF?Ln@ipM z@w92$CLY^{c&)U_p1`2g0hhKAC7jTi<&08t;r8@CLHW$Hsxds-6)G{;eh-j~^OmV} zMP^6Ift{wb{Mb2g|6<0mF0%_C_sTx$Bj2>roy$&I?Z=MWvANucdEChv+sN6n52Uct zbfd3*by?ocHew(_aqa>=cRH6nIc8ln{=gW&8yuVhTyqtgAMos4~qL@3WGAXeqEXzd;!o+0MoLWKoxCyc!!x zswx?_)eHsaN%%&a0G~7((oCo=-w#Q2W!TMgmB8N*4M$n6N&F^3C9%T{hN}ySQ_@Qj z6g_efxT-W9LH}oMn!|or923R)al>=Q`8=&$9>*jb>)KexEB*kYczx(R2IY1{NWPIz zAyg>L`@L!9v6WrAA&h)#&*UxX*r^#D*}FM&&oXV$B(UTC9R1Mp<*%aHaZ zP)WpmfS2+{5d3 zt6ED~WT_{eSrz{fry*5V+HtPgWb~Tv%K-Z=ATb>9kh1p>`DNpn1Q&iZr5h5uye(Qn zCes?qp15r4+5Q`^vkfQQ)>7DxSaKHEwa1~>)O29wmQu$&_X@}%Vn`BY9E zEIX#n!rfMkv*aFH?9V%zm=&Hcl z)srAK;r?Tv>d_o=!(?}8LWY8VVGiCS-nmS4&a!g*Y8yvsmTbaEH9SmyNz&1s^&1YI?`tKb1@%>jx>?5pR6zX|Z*Fs0DgTUtt5c>dOF^ zZjvJ-5~ws{k%lLLl3H_ss^+K!OiNWXY#?U-A4=NGLAY#`FM0)-b6BW=a)t7%U-(t3 zD;jIethRAMjjJ3Vkf{bP;~)WTfExx_gy>ZaYt0y zkE|@_ElGI}HcEZi z+p}{(4ik&BoowGI+bvt|Z`(*5#p;&?=!5lBzq?uqbO$7o~FMB(tnf3zsam?)+e4vKMZmZk41aOawj97*1B?i!5Uw-Fgr@Jb3@LU z-^A)R7n>-)yt(rCT$oW=Wr9gIJW`}?=;%gpWNf7C;n>nJ!*C==kX)+oD^aikf+j_@ z+PGJW6yw+GnBjMXnXs?in3^P;Tk3+@8Oxnn*5BO~Rla+^N=(5)s1Ohb*~aegU=w%I z*vNhGy_S3Jd!GBr_u7++x=a{jevZ@)&TU;11q?yon{IlU;_#hvhg{WP9YBg+Ga?>IpR|tz{>B+OLuKh<%g@MD!pW52xCX4=I|tR{FWN^>AoQX) zTu)d%vW|q!A=Cbv*M5ELnv@qAyED>DlU?~B_vxwr(Z8kLCd9V>N5D>lsbC7<+8~Is z15-kkj$h`T%oP|vkDV76}%w#I&)r3)g*q$&k(E4ZeIjI^5Wy`Q|%)NcC^ zp*wV*p3oL1PD(#+b}_l>ecg84k61FHzunwiB+ZX}=05wI27a*3dilBOU0wJOXJ`1N z59jeq{j)QXYjxn6NY~-%iGSDuoQH!B^8IBJJvEFe^PDpPTgr|G&6sfw^gv0c8{uVXm*QY%7lhD{iwVn1tnFM0#|?ssK|9c2&}uI@qj$ap4emEUTHLSu#sS~Z1(nHy?QyRPN7 zt|q3VHud_3E-`2t8TNAdwF37ft*tRIZ!jc9*3%d=Z`h-0)To%l$QdVkaEU`X+hg|L zfJxzP;|`aR8_G8{hBlZ%M{qfPUMVLiRYr3R*3O6qVIrtBJCaT)=5?Fqfot9>1+~)x zfB5utY7-f#Vd^!qaUoWnoDDYBePDIaS6*=FS+e`E8Na~Bon?zPu) zEZAc7RE}(~7IIDt5Ia_?{P|@svz$<70ihY#Mhv8cDmSR=dy;3sCu4pODrzlV{+CxQ zd;^!)U9r02y2ZHhXz6QguE?d8MnPY-KpVGQNqF0)&fFVKkJ~oYHl%63^EV3rgRMV1 zyCJ*G{Gi={3sKHk4D)Ifz4e2O&E*b+lzxr3^-p&>k&u>?y4nr=UxHsWr-ifk+JBfn zlqj64cX;FtO#Asz=R=+AQN)e?1$mCR@Fm3*H~hVukj3zeYo>SlpgEMvez*_SJ#pM^ zshv4?cB|(-IU92*T}6n3k>v)&qjJ@!p5Dt4U>~j zwcN>DqQfNj$`k#4;LJG}Ots22o`om-+;&d5Q+u9z>l@T}(2U8?-u>n6m3vDMNbj}1 zpiln2I0OK*$N{i7SN!-D(I*Bo8)DiNMbtQ^XB@d%^OHj+?n}h@Arm`+&`C*9 zPiq@q|MF9;c4+8~Z7mVy_b885t9Pn=BJKM%h3IOIdG}F%<;pz}xXN1q-$&1tA;cb# zstg@nO!18A0SRqR@*hN`l<+xL;yj2s2T9pwfuX#Fs>(FmVhgXB))#**QrX)`#ojSr zfmf`pyC;CYo8DEUko_A@4DA`S7yEa%N_>1Fykku&T8Q1d>Ncd9W{=8}MhTkQGu!OP zP{{rm3Q4dRxZJu{Be^;aVp_kh#2dNXAOgd*QpqJ+>!36lMm zrpPWBN^l4r-!>YPYyaA4SmJ_~d#%J{pM0Q?>Aj{J&8vU4Q$ID1Acbpsc~G^LpFPm4 z_I}BMUP65R>WVc9qKU=A;{@@phW5Vj0a9coOwB8G5pE(Rb+2SAf-9z)>C`d5bZ*ep z3T#b7vrS*NggJPSvYwRLN^QAWuF=bcKQhUtS@niZ--Nbb69sK45Ce|)>0U8HOSXksh-)Ts)E7_j+t!@_#ZG#KkE^r8+yrVKXcD{hhA z&8=v+)7HV&ubPW1 z75Fr0GRjgD^|4pMG$E%xx9T%iUv6M(uW)&|eyFUXlulHcrpohrQk5!C1y;==HAKQ7 z;bzCo;g0!8DAE?rj~}gUG%L(T22mJXu8^A=vDvFFkL6qT4z98*P@HBxAN;9wsda*& z)E+^u9qPJaKCxtALiSMX1gY|iH^x#oOB-7(+EB&7`RmX-h5@)m0dcIkIufjl|?eabMk{^hWVaGs4ux;lOOeu7JUXJp=zC z=l6!2&3duN8^gzq?EvTNT>0%ewWxj@var|hKMSKs48YD4=A&s^d;k6;P*Y9Wjjz-5 zGN%zV=u1DKymAazL8cR$Fz=@(EprqT7fmS$s}KI;!FKZ@*P~3H7Xr2ZB6WOa4bs$s zVL((=U0g*{#(4O`J)zsR7&e6p#e;mGC6PvsxGL4eWcReiJ{;!Kn-b^2`78S6*PIErLXy@aH%6Jbp>6~x=37tpT%M{? zAI8t0!w2D?iW#O)l%w5DKBm+5wn=1w{VmM_$vcr2c1B{%*KD_YZpt`AavlW%wy(Ym z=6N=08r*~E6;8&qKUuCBMZ$}za$Tcd@^Kfd$^_OpC{YrL32)Mi_=Hg>WG`DgCzkK4 zB*)<1`10njxp8-sU@Y07E%NY%AgX!$#=qezO)~uswDaAY&E$^X-G-Oj#@*F9M;P_} z<=qu~$Efc7Pq;a<2Ok-)+-v&N*pRI2lm8$)@F1*q?P>2K$UfeKO_nKC#z+$~m7RW{ z?gyA({>XSfM|`P~N`5c8SqTEBBkvRwSED1MD0USXkw;+{QGoj3`l7g6UneIf=>N z8`IXfbxE;?&5qqaOfa8WyB7_!7cNUvFL;a;iTb7M=kjNxCg(3Pn-sw1wqzviFr$AnzhSO6&_b8pa`=keUQUxUus5Al>1adX`6f8Drz`e?I z{l{8O168VZxs*nU#*Adfr&X2GJb@Aay!3S-3JiIbRlg+jGY1yQSzw3qZ>;qu#H;4|F2sh*nbl z6_jBrA5~9M=4(5ghL_Q_hBFb1&Jt=@^k%QjvW~O_!Gy!*XFT%-h?|c3QjNYyq~P!$`gd*v9ww=%zL@D`HK=!N=;xs zGqd@sdcY-YANS#oe*bC16+PWzedU;+gu4aN{WKW!wnz`a?n87%Ry<9&4@Q#tuCf3m z`q02Zf09Tm6^XdpO-YU^>Sb|~=3>vR0G#}}6^Io<^rY&c5V{$k3gbTVomkil&6qO9C8~M-K5e|F zMGrBo2YMM(S*Z}punQh^j_vmd)0>?WV*B>`s*#;zgOavFJ(;4xF_@c1BqYsxlt0A+ zK0wx!fH;i)%(k^Kcm_hBOpi#j>4heNyf0(bWXzg8(nMp=)>m3ntL{zVF4VY&E`YY1 z3SLXVZ+Mw$_&udxQfP1CG$&+FnD}j$4d#@>40q9oS~i@19L`y+deI5$h}CpS|6aKQ z#1hM&Lh|$!q4p*BuQg3jO{+B~Y#KR=Hlc3o``g&MzZHB7xy>Ud;G9j`TqNQaHrCxC z8+V7|fnb|TI6LEFR$4Gx$WmjS0!LA|OkUR5N0CNa)-DoThB;rIlsSUoufo{|iw>rj z>qvXKmd!uaNS&|$`j^E| z-+up>4>rkT(Kt&o&a5y#rDm0~B|b(S z!XS_N$V4ef#7eBRH)xj2>@vQ(5>HGlYq%Uz#k*byrg~S zoEiFG@t@{(D3_6$#_pBr_K#ow!VV*o23MDq;+z*v*K2gp*?t2QsEV>e$bL?WM{xoU zgIu9LJ&`jb2V5^`kh>tE_p|Kvta*2ucX2Q6>r;hgkI8IGCvf!Lm$u1E5`~E)HHCQB zNL7&PP}0hYk|9-SALZDm962t`aMMlZE6_04-$%PI%pc76+|CkK{a3@KFhgqd`T#rP87xuSq@l)p5ez z#_rn8t@=S$Sfz`(Lelen9A7~BT937AlD<}@7TKEv5aNur0|{BL(hK4fQ%WLgE>(&I^hP8UG&X*c!C~y~ zOHY%L!0EtP#fCk3$e_~u;&LgRRAGKlZgaGFYVC9)$LJp}v;av<`rh?`#gWpiQ*lIz z^^%T?^Rha1APKj`A7sR@(cA%Hb`#$ID#e}HJbfQO3p-m|GEJ91n=HMXbJ?h)4j)VL zW|C>)-sK|`E`X+uKfenyvj3634WfNbi67#6ZILCrri(F%iNiOhmzXFEl1=wXY`CB# zUZ>gH^hHCO26y8H6( zF?#s}_nVpT9rcN|B3uauWZ)6K;!Zfejk5UP!r=3`wu!=f?g^-(yFVnsr!d~9;&sL|N7T;zxgZr&o4f(iHZ<0GazDC)@ONbGQ$?ESj{adeJ1L5#cYJTu4FBJS6(|W ztc}4}LQEEOC$aevd}oZHv<=R}Ds^UHk^2Xnq$_Iogz7xuvX(Ildt@+>X=`TA(^GIx z%?hiE<^3Y9@B%b^_r!X(_RPuU@!}VfD(0GL9g5R{6wOI#`rzIZMam~>#E-`ReWt1zR&K0B4%wFVEC0? zaCIDq`+DvU7`fPCnlcY7U%!v?7*%hRl3vS%qkR|s{My+=7b5mlAdejXZ1m%gch*7a)td-bV%4{wcl>3Xn^Yxr6bq59Nz;Yxt%i zNjm#phr58=uYU%=0DiFdDCKx zk|o>OB-1`#lXQ05SsmX#v_#2FBvMUMUSjLNPXV*t!z+9co7ds-~aJ((CM3uwPA<_@WoG+vw3@mg?T@|GsT%?d0Iko z2FSu1&?1~1LI-RhKFS#;02PfQ9!2?Ygo`77q(k{^x$g$j%W|@7XE`s z?;N5&ICWU%15#1`KR5iJ_W+IdS<(18Oj~?n;jo1&zjtzrv>bFD=yGuR4F4Mta{2;DV4pgQa7kg+ zX$mB&cwC~Ta85Uf?hBnqcb)I@ks!Fn87k6lna*YA3j8ZT)A_JaM4NZ_eDB<4zW)W( zwqRz^N;n-5>Qn>4`ZuXY77xx#$;Khg)aeFIyc^-bI{yacC;{I9dw*0~aqM#oSBy-GuVGr)8vY*f*w|L3s# zU%_k}R1PGaOD4L`p&b;oe~WmG!-2sTu^D_zGAMggD%kTPW#X*eHrMO14K4a`YY%WR z^E!cvc6C&d0}wyyjDIM>3)0ZM&g7h_GL$l7AWO}hFDlQK&6X~iS#wn;{mPjtZ=TPS z2KWq+`E-=GNP9JeNt|J5l6t#wG@KEF6J_8s2kY-#gK^R7pGw9sypFP6ynRF`N6#YI z0yCkoRv+P@%YP?GegP25;MjawMb+Ei!V-@vctIu11bPl;=8FQv7x#2P#j4U!7P%Utllq0qRi7<{{UWY0K9`YA zy%#vYkfaz=g@#_%1eT#3w8r8$&!BY*Qqcpz)j4)Mr#mHF^djAfv0Ac=fv(ng%aK@& zmwa#xTBPemy6r`}-O3)meT17B{6X<)kEzXA=8SW(9;p7|GtKp3;X)9mjan@{_Kj%Ad{#LV@Z&C|)} z48Ip%+SaV=3~jpEK9FfMCiFP{RTK57l^LA_*RN=8r76#(=$UL7-7Lr9nNTRhZznWoz<0f&ZTu#_i+Zuu z0HUCj0zqs1rtWb>u35olI^k%3@~iW4C%ze*bxaI`a>`*kodMJH1?K2ZAjN3!#a@!Q z#ZX!V1<+qXQQ8di#XO^*tU;kUjK)!jcLt;iyt4G!^}+3J%lk!G@a45BCo9&vZ%V{G zsD_5@zu13~g-Je6VNKw{qeJ*S=GbstA}{e4UeXra5S7#s(sMpbh*8A73B2eAUtkV3 zIS2H8nP8_p2mi%cONa1y-3fSdz9ayk zX{|eZJL#UM84Y4w+6FIF+6wIi!>DqtACDsq`yFEedD26qRSMpUv*_3*9@4-!uJkgO ze9iw{@xcv^beKD_sIJyi$%soz79Ui~Q^KG+jt57ZUymoaVG}uhH(psyX`g8hE=bcur z9Tq1SWMxbFyJZypTgt^S627mKh=Fwx` z`)d2ibOAwl{*IZu&v|dBMc4sj0X)ToGmF zKXyfG=*dZ#>B8iKmMdL<&v<(8kBkZyMtIW6$$*z-Z`-fww}BvJ`XPb)hxN}&T;D>3 zsWd4lIdX3>8HAf1fVRp!};dfsvisJSWQbcHr zN0OmP5+IpB2Ro9YO5;djAO~88{2}vweT+e>xD$9iQSrHYya)&8~ef9UsD69mk_6Gw@_q3$xac`*@vXZ^q2;qdpFfr&t2G&|Pc-ed9Wzl-(#C z@z3@rroX(`sZyRsZlTWovgm>&aA&`ICr)2B*aEwfV4zVT*s5uPt61~0)HLF5e)uzB z?tczpiUP4ywPlo>MICn_Je>*4F7R$e9XL^EK#T)CPRDJX{EBpSVua%?kXRTc&@*&~ za#?d7>!Px?+SEqdIrEBcolK`unol6PiXENYokfIihHDJb7vqkKz#dGeP{(Ni4w0B$ z>Ge8~zJuX{wCU*3fGhcBjKLnf8`Nvjr`C0Dd(}0*7WDp}!s#GATzvq@7# zddp^j7JgHQj(Q0lcr$+_(c$&J-Jt7m>c&&INhE zHz{*HCxVd@{4G0TI1q;hH%h zlPCD>W+Ty-@B~^qKYHXtrCqyHRhe%d5Yct0u{Ag2St7+?IIbRy#_2v)H#BPsz2%9R zffS?CeqZuzjCn|S*k8&L>FmE+15{A5)~-l%)hM_u@E)U~%4)}YMtN^M0H@I*OD?Y` zBF>sMMaJy9u2G7(-=#GV&?l5$3({uP$WjcKi!RHIiZZLbKHQ+VtIM1jwPiq9v$n`7 zuf3flX+fDLqqfW`uPsBM%F4)Z%tOE;s8PZs7HHJHHLw`Kd(Hh-l z*JSQt=>1FCMRc#rBHmQ(7vfxORoz>Zxehf_RWT;ggtM6&U2;=Wq88Ch)NRgtl__OC z&LI>w72r)9$#(m9Br7J>Fj!F|S9T|g=;K<5B-!*vpE!|RHhT*bFpE6d9nD&$1&N(T z&h#E2rL6Ti1kpw7jK*b#r7#owJNYSU>Y$W*-!grHuJ1sI9YogXSfnq~@!~YxL7(-G zW%>dg-+}xaL{W6Aq%F|lVkd@u9PsXp<$+=^?VHv*)=CEY$%9=mhV8HlG1fq+E}=%=a(#ylA{AzHK0^T zikT(%yp{j%KLD`OcLfBbyyWna`Re=f`Fr%4$riZ^Fb@!QTc~Xtkrq0?+N=Ir@ zC1`^wTInJhgH(!QR9&bGyp9TJCBcg$TeO9-R7Jk_aJR${+WACIRXPB zH#odpRU0~A&(g}QfN;N_121H`idXoeLo6a=seyL+JQ|rZX5kJN!aNC|QBj9YROSUW zdAYbA&VrK{k#J6u1**wHvLfmJfb8ibZDMp#2mDg0TIsW*74P;o20hGpQbax4B*lGx zrRghW<-qK&A|a^ToyY(~_s-+N`4H^5c2Mb8Xjf1grrbNDC7$sbQa7Z&Yh|Qrc2$EY zS@|?RkMPbfp?n)9ikE(ruIO>naTf&V{OlqlofPWTT;wX;>KG9 zS}^C*_;f+8<;?k}!Cy=xL$h$V*mzY$QD0v9dRE}FZ z^^MZFM~bRDLr9qs?YCK1ee#hvfjOLBaDNZd?G-_tOAE z=F$q>fR@&n&=NsV*{FCoy>w|3#J<(GAA@xpD;ebQVM7PAP!Z~6(J-{UmDXx)HD#r8 z|9)Dpd!5U3a>`Xn^XX>Lq`FvuA`T`Ffd6eUCgf{_fYC9AKc!RqOG`>4gjW&-s6`^#3hW@U{s4HuwH{j@vL2$Di<%IJx-`oY>&VFzMo(DXPzfbXbR zcAU$KqNu2RHk@SE$to*AwkVq>2l{xlXg0iQO{p)FMKl`8)10T5l-OC!{6(Bk!XY7$ z2Xv&2JEsmUaP$hRkS06YAhb)t`Czq-zR%-cG!LvDoE8l#m?@Qi>8iQ_bAk=2g?A?g zWGF#x(`TJanMlEj8b0%z=74;#>*X!+tNlFbgOv{pplZNEohT@6_=yPBY)C2<5u;2S ztq@abgJSo9K{$PTtc=uDkGib9Nk%vW)`DJ}lZ_3R>auB5LsGg3{7Uh9 zbP1bMb_Y*GkGh5?NicGwnihgk1Lhul}8rgA6mpk}v3<1=%T40iC1dtshOqciYKIM^qvdvkf74$-Xv zJSYNN!J{YvvU?FhLJ~#2Vbo5iJo@g^M4s{1UEmz%P$`-#jFWY(H>Vj{($R{%qnp=? zC~3E%T)35UL{TA&4c;NnzGPPlL`^LN_4!wj&?kJhh8y$JHY9We8b* zB6X0`iJ^|9?vTZ-r>S`wa7T%r&>uoUd5*@3@lukR+sDa=I4g*BDwYoo8(1FmY=I2b zjiBw|=ApXsHT#;}e$8&bCM)8^Eq@n_B$~er&P23dp0u$_*wq9=#5&@`^9j_Qao{`_ z@^NP@p38P(2o8NiHG>&Meb2R{%hvH%&HH9HboPkBPe>!)lv^YNG*+a0>wZiJKH~6l zCj1bp!Re)MT+Xv|X@KPIMCTzqhsg5%1cfiS6Cl;TGA%tQEpu5fuL~B_Ov- zWx}%~dN9*NehyEV&fs4H*Rt~v%;t;Xskoys08+wx@h(w>X!Nsm^p>7)u^)S#RONR> z*mBNt zJ7TdJU6;gki>alwt87QzQeH=k>4%v{tiRGLW=Bjw4m?$K9gQPZ|L(Zs&Sg1;4IPv; zPy-d$k_jO0&&q^s*W)DQl+Oj>l+B-4f^N<@4ks&SS#3<+DN3%W5E%HB%0f(U?jj z;vC`|(1YgbB<{_F%TYlCZf1k!5W1Q*X6`LH=0N8$h?DtKrxdp4&e_oH$y1wCz*3Uw zP4{fTtl}DIGa4%g&Tdix?~pmTnYk~y7aV;n+Eq&_g=j$O*^*Lbf^cS*)?t~^SSe6; zlL~a8p}8A`m#!K*lye#_h1A`&f%`IWyJLH*C#hc6I7-VJDnCn&=2RQLuoo=~RbMZw zLsi;Px%r{d9B+(@J1$5pkrD;cfO?`gP!NnKT6quSmES#U@(qjh|T7@XA==9kQmDgGMpRc*1 zEl2AZrMr~d_e`fTUJ}OoD=#Iwh+9-w7gjh7c5vj51$M5S;&j+4u9q$4qVNIM{33W1 z@qRmWiZ|_F08sJB{VzedpV<2EyTOOH=pB~|I#wg$Xcwr=B!+&0{k_Xt1}}Cs-=mTA zJ?fs1X!gK`Q{6>|%>AMK+LW6!nyCqbM!txapGDu(vH&?OFD=PHR_C zdDBTpiiTuNzmznjda6{RgfsKwPO-stN?TPRvEB19+Xn4-P5!R8kjSFmC!$6J^_I_m z)mrd?M6F7StCd&n%B#GxXCVjm?is@cG*>zZx4iQ%QWPxy3Gz~%cWU|eY-*>3b0meI z=$?hGM^UzhO(KtUll*_~*cDIDcNshNi2jRL_kvh$$fH?hE~M2!)H_TsbEJQ?XZ%c< zv0Q@2a(?B%DxPA)tzVmOXxHX9%%P%-msr-AgUtI~AWgXk6{n3s$_*6IQ!&$!!d)wP zA&x*Tj@sAb^axFQn9!6`Z?&p5fQbn2^XMq;LvwHqO?BgwdicL4{xHaOzwMQ!ir-f* z*7^Y{#*M^JOaltwvz99N@Ao|;r|$Rbbra8RTq?l2noQ7CWtSNNA4&jMK&ZcyUg1H% z1lb%bqD_IaI1yW%NG^`r4O1=8MrsY4&AwRh0@j%{{t@RUk2$vRSbW{2iEQ+fQ@mXS zM8eT@;*Ed~s1uXpJfSXa3wgbP3U=sOnr5r_f`)5#vQM<{t$M3%6xlS3wA#%n_fblZ z67auE{!hIKb%V>8dKKJ`YH&u58evz)e={~F7x!0!q-Ag^T4z1M<*2F|R|Bgpu*Ou9 zDLL8co-G!`Kt=koBfLevPBNYLzjmax@&m`ggt*7X*oxEIr&;Y-8yO3pPbgJTkWq6`qSH58FVNSh24J@G&`EdGJ|8{Z%C9H8wK}SmC)Pn zj9pUVdzB4v@5X-D;*;hnHv;&SPNv3dyK~4%TMHsTTrt{Z7s??) z{Db%^>QyK5T~Oh3bBuyEQ^ITw!SlT(kdW%agpiNEJs;73y%t@9UOOA66tI=W(aOCDrf ztav*?3n{{-1HFiDix*+C-_3LRRF5$dxn^v6##wQ=KI*?P+e2{Dn^q`dJt_EQ@{GDZy zzR6;6vf1NDR~fsWD`sKr!I2z-!Mqn+%{Fx}7qRz@8Ij+8x)eLtgxerrFFD&l5el6ie)R-WRE#T~VQ02S8r7VN9e;AJQh=~g~ID2hvl7PtMz!ic^B; zY{{ja)gMVJFshe4FqhlX`L&jM zV(nbN4F_&xYONi9gt(j|!z+?Mk*VtsQ$mjkdPQ(?vqDM{I`s@c7%OJE()K|`yxcTz z_7FJ9g_(#fIZ8s(VjluAx3M9`u`F-ODr@TeEWNw$0+l(*hTAydL%G9$la`x){HHcx zpHO-bhQLqkOvl%LVtZ`P<^3(d1&dV9jnGBZ*b!N+jPYTWG|p#`7U`m0waiKjbR_D~ z`BzUBP)OdOt4&woP-Av>+g0jk+675u*>)1&Z z;>#ML>fU(_D95&ZPq z&TBLu^C@Apms>=>xS0|GgST1dx{jgW4Q?u4rCq63eDXi~?t_(a6B$!TrLsxs;zrQ@`^g)&ZIJ+k-_oRP% z>Ve0uIGIG9VW4HyDve4lrw(ek4yKZUpA~rFKcqj%9HH_n1i6HqmGCb(pkeVHWOFRg zLzRVKIAQ;i0YVibKPYh)JeGON{+-f7M0UaEnOu?v72#}U0#5O#^mzxqE|}+5heOQ( zWU%wE0HspZ@s7-^)!MP)fk$Q{h@uq2)SVP>O@x&n+iKeefVe<*Xc5jAB)) zV%53dgG31KCr0nxoLf3d<_m#qX0V}iC`ff~C2o95o%q!H@Y?q$DtUe{IHxF&QtRz4 zy@&{CJkR_0@lb(_HF121?YFV&%^6sauQ{I*m}iRP`R#2v7U0UL(|W-bubrQrq5A5b z=cm4k>vGQB7ny-OsmT^l5wh<=NhADP=^mw=uC}_vG?(~(4sssIqIX`y7HDfYx?e1` zwTz8(;odSAbhBK*HUU3PbayBYwFv%CXYOTENg$Wc&}tE^V)a1N>`lopm>%i|goGqsY*lk%z4oVs|Q{1qd<*22USxRM_9n9t2 zvt74OnIsTf!|v*|###TM0+v2;0fSH#h@&+Nyl$5PF*9*VYoPp`v&Is0yrwEDXfZ6LF^b|o0iI`?*@}j~4(?E!>RY_n8G(#aJS!oG6e zN;?JFdUShBW~*rqSeK_38S?)rBPIiOj8`|~jON&|sl#y)0Cw=r90IDjqX3{`v@fdH zy;8ubji~$CrZE)5V)j?Z5Z#;1DQXlA-l%gjOY zLM;nt$_ux=_>3s7m=|h&5rb>lx@B6uKh;{S=ldi-#VOB-wCL8W*pnTX^Adb6l|JVBZP0JLBY8;abDIeip=w*ijV-DrGaVMt zlF%O+TwAerVfuX|=^Xp8R|hldC;$uZ~bg!848 zj*vCtM<`F54IoWo*N)P6Wvr_v{n;IJ+)?(@4fEv`OG@o(KYl{s$h#S=M3J@{oW;Z2bPOPHP zYtwFmk!*zfCjTCfnfM3}uSCD?<<`_!*k~yImIZY!Z7uR=wAY-<)|4^38Y@?wYO;WzvT}DPaj>|3OLT52b&ot)rQ3+n*0MS@(%?-pUB%4XnOXup2Yrcu?;MRqOVkaCP zG*YHSt~(E{k{c+oKEDAdXykVS)r$z7OKta3q7hcW@&?M%nfE9SYQux3XhC_BJ}FWP zH;w1Pp|jZYNL5P}%)-QnAern0reoYjiHW}p(h>uHlhNpA5y6&y7T3Gdi!Umk?$1!I z*8zHPJ&YRNJVz_33ct>8hi5q`@L$pKyKSaZ?zr3-o{M=z%N__`W3l zB&y$R@O4E=_)dC-SF`*>E#>jcISHYk2N8GT`w}j{8~4WXRWu|L6&ZS@U5JBWXOWKU zDa6$y*wn#K^o%&EfhqZTqqzms*2avDl--!4_ADLKBDGYxP2RjDls3I23rMDjCP4$O zHg(kLXZ)_Y%CUm95KL;7@m0m=N$`diZOHqDo$fgwKMI?BDc2{41Zi0 zsHtKKHS`i5%<;S$rD<`#L+1NCoC_;CezONS7|#e4F)TY+=HSui`}gmIcj3zzJR-(u z5tQeq4-&W#fN_o(Z~-(pHpLo zq3F~%Jjk_gcvH)$p5-y4Pwnwqz8u;&RvD)k1xLBCgd~*A!3-h-H_%i6yB_Yiycs** z^3)&b=w$>|7BQR&5@DtMC@LsUG5f4A+r~*_8t`_76N-v|F~5kz!;hLBYHn=QoLuuJ zW9BFxNz|;d>8PY6Q%yD;J(xYs$b!Mp_Z3za9j%($vwhEKP_RH$X4*kGipeHaQn@d6 zEseQJ*T7&#M>*WaY0bj32r{JN+=jA%@L+Z;==G~zxi=!hRK$>r42gT>a^~>uVdh~F zjpLXk7FJ%7ro$p0lQ|!zm-#Emv+Dz^C#Sw$$$6~2lzT~2(h}OYxGhB z-pox(f|wAB2NTPLIwG?1wAQH~QJE*HwcnQz%VYq8!zWCe-?9^vNM@J9QBTKuTK+00gB4Ks1$X+bqUVK$OL)qBeK- zyzBF(LP}_Wtu_&@h*g@ia6ywb$PlPhcP!y!4>*;IhtZ6Ra@vfFqcHovJB&ix#?T31 zoLhy}ezZD)sCCbnb6H)!%%%!yUcp)>mrXt;LPD6yRAHuQD7vX2GtLH-*jEO4e9t)? zd|DwsTOr4Z@|8l^W$`r(!6CNzL`5(sw$^aaL@G6nks#fwbR z`}7+7@V!qz{fTY5$;3r)1nf{g`D&R)7evh0;V24FxWwsOf?sqB>zGg>)G!>6$pM0j zq^jD2P{Nu1&A3)fPi4hv>&R*aEC$)VPzD;1+lxwjN(_RaB;5)KeXko0htQIKkjIU9 zG-eZmYQ0n$ff>fvaCvK}80phfTn%_a6(vNj5Mj7Vz|?h?K}5q1OKn_vMYe&$UXL=T zdr>#djL;5vbTh3IIePMRNSbFqFb0+W1^U!+7Qxfg-V!1%8=0e%iVnG}h-#}t=jPvs z)ZLE>th8GUrvQiAyn`R{} zCv|u>6>wVAsB@^_oy*9tGK8M=ELKOmSg;>xdKg2Ca?u1{iZ~U|ZXSGxQSU?W)Ey%b zi^sB=!Z>4CUX1#D9{0i7K+Ch~9cvAU?2wtmtJ%ss?MYckJ{8|_Y$y#LBJPQZKJ-yM zNvuVT1iwLDHho6UBaVT^F!N;sH;zEPQNNbJv6OQ+2wK=eUj*mT$vp(B>dQ|*#5kie zV2$60gr3-vxj%#iLz4Bou!A;tMXce0&!LkeL zRDro=cMb3Y)X!x@#Jk{&&6toaw5w7M8P0n3$XbsBHG{IU+KEe1iXNn6af(vY`>9s@ zq*m*l`eQ;P#=#9M*rpNf3DmDaUdAsu!OV1FJdXt!H+T!?Mb$A&uU4=a2Uzwp`@wPEKBFoW+EjF^fYX(_>(=U)(sUE4?+z!6Yxb?72C zrBqi!%s4gTtk(@RicWw5NG~~@Scw4I1#_ovqeyuW3r5KZnuBLWattyi-QQOvS$xw))ES$#6P`@>&E)7H3RQsb~U^TG(}k!)h%PHs^*< zynX3Vso-q{ppP?iD$UVKJ2j2b^m0?*c|MB)&T(`dZDqjm%R5PBeSASMz#Jsv9<9bgXT*%BMufVW;aC25XdR zxvOQ3XeN|mbT?Cdxb%)6eMdb{!0!c12a8;<*1ElI8s!lhM+LMG_N?-%+xdYh|Eemw zIh&umV&MZVG5Y8ri+#0GP&$#|KWsiLBN`4-p>h^SN$PGUbd2?a{>y7CtY$@Mk0!eI zh?0X~;#3^b?iW%VWh^AKszkbjK8RNL8fe?5>4d13$U#mxQy2e=UWblw0liN7{Re+9 zPba+^f#XE)wpwhh;=jq(I{uq&JtqH7b=;QZ#@cU!YVxv?l+EX9X4JAQqNZJz;g%>{ zB1_@x2`tb>%b$*B5~gGX5fdvFeLzBkam(Jgk5)D9Bss-KGwOeb%p`+_IUv-O7hufG zp9fEQFg~nD7C9cP9zhQ=UNIB#xSK%nwnV%!j?vW=ePOS}nN)3FGhy_ixy=KACJ=dD zHRp|ll^9>Rnr`81F%uoxIvH^6r+y9!Vr0uQR7nsf6Uof?lFzj{eHzHdaP2Ek47K0{W^P`dG5TQ3CC(8=-sEEG1ITWV@!R@D0t zx6B9a>5USbm!oW`dbq=v_e@G4;(f@Z`6dz9C(M-%EDgn4_U3g6Zb=BKsA;rp9Y7v&Wy@kKE78*IKlhWNF z5N?ir=$jlKK7*kJmT-OFQ z3C}?et>TC5JN7GoY;LTO{x&O~Jra(m8F!bd`rEe0F&F;T*Mc+6T7=FDHl)w~^5v_w_`rvO;dq=M^2&4&{Cez_PQh?XBJYqOGXeeAR?s;K z)AF6=z;0jocs1}@8&|Cw!vpBLJ^`M!`k>96u@CyjsW@*>l;YB2C^XSgC^Tk|V_1&+ z&OL+r0XvsExQDIJZAZyn4g|V_M~+(g-mB+cIcbfyg6d%rYDDu{gyufUOW*=|wh`v^vEne&B?e^}z3dEy|q1Xmyf}s7C%03D~g&TLou4;0};;9@M&mm08lh{w6*Bu?ha>v~W5aH7DnEt+KHK zEfSWa&AKpZKmeY^lVN-ubI-S0EYl97VC8H6_2_o#YjOLvSi1e1-&Vt21OVr8_h(L#;O{9#|FSH@6gWF2XC-U0R+leNL#b{+ChO;RL zvj9AWG7HK@jMamDn{2gW5msgTIR#5E3EJ=JhFknoK!bFTU(J;5{~Wesx|Pl%EBWSx zkd-`06|yp~S+J@uYnTRG+DsI(5|+u;eJ640`?{Tm-DRs2j_t`J)P88VeqGKFTLOVnmC)GP?}ZnW)~6B@?7K9%2A+Giu&Me5d{ znLL9bLMlHD%T_KfH-Hof5u-U}Y?@QfY<8|?WxSa&gmA7H7?Rp*G=1fSK20do7F;PZ zXtGj&Y*svLU*e@4!L>L5yKBU?dGK-dd~BL^&AO@s)et&;Wrp8G3ZibF;n$G=(&+{* zZ~L*Abc#&*3Sp-2-)`J)-d2}t-fi{d>s7N^|9aKxf4zDPKf)&YU+?Rr_3&|%{C(Wq z2Yn5cfq(k&cl9y;eS&`v;O_(Sca0SKIyu-sAioa|4xZHUpWRdM_Jp+4!WLRBDA{Ul zui?k`Blvr;jUP~Nb!`>uk$<+y-~Gqf>;97`_;&|C4%W!u0}9W<-UIl1KtB$4C=hk{ zXKf$;uD9^x$wU161V5mkwN~>1e6&{g;O`n1YdwZKttZ$(YiAq&?$VF_HTaADtgW`7 z*y<|%Sbqe6AJC5j$XP=O*7tTuKkNJWvAzCy7ydq>AG-vc?I#cM&zeWAx?6O;jjC?*gmHB|HhefW*WiZnPK*9r`S;-r7-cY`7GT2BzKk8ae< zbzU)%Q(3g%Zs1-r0#}!#aaXa~s*9>XiQ*dn+L(A@U~vVcl@P*P02d-E(g#Y+x4URy zGnm-|n^w?@lIf{~L&k2Pra~HFk0yS0dmHIIknd#HY&K0(9m#8X&Xc)OfnG*6D?X2n zO(08aH4G*Q%b1?t-csY|#;fg5e}CA1`F_8{2fd8$?v=UmXHBAvSIV-F@P5t0C;s%W z3GTE2kHA!qB1aicAR}Fh2{7BS^735=j$TNsK3rR!Tw*GbAv}O1SK#nxwPZ`Bj@`1H z-M^pF>2oUuDA!E2znQ1X%t`_57+eWt^x52!=B`xg$5}BVLMzDi3pn+sTOQnMxnc)0 z=>QOmp&~V@WL%4C37}Uz8V}=QFDycU9K$EjDqAH)30B$%hoNmZk|8Ec9Xf7U1a!J5 zqKlWDEwc{tC>{O*>fyi+N-Z7)@(WaYeXQS}DhHM4Cl(Pds z%OQFms{v&R6tzGHVrsiqCUolrT(_v3PjRr^xD1Eis~SxpESDd8HxYGJsKZE^CI(dX1!ndCBGDO1dCYFkc}Tq5;_MxJZG1ym6S*=adBPYR{EMz2DcuF zxxY4XL$3O5WcSl&kigL)XhmxbQ8g!!q5b63=tdnZIr6%KGVsa#1x7Fk~bSk`3Ga`2zr57o*bLD)-tmf)KIBiIuq9ra-f!n(%L$2NfF{ey73fF%G4r*_en% z!T*4SvERmZ^q#O&*N zkBG&P4b7z!rl=_B2V^?8$N~d0w*pxyKzpg>l9b~1cG=$9JW))f_KwX2h-^zf0L`3q z_EK9gY6f}iUdmiqF*kv`Q!-2l`P+E-r#&dGgO0Hf(4JT%y+I%sV*T|Nl?;f0#hief zu~9)x5i?JPOFqH;^_>1L7>u}^(+-5kFs#3v(Q`G+fVn|&BacV$7H_xF<Q7qckF=jZ%c!qx(r4ik-jSujim<#rF)2AvFjDl0BTpXHY zFxQwt(<_3L8@ko0;}g|5t_ePu1VgY9qm`U0vYX3XMTUVk=d&$Vr9R&I&2KGYzTYvf zB{+Qd?%z)c=@n`^D#2+4`XsB>PMP_W!s&UGH(`pQEMydL%lNM1<47N1(*z+ROr^H( z_Y^(EQ-AX;fx1mFpJ4J_$Bi~-@eru4lP2@5^Qp=`N|~b78}4|Pn>d2quuPl?b6vI) zK|X_G%UPj*e(VOFjEQi5%lQ$J05-F89UF+!@>E&GwSlAB-DJx}kCw7$A8e+~XCKrg z>MUGb2%Pom1D{d+`V$Z9g@^UPL+On_@L0q*;@aw?hmU{rdk!&!OWIeZMmGx-KAQCV z@f8yt;nsgvFdB9F#%K(9XaNdBgLn0;I8R~dVVXAN&XzH3= zGrpfy8=Y16(o2Z)z(XqSMg4FxG@T7t?^jX_`qC9;A|F$=Gm$Sz6Yg12a+DF*5l8(# zsKXq}6!r#GX8=N44gnK!i+HdhAxmNcd&5D}c$gQmp!5j_mZHR&2jt*+)kwGS($GY8 zhT|AF&8W)OZ*N-6v ziEvCpfPsl$4s^jq?m2K6Lg#PAn$eD{C-M1bwN;P26{VLte>Kk>193#AQ7QD=Q?6-O zc7@~&XTF~ixV0tczpXqKGN1IgQJ0^|>YE_sX+@M6e$29nWM$22I7p7V&B>NBC&6Te zqy-ap>A+WmAChcaIB>57z9X?3C4i8uf1!pji^KY>$Qec`;zn*;e0~@1h(AgV1 zHi^`Ca6mAh{&J|U^X_>BP&=ei)|UEl8%d=K>ziHMumY^EfUBv$0p{XDtxBX0fG?%V^LxqCusSXWc7mBdFumj4F4X{M~44zdF=ha z_kDL09na2uz#0u_GVLIDzLIxw=;uwyfs}&yQa?Qk8wbJ44l?RvIUG`_aQ46yb7|A^=TimFPFh2Ir5xNap3655 z9QP~U#U9Ns*o9+Qwp!V}Se+S*B^D>rj-^Vou?i|2;l7vu*mqtv2>;h5KKW>?onjNr z*EU*PVep{Y4ue*+>Cd<|n9jg5gT#yDl=Dax2nB`~`gq=<;;PbwA!+x6{Av)u;QH8# z424OWJ&%j%2y9V<${1)`N_daw`x}q9qLT^`zIq=6MZr@?#(P!TQ3G;h0%-^IHT@x+ zC|kVGc7;D1UF`9=dUL=K8A|5N2zkKapL+Zc!TkxlX$ zSYT+ci4DLOX{6%Z2a!0I@jDORU>s_O;280hZJ-chR_zc-fZmcr7v4%xY!IV{B!(Dr zj2f%zeETn>3NG*>UpxkK8g0yduiuf&+nN8kzw8pC%%8x6W>dLteM@8O8ZKC!-Br2K zmG-#Q!NYIAgBrk))V znfiX`w<`LTiVXh&{XUx#O}TF~_xi+m%$YA?=#@-1MILi}ML2yW6DP|<6FGmVX0S=~ z*u9D0rI~WNJVk)^&+S|(ZTn-It4yt@2x)##?N^&RqzI>SPB&;)oQ*=Rutw*&=btEyo4cn=pf(@m@JBO4A|pYdR5QkAB1eTm(J3RU;`wHZcDOD zl1Fh;r>E8uVbcE>g8`z84oJ}@ZCcwjHns~eHkWvlzr?-EX_L!_)g~+b^$%sL333h2 z!s_aSroSZrG#ky9*ZEP$_(KR<(*TWrke%s<(dqyirT>pjGlZcA1IfT&(!ZDfT)I)$ zW@(uSb%Z*H3122kI%Z!!yu~IXvZgw_t&F$S#tF2{~rFSW2uA4c@fp&3g0;{ zYjyQqr+n0*=+X`1+iE}OmUV9l{43}aOe4D7FuRmG1)=q1 zeAVGe3>wm+x`8v~d|;I9r`>8pgqvDY(4`)a$WhT=nq)&FRfAZ72`l4dK-$lvhwFa) zVdu@^W%I?;LAp);dwul&eEVtcZd1q z!S>n8`*@xF`Z5$pwJ9~SzGI;-^-@AOd_Wj4J z_~OORHsqaMoF(UPuO2>p4c_r79AEw#JcfU-UhM3BnPmNy!<~ntS62j<-B%ozt9LtV zwZoltZ2#T)_4=Fh+WNb=fA;#YtBi@{9scOOJ|FP!@Z!y*7xA8mp_x)37e<$m|xmr8B z$Szhs?2s-(4rs<>S5aYVoaqdDcYOA4cCM4{B%E4<|{!K6&D5EZpbh@aTB>YWrzXd$^t@A15nk>Emd7d;NLxY^}C;nZADXZ9RG! zuV1}=^5k`YuwFZ>txTTmtVDZx>(yRs^yX1*{q3{C>Z?!T+WMoxql>-x$E%mG*Q2Mk zw-=A%2hl~oa`EWN_2kjf+REOCM=R@39)G@AU5}pC)+haUYj1u`NPg|QwU!_Lb4eiD zdwKN!aOcCbZ{e5j%BQ{jVDR+$&Uvwy<>$k=7=2%To}E2A_~+&7_~KK4rS|CY-rMy1 zw@0;uA5Z=nzh8Os{?lL2hv%cW;c@ux;k&otkLGApdoZ~CK1eURA09sa@}u|QuVVMz zrLyy_hEGSayxl7cy{o7|LFbx+fjJA^CTIJqTz87k1sF#+eh*6>dnjR z_``$uAKqVo*zTV_ZFYCxK8pvnr#s(&Z12B*cGTR?iw_46$p-uK{LPQS%h6T-?5tRQ z6Lnt?{@Q)K_SgR5D0=(;^FNQb51)Sj>+0dB;vnz!dOPn1U-nm%w}%gRpYMJ-4==xM zuOFPPbk8qpYfqkh?;qA)y?V9x^vye1v7NsT-#^&TzW+5C41%EI&87rOrlfL&gIVfE zAT5+o3KoCv-=!7XqYs=`Jce~=|Kb?m9{o65d647pm9ycql}BqoRwl#mEPwCugE9ZT zy}LblyK?dL$4d5nFUp>tJET{KsU3e= zAFrLSo*(zui?#1-lkRo)y7l5g?Nj(Yf3SMg&!6mm8f4Jsx9`LKcOMSdSJSn(XYXpe z&v)J(eBQr2OW&R!eIBHrC&}}F{&|@^T>0^M^11iy@rO|_nLN4pvHtP$)8O^W)$!ZI zz13Pic+>szEhkHNdH(6k;C=Y{^TqMwcgf_h@O}0zd-nca7Cr6$nCyrBce`&^j{Z8H z^pDT7^ke>ZkPn9+&i`4v{A>UF>bLhtKR&JPzTe*?sJ;HE`Kb5pu>0WE@%Fo`^yOeO z{&;x#@!|WO2mPa3?e&Mp+h=dS43d2J(axC8*epE01FAyQ!{3gl_}|0Pi`^&ir-=^ViwOgXGJHzlNVb9zN)Hhr_p6^{?jp?+*x$ z@2q}*++2s0x43riJ~vli51#KleEe?mX03={{z$%UUyffK4_;sIoxO?%mvO%P?92Q8 z~zYg~g-bb&;-#)+E ze%s4meSQ`VuK)US@NQ?AzaPFj_^|u&{pT0ox4*o)`m+7BcQxF5MZkJmJKlM_zVq<# z`Y&vEe|T{G{b=%Tw7XmJG~N$v*jx;wLktj1?L)H#YMqrXj%31C9OUytk!2uaxiEE<19{!`Y6nZXyP0K(;uor77DR(GM>0)Juy>F zEo5RIu)!s^1sj^|5^ONXPQmM(Iw}v^OXDoE zVjWug7&&^-XNNbkQfCnb#U)vj`ehc5VeUb)^KT6HH(`oJ?-?quLa-co>hk zk@%7ZztWyi_K@vJt62u-bL%!c0#-`aTLMJdr2cwJZ%>k}#wrI~fA^!8=QD^SW>e4F zAWgI$=biGLsiMxrpCgD{L+QjFW=IWn#`Hu*G-fIzS0*7Jvq}0|dCU9>%j^aols0gd zk=~;@N6N#}>hp9!qKVZxLx>3JB9l71k@bIJ^Dv4F1HfP4Jb<9lZ|}!VY6L-+$6p;; zjXK%K9kSJmxEl^RF&dGLGK@MFKlxMaB#ID!?QVYtcJlqhSKU`X#i;)^=Imm;@^)qA z?d6-{VEfb4&rc7(54S%YrQi1+KOKF${M@<>^B2Q!@5Z0EcZ>1vLA1TsefHs9|K0Vg zciWdgF1NotCqmJSi`|#s`!9CFS4X?Uo#El5oj32|@4E+2-|g>b&!06v{PR6Li=Xap z|8x01>}~(}^4HFQz5na= z`Od}avlr>RXV1R<^E%sJ|M+J8$LHo?c>Vgt%j4A-&->5G47|&GgQxMQi$U_)ArSaK zGt=8R(`#&|U%!sGANFJXzI?m4bG3K1*L?K&@aR+RbF_cGckpT# zM)G{^`RmcA__Dw18p%wRhrdMstzWq%AbKdWfBYqau=HAmF+D0j$r(jK^Ow$sq)C1x zWMMC!D9Z~z)lwzp54w8Wuq2p&DwjUnQL?F!O5fEyr3wCY^2%dn#XrI-NU2s zO1lgc(%c%UybgCRf?{CMYk81A!T`#8ROIm~{% z`}SkB6YqZ;H@6>tyxiG6dOLWr{V9F<{hy<>c$BBTB{pC~i?fsjU`>w`4yzVf~qu)0|deGAmZa;l+^bQl=yk{f)_UQ#3;b8Cb#pORQ z_SW|=->p8(kKTO$@bTN=`SWMnKigYcjDpX9G+Uy>KkcX##=pS^B9S%353?8(L1 z%gOeK!KI|Uya?=bKYS7jor$}v)%m=#yFmRbv!jPp6wrlz3si>n>X7( zl4sj525&!ZUv3|Miyyy#zIWVzH;djl$0GOR;<&oH_|9z2?p$uVJN53SpUjzd38%ZW zzO&9xHlDh-|A73*n+tnUU1>9S?84cqx%GT0BI}I1zf4J|mr-srN`PSNb5~GEPvXYG7q-EoREMk|HV7x0$ zc0gYzK(v{2iugSo9g<`a~)gwB;Pm{jjdIV{5O zEKx3t7hTngA_FbU>P6S)x4Kl)RvU__ZLN#8sC;IWR*ODZyxX~LJ)A$VC7 z&K{fdrS_*6eRAjdQp&XTWok9=I$tx|YW?>4n$g+nT>M(Rt+iiAz{NXT|8)#qyt4=Y z0TiAE4FdB=CvMRD#@#$;u{}rBKNGuM>gIWczOfk?FBYXIHW3^Sg8RV(_1oK-k8Zz5 z(HI^WY?C6}%(q*x4DS-(413S_{n++6B^pkZJsB<1DK9CbJ{I$QG_f+4_f48yF(9*gWaacZdkJ@9K@wdq zOQuG6CCVUPf+)fF%Ch9}Cg!^^bPKZDQsql7BdSjISYpPKLT;8O4dj0FVS2^mLh;33N|W!o5yXYR1m_EX zpA(R0X2M5S@?I~_h|nP-wBfb-F7A}{syX;~6{J#Hnt8u$=Lm!8tHaN9x~-+i|I`sx1P2k&3L^i&t4CVGgc({z%n z>)?zoi@-bN7*H!`Ac+U%@-Zi7IQ+-3u6N%b9=$mX7>mcJTH@39$Hydb zT}wRLJ$&=>W$;)_eEIzK{!!3+s3jine>x7<^d^shvduMz1MbKJ(?8-Yh zeDnG^Sbd;(0FxLzXz4vX;}Eu*tLwhy1>>T8)-88b>c-dJ{4-CS_w-cZ5W#d1FtaV` zi3!ANe4xuj^9qkRtXJU2t+FQ#Z>aK7vzewqVZEcSI@*<6mex1F_4ZzhT;TwPPV-wZ zOQn0Ws(N9c<8Yow(3Xya!Cx(>dat8P=n%qO2nJ=>%n=)jd9e2*EiAV@3-8~LSR6fe zYI++G6e!Y<(z>&*gXvI)SB-4`Xht@2HqLyNPjltVwa{|W4V3ODdojYK_%mMUoK$!i z(R=OA=&0>t8e5-1w2`AN? znmZLcKZsmS$_U-=+AKRLJnmIP%?@tFxgCjPx|qr+!|tw38X*H*1EM85qPfAb$PCSx zx_cILR90_M+{ROiFRTmatOKCDEjZj9EG0#k{d5SlwQBao;&a}$pIiGxw7WL?sOkue zF?8-aJgtR;$#Cd&;G%I$7A*m%VeN&8j@}!gF7wXh64x^-1_}3iY+<12c7C07OXh-k zx7(83bAz(N!E&?BmXa~;a&2jXBeonzXMD#%n%!L0FjXWsx3uqCt*w0r(N?QXz4Nh< za)JfzWVg3fRAVUaUqGFs`bxzpX4OQL`bhmU@k01XrE@*h$ZiO0g~-H*q(mdd$*}`DF1WZSrX2IH!KfB`oG~mkU1J>!>Nc<;E%)!ko;;?`a3TC`I7$pF82o zJP2dP{r+Trd>fc7yKi<980z&R6dgqSE~UZK;XZgy#%_`R4TU3YJqzH zH^D|J05LYC@>+G4Mh>VR7CdLNblnS2yR6`*pVG*6ck~+%N0hTRBF{6fjrK1=mZk z8E$6ZjAO^L!``<^UO@887{p%h_BQg2wS?1zM}W=+{U$VUIfLk!K&rAWkh$m=|_qlhfxD1fxFK0e`@Bo7CM#N)={`%JwC{E zG@cL!T5@gG`Pvc2^0)N=4|U8dI{wh6`*d`!WqrwGwJYQL!g{pp`YFyRE*bH=&5$ zTHMu{Q0O6AbtuZ3(V-ZWHl{SSX9p8rpgl(j;)*iaGaGe`)zzFFFq=1J!RJn#Qr4b1 zXG1fmPHj&0uV~`iOt>uU)FGSESSf6Flg3afrCe~7PnkP3ecH_?A~OK0s|{^r2VpOQ zki8$N70&|D^z|AlNTrQAX54H>L#b!n#D#)v#HqF$JGaa0!<^Y*=}=wGdOD9Qb3_+q zv{+SziD*cE;Sl|07%qb$unscy4tsXou?~+LMtEx%L{_YuxfX#fK^c({ z+6Gzm6~sQmo6utdWK>#}b7Qh5HzX0AFWT!p@O8>-AE(Yhq70K=1}hxj6(XhVO-`BI zbPKk#pUf!{G?_HO@78nVoWzq#$@%Jf8sPz!8itj zKBEI(1?E@ODAXEa6;%2Q90U*u76}G4*(JE^QjZ&rfI9X1=US>&OO6)w+1zZmls*13 zoY__BZiu*U-JcV^lN2FS*Yy63?1-96N!>h8mHRb`>}u7mqTXs3`T*`WP5d%}A0>)* z(Y#fk6&Kresm3qkqmmmxE8n=%E6L|Kf>!oI*K~94SXH|STQjLBmDO9#PD~k@+om52 zg${mDy-Ez`J|Q4NsSgu-e7E%Mxx{>%=QCN-;i5HS02z=N{3%GpxJ ze%k$?+uCB?lFvBg9ZgWHK5mhhr9YxX*irV$apAhqv4Im_twHi$UaCU`SNld1>lkahHnMU0Pb zpuY?~H1jf)HY9Z2)F(Cd++NXQb1UdVW4oAV&F!t82KOaq8eUZ!X?W#sRmQ6sGnE@| zc{g&Y9Li(7&=I`QvQ2z=*8Tgk80A%h^1`$L594KQRi!^$su$)Df0}H42GNI%Z69QQ zKIf=-?(Jn8H_&CO z@+f7>brWAmb-m2e3Sa5YqAaPIr?RtFJ%{)$aL1uM)bY)sI<&}B*vCsZMx7+xbP*3i zBo?DRTcs1*witZ6tiX%>zi8fnWolUty8vRdBn{%3a+K;yVYbr_FPb80bIH)bx}7}#waZMimp z8{If32R^uF+_vi)1aeX{rMz|M`ZBZ>l`5&RBRLeH*6nS}ZaVTj7u(O& zF@|jq4@IXN#&FHnOiLJm9j_;7I^knB-RVM&rf2Y%R?#M^78AxJ^$0haMLnH?RJ2|0 zVi~t}XObcjN{tkO@BHCZ=8}V$U|G#P&uPh~+NK!~6peFVy+CoJDR{BcV39 zATcqMAz?+v-?O=~*%+z`yr4T{U~dGg7CvQjaNCcA%&Npq#XvQd0+)|g_f?291;%%5 zDM}O&WYtY&Xx(7DHkuHd%EH~{AV@nC*}n2{E_F$be7RG$+@X#$9f7y1=r4!4$*(U2 zVW`q}`UY?Qzs&g=28E$#sF_8&!6KRmav+&jY(_&)9Ynj?iEBX@fjxI9*0d$p^aFwx z)z9(5L6RwL#C}}2MtIJ&Zk}liq|5JW55SE&yFm4QZgS&w193=~88tql>oQicuSBV& zVjr8)xYoss4{d~-=Tytr3qpc+<4(__FymPiX3RjkpoG2~#lz}w#az33%O9zBbodk9 zN>q&rulGHxw&xFmQSHLN_RoB7&n^YOQGmKGvXzfh{yYryO#jx?F~nQEOmxxMXqM>CAzFh`~51viBgPa<_X zPQg1Pcp>gqsY;|*Ay@_WsU<{IH~w-wdd$V6M{Re=2aqH40pzuKSus!_Kwg>;AnB2( zr72G$hsu-4m_Lc^>n|ZMw@h?K)UWnye4Z@A;jLT}Zd^RAR9FJN+|)nP6_dt$7{m6% z^>{qFlE>&z2d;X? z^9>LtXuQhY*5ewtVyv8H{KM0io8J5jF-@}3U;$xd4k-KrZXP6y!+}DPFkkIaG}{xt znw+|775f}@u;`ROXaE87&aJwusSUF!0}rO?H_~C(He>KiidKzXleEB2Tn!ly8kNF} zT!HGHv4g|13YpgmmDzbK=W(yJ4ON_%<>Xx}*@lZ$mE~kr+Ii-NY!oOHrkx(UxN@88E?rXT=}Ks_k_EFCHY^9|sB znlKDAU;aAz`J5cBVXd_B`eefe5du52k|~A&c(vKXm;s~-LcP2hhXe+~LZ`nOZ&l+B z?ZDvjL-`|h0(R`0RlGu+CB?*KUi+>o!e%$(n&Wudn$ezev^nd#W`v!2?fyof4g3E6 zxZdAzG*V{OfDklQV`*_yRAy4=M18XXyxLf_1q8wc!wicXvCB-^$ZTc@ceJ}DlVPRr zGMqQ%PK+EwdZLYW1n12(rlA*x7*>e-)Fs&sU%vo^|DzH>S{-hX?<9eLdAhQsbr5sl4z zbP9TtgN2nyzbB`@{UDy3ef>!{)tCsJ5fQZ4Ji?;aifN}$R+qHZNj9=ht(JIkV?4>v ztAssXQ5q+W)gvj3#m0&n2J#L|rrA?$tqvIo+7)&9iBLBEE30%RQ$q@#q0|9u#^oSb z7UsD0Jq|4Zwq7ZLo#UC2SL(n`=~)`R>Mwol6B>o4AV^f9$aTQ#GihWtAmR`<1-4zF z8SrkRAUNMNy4(6n^(earTtiZCP)E$s{^`s*O3{JKM1sHu@JX&eeH<(;dmi&qlW0pU-b9WU~_&vMZ zTt({nlxfmE4T-6m*#fH5Tr;h{>QWyyaURyWsB=f_o;s_ShI5H#&6nK-%kgd8P+Z7x zhsXvc;9pB=l{yn5EMx)Yp7)l6NEi!noUr6l~!B~gVDtV*0LWm{Q;-@qy9RaW=*_GapBtrKd)saz*fbTc{O$(7GU zeRBhX8k^og8x>13wv`IFGUcQc>;_k<3JgyO| zLl|#i*eH}|POuM6W>{MbgWi)8D3^=-gT&Fw{9{9X$WIA`-G+XaGm3#_mrWVS$Pd)! z@y)HJhMLuUz#j+oBC=rVwS6%mFDqG*s>>u*N_Kk`jZFtn7-(P)&wF=1w$s}p z5`gvg`=?ubtheTv6qgQ?ae9^~k4QDuRUHW|FY^bFPLKvV@Y-Hn)CbO#PBFcGEL&XW zM2TWC^TrZHTNMmKS7}!uPGDuOia>cCsXKFWE|%e)!v@VkNEo1uZ8YNp(dTnc44c`J z+O&q^O0BBhbdxp>iqY4I0(WUzsdcAYR|^D(@0^9Uu){~s&+lUbhr@c>v7~~nbok&f zW=r#TvOtUq-JgduU`1VtZ>~E7DGgnrL&!}}%KNppkg>CzmQY!HvF@v zpHF_Nohr|lcBTtpgwP9GJFmndu^g~c6GlD%mw@UsAEyh_^r#kq<+J65o-Q@_gAB3ZLcwMqjU476BrM*mjZd6;+ruJ%k>T`qp1xsso?u*pXM-7BhGuE|Q zh=N)Ko;i)%5mr733_sd>ZZwyAx{;yj6P~+A_?IIB4W394)flxei=38h56eo*X+EEj z1B(cZzPk$%t0$Vn1u%}B2?F?KjIz>L!Q>U7{=f)UjA4V+()bW(#UvaaGPW@okW|WE zqHFw>%M?tp*gt>MM*|iAgz%aFOyZ2RS&6PdS|w+2g-W;;Jfv5K@!1NQ4CO0{3grs} zDq}1K^c#lhT~z&6PJLCdfQ!xwVa1m~2} zx9sdwEf_Tta>^a2@3Z0k`^(@13x8GFuRzI1kun7_uS%r&?)MN)bKwy+E$hWWe0!TV z=mL_2YT{Sul7sUpA}!vi?uu!sLPCJvhTsJU>gK##2i7#c5#+#ovdZ5TX4NtYZl;}r zP`GSA?4HZZK*9@5PKwh&wpYli(t%F(D{0i*s(#&S{ON7oLr*&1)SDLBHCrg!HHI1a zh(D{bH|>J(T@5KaQVo~lBrn3G3$*`|Ol*4D*n9J8|Ee3IWaTl9PN>@9u!eVr=^5PZ z4+B>5{o%{oTlSjMpzfhZS(jdu6@^B#{y!c%gx7{1m=nv9(Ir$;%l zf_>QNs}eZs;fsbR>g1O(tVPj4nf9g|=1~PVX@x3dxp8@cSnS_mDA@w*PQ4C>eD7c- z7(}J5Xz|6UPKrj{JMF+b34&Ny6=>TqDxxJFx)fG}gz50&79r5$cF;D(l#@3Cp^gt=MM5AFNER04^IYDeIc^W+O4#cL(;dl4 zs#f4F5O5rXEx=bS_)+yv;fP9;*-JQe9+4J661DifkAiGq8b#Qqcoe0Rg0qp@kqnoD z;J6SQB}_i`Nm$u3TB2(e(KkUp^^%n{E7$T;q$jcA4EDhN%0M>d2o+;)qKMhXY(Bu~ zIP61i66Iyl=4NZly)0UBu{>>of^v;0N=0HDD94?HmRIOa1(D6-agkU5sMHLCQmg#o zbt)aeX>O}VPCGn2$tmxn;MJ}GNsPN_PqXqZya;n_ucBf!-E)i#Lj9cy5!j~r<(=&9Y5~13tw%;b&`~{K-nxG zxkGl6;JKITH%5&A_lr|4z9MBMd4`RlX7w1t%Rq6qE#+4@T zQF+6;eEMaP7CoF-#i-2r0@?xhMnJOZ-5I^#R5zo#r)6r|&}$&>u(k*i2MLoKakTFV zWq%bW1mm)**SI$!pGUys+}@UD=QR6<&L&t)F_I?g?h&c)oFFJIA*jq`3@)A&zt?gm zD7Y2pfQ^8VxhX2ep3;MxQQ%KF$@CjuLAe1m1Bp6U4pisdMf%s#o7WijR3^sBtI4p4 z>BA@bKvA!A6eojWbV#S)=kz1s$H8{eJqHnpuL)Qw$rWNYO`5w2lH7?K_b9)0hzfnQ znCV5pf`ZG127M7oPA!P~(4#N^s(3_KW9%Si4g30MP1zhK&Qq1aa?4XuANWKSQ*Gsg zB@HTsl_Ah+6ovflflR6K$yD zqu_L+TFq1EhuIadktr2UqEj(?8DosmMdJ#KQ4GifD@Ro!OSRw>Vcadhw2P>L6%PRc$CpP=Og+Z>`}G1MDjgY>(}U@Hm#R2P7JX z)LWf&lVDF;uhVTmQ45`%iXcdw$1Kc=sSLVBdOHU@kY z7yo1M(eBuG4zYO1*IfUsCmz=}N>pp9cTeJJw)PH~EuJm7!&>u5iLfj9hzrMvJ4LkNMZ?;T@cRVj)XH3gfo`Jvcp`%jMLmW z(&W^|uBnS*>Jp8v#ithIr^Lr}@@6h7$FE@7?5NYH&s)PC8U%@2pc6HqBQr?M0>p*6 zuQSh2;cJg+H4upXghi&|L9)!F$XV-U6kecTW=|M(!3l3W1};5c#^Qb-#vqYqCJb`F zIs@OAFyHnP%xGgK+iE@4QTdjpo~>$KyKs*(bniT!!-ilP<$R3AzLVWaXs6ENOOD>- z)Y8?J*fR7DWYI|oQxG+vkaY5EaM9L_AwHpS)*w&qswFM;Qq@wgXuJi9^%+X6L25{| zBQP*r839ZFH*N24dO^FGa4RHE<(o8^k!d4owm2)yn{%ojVBAYY_h&)(WyAyd1biD# z6|-pd5+@xYa-q+)a9F&Eu8BljP@M{VOrV7#8^Z69N^RR+f+FObENY*o>`aORkOf?w z#f>tM2E?cv1j~0}r%U4vab9A`FrhOYvdks=%xNA%%{IU zPyI85lOBkd0o+Pb1A)?aR@IR|@cjMY(m#Sl8^RL=f{xE9MmO$73A~{DYcd)ir+ZP~ zBXghJ-iGAw)=`j3i$ijXR@!7yNCTKe2e*&4d+6DU6{Q!`z*>c{jNT2&fy$^h88Un(F8ujU%Zk{W$ghl!$gL#g6OxErU zfqM|^$WDq==KEI)<8TRQwrpt>yz#F~bhoCIs9jvS3O^d`wlo zSG?i;q#~0=&(dqyPDd$S0eX{jHMiAzYCK}A%PJnpAinon7Dd<#>BOzl9h*bW*Bn=_dxJK zbJmz^y6;Cg=>-}5FbaDfN67skvL^sB zN1k~2geVmq6x29@LF)8-jKgh;P;y z;*{)iRcO#69|UDp#HvCHhLjZ@p2Qf$D#GI*fAD+Y6veh*; zYi*znglJV?yY`Ilqy?`D(COAC!GO|Nhir-4U32BeZe-u5@?*Wlg-1||0!qHrjtKoR z{F^yz%+~1kwo1_5F}hO+EM%r$&)CVYVe9HsNM=J3C7YdMV^;`~gvV2M`YsV7fk>9_ z>v?!bNu_Ja{q5j;2M&WV*-{Y!Up`a0_FqyB(3>)!2iqXJu1XIg5#bw=nx}w$D-&udbr5ZV<`{&?~}KQ(X%Bn1L$^aum105~f|*B?ohT zdsx)plXGYkcJ&l)bjrz6n@MyPKO_6&O)|VjqfZl}ooJX|E(FmGfMDiLkTC5hfx>Az z`W}zTXNJ7~LNf;8HA`VU0v6pdbt3&&Ch)GXE&{4+Qk9&$fhz%^qT3uOXQCfGxHbX9 zw4ViOyH8aWGa;G*5MD@_5Yfb+0qHeiZx@}V1=i6uT}sZ+Lb%wZEdZZ$_SCF9LO34A zK>N{yQtkwBBqhIwUc5R3>nxNbfH`-jbfo3(UM(=A!)>#}?eduros)y7w~bNM?S5I_ zj4of8T|QlK@=yIjomJ}q%8`o@r+Y;JP>J%c6IiFTzYs8foNr%*F}jY?8s%p`3P+~+ zKb@X-)RW(R=z5K3D*TaLeq6_I9Th-m)02Wmn^N4ltd93PEe?6 zV9;|(mLm@m(07t7zQfAM-2}vC7o?@2^_WPsRiPQf z2m?&v3%^HE5t5%^QRh^(#arOFWyTl?P0jQ3FwW>;njUBZ!EcG@yC4QNROZM!8%}@{ zdx`|55-n!B1vR+&mTuF+}ifB48B$qHM_~Cc)xEO-s8L~A3>NWPsC&P5jrU@@Xz`>WH z2PpL-ksAfYrO8;mG%NF{XFv(5pq-IPk4_?CBzH>q#2Duj=~hnAuX)PeW)<}8vMF>` z8ea?Mg`I+=5U8&%wM!J&)?fNiX3(kcTk5V_j;}3C~pMWH>KwGoJ_+=_0G) ztZ%)TqeDes_gn?C!Ep{Zk4MdAc_y_oqS<2Kq#_MuFP=@G=%Jcrqu`q{^yp5Ym*+#O zevvKpX@Wnb1v)ACNv@_uHt_rSvyVT60Ar1UysB)6KG_Vx5O>23jZUaxi*9CCcB|h7 z9m1kTVS|%Foy&W1#Pad|`xhh;sLa^&=)-jyLl6_E=N#|yt#gWaZCaW=#yj_>A(6tt zF#!?UBIf*(tyV9{q`@+M4VInsw5$2vX4C5trh(LgpIB`aG)3u=Qra8UYJ%w)1ij8+ zGZ=LS^}3gx4764=&Q=V7tzgGhHl0$5GB;mm_M~W=W=yC}Gh3c@U;0~CpF)G7#z7Lo zmY%5u#1i((_6@%-HO!X83PC+ZBj^UPs$3^idsBVuOAFPV0V$F09*%dh~oD=@q({MK)q zi&-;~m&tCWjdtd6?ZBZ^2ey2sz;Yo@Cee&p&9qqststK`k`%Lv<8u=WR)6-~=)<2W zra5e4B6={pcio-0Xw+L1ECIA@z&>WMUl-#q3_Z4 zPK;j9VYXlBH%isMdB-F?qcQa(_!guZNnWJ_*J%~k!1hVT@0&60qQNy~91GR^R$&pe z$Q1H7Fv(pekz&l9=aE+Xk4~lj{()V32<5jEHKALldmlCqKM_XHlwVLMUsK7d8Qa*L ze1{36hG3rf1Rvc^cl1>h!j7J7>1*+=j#9v_uBtL4PX|mvP+@FtWh*0s3Hy+?*M)Et zFtawuJ9An9IjE!&s==sik>NV;rG59Ld2L9y8Z>5BFi~{9P54T~7P@Wg^pHpxZ4ey1 zzsbN0M-2C(t=n5nzIS$wdI2tLaJ%yf|KwLMVK9+W8R5ID+18{TdR#smB0lx`!z#fF z!F+7df9T`u0>|5q)UOWZ+9zZeTwuh90qG;V?wASSxQw#%pl8Xesn?k?31I!pPvddG zLF5PAj}6MyEEwR~&RiEvZ8Wm)uboyeJi znzUOA)6)Qd6(`^j85cx$!YL1e3o>MWQN(+(!i&+up3k2}IX0>D;j?w*FumgJt%XH& zvZv`9l-PinANBNT5nSC-sdP%23wa^qghXXXRY)x5Ndo?6_*Te>_?K;P_OFu>897lj zM#@_-0GMe=PqI@_^DdwilkP9z>ve=~mUnqz6;N^$g8Pj~-r%$^5{Bf}L6i3reAPlAlSd`H+|pF(j_JJbiJO1Ut2~7!KIIB#vy9k zx#D747$lVQM)w&DHzvb3Jh?%%icwfv1##+0d0L^P23;xVgf*dMg~SeHu; zo8=h+q{MpIuR4I^liL8)Ym4e-c|G&NYU5rn%Hu5R?Xs8CRsK@ighnr@2i2UXR>TL} zwaCxamqp78qI!yRg1KYK^sUd`i_HgP!oZjaFoc#i4AKtXr`%ATt)^y8{g7Z3pZPxR zR_fJ_(xIPfr9nLkb~eiF1-YV+UN(2HC7K%rq_`rVFBTp(%@JgoL6WPgXReFaC|9oBjOE&$ zlGjo4fL$ypC$gB1Kj#cG$zZ=&nkX+nrqg6LA30Iklv$&l2qS<(C$2d;E~1U*mMk!# z7wukqLV28t2xq!TPedxp`NK8vroen4=l+Cbdj3yM+SHu;b2nrO zRV42#dwv*9h{%j@&uKGViv!}GQvLHzFC`MZl@B)YeeTt8Rr-2@#6c%$PaDc-msDHj1oatHOJ?X=!kJ;zbN z@}O7eLJ6VZqm$&ce$mM{)2)avQ07BCLkR447>%Q_s8*ILeqK*Ka5bvEvT$JamW zc`XId`L8PMxx}mBZ&?h+iSkayF-@we zd|!Q1bFzB6H6cQN4Sv-o)w~WrxF@j`($`OAAc6m>!dCUZ=Cu{Sa<8>iA#)EljiT|P zqw$*7sOT#731oNfpgRlth2f>!0z46-gGE30Q}rr%Ty<&cN9bL7rTR7h)2lZA-16uz z=%Mkaw<0Zjx5!SR(bb7~cp~TkNHB69Kzn<#CcX-<4Kr0sm(?mYr9w?9PIg!Zj~Dz{ zD^ATSAbC?y)!-m(!-mo>2tq1go}X^&U1^Yd0P0C}I`wd(imiS-*~+$t?S8u}{rdED zzdpvB6z4^VaMpVNIBT$Ok+(!V+f+lVA>tMpJa9e&1 zjG(a-=y6|~u$q^$<{b(a*GxDa7pcxls_nMxa>-dqv)**x{h8IkAA%!{K#9i9tWC97 zcc_m%n*QbvUj)sXQM>f~3AO9YpHI8aBGXworqgl+TsE79b2b;PE*V}+s9si)-)#^) zD}T!|L0qF|%mDQ_-cWDkM?QP0Lt_OQu{e8bEKdIF@P_(6QpRXUe;V%`mWV`>`cx;fJW=NeW~DDUE)^Ri=Yh7W`JGD`+Po3XC?0J5Gl( z8E>>{g~>3cf{j-=%dHWamkCpK9l8mG%jP^_tnh#ap)w=wE$F|omyYIVtNRaSX;+y8{Eq{6MueU3M)Oog zUAmc3B<6vsMX79XR&70L`AhtdXH?0_0UZ)ruO)tut}oN9r}RZOzX45(q2mgpr$_$M zL(-4c4KI!#XAp@7rdO%@__4qAXw_d@U4J;UE<6{W5P+@9PZp^hpJicotY9-9I5c_gA!2Kl%85TezxX1GkGp9&OQ!1dOeF}8+bfk zY%kSYFc9*8bvy=BFki$YaVbxMJW|3B>&E`f??VYjZowO}y@FKL-r;sQbDKUd5sdD2 z;s55(88Zv3)AP=rf51ulhhT+!@T*PS+O(v7hycf5A3&ISz5NNqipAhl@rWE~E8}E9 zn2bCk%N2jvd2@K#eDQRUZj=9BAH6@{e?Neq`|xLXcl$H^^JQ@MIl$Ea|N84^FNfDFD?69lqYr~#Yvr=lTEY4|e;vMmu%CVZYcLoPM%G)(z^@lMvp}(2 zzwS)`u%ZhCiv}TIXsEm0JU_zCSQUJi!j+j^A*|2emz3B3$)L&5{T&2a-C4JKEyN>6 z@mnGa7IU-C;vg88T8HW7OBQ^JiF_i(cq;_=yVxEz_fTuO^O!k3-VwYJu72z^D;5>K zUtsb}U?*7>Mp2kgvPi3;r&(3_u>PjX5-u$%0fZQI^buL$N-S;EQh@0LE-ekRm{9|g zO3Uvv<&z6I%`uJ{LR(@z_k*LUMVu~RB&Jx3a7|+Y8-mT|7BfCkl1?J-*g;PO=@B0c z-QG6aMbPxA+08wI_#d-yOwDCk8u;hhBUFV{+iKN{wv{TP)6@!n9p%Pe>%P2MHWX(V zYt+DV!0`s)Jnj)<2-c;wKxP5Wh^B7DvL8WF2POPrg}CQ0^w1RWf)JdDX?xsCSjGjg zl7$7guneW01%Vl7*QjJ{HMREHCSbBzjC28FGifgNSW{nX1JZcrRonIQL zLpOF(o}}mw6xax;Zq670OO)V%K6HT*m{sNtp`#fS(k-nZS_hv?xUSY|c!DAQ+Zc!7 zfAuxhg+~o?3X533%Prq1!mgTk&xuqDm^Jid&@PqIxXm6l@X){m!^+cGN4kYD4U$Rk z=cNG<`QjEFsS?eKy7K4dQIjC9wK|iHyfXn)@sr6Z++C4>*rp0nualhQkeY5KC-LbP ze2L69Bn6PvuHw&t6~+%~lIv@=JaZOG@A^vDOT#jL1t$m39`&N)4DAUsj2xjwixR=2 zgf}+!#xkk3e0X|Uh7SzApz=!rlJF12jgsit2>s@7pP1ztC@i>dHp87#c`PA7V zPn=HK6E);b^hW`fqZVx_ zW{?8NgSFPFhi5PxcK>h&2&Pjls}eUBNrh8KvasjHh=90EsTk6sAZB40_nGg)N-w^s zc$9v{NfKqxj$geDXjPgFmI3Hzkul`h4t?q_0o~BP&!#Fo@jZS3TfkVfZQ7zMRNh`35iC$+;_? z6!|x7EhVj`uvOGs+LQydtbwPMA+?k}Yr6_iQ5>&0PnQWxC|XDjIuBYP=dpmmP1D9X zm@4b^+fN&PLZD%`Fk(vDxKs;aGATpf#Nb!(DlE<$-6)1YbC)YwqsyN-Vz$TMFp%y@ zrlj$mlpaDrzTm31Zc%%X;Ni(6930h@TGC2;WzSE=v9cV1?Y#UBCNy&+M!P&(*PF)6 zVm(ccYN6d2%bjR137rh&#^$MPrVgTCCdx=m^|RTmX{KW?F3TupKD7FAmcxYliTDY+ z6j~^}VzF&QUWWhTFF?2zc?@sDm*EMB2X8{OrUTiuuQnIR=8DEW7ReHZ)u0ATgfUj0 z*LBj3An&AnTTO!OB&FMGLblb!+*T8IK6^J4$-@-sIH4gdpwyP04);R2n@+IG>6Gu( zkR$3axB&tnS%NuWQ5Rw65uJN@wvkShgYKfH)K^Z-`U83bBIsp6!Trt{4w7+M5glSuPAZUw z7%782j@vlPHpxtn7n&vN$8<<{$PyP|QoUmmWmP8(Q-@faCc<hvrZH|T;jP?5u!Uy4u#xKJROpwc)X9dbSIB4xXZatdOK}?RH z^41}@tZ9IJChY0=@`lsz<;{kr&9Xy7ROPDn_7YdMn;6D0;(?7a1fh7J)Wrp=PnYQi z2on=m>nN$*sRkTJi&a46u5%!#L=dT%CP3tW3tRpWu7I!E~uBNzd6}q$(Jec6YQVAX&CsKQD12uK1)3(P>U2jn%vA+JWk8`5(#m3 zXVE#D12#Ve&_@1TROH2xGVO-<4Y8!PN=9p-C>-KTKgx4n;6_?gA{i;$%`3VD6Qu zQ$5ngN(@2RZebn?AqiJv`lgDARN(-aQIBiiqE1SLTzn1ZM?}sxm`-x2q54LAl&?pa3?k%=%!q$=v*68?rLXAWuD0$QTa zJ!anUnQ!-fIsxsW4=+~p_(#-+px*F;lbn`8|l#J(8tF-SQMV(UXVxw~PKA?P+sL`!Ii~ zZ4wFybeN$~1)O3s_5>PLnCnGouw>7HK-IArv@q{_4$ zs%2K6jKwSOPZlCQh9$l9$tFh?IU%uRw=aQ&XG{|Aj501e}41prG$^4I_X literal 0 HcmV?d00001 diff --git a/data/config.all.json b/data/config.all.json new file mode 100644 index 00000000..b01644ad --- /dev/null +++ b/data/config.all.json @@ -0,0 +1,144 @@ +{ + "configs": [ + + "/config.live.json", + "/config.setup.json", + "/config.option.json" + ], + "class":"col-sm-offset-1 col-sm-10", + "content": [ + { + "type": "h5", + "title": "{{SSDP}}", + "class":"alert-warning" + }, +{ + "type": "h4", + "title": "Device ID: {{chipID}}" + }, +{ + "type": "h4", + "title": "IP address: {{ip}}" + }, + { + "type": "hr" + }, +{ + "type": "h2", + "title": "Конфигурация устройства" + }, + { + "type":"file", + "state":"config.all.txt", + "style":"width:100%;height:400px", + "title": "Сохранить", + "action": "/all_modules_init", + "class":"btn btn-block btn-success" + }, + { + "type": "link", + "title": "Инструкция", + "action": "https://github.com/DmitryBorisenko33/esp8266_iot-manager_modules_firmware/wiki/Instruction", + "class": "btn btn-block btn-primary" + }, +{ + "type": "h2", + "title": "Сценарии" + }, +{ +"type": "checkbox", +"name":"scenario", +"title": "Включить сценарии", +"action": "/scenario?status=[[scenario]]", +"state": "{{scenario}}" +}, +{ + "type": "h6", + "title": "" + }, +{ + "type":"file", + "state":"scenario.all.txt", + "style":"width:100%;height:400px", + "title": "Сохранить и включить", + "action": "/scenario?status=1", + "class":"btn btn-block btn-success" + }, +{ + "type": "h2", +"title": "Данные модулей" + }, +{ + "type": "hr" + }, +{ + "type": "h4", + "title": "Модуль уровня воды (level)", +"style": "width:100%" + }, + + { + "type": "h6", + "title": "Расстояние от датчика до воды: {{level_in}} см" + }, +{ + "type": "h6", + "title": " Заполнение бака: {{level}} %" + }, +{ + "type": "hr" + }, +{ + "type": "h4", + "title": "Модуль аналогового входа (analog)", +"style": "width:100%" + }, +{ + "type": "h6", + "title": "Прочитанное значение: {{analog_in}}" + }, +{ + "type": "h6", + "title": "Преобразованное значение: {{analog}}" + }, + { + "type": "hr" + }, +{ + "type": "h4", + "title": "Модуль температурного датчика (dallas)", +"style": "width:100%" + }, +{ + "type": "h6", + "title": "Текущее значение: {{dallas}} °C" + }, +{ + "type": "hr" + }, +{ + "type": "h4", + "title": "Модуль pH сенсора от df robot (ph)", +"style": "width:100%" + }, +{ + "type": "h6", + "title": "Текущее значение: {{ph}}" + }, +{ + "type": "hr" + }, + { + "type": "link", + "title": "Очистить все логи", + "action": "/cleanlog", + "class": "btn btn-block btn-success" + }, + { + "type": "link", + "title": "Главная", + "action": "/page.htm?index", + "class": "btn btn-block btn-danger btn-sm" + } + ] +} diff --git a/data/config.all.txt b/data/config.all.txt new file mode 100644 index 00000000..c66ef541 --- /dev/null +++ b/data/config.all.txt @@ -0,0 +1,19 @@ +button 1 na Включить#все Освещение 0 1 +button 2 13 Прихожая Освещение 0 2 +button 3 14 Кухня Освещение 0 3 +pwm 1 3 Яркость#коредор: Освещение 1023 4 +pwm 2 4 Яркость#ванная: Освещение 510 5 +analog Аналоговый#вход,#% Датчики text 1 1024 1 1024 6 +logging analog 1 144 график Датчики 7 +input value1 20.0 5 порог.#значение Датчики 8 +button 4 na Вкл#по#analog>20 Датчики 0 11 +//dallas 2 Водонагреватель,#t°C Датчики termometr 14 +//level Вода#в#баке,#% Датчики gauge 125 20 15 +//ph pH Датчики text 0 16 +input value2 8.0 1 период#сек Таймер 117 +button 5 na Вкл#обратный#таймер Таймер 0 20 +button 6 5 Включится#по#таймеру Таймер 0 21 +switch 1 0 20 +text 1 Квартира Двери 22 +button 7 scenario Сценарии Настройки 1 23 +button 8 line1,line2, 2строки#сценариев Освещение 1 24 \ No newline at end of file diff --git a/data/config.json b/data/config.json new file mode 100644 index 00000000..7e08ab5b --- /dev/null +++ b/data/config.json @@ -0,0 +1 @@ +{"SSDP":"MODULES","chipID":"12884479-1458415","ssidAP":"WiFi","passwordAP":"","ssid":"MGTS_GPON_DC15","password":"HKC4MRE4","timezone":3,"mqttServer":"91.204.228.124","mqttPort":1883,"mqttUser":"rise","mqttPass":"23ri22se32","scenario":"1","timers":"0","pushingbox_id":"v670C4F8A2581A11"} \ No newline at end of file diff --git a/data/css/build.css.gz b/data/css/build.css.gz new file mode 100644 index 0000000000000000000000000000000000000000..4bf6e06001ba59fb28f775adfad194fffa985f28 GIT binary patch literal 15178 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 E0O(?Z-~a#s literal 0 HcmV?d00001 diff --git a/data/edit.htm b/data/edit.htm new file mode 100644 index 00000000..5e2f46ce --- /dev/null +++ b/data/edit.htm @@ -0,0 +1,572 @@ + + + + ESP Editor + + + + + + +
+
+
+ + + + diff --git a/data/edit.htm.gz b/data/edit.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..f1e48f7e7ebc62dfd1606da393b77a6d8c7f6444 GIT binary patch literal 5794 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

0jH>*O} z&|_p~!HcJ4;WyL1n&R|Ef~SbQIsbbSza>(#KN^i@33un)fiaqF59VJg47~`4CJyis zH}7jM{LcoCZ}0MK0r%I8aF00iS0>UVGYF*7-YIL#!HA(>b+8aF6PX$a7D>JK^0RNm zU@x`>m*^JUJp0CT(Ns^3dzKl*;U`Ms^wUn^mT>wSw7dbdNn@TE+~azh0sAi+4c0%F zo)f4fEOE2mY18EDsB|?b zqTpbZk}jliN>e*_3j28`nN6DLdVeQCN{*E0t0)ug7+Gc zMH}vl7Njw%g(9z!xds2kH+&8txv@#Y=97R;ShssgymY%OD7XKUj3f}@DUa8J_eox+ zE|B++;7WoDZ)l?gT}t*PyFSwKdtuneOd`-74HM!HD3P1I8|26(5)En}ZrSf(ZsOBX zf24I^3f#534TV& g5LW_-D}YE5h=^D;_~p+O{pru&03N9usuENH0JWN6kN^Mx literal 0 HcmV?d00001 diff --git a/data/favicon.ico b/data/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..198474d246359b14553a1d0eac6b208cd8fe6160 GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x%b3`hubNaqE~Hu_nK#=vljw{%%U zywY^%yv*t1zH!Ndo-r{XEaVjzCz;;b#v&vk0dr76xKYc^rJ?_CEVRPF2B-f2N5_T- z{{9z_tgMFV4|32-xVfs}|IKA#|8KAGgyUPw-TvF1`~Tko2^$0T8gBpdU&tvs23`N% zO|}1#!S^>e{@?tHEb{-qzCB7Z86IJ@ZY%U zGb(QW@ZW1!BL;Te)A?5^#;Xbz{_H$5a+20njlzb}2{0^bk&vkxQ#D7oC}56ioMVHG zn_&VBtHwCgvkUP_!t_%@|Nqaxa1WT18kiXv4xr%%MxZzlV~7LQ-Lq$40O + + + + + + + + + + + + + + + +

+ + diff --git a/data/index.htm.gz b/data/index.htm.gz new file mode 100644 index 0000000000000000000000000000000000000000..139f0040889174476a6bea5be844dae04d7ea073 GIT binary patch literal 1444 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
+ + +
+ + +
+ +