diff --git a/app/commands.py b/app/commands.py index 6d4b3a3..1e02ec2 100644 --- a/app/commands.py +++ b/app/commands.py @@ -10,15 +10,14 @@ def seed_defaults(): "butterbox_logo": current_app.config["BUTTERBOX_LOGO"], "ssid": current_app.config["BUTTERBOX_SSID"], "wifi_password": current_app.config["BUTTERBOX_WIFI_PASSWORD"], - "enable_access_point": current_app.config["ENABLE_ACCESS_POINT"], + "disable_access_point": current_app.config["DISABLE_ACCESS_POINT"], "apply_changes": "false", "onboarding_complete": "false", "lock_root_password": "false", - "enable_file_viewer": current_app.config["ENABLE_FILE_VIEWER"], - "enable_map_viewer": current_app.config["ENABLE_MAP_VIEWER"], - "enable_chat": current_app.config["ENABLE_CHAT"], - "enable_app_store": current_app.config["ENABLE_APP_STORE"], - "enable_deltachat": current_app.config["ENABLE_DELTACHAT"], + "disable_file_viewer": current_app.config["DISABLE_FILE_VIEWER"], + "disable_map_viewer": current_app.config["DISABLE_MAP_VIEWER"], + "disable_chat": current_app.config["DISABLE_CHAT"], + "disable_app_store": current_app.config["DISABLE_APP_STORE"], "ssh_password": "", "admin_password": current_app.config["ADMIN_PASSWORD"], } diff --git a/app/forms.py b/app/forms.py index 72cf5e5..43548bd 100644 --- a/app/forms.py +++ b/app/forms.py @@ -14,17 +14,16 @@ class LoginForm(FlaskForm): class SettingsForm(FlaskForm): # Access point settings ssid = StringField('SSID', validators=[DataRequired()]) - wifi_password = StringField(_l('WiFi Password')) - enable_access_point = BooleanField(_l('Enable Access Point')) + wifi_password = PasswordField(_l('WiFi Password')) + disable_access_point = BooleanField(_l('Disable Access Point')) # Customisation settings butterbox_name = StringField(_l('Butterbox Name'), validators=[DataRequired()]) butterbox_logo = FileField((_l('Butterbox Logo')), validators=[FileAllowed(['jpg', 'png', 'svg'], 'Images only!')]) # Services settings - enable_file_viewer = BooleanField(_l('Enable File Viewer')) - enable_map_viewer = BooleanField(_l('Enable Map Viewer')) - enable_chat = BooleanField(_l('Enable Chat')) - enable_app_store = BooleanField(_l('Enable App Store')) - enable_deltachat = BooleanField(_l('Enable DeltaChat')) + disable_file_viewer = BooleanField(_l('Disable File Viewer')) + disable_map_viewer = BooleanField(_l('Disable Map Viewer')) + disable_chat = BooleanField(_l('Disable Chat')) + disable_app_store = BooleanField(_l('Disable App Store')) # Access Settings admin_password = PasswordField(_l('Admin Password')) ssh_password = PasswordField(_l('SSH Password')) diff --git a/app/routes.py b/app/routes.py index 11aefdc..f715551 100644 --- a/app/routes.py +++ b/app/routes.py @@ -1,65 +1,18 @@ +from email.mime import image + +from alembic.util import obfuscate_url_pw + from app import app -from flask import render_template, flash, redirect, url_for, request, session, send_file +from flask import render_template, flash, redirect, url_for, request, session from app.forms import LoginForm, SettingsForm from flask_login import login_user, current_user, logout_user, login_required import sqlalchemy as sa from app import db from app.models import User, Setting -import os +from werkzeug.datastructures import FileStorage import json from flask_babel import _ import base64 -import random -from wordfreq import top_n_list -import secrets -import string -import glob -import time -import qrcode -from datetime import datetime - -def gen_username() -> str: - words = top_n_list("en", 5000) - prefix = random.randint(1000, 9999) - return f"{random.choice(words)}{random.choice(words)}{prefix}" - -def gen_password() -> str: - characters = string.ascii_letters + string.digits - password = ''.join(secrets.choice(characters) for i in range(20)) - return password -def get_file_suffix(path: str) -> str: - return os.path.splitext(path)[1].strip('.') # in case of multiple exts, like .tar.gz, it only splits on the last one - -def get_file_icon_url(path: str) -> str: - if os.path.isdir(path): - return url_for("static", filename=f"images/extension-icons/directory.svg") - - suffix = get_file_suffix(path) - if suffix: - if suffix in ['apk', 'deb', 'dmg', 'exe', 'jpg', 'mp3', 'pbf', 'pdf', 'png', - 'ppt', 'pptx']: - return url_for("static", filename=f"images/extension-icons/ext-{suffix}.svg") - return url_for("static", filename=f"images/extension-icons/ext-unknown.svg") -def get_last_modified(path: str) -> str: - mod_time = time.ctime(os.path.getmtime(path)) - #print(mod_time) - #dt = datetime.strptime(mod_time, "%a %b %d %H:%M:%S %Y") - #formatted_time = dt.strftime("%Y-%m-%d %H:%M") - return mod_time - -def get_files_in_path(path: str): - file_list = [] - if os.path.exists(path): - list_of_files = glob.glob(path + "/*", recursive=True) - file_list = [ - {"name": x.replace(path, "").strip("/"), "path": x, "is_file": os.path.isfile(x), - "is_dir": os.path.isdir(x), - "filetype": get_file_suffix(x), "last_modified": get_last_modified(x), - "icon_url": get_file_icon_url(x), - "relative_path": x.replace(app.config["BUTTERBOX_USB_PATH"], "")} for x - in list_of_files] - print(file_list) - return file_list def get_setting(name) -> str: setting = db.session.scalar(sa.select(Setting).where(Setting.key == name)) @@ -67,6 +20,7 @@ def get_setting(name) -> str: def set_setting(name: str, value: str): setting = db.session.scalar(sa.select(Setting).where(Setting.key == name)) + print(f"I have changed {setting.key}") setting.value = value db.session.add(setting) @@ -79,67 +33,33 @@ def dump_settings(filename: str) -> None: @app.route('/') @app.route('/index') def index(): - display_wifi_password = False - wifi_password = get_setting("wifi_password") - if wifi_password: - wifi_ssid = get_setting("ssid") - wifi_encryption_type = "WPA2" - img = qrcode.make(f"WIFI:T:{wifi_encryption_type};S:{wifi_ssid};P:{wifi_password};;") - img.save("app/static/images/wifi_qr_code.png") - display_wifi_password = True - else: - os.remove("app/static/images/wifi_qr_code.png") - enable_chat = get_setting("enable_chat") - enable_app_store = get_setting("enable_app_store") - enable_map_viewer = get_setting("enable_map_viewer") - enable_file_viewer = get_setting("enable_file_viewer") - enable_deltachat = get_setting("enable_deltachat") + disable_chat = get_setting("disable_chat") + disable_app_store = get_setting("disable_app_store") + disable_map_viewer = get_setting("disable_map_viewer") + disable_file_viewer = get_setting("disable_file_viewer") service_array = [] usb_inserted = False # actual test of whether USB is inserted - if os.path.exists(app.config["BUTTERBOX_USB_PATH"]): - usb_inserted = True usb_has_maps = False # actual test of whether USB has maps folder usb_has_appstore = False # actual test of whether USB has an appstore - if enable_deltachat == 'true': - service_array.append({"name": "Secure Messaging", "image": url_for("static", filename="images/deltachat-icon.png"), "url": url_for("messaging") }) - if enable_chat == 'true': + if disable_chat == 'false': service_array.append({"name": "Message Board", "image": url_for("static", filename="images/chat-icon.png"), "url": app.config["CONVENE_INSTALL_PATH"] }) - if enable_app_store == 'true' and usb_has_appstore: + if disable_app_store == 'false' and usb_has_appstore: service_array.append({"name": "Apps", "image": url_for("static", filename="images/appstore-icon.svg")}) - if enable_map_viewer == 'true' and usb_has_maps: + if disable_map_viewer == 'false' and usb_has_maps: service_array.append({"name": "Offline Maps", "image": url_for("static", filename="images/maps-icon.png")}) - if enable_file_viewer == 'true': + if disable_file_viewer == 'false': name = "Files" if not usb_inserted: name = "Insert USB to browse files" service_array.append({ "name": name, "image": url_for("static", filename="images/explore-icon.svg"), - "url": url_for("files", path=""),}) - return render_template('index.html', title='Home', get_setting=get_setting, services=service_array, display_wifi_password=display_wifi_password) + "url": url_for("usb")}) + return render_template('index.html', title='Home', get_setting=get_setting, services=service_array) -@app.route('/files/', defaults={'path': ''}) -@app.route('/files/') -def files(path): - base_path = app.config["BUTTERBOX_USB_PATH"] - if not os.path.exists(base_path): - flash(_('No USB inserted.')) - current_path = os.path.join(base_path, path) - render_files = [] - if os.path.exists(current_path): - render_files = get_files_in_path(current_path) - if not render_files: - flash(_('Empty directory.')) - else: - flash(_('Path does not exist.')) - return render_template('usb-file-viewer.html', title='File Viewer', current_path=current_path, render_files=render_files, get_setting=get_setting) - -@app.route('/serve_file/') -def serve_file(filepath): - full_path = os.path.realpath(filepath) - if not filepath.startswith(app.config["BUTTERBOX_USB_PATH"]): - redirect(url_for('files', path="")) - return send_file(full_path) +@app.route('/usb') +def usb(): + return render_template('usb-file-viewer.html', title='File Viewer') @app.route('/login', methods=['GET', 'POST']) def login(): @@ -165,9 +85,9 @@ def logout(): @login_required def admin(): form = SettingsForm() - populate_settings = ['butterbox_name', 'wifi_password', 'enable_access_point', 'ssid', 'enable_file_viewer', 'enable_map_viewer', 'enable_app_store', 'enable_chat', 'enable_deltachat' ] + populate_settings = ['butterbox_name', 'wifi_password', 'disable_access_point', 'ssid', 'disable_file_viewer', 'disable_map_viewer', 'disable_app_store', 'disable_chat' ] - bool_settings = ['enable_access_point','enable_file_viewer', 'enable_map_viewer', 'enable_app_store', 'enable_chat', 'enable_deltachat'] + bool_settings = ['disable_access_point','disable_file_viewer', 'disable_map_viewer', 'disable_app_store', 'disable_chat'] if not form.is_submitted(): for s in populate_settings: @@ -175,7 +95,7 @@ def admin(): getattr(form, s).data = (get_setting(s) == "true") else: getattr(form, s).data = get_setting(s) - non_admin_settings_changed = False + if form.validate_on_submit(): if form.submit.data: for s in populate_settings: @@ -186,8 +106,7 @@ def admin(): if new_value != existing_value: print(f"New value was changed for {s}. Existing value was {existing_value}, new value was {new_value}") set_setting(s, new_value) - non_admin_settings_changed = True - if s in ['butterbox_name', 'wifi_password', 'ssid', 'enable_access_point', 'enable_chat', 'enable_delta_chat']: + if s in ['butterbox_name', 'wifi_password', 'ssid', 'disable_access_point']: app.config['SETTINGS_CHANGED'] = True new_logo = form.butterbox_logo.data @@ -198,21 +117,18 @@ def admin(): new_value = f"data:{file_mimetype};base64,{b64_logo}" existing_value = get_setting('butterbox_logo') if new_value != existing_value: + print( f"New value was changed for logo") set_setting('butterbox_logo', new_value) - non_admin_settings_changed = True new_admin_password = form.admin_password.data if new_admin_password: existing_admin_password = get_setting('admin_password') if new_admin_password != existing_admin_password: + print( f"New value was changed for admin password") set_setting('admin_password', new_admin_password) - non_admin_settings_changed = True + print(get_setting('admin_password')) if app.config['SETTINGS_CHANGED']: - flash(_("⚠️ Some settings won't fully take effect until the Butter Box restarts. Click 'Apply Changes' to restart.")) - else: - if non_admin_settings_changed: - flash( - _("Settings successfully changed.")) + flash(_("⚠️ Some settings won't take effect until the Butter Box restarts. Click 'Apply Changes' to restart.")) db.session.commit() if form.apply_changes.data: @@ -220,20 +136,5 @@ def admin(): dump_settings("settings.txt") flash(_("⚠️ Changes applied! Please wait for the box to restart.")) + return render_template('admin.html', get_setting=get_setting, form=form) - - -@app.route('/messaging', methods=['GET', 'POST']) -def messaging(): - return render_template('messaging.html', get_setting=get_setting) - -@app.route("/deltachat_credentials", methods=["POST"]) -def generate_random_deltachat_credentials(): - ip = app.config['BUTTERBOX_DEFAULT_IP'] - username = gen_username() - password = gen_password() - - flash(f"Username: {username}") - flash(f"Password: {password}") - flash(f"IP: {ip}") - return redirect(url_for("messaging")) \ No newline at end of file diff --git a/app/static/DeltaChat_2.35.0_APKPure.apk b/app/static/DeltaChat_2.35.0_APKPure.apk deleted file mode 100644 index 94b5a3a..0000000 Binary files a/app/static/DeltaChat_2.35.0_APKPure.apk and /dev/null differ diff --git a/app/static/butter_styles.css b/app/static/butter_styles.css index d7e2e4a..c45feec 100644 --- a/app/static/butter_styles.css +++ b/app/static/butter_styles.css @@ -18,11 +18,4 @@ html { padding: 10px; } -} -@media (max-width: 468px) { - - .file-viewer-date-modified { - display: none; - } - } \ No newline at end of file diff --git a/app/static/images/deltachat-icon.png b/app/static/images/deltachat-icon.png deleted file mode 100644 index 0715643..0000000 Binary files a/app/static/images/deltachat-icon.png and /dev/null differ diff --git a/app/static/images/extension-icons/directory.svg b/app/static/images/extension-icons/directory.svg deleted file mode 100644 index 897a905..0000000 --- a/app/static/images/extension-icons/directory.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/app/static/images/extension-icons/ext-apk.svg b/app/static/images/extension-icons/ext-apk.svg deleted file mode 100644 index 89ef6bc..0000000 --- a/app/static/images/extension-icons/ext-apk.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-deb.svg b/app/static/images/extension-icons/ext-deb.svg deleted file mode 100644 index 6aa2f95..0000000 --- a/app/static/images/extension-icons/ext-deb.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-dmg.svg b/app/static/images/extension-icons/ext-dmg.svg deleted file mode 100644 index 52c8da0..0000000 --- a/app/static/images/extension-icons/ext-dmg.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-exe.svg b/app/static/images/extension-icons/ext-exe.svg deleted file mode 100644 index 7014d94..0000000 --- a/app/static/images/extension-icons/ext-exe.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-jpg.svg b/app/static/images/extension-icons/ext-jpg.svg deleted file mode 100644 index 31a1c39..0000000 --- a/app/static/images/extension-icons/ext-jpg.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-mp3.svb b/app/static/images/extension-icons/ext-mp3.svb deleted file mode 100644 index ed31bce..0000000 --- a/app/static/images/extension-icons/ext-mp3.svb +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-pbf.svg b/app/static/images/extension-icons/ext-pbf.svg deleted file mode 100644 index de2298d..0000000 --- a/app/static/images/extension-icons/ext-pbf.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-pdf.svg b/app/static/images/extension-icons/ext-pdf.svg deleted file mode 100644 index 6ecc493..0000000 --- a/app/static/images/extension-icons/ext-pdf.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-png.svg b/app/static/images/extension-icons/ext-png.svg deleted file mode 100644 index 31a1c39..0000000 --- a/app/static/images/extension-icons/ext-png.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-ppt.svg b/app/static/images/extension-icons/ext-ppt.svg deleted file mode 100644 index a51103b..0000000 --- a/app/static/images/extension-icons/ext-ppt.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-pptx.svg b/app/static/images/extension-icons/ext-pptx.svg deleted file mode 100644 index a51103b..0000000 --- a/app/static/images/extension-icons/ext-pptx.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/static/images/extension-icons/ext-unknown.svg b/app/static/images/extension-icons/ext-unknown.svg deleted file mode 100644 index 287dd02..0000000 --- a/app/static/images/extension-icons/ext-unknown.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/app/templates/admin.html b/app/templates/admin.html index 9523433..2ed362e 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -1,16 +1,13 @@ {% extends "base.html" %} {% block content %} -

{{ _('Application Settings') }}

- +

{{ _('Application Settings') }}

{% import "bulma_wtf.html" as wtf %}
{{ form.hidden_tag() }} -

{{ form.submit( class="button is-link") }} - {% if config['SETTINGS_CHANGED'] %} - {{ form.apply_changes(class="button is-warning") }} - {% endif %} -

+ {% if config['SETTINGS_CHANGED'] %} +

{{ form.apply_changes(class="button is-warning") }}

+ {% endif %}
{{ wtf.form_input_field(form.ssid) }}

This is the name of the advertised Wi-Fi network. Current SSID: {{ get_setting('ssid') }}

@@ -26,27 +23,23 @@ Current name: {{ get_setting('butterbox_name') }}, accessed at {{ get_setting('butterbox_name') }}.local.

- {{ wtf.form_bool_field(form.enable_access_point) }} + {{ wtf.form_bool_field(form.disable_access_point) }}

Whether this box will advertise a WiFi network.

- {{ wtf.form_bool_field(form.enable_map_viewer) }} + {{ wtf.form_bool_field(form.disable_map_viewer) }}

Whether map services are enabled.

- {{ wtf.form_bool_field(form.enable_chat) }} + {{ wtf.form_bool_field(form.disable_chat) }}

Whether chat services are enabled.

- {{ wtf.form_bool_field(form.enable_deltachat) }} -

Whether secure messaging using DeltaChat is enabled.

-
-
- {{ wtf.form_bool_field(form.enable_file_viewer) }} + {{ wtf.form_bool_field(form.disable_file_viewer) }}

Whether files services via USB are enabled.

- {{ wtf.form_bool_field(form.enable_app_store) }} + {{ wtf.form_bool_field(form.disable_app_store) }}

Whether app store services are enabled.

@@ -62,7 +55,7 @@

This is the logo shown in the UI. Current logo:

- +

{{ form.submit( class="button is-link") }}

Logout diff --git a/app/templates/base.html b/app/templates/base.html index 47d81e2..c869fc7 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -19,7 +19,7 @@

{{ get_setting('butterbox_name') }}

-
+
{% block content %}{% endblock %}
{% with messages = get_flashed_messages() %} {% if messages %}
@@ -31,9 +31,6 @@
{% endif %} {% endwith %} - - {% block content %}{% endblock %} - diff --git a/app/templates/index.html b/app/templates/index.html index b995f90..c258b68 100644 --- a/app/templates/index.html +++ b/app/templates/index.html @@ -2,8 +2,7 @@ {% block content %}

Hi, welcome to the {{get_setting('butterbox_name')}}.

-

View and download the information you want from this offline box.

- +

View and download the information you want from this offline box.

{% for service in services %} @@ -12,14 +11,7 @@
{% endfor %} - - - {% if display_wifi_password %} -
-

Connect to this box with wifi: - -

-
- {% endif %} + + {% endblock %} \ No newline at end of file diff --git a/app/templates/messaging.html b/app/templates/messaging.html deleted file mode 100644 index dc09044..0000000 --- a/app/templates/messaging.html +++ /dev/null @@ -1,19 +0,0 @@ -{% extends "base.html" %} - -{% block content %} -

{{ _('Secure Messaging') }}

- -
-

To use secure messaging, install Delta Chat and then return to this page to create your local offline account

-
- - -
-
- -
-{% endblock %} \ No newline at end of file diff --git a/app/templates/usb-file-viewer.html b/app/templates/usb-file-viewer.html deleted file mode 100644 index dba7fbb..0000000 --- a/app/templates/usb-file-viewer.html +++ /dev/null @@ -1,39 +0,0 @@ -{% extends "base.html" %} - -{% block content %} -

{{ _('File Viewer') }}

- -
- - - - - - - - - - - {% for f in render_files %} - - - {% if f.is_dir %} - - {% endif %} - - {% if f.is_file %} - - {% endif %} - - - {% if f.is_file %} - - {% endif %} - {% if f.is_dir %} - - {% endif %} - - {% endfor %} - -
File NameDate modifiedDownload
{{ f.name}}{{ f.name}}{{ f.last_modified}}Download
- {% endblock %} \ No newline at end of file diff --git a/config.py b/config.py index c8a9fb8..1b77d7e 100644 --- a/config.py +++ b/config.py @@ -9,17 +9,14 @@ class Config: BUTTERBOX_SSID= "butterbox" BUTTERBOX_WIFI_PASSWORD= "" LANGUAGES = ['en', 'ro'] - BUTTERBOX_DEFAULT_IP = "10.0.1.37" - BUTTERBOX_USB_PATH = "/media/usb-butter" BUTTERBOX_NAME = "Butter Box" BUTTERBOX_LOGO = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjc5IiBoZWlnaHQ9IjIzNiIgdmlld0JveD0iMCAwIDI3OSAyMzYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIG9wYWNpdHk9IjAuOSI+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTEzOS4zODggMTk3LjYzNkMxNzIuMjg0IDE5Ny42MzYgMTk4Ljk1MiAxNzAuOTY4IDE5OC45NTIgMTM4LjA3MkMxOTguOTUyIDEwNS4xNzUgMTcyLjI4NCA3OC41MDcgMTM5LjM4OCA3OC41MDdDMTA2LjQ5MSA3OC41MDcgNzkuODIzIDEwNS4xNzUgNzkuODIzIDEzOC4wNzJDNzkuODIzIDE3MC45NjggMTA2LjQ5MSAxOTcuNjM2IDEzOS4zODggMTk3LjYzNloiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTM5LjYxMiA0LjAzMjU5VjYwLjM3NTRDMTM0LjgxNyA1Ny40NTM0IDEzMS4xNDYgNDUuOTE1MSAxMzEuMTQ2IDMyLjIwNEMxMzEuMjIxIDE4LjQ5MjkgMTM0LjgxNyA2Ljk1NDYzIDEzOS42MTIgNC4wMzI1OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNNjAuNDE3OCAxMzkuNDJINEM2LjkyMjA0IDE0NC4yMTUgMTguNDYwMyAxNDcuODg3IDMyLjE3MTQgMTQ3Ljg4N0M0NS45NTc0IDE0Ny44ODcgNTcuNDk1NyAxNDQuMjE1IDYwLjQxNzggMTM5LjQyWiIgZmlsbD0iI0ZFRjVCOCIgc3Ryb2tlPSIjRkVGNUI4IiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBvcGFjaXR5PSIwLjkiIGQ9Ik0yNzUgMTM5LjY0NUgyMTguNjU3QzIyMS41NzkgMTM0Ljg1IDIzMy4xMTggMTMxLjE3OSAyNDYuODI5IDEzMS4xNzlDMjYwLjU0IDEzMS4yNTQgMjcyLjA3OCAxMzQuODUgMjc1IDEzOS42NDVaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTIzNS4zNjUgNDMuODE3M0wxOTUuNTA2IDgzLjY3NjlDMTk0LjE1NyA3OC4yMDc0IDE5OS43NzYgNjcuNDkzMyAyMDkuNDQyIDU3LjgyODFDMjE5LjI1NyA0OC4wODggMjI5Ljg5NiA0Mi40Njg3IDIzNS4zNjUgNDMuODE3M1oiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNODMuNjQ0MiA4My41MjY5TDQzLjc4NDcgNDMuNjY3NEM0Mi40MzYxIDQ5LjEzNjggNDguMDU1NCA1OS44NTA5IDU3LjcyMDUgNjkuNTE2MUM2Ny40NjA3IDc5LjI1NjIgNzguMTc0OCA4NC44NzU1IDgzLjY0NDIgODMuNTI2OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTgyLjkxOCAzNC45MDEyTDE2Ny41NTkgNzIuMTM4NUMxNjUuMTYxIDY4LjkxNjcgMTY1LjkxMSA2MC4zMDA1IDE2OS42NTcgNTEuMjM0N0MxNzMuNDAzIDQyLjE2ODkgMTc4Ljk0NyAzNS41MDA2IDE4Mi45MTggMzQuOTAxMloiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNNzMuMDA1MSAxMTQuMDIxTDM1Ljg0MjggOTguNjYxNkMzNi40NDIyIDEwMi42MzMgNDMuMTEwNCAxMDguMTc3IDUyLjE3NjIgMTExLjkyM0M2MS4yNDIgMTE1LjY2OSA2OS43ODMzIDExNi40MTkgNzMuMDA1MSAxMTQuMDIxWiIgZmlsbD0iI0ZFRjVCOCIgc3Ryb2tlPSIjRkVGNUI4IiBzdHJva2Utd2lkdGg9IjQiIHN0cm9rZS1taXRlcmxpbWl0PSIxMCIvPgo8cGF0aCBvcGFjaXR5PSIwLjkiIGQ9Ik0yNDcuNjUzIDE4NC41MjRMMjEwLjQxNiAxNjkuMjRDMjEzLjYzNyAxNjYuODQyIDIyMi4yNTQgMTY3LjU5MiAyMzEuMzE5IDE3MS4zMzhDMjQwLjM4NSAxNzUuMDg0IDI0Ny4wNTMgMTgwLjU1MyAyNDcuNjUzIDE4NC41MjRaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjxwYXRoIG9wYWNpdHk9IjAuOSIgZD0iTTY3LjIzNTkgMTcwLjg4OEwzMC4wNzM2IDE4Ni4zMjNDMzMuMjk1MyAxODguNzIgNDEuODM2NyAxODcuOTcxIDUwLjkwMjUgMTg0LjIyNUM2MC4wNDMyIDE4MC40MDQgNjYuNjM2NSAxNzQuODU5IDY3LjIzNTkgMTcwLjg4OFoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMjQ1LjEwNSA5NS4yODk5TDIwNy45NDMgMTEwLjc5OUMyMDguNTQyIDEwNi44MjggMjE1LjEzNiAxMDEuMjg0IDIyNC4yMDIgOTcuNTM3NkMyMzMuMjY3IDkzLjcxNjUgMjQxLjgwOSA5Mi44OTI0IDI0NS4xMDUgOTUuMjg5OVoiIGZpbGw9IiNGRUY1QjgiIHN0cm9rZT0iI0ZFRjVCOCIgc3Ryb2tlLXdpZHRoPSI0IiBzdHJva2UtbWl0ZXJsaW1pdD0iMTAiLz4KPHBhdGggb3BhY2l0eT0iMC45IiBkPSJNMTEwLjA5MiA3My4wMzc3TDk0LjY1OCAzNS44NzU0QzkyLjI2MDQgMzkuMDk3MSA5My4wODQ2IDQ3LjcxMzQgOTYuODMwOCA1Ni43NzkyQzEwMC41NzcgNjUuODQ1IDEwNi4xMjEgNzIuNDM4MyAxMTAuMDkyIDczLjAzNzdaIiBmaWxsPSIjRkVGNUI4IiBzdHJva2U9IiNGRUY1QjgiIHN0cm9rZS13aWR0aD0iNCIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIi8+CjwvZz4KPHBhdGggZD0iTTIwMy4xMyAxNzguOTM2QzE5OC4xMTkgMTc4LjIyIDE5Mi4zOTMgMTc3Ljc5MSAxOTAuMjQ2IDE3NS41NzJDMTg4LjQ1NyAxNzMuNzExIDE5Mi44OTQgMTY3LjYyNyAxODguNzQzIDE2MS44M0MxODcuODg0IDE2MC42ODUgMTg2LjUyNCAxNTkuNTM5IDE4NC45NSAxNTguNjA5VjEzOS43MTNDMTg0Ljk1IDEzNi4xMzUgMTgzLjE2IDEzMi44NDIgMTgwLjE1NCAxMzAuODM4TDE0NC40MzkgMTA4LjA3OEMxNDAuOTMyIDEwNS43ODcgMTM2LjQyMyAxMDUuNzg3IDEzMi45MTUgMTA4LjA3OEw5Ny4xMjg1IDEzMC45MUM5NC4xMjI0IDEzMi44NDIgOTIuMzMzIDEzNi4yMDYgOTIuMzMzIDEzOS43MTNWMTU4Ljc1MkM5MS4yNTk0IDE1OS4zOTYgOTAuMzI5IDE1OS45NjkgODkuNzU2NCAxNjAuMzk4QzgzLjk1ODkgMTY0LjMzNSA4OC4wMzg2IDE3MS40OTIgODUuODE5OCAxNzUuMjg2QzgzLjAyODQgMTc5Ljg2NiA4MC40NTE3IDE3OC44NjQgNzMuMDA4IDE4MC45NEM2Ni40OTQ4IDE4Mi42NTggNjMuNDE3MSAxOTQuMTgxIDg2LjUzNTUgMTg4LjQ1NUM4OS4xMTIyIDE4Ny44MTEgOTAuNTQzNiAxODcuNTI1IDkzLjQ3ODIgMTg5LjQ1N0MxMDAuNTY0IDE5My45NjYgOTMuMzM1MSAyMDguMjEgOTkuOTkxNCAyMTAuNDI4QzEwOS44NjkgMjEzLjcyMSAxMDIuNDI1IDE4OS40NTcgMTA4LjE1MSAxOTEuMDMyQzExMC44NzEgMTkyLjM5MiAxMTMuMzA0IDE5NC4zOTYgMTE0LjMwNiAxOTcuNjE3QzExNy4xNjkgMjA1LjIwNCAxMTIuNzMyIDIzMy4yNjEgMTIwLjAzMiAyMzQuNDc3QzEyOC40NzggMjM1Ljc2NiAxMjQuMTEyIDIwMy43IDEyOC4wNDggMjAyLjI2OUMxMzAuNDEgMjAxLjQxIDEzMi43MDEgMjA1LjU2MSAxMzguNDk4IDIwNi4yMDZDMTQzLjE1MSAyMDYuNzA3IDE0Ny45NDYgMjAzLjcgMTQ5LjY2NCAyMDIuMjY5QzE1NC41MzEgMTk4LjExOCAxNTcuODk1IDE5Ni41NDMgMTYxLjgzMSAxOTYuMTE0QzE3Mi4zNTMgMTk0Ljg5NyAxNjMuMTkxIDIyMC45NSAxNzIuOTk3IDIxOS44MDVDMTgxLjY1NyAyMTYuOTQyIDE3MS4yMDggMTk1LjA0IDE4Ni44MTEgMTg5LjI0M0MxOTIuODk0IDE4Ny4wOTUgMjA1LjA2MiAxOTAuMDMgMjA5LjI4NSAxODguMzEyQzIxMy4zNjUgMTg2LjUyMyAyMTEuNjQ3IDE3OS43OTUgMjAzLjEzIDE3OC45MzZaIiBmaWxsPSIjRkNFMzYzIi8+CjxwYXRoIGQ9Ik0xMjAuNTMzIDIzNS45MDlDMTIwLjMxOCAyMzUuOTA5IDEyMC4wMzIgMjM1LjkwOSAxMTkuODE3IDIzNS44MzdDMTE0LjE2MyAyMzQuOTA3IDExNC4wOTIgMjI0LjA5OSAxMTQuMDIgMjEyLjY0N0MxMTQuMDIgMjA2Ljc3OCAxMTMuOTQ4IDIwMC42OTQgMTEyLjk0NiAxOTguMDQ2VjE5Ny45NzVDMTEyLjIzMSAxOTUuNjg0IDExMC41MTMgMTkzLjgyMyAxMDcuNzIxIDE5Mi4zMkMxMDcuMTQ5IDE5My4xMDggMTA3LjA3NyAxOTYuODI5IDEwNy4wNzcgMTk5LjEyQzEwNy4wNzcgMjA0LjEzIDEwNy4wMDYgMjA5LjM1NSAxMDQuMjE0IDIxMS4zNTlDMTAyLjk5OCAyMTIuMjE4IDEwMS40MjMgMjEyLjM2MSA5OS41NjIgMjExLjc4OEM5NS4yNjc2IDIxMC4zNTcgOTUuMzM5MiAyMDUuNTYxIDk1LjQ4MjMgMjAwLjk4MUM5NS41NTM5IDE5Ni44MjkgOTUuNjI1NCAxOTIuNTM1IDkyLjc2MjUgMTkwLjY3NEM5MC4yNTc0IDE4OS4wMjggODkuMjU1NCAxODkuMjQzIDg2Ljk2NSAxODkuODg3QzcwLjcxNzcgMTkzLjg5NSA2Ny42NCAxODkuMzg2IDY3LjEzOSAxODcuMjM5QzY2LjM1MTcgMTg0LjE2MSA2OC45OTk5IDE4MC41ODIgNzIuNzkzMyAxNzkuNThDNzQuODY5IDE3OS4wMDggNzYuNTg2OCAxNzguNzIxIDc3Ljk0NjcgMTc4LjQzNUM4MS42Njg1IDE3Ny43MTkgODMuMDI4NCAxNzcuNDMzIDg0Ljc0NjIgMTc0LjY0MUM4NS4zOTA0IDE3My41NjggODUuMzE4OCAxNzEuNzc5IDg1LjI0NzIgMTY5LjkxOEM4NS4xMDQgMTY2LjQ4MiA4NC44ODkzIDE2Mi4xODggODkuMTEyMiAxNTkuMzI1Qzg5LjU0MTYgMTU4Ljk2NyA5MC4xODU4IDE1OC41MzcgOTEuMDQ0NyAxNTguMDM2VjEzOS43ODVDOTEuMDQ0NyAxMzUuNzc3IDkzLjEyMDMgMTMxLjkxMiA5Ni40ODQzIDEyOS43NjVMMTMyLjI3MSAxMDYuOTMyQzEzNi4yMDggMTA0LjM1NiAxNDEuMzYxIDEwNC4zNTYgMTQ1LjM2OSAxMDYuOTMyTDE4MS4wODUgMTI5LjY5M0MxODQuNTIgMTMxLjk4MyAxODYuNTI0IDEzNS43MDUgMTg2LjUyNCAxMzkuNzg1VjE1Ny44OTNDMTg3Ljk1NiAxNTguODI0IDE4OS4xNzMgMTU5Ljk2OSAxOTAuMDMyIDE2MS4wNDJDMTkyLjk2NiAxNjUuMTIyIDE5Mi4xNzkgMTY5LjI3MyAxOTEuNjc4IDE3Mi4wNjVDMTkxLjUzNSAxNzIuOTk1IDE5MS4yNDggMTc0LjM1NSAxOTEuNDYzIDE3NC42NDFDMTkyLjk2NiAxNzYuMjE2IDE5Ny40MDQgMTc2Ljc4OSAyMDEuMzQgMTc3LjI5QzIwMi4wNTYgMTc3LjM2MSAyMDIuNzcyIDE3Ny41MDQgMjAzLjQxNiAxNzcuNTc2QzIwOS43ODYgMTc4LjI5MiAyMTIuNTA2IDE4MS43MjcgMjEyLjkzNSAxODQuNDQ3QzIxMy4yOTMgMTg2LjY2NiAyMTIuMTQ4IDE4OC43NDIgMjEwLjAwMSAxODkuNjcyQzIwNy43MSAxOTAuNjAyIDIwMy45MTcgMTkwLjM4OCAxOTkuNjIyIDE5MC4xMDFDMTk1LjMyOCAxODkuODg3IDE5MC4zODkgMTg5LjYgMTg3LjQ1NSAxOTAuNjAyQzE3OS40MzkgMTkzLjYwOSAxNzkuMDgxIDIwMS4xOTUgMTc4Ljc5NCAyMDguNTY4QzE3OC41MDggMjE0LjI5MyAxNzguMjkzIDIxOS42NjIgMTczLjY0MSAyMjEuMjM2TDE3My4zNTUgMjIxLjMwOEMxNzEuNzggMjIxLjUyMiAxNzAuNDIgMjIxLjE2NSAxNjkuMzQ3IDIyMC4yMzRDMTY2Ljc3IDIxOC4wODcgMTY2LjYyNyAyMTMuMzYzIDE2Ni40MTIgMjA4LjQyNEMxNjYuMjY5IDIwNC4zNDUgMTY2LjA1NCAxOTkuNjkyIDE2NC4zMzYgMTk4LjE4OUMxNjMuOTc5IDE5Ny45MDMgMTYzLjQwNiAxOTcuNTQ1IDE2Mi4xODkgMTk3LjY4OEMxNTguMzk2IDE5OC4xMTggMTU1LjI0NyAxOTkuNjkyIDE1MC44MDkgMjAzLjQ4NkMxNTAuNTIzIDIwMy43MDEgMTQ0Ljc5NyAyMDguNDI0IDEzOC41NyAyMDcuNzhDMTM1LjEzNCAyMDcuNDIyIDEzMi44NDQgMjA1LjkxOSAxMzEuMTI2IDIwNC44NDZDMTMwLjEyNCAyMDQuMjAyIDEyOS4yNjUgMjAzLjcwMSAxMjguODM2IDIwMy43NzJDMTI4LjA0OCAyMDQuODQ2IDEyNy43NjIgMjEwLjcxNSAxMjcuNjE5IDIxNS4wMDlDMTI3LjI2MSAyMjMuNTI3IDEyNi45MDMgMjMyLjMzIDEyMy4zOTYgMjM1LjE5M0MxMjIuMzk0IDIzNS41NTEgMTIxLjQ2NCAyMzUuOTA5IDEyMC41MzMgMjM1LjkwOVpNMTE1LjY2NiAxOTcuMTE2QzExNi44MTEgMjAwLjI2NSAxMTYuODgzIDIwNi4yNzcgMTE2Ljg4MyAyMTIuNjQ3QzExNi44ODMgMjIwLjUyIDExNi45NTQgMjMyLjQ3MyAxMjAuMjQ3IDIzMy4wNDZDMTIwLjY3NiAyMzMuMTE3IDEyMS4wMzQgMjMzLjA0NiAxMjEuMzIxIDIzMi43NkMxMjMuODI2IDIzMC43NTYgMTI0LjE4MyAyMjEuNDUxIDEyNC40NyAyMTQuNjUxQzEyNC44MjggMjA1Ljk5MSAxMjUuMTE0IDIwMS43NjggMTI3LjQ3NiAyMDAuOTA5QzEyOS4yNjUgMjAwLjI2NSAxMzAuNzY4IDIwMS4yNjcgMTMyLjQxNCAyMDIuMjY5QzEzNC4wNjEgMjAzLjI3MSAxMzUuODUgMjA0LjQ4OCAxMzguNTcgMjA0Ljc3NEMxNDIuNzkzIDIwNS4yMDQgMTQ3LjMwMiAyMDIuMzQxIDE0OC42NjIgMjAxLjE5NUMxNTMuNTI5IDE5Ny4wNDQgMTU3LjE3OSAxOTUuMTgzIDE2MS42MTcgMTk0LjY4MkMxNjMuMzM0IDE5NC40NjcgMTY0LjgzOCAxOTQuODk3IDE2NS45ODMgMTk1LjgyN0MxNjguNzAzIDE5OC4xMTggMTY4LjkxNyAyMDIuOTg1IDE2OS4wNiAyMDguMTM4QzE2OS4yMDQgMjEyLjA3NSAxNjkuNDE4IDIxNi41ODQgMTcwLjk5MyAyMTcuOTQ0QzE3MS4yNzkgMjE4LjE1OCAxNzEuNzA5IDIxOC40NDUgMTcyLjYzOSAyMTguMzczQzE3NS4xNDQgMjE3LjQ0MyAxNzUuNDMgMjEzLjkzNiAxNzUuNjQ1IDIwOC4zNTNDMTc2LjAwMyAyMDAuODM4IDE3Ni4zNjEgMTkxLjUzMyAxODYuMjM4IDE4Ny44ODNDMTg5Ljc0NSAxODYuNjY2IDE5NC43NTUgMTg2Ljk1MiAxOTkuNTUxIDE4Ny4yMzlDMjAzLjIwMSAxODcuNDUzIDIwNi45OTUgMTg3LjY2OCAyMDguNjQxIDE4Ny4wMjRDMjA5LjU3MSAxODYuNjY2IDIxMC4wMDEgMTg1Ljg3OSAyMDkuODU4IDE4NC44NzdDMjA5LjU3MSAxODMuMDg3IDIwNy4yODEgMTgwLjg2OCAyMDIuODQzIDE4MC40MzlIMjAyLjc3MkMyMDIuMDU2IDE4MC4zNjcgMjAxLjQxMiAxODAuMjI0IDIwMC42OTYgMTgwLjE1M0MxOTUuODI5IDE3OS41MDkgMTkxLjMyIDE3OC45MzYgMTg5LjEwMSAxNzYuNjQ2QzE4Ny44ODQgMTc1LjM1NyAxODguMjQyIDE3My40OTYgMTg4LjYgMTcxLjU2NEMxODkuMTAxIDE2OC45ODcgMTg5LjY3NCAxNjUuNzY2IDE4Ny40NTUgMTYyLjc2QzE4Ni43MzkgMTYxLjgzIDE4NS41MjIgMTYwLjc1NiAxODQuMDkxIDE1OS45NjlMMTgzLjM3NSAxNTkuNTM5VjEzOS44NTdDMTgzLjM3NSAxMzYuNzc5IDE4MS44MDEgMTMzLjkxNiAxNzkuMjI0IDEzMi4xOThMMTQzLjY1MiAxMDkuMjIzQzE0MC42NDUgMTA3LjIxOSAxMzYuNzA5IDEwNy4yMTkgMTMzLjcwMyAxMDkuMjIzTDk3LjkxNTggMTMyLjA1NUM5NS4zMzkxIDEzMy43MDEgOTMuNzY0NSAxMzYuNjM2IDkzLjc2NDUgMTM5LjY0MlYxNTkuNDY4TDkzLjA0ODggMTU5Ljg5N0M5Mi4xMTgzIDE2MC40NyA5MS4xMTYzIDE2MS4wNDIgOTAuNjE1MiAxNjEuNDcyQzg3LjY4MDcgMTYzLjQ3NiA4Ny44MjM5IDE2Ni40ODIgODcuOTY3IDE2OS42MzFDODguMDM4NiAxNzEuODUgODguMTgxOCAxNzQuMTQgODcuMTA4MSAxNzYuMDAxQzg0Ljc0NjIgMTc5LjkzOCA4Mi4yNDExIDE4MC40MzkgNzguNDQ3NyAxODEuMTU1Qzc3LjAxNjIgMTgxLjQ0MSA3NS40NDE2IDE4MS43MjcgNzMuNTA5MSAxODIuM0M3MS4wNzU2IDE4Mi45NDQgNjkuNTcyNSAxODUuMDkxIDY5LjkzMDQgMTg2LjQ1MUM3MC4zNTk4IDE4OC4wOTcgNzQuMjk2NCAxOTAuMDMgODYuMzIwOCAxODcuMDk1Qzg5LjExMjIgMTg2LjM4IDkxLjA0NDcgMTg2LjA5MyA5NC40MDg3IDE4OC4zMTJDOTguNzAzMSAxOTEuMDMyIDk4LjU2IDE5Ni40IDk4LjQ4ODQgMjAxLjEyNEM5OC40MTY4IDIwNS42MzMgOTguNDg4NCAyMDguNDk2IDEwMC42MzYgMjA5LjIxMkMxMDIuMDY3IDIwOS43MTMgMTAyLjU2OCAyMDkuMzU1IDEwMi43MTEgMjA5LjIxMkMxMDQuMzU3IDIwOC4wNjcgMTA0LjM1NyAyMDIuOTg1IDEwNC4zNTcgMTk5LjMzNUMxMDQuMzU3IDE5NC45NjggMTA0LjQyOSAxOTEuNjA1IDEwNi4yMTggMTkwLjI0NUMxMDYuNzE5IDE4OS44ODcgMTA3LjUwNyAxODkuNTI5IDEwOC43MjMgMTg5LjgxNUwxMDkuMDEgMTg5Ljg4N0MxMTIuNDQ1IDE5MS41MzMgMTE0LjczNiAxOTMuOTY2IDExNS42NjYgMTk3LjExNloiIGZpbGw9IiMwMTAwMDQiLz4KPHBhdGggZD0iTTE1MC4wMjIgMTY2LjEyNEMxNTIuODEzIDE3MC4zNDcgMTQ2LjA4NSAxOTQuMTEgMTM4LjI4NCAxOTQuMTFDMTI4LjY5MyAxOTQuMTEgMTIzLjg5NyAxNjkuODQ2IDEyNi40NzQgMTY2LjEyNEMxMjcuOTA1IDE2NC4wNDkgMTMxLjQxMyAxNjguMzQzIDEzOC42NDEgMTY4LjM0M0MxNDUuMzY5IDE2OC4zNDMgMTQ4LjU5IDE2My45MDUgMTUwLjAyMiAxNjYuMTI0WiIgZmlsbD0iIzAxMDAwNCIvPgo8cGF0aCBkPSJNMTc1LjIxNiAxNTkuNjgzQzE3Ni45MzQgMTYwLjExMiAxNzguMjkzIDE1OC4zMjMgMTc3LjA3NyAxNTcuMTc4QzE3NS4yODcgMTU1LjYwMyAxNzIuMTM4IDE1My4xNjkgMTY2LjU1NSAxNTMuMTY5QzE2MS4xMTYgMTUzLjE2OSAxNTcuNzUyIDE1NS42MDMgMTU1LjY3NiAxNTcuMjQ5QzE1NC4yNDUgMTU4LjM5NCAxNTUuNjc2IDE2MC4zMjcgMTU3LjUzNyAxNTkuODI2QzE2MC4wNDIgMTU5LjE4MiAxNjMuMjYzIDE1Ny42MDcgMTY2LjY5OCAxNTcuNjA3QzE3MC4xMzQgMTU3Ljc1IDE3My4wNjkgMTU5LjE4MiAxNzUuMjE2IDE1OS42ODNaIiBmaWxsPSIjMDEwMDA0Ii8+CjxwYXRoIGQ9Ik0xMTkuMTAyIDE1OS42ODNDMTIwLjgxOSAxNjAuMTEyIDEyMi4xNzkgMTU4LjMyMyAxMjAuOTYzIDE1Ny4xNzhDMTE5LjE3MyAxNTUuNjAzIDExNi4wMjQgMTUzLjE2OSAxMTAuNDQxIDE1My4xNjlDMTA1LjAwMiAxNTMuMTY5IDEwMS42MzggMTU1LjYwMyA5OS41NjIgMTU3LjI0OUM5OC4xMzA1IDE1OC4zOTQgOTkuNTYyIDE2MC4zMjcgMTAxLjQyMyAxNTkuODI2QzEwMy45MjggMTU5LjE4MiAxMDcuMTQ5IDE1Ny42MDcgMTEwLjU4NCAxNTcuNjA3QzExNC4wOTIgMTU3Ljc1IDExNi45NTUgMTU5LjE4MiAxMTkuMTAyIDE1OS42ODNaIiBmaWxsPSIjMDEwMDA0Ii8+CjxwYXRoIGQ9Ik0xMDkuODY5IDE4Mi41ODZDMTE2LjE1NCAxODIuNTg2IDEyMS4yNDkgMTc4LjUxNyAxMjEuMjQ5IDE3My40OTZDMTIxLjI0OSAxNjguNDc2IDExNi4xNTQgMTY0LjQwNiAxMDkuODY5IDE2NC40MDZDMTAzLjU4MyAxNjQuNDA2IDk4LjQ4ODMgMTY4LjQ3NiA5OC40ODgzIDE3My40OTZDOTguNDg4MyAxNzguNTE3IDEwMy41ODMgMTgyLjU4NiAxMDkuODY5IDE4Mi41ODZaIiBmaWxsPSIjRkVGNUI4Ii8+CjxwYXRoIGQ9Ik0xNjYuNjk4IDE4Mi41ODZDMTcyLjk4MyAxODIuNTg2IDE3OC4wNzkgMTc4LjUxNyAxNzguMDc5IDE3My40OTZDMTc4LjA3OSAxNjguNDc2IDE3Mi45ODMgMTY0LjQwNiAxNjYuNjk4IDE2NC40MDZDMTYwLjQxMyAxNjQuNDA2IDE1NS4zMTggMTY4LjQ3NiAxNTUuMzE4IDE3My40OTZDMTU1LjMxOCAxNzguNTE3IDE2MC40MTMgMTgyLjU4NiAxNjYuNjk4IDE4Mi41ODZaIiBmaWxsPSIjRkVGNUI4Ii8+CjxwYXRoIGQ9Ik0xMzMuMjAyIDE1Mi4wOTZMMTA3LjQzNSAxMzYuMjA2QzEwNS45MzIgMTM1LjI3NiAxMDUuOTMyIDEzMy4wNTcgMTA3LjQzNSAxMzIuMTI3TDEzMy4yMDIgMTE2LjIzN0MxMzYuMzUxIDExNC4zMDUgMTQwLjI4OCAxMTQuMzA1IDE0My40MzcgMTE2LjIzN0wxNjkuMjAzIDEzMi4xMjdDMTcwLjcwNiAxMzMuMDU3IDE3MC43MDYgMTM1LjI3NiAxNjkuMjAzIDEzNi4yMDZMMTQzLjQzNyAxNTIuMDk2QzE0MC4yODggMTU0LjAyOCAxMzYuMjc5IDE1NC4wMjggMTMzLjIwMiAxNTIuMDk2WiIgZmlsbD0iI0ZFRjVCOCIvPgo8cGF0aCBkPSJNMTM1LjYzNSAxOTAuMzg4QzEzMi4yNzEgMTg3LjgxMSAxMzMuMjAyIDE3OC41NzggMTM5LjE0MiAxNzcuNTA0QzE0NC4xNTMgMTc2LjU3NCAxNDYuNTE1IDE3OC4yMiAxNDMuMzY1IDE4NC45NDhDMTQwLjIxNiAxOTEuODkxIDEzNy4yMSAxOTEuNTMzIDEzNS42MzUgMTkwLjM4OFoiIGZpbGw9IiNGRUY1QjgiLz4KPC9zdmc+Cg==" ADMIN_PASSWORD = "admin" - ENABLE_ACCESS_POINT = "true" - ENABLE_CHAT = "true" - ENABLE_APP_STORE = "true" - ENABLE_MAP_VIEWER = "true" - ENABLE_FILE_VIEWER = "true" - ENABLE_DELTACHAT = "true" + DISABLE_ACCESS_POINT = "false" + DISABLE_CHAT = "false" + DISABLE_APP_STORE = "false" + DISABLE_MAP_VIEWER = "false" + DISABLE_FILE_VIEWER = "false" CONVENE_INSTALL_PATH = "/chat" \ No newline at end of file