From c8881407f6a983b47f3943e4d752025a612da5d2 Mon Sep 17 00:00:00 2001 From: wupg98 <106410199+wupg98@users.noreply.github.com> Date: Sat, 2 Sep 2023 08:10:50 +0200 Subject: [PATCH] Add files via upload --- src/Test/BenchmarkSsl.py | 162 ++ src/Test/Spy.py | 23 + src/Test/TestCached.py | 59 + src/Test/TestConfig.py | 31 + src/Test/TestConnectionServer.py | 118 + src/Test/TestContent.py | 273 +++ src/Test/TestContentUser.py | 390 ++++ src/Test/TestCryptBitcoin.py | 48 + src/Test/TestCryptConnection.py | 23 + src/Test/TestCryptHash.py | 31 + src/Test/TestDb.py | 137 ++ src/Test/TestDbQuery.py | 31 + src/Test/TestDebug.py | 52 + src/Test/TestDiff.py | 58 + src/Test/TestEvent.py | 65 + src/Test/TestFileRequest.py | 124 ++ src/Test/TestFlag.py | 39 + src/Test/TestHelper.py | 79 + src/Test/TestMsgpack.py | 88 + src/Test/TestNoparallel.py | 167 ++ src/Test/TestPeer.py | 159 ++ src/Test/TestRateLimit.py | 100 + src/Test/TestSafeRe.py | 24 + src/Test/TestSite.py | 70 + src/Test/TestSiteDownload.py | 562 +++++ src/Test/TestSiteStorage.py | 25 + src/Test/TestThreadPool.py | 163 ++ src/Test/TestTor.py | 153 ++ src/Test/TestTranslate.py | 61 + src/Test/TestUiWebsocket.py | 11 + src/Test/TestUpnpPunch.py | 274 +++ src/Test/TestUser.py | 50 + src/Test/TestWeb.py | 105 + src/Test/TestWorkerTaskManager.py | 128 ++ src/Test/__init__.py | 0 src/Test/conftest.py | 497 +++++ src/Test/coverage.ini | 15 + src/Test/pytest.ini | 6 + .../content.json | 133 ++ .../css/all.css | 385 ++++ .../data-default/data.json | 10 + .../data-default/users/content-default.json | 25 + .../data/data.json | 244 +++ .../data/img/autoupdate.png | Bin 0 -> 24460 bytes .../data/img/direct_domains.png | Bin 0 -> 16185 bytes .../data/img/domain.png | Bin 0 -> 11881 bytes .../data/img/memory.png | Bin 0 -> 12775 bytes .../data/img/multiuser.png | Bin 0 -> 29480 bytes .../data/img/progressbar.png | Bin 0 -> 13294 bytes .../data/img/slides.png | Bin 0 -> 14439 bytes .../data/img/slots_memory.png | Bin 0 -> 9488 bytes .../data/img/trayicon.png | Bin 0 -> 19040 bytes .../data/img/zeroblog-comments.png | Bin 0 -> 24001 bytes .../data/img/zeroid.png | Bin 0 -> 18875 bytes .../data/img/zeroname.png | Bin 0 -> 36031 bytes .../data/img/zerotalk-mark.png | Bin 0 -> 44862 bytes .../data/img/zerotalk-upvote.png | Bin 0 -> 41092 bytes .../data/img/zerotalk.png | Bin 0 -> 26606 bytes .../data/optional.txt | 1 + .../data/test_include/content.json | 14 + .../data/test_include/data.json | 37 + .../content.json | 15 + .../data.json | 12 + .../content.json | 24 + .../data.json | 12 + .../peanut-butter-jelly-time.gif | Bin 0 -> 1606 bytes .../content.json | 17 + .../data.json | 12 + .../data/users/content.json | 30 + .../dbschema.json | 54 + .../img/loading.gif | Bin 0 -> 723 bytes .../index.html | 137 ++ .../js/all.js | 1892 +++++++++++++++++ src/Tor/TorManager.py | 309 +++ src/Tor/__init__.py | 1 + 75 files changed, 7765 insertions(+) create mode 100644 src/Test/BenchmarkSsl.py create mode 100644 src/Test/Spy.py create mode 100644 src/Test/TestCached.py create mode 100644 src/Test/TestConfig.py create mode 100644 src/Test/TestConnectionServer.py create mode 100644 src/Test/TestContent.py create mode 100644 src/Test/TestContentUser.py create mode 100644 src/Test/TestCryptBitcoin.py create mode 100644 src/Test/TestCryptConnection.py create mode 100644 src/Test/TestCryptHash.py create mode 100644 src/Test/TestDb.py create mode 100644 src/Test/TestDbQuery.py create mode 100644 src/Test/TestDebug.py create mode 100644 src/Test/TestDiff.py create mode 100644 src/Test/TestEvent.py create mode 100644 src/Test/TestFileRequest.py create mode 100644 src/Test/TestFlag.py create mode 100644 src/Test/TestHelper.py create mode 100644 src/Test/TestMsgpack.py create mode 100644 src/Test/TestNoparallel.py create mode 100644 src/Test/TestPeer.py create mode 100644 src/Test/TestRateLimit.py create mode 100644 src/Test/TestSafeRe.py create mode 100644 src/Test/TestSite.py create mode 100644 src/Test/TestSiteDownload.py create mode 100644 src/Test/TestSiteStorage.py create mode 100644 src/Test/TestThreadPool.py create mode 100644 src/Test/TestTor.py create mode 100644 src/Test/TestTranslate.py create mode 100644 src/Test/TestUiWebsocket.py create mode 100644 src/Test/TestUpnpPunch.py create mode 100644 src/Test/TestUser.py create mode 100644 src/Test/TestWeb.py create mode 100644 src/Test/TestWorkerTaskManager.py create mode 100644 src/Test/__init__.py create mode 100644 src/Test/conftest.py create mode 100644 src/Test/coverage.ini create mode 100644 src/Test/pytest.ini create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/css/all.css create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/users/content-default.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/autoupdate.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/direct_domains.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/domain.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/memory.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/multiuser.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/progressbar.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/slides.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/slots_memory.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/trayicon.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroblog-comments.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroid.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroname.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-mark.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-upvote.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk.png create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/optional.txt create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/data.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/content.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/dbschema.json create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/img/loading.gif create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/index.html create mode 100644 src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/js/all.js create mode 100644 src/Tor/TorManager.py create mode 100644 src/Tor/__init__.py diff --git a/src/Test/BenchmarkSsl.py b/src/Test/BenchmarkSsl.py new file mode 100644 index 00000000..06181b89 --- /dev/null +++ b/src/Test/BenchmarkSsl.py @@ -0,0 +1,162 @@ +#!/usr/bin/python2 +from gevent import monkey +monkey.patch_all() +import os +import time +import sys +import socket +import ssl +sys.path.append(os.path.abspath("..")) # Imports relative to src dir + +import io as StringIO +import gevent + +from gevent.server import StreamServer +from gevent.pool import Pool +from Config import config +config.parse() +from util import SslPatch + +# Server +socks = [] +data = os.urandom(1024 * 100) +data += "\n" + + +def handle(sock_raw, addr): + socks.append(sock_raw) + sock = sock_raw + # sock = ctx.wrap_socket(sock, server_side=True) + # if sock_raw.recv( 1, gevent.socket.MSG_PEEK ) == "\x16": + # sock = gevent.ssl.wrap_socket(sock_raw, server_side=True, keyfile='key-cz.pem', + # certfile='cert-cz.pem', ciphers=ciphers, ssl_version=ssl.PROTOCOL_TLSv1) + # fp = os.fdopen(sock.fileno(), 'rb', 1024*512) + try: + while True: + line = sock.recv(16 * 1024) + if not line: + break + if line == "bye\n": + break + elif line == "gotssl\n": + sock.sendall("yes\n") + sock = gevent.ssl.wrap_socket( + sock_raw, server_side=True, keyfile='../../data/key-rsa.pem', certfile='../../data/cert-rsa.pem', + ciphers=ciphers, ssl_version=ssl.PROTOCOL_TLSv1 + ) + else: + sock.sendall(data) + except Exception as err: + print(err) + try: + sock.shutdown(gevent.socket.SHUT_WR) + sock.close() + except: + pass + socks.remove(sock_raw) + +pool = Pool(1000) # do not accept more than 10000 connections +server = StreamServer(('127.0.0.1', 1234), handle) +server.start() + + +# Client + + +total_num = 0 +total_bytes = 0 +clipher = None +ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDH+AES128:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:HIGH:" + \ + "!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK" + +# ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + + +def getData(): + global total_num, total_bytes, clipher + data = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + # sock = socket.ssl(s) + # sock = ssl.wrap_socket(sock) + sock.connect(("127.0.0.1", 1234)) + # sock.do_handshake() + # clipher = sock.cipher() + sock.send("gotssl\n") + if sock.recv(128) == "yes\n": + sock = ssl.wrap_socket(sock, ciphers=ciphers, ssl_version=ssl.PROTOCOL_TLSv1) + sock.do_handshake() + clipher = sock.cipher() + + for req in range(20): + sock.sendall("req\n") + buff = StringIO.StringIO() + data = sock.recv(16 * 1024) + buff.write(data) + if not data: + break + while not data.endswith("\n"): + data = sock.recv(16 * 1024) + if not data: + break + buff.write(data) + total_num += 1 + total_bytes += buff.tell() + if not data: + print("No data") + + sock.shutdown(gevent.socket.SHUT_WR) + sock.close() + +s = time.time() + + +def info(): + import psutil + import os + process = psutil.Process(os.getpid()) + if "memory_info" in dir(process): + memory_info = process.memory_info + else: + memory_info = process.get_memory_info + while 1: + print(total_num, "req", (total_bytes / 1024), "kbytes", "transfered in", time.time() - s, end=' ') + print("using", clipher, "Mem:", memory_info()[0] / float(2 ** 20)) + time.sleep(1) + +gevent.spawn(info) + +for test in range(1): + clients = [] + for i in range(500): # Thread + clients.append(gevent.spawn(getData)) + gevent.joinall(clients) + + +print(total_num, "req", (total_bytes / 1024), "kbytes", "transfered in", time.time() - s) + +# Separate client/server process: +# 10*10*100: +# Raw: 10000 req 1000009 kbytes transfered in 5.39999985695 +# RSA 2048: 10000 req 1000009 kbytes transfered in 27.7890000343 using ('ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256) +# ECC: 10000 req 1000009 kbytes transfered in 26.1959998608 using ('ECDHE-ECDSA-AES256-SHA', 'TLSv1/SSLv3', 256) +# ECC: 10000 req 1000009 kbytes transfered in 28.2410001755 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 13.3828125 +# +# 10*100*10: +# Raw: 10000 req 1000009 kbytes transfered in 7.02700018883 Mem: 14.328125 +# RSA 2048: 10000 req 1000009 kbytes transfered in 44.8860001564 using ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 20.078125 +# ECC: 10000 req 1000009 kbytes transfered in 37.9430000782 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 20.0234375 +# +# 1*100*100: +# Raw: 10000 req 1000009 kbytes transfered in 4.64400005341 Mem: 14.06640625 +# RSA: 10000 req 1000009 kbytes transfered in 24.2300000191 using ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 19.7734375 +# ECC: 10000 req 1000009 kbytes transfered in 22.8849999905 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 17.8125 +# AES128: 10000 req 1000009 kbytes transfered in 21.2839999199 using ('AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.1328125 +# ECC+128: 10000 req 1000009 kbytes transfered in 20.496999979 using ('ECDHE-ECDSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.40234375 +# +# +# Single process: +# 1*100*100 +# RSA: 10000 req 1000009 kbytes transfered in 41.7899999619 using ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 26.91015625 +# +# 10*10*100 +# RSA: 10000 req 1000009 kbytes transfered in 40.1640000343 using ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.94921875 diff --git a/src/Test/Spy.py b/src/Test/Spy.py new file mode 100644 index 00000000..44422550 --- /dev/null +++ b/src/Test/Spy.py @@ -0,0 +1,23 @@ +import logging + +class Spy: + def __init__(self, obj, func_name): + self.obj = obj + self.__name__ = func_name + self.func_original = getattr(self.obj, func_name) + self.calls = [] + + def __enter__(self, *args, **kwargs): + logging.debug("Spy started") + def loggedFunc(cls, *args, **kwargs): + call = dict(enumerate(args, 1)) + call[0] = cls + call.update(kwargs) + logging.debug("Spy call: %s" % call) + self.calls.append(call) + return self.func_original(cls, *args, **kwargs) + setattr(self.obj, self.__name__, loggedFunc) + return self.calls + + def __exit__(self, *args, **kwargs): + setattr(self.obj, self.__name__, self.func_original) \ No newline at end of file diff --git a/src/Test/TestCached.py b/src/Test/TestCached.py new file mode 100644 index 00000000..088962c0 --- /dev/null +++ b/src/Test/TestCached.py @@ -0,0 +1,59 @@ +import time + +from util import Cached + + +class CachedObject: + def __init__(self): + self.num_called_add = 0 + self.num_called_multiply = 0 + self.num_called_none = 0 + + @Cached(timeout=1) + def calcAdd(self, a, b): + self.num_called_add += 1 + return a + b + + @Cached(timeout=1) + def calcMultiply(self, a, b): + self.num_called_multiply += 1 + return a * b + + @Cached(timeout=1) + def none(self): + self.num_called_none += 1 + return None + + +class TestCached: + def testNoneValue(self): + cached_object = CachedObject() + assert cached_object.none() is None + assert cached_object.none() is None + assert cached_object.num_called_none == 1 + time.sleep(2) + assert cached_object.none() is None + assert cached_object.num_called_none == 2 + + def testCall(self): + cached_object = CachedObject() + + assert cached_object.calcAdd(1, 2) == 3 + assert cached_object.calcAdd(1, 2) == 3 + assert cached_object.calcMultiply(1, 2) == 2 + assert cached_object.calcMultiply(1, 2) == 2 + assert cached_object.num_called_add == 1 + assert cached_object.num_called_multiply == 1 + + assert cached_object.calcAdd(2, 3) == 5 + assert cached_object.calcAdd(2, 3) == 5 + assert cached_object.num_called_add == 2 + + assert cached_object.calcAdd(1, 2) == 3 + assert cached_object.calcMultiply(2, 3) == 6 + assert cached_object.num_called_add == 2 + assert cached_object.num_called_multiply == 2 + + time.sleep(2) + assert cached_object.calcAdd(1, 2) == 3 + assert cached_object.num_called_add == 3 diff --git a/src/Test/TestConfig.py b/src/Test/TestConfig.py new file mode 100644 index 00000000..24084392 --- /dev/null +++ b/src/Test/TestConfig.py @@ -0,0 +1,31 @@ +import pytest + +import Config + + +@pytest.mark.usefixtures("resetSettings") +class TestConfig: + def testParse(self): + # Defaults + config_test = Config.Config("zeronet.py".split(" ")) + config_test.parse(silent=True, parse_config=False) + assert not config_test.debug + assert not config_test.debug_socket + + # Test parse command line with unknown parameters (ui_password) + config_test = Config.Config("zeronet.py --debug --debug_socket --ui_password hello".split(" ")) + config_test.parse(silent=True, parse_config=False) + assert config_test.debug + assert config_test.debug_socket + with pytest.raises(AttributeError): + config_test.ui_password + + # More complex test + args = "zeronet.py --unknown_arg --debug --debug_socket --ui_restrict 127.0.0.1 1.2.3.4 " + args += "--another_unknown argument --use_openssl False siteSign address privatekey --inner_path users/content.json" + config_test = Config.Config(args.split(" ")) + config_test.parse(silent=True, parse_config=False) + assert config_test.debug + assert "1.2.3.4" in config_test.ui_restrict + assert not config_test.use_openssl + assert config_test.inner_path == "users/content.json" diff --git a/src/Test/TestConnectionServer.py b/src/Test/TestConnectionServer.py new file mode 100644 index 00000000..82ee605c --- /dev/null +++ b/src/Test/TestConnectionServer.py @@ -0,0 +1,118 @@ +import time +import socket +import gevent + +import pytest +import mock + +from Crypt import CryptConnection +from Connection import ConnectionServer +from Config import config + + +@pytest.mark.usefixtures("resetSettings") +class TestConnection: + def testIpv6(self, file_server6): + assert ":" in file_server6.ip + + client = ConnectionServer(file_server6.ip, 1545) + connection = client.getConnection(file_server6.ip, 1544) + + assert connection.ping() + + # Close connection + connection.close() + client.stop() + time.sleep(0.01) + assert len(file_server6.connections) == 0 + + # Should not able to reach on ipv4 ip + with pytest.raises(socket.error) as err: + client = ConnectionServer("127.0.0.1", 1545) + connection = client.getConnection("127.0.0.1", 1544) + + def testSslConnection(self, file_server): + client = ConnectionServer(file_server.ip, 1545) + assert file_server != client + + # Connect to myself + with mock.patch('Config.config.ip_local', return_value=[]): # SSL not used for local ips + connection = client.getConnection(file_server.ip, 1544) + + assert len(file_server.connections) == 1 + assert connection.handshake + assert connection.crypt + + + # Close connection + connection.close("Test ended") + client.stop() + time.sleep(0.1) + assert len(file_server.connections) == 0 + assert file_server.num_incoming == 2 # One for file_server fixture, one for the test + + def testRawConnection(self, file_server): + client = ConnectionServer(file_server.ip, 1545) + assert file_server != client + + # Remove all supported crypto + crypt_supported_bk = CryptConnection.manager.crypt_supported + CryptConnection.manager.crypt_supported = [] + + with mock.patch('Config.config.ip_local', return_value=[]): # SSL not used for local ips + connection = client.getConnection(file_server.ip, 1544) + assert len(file_server.connections) == 1 + assert not connection.crypt + + # Close connection + connection.close() + client.stop() + time.sleep(0.01) + assert len(file_server.connections) == 0 + + # Reset supported crypts + CryptConnection.manager.crypt_supported = crypt_supported_bk + + def testPing(self, file_server, site): + client = ConnectionServer(file_server.ip, 1545) + connection = client.getConnection(file_server.ip, 1544) + + assert connection.ping() + + connection.close() + client.stop() + + def testGetConnection(self, file_server): + client = ConnectionServer(file_server.ip, 1545) + connection = client.getConnection(file_server.ip, 1544) + + # Get connection by ip/port + connection2 = client.getConnection(file_server.ip, 1544) + assert connection == connection2 + + # Get connection by peerid + assert not client.getConnection(file_server.ip, 1544, peer_id="notexists", create=False) + connection2 = client.getConnection(file_server.ip, 1544, peer_id=connection.handshake["peer_id"], create=False) + assert connection2 == connection + + connection.close() + client.stop() + + def testFloodProtection(self, file_server): + whitelist = file_server.whitelist # Save for reset + file_server.whitelist = [] # Disable 127.0.0.1 whitelist + client = ConnectionServer(file_server.ip, 1545) + + # Only allow 6 connection in 1 minute + for reconnect in range(6): + connection = client.getConnection(file_server.ip, 1544) + assert connection.handshake + connection.close() + + # The 7. one will timeout + with pytest.raises(gevent.Timeout): + with gevent.Timeout(0.1): + connection = client.getConnection(file_server.ip, 1544) + + # Reset whitelist + file_server.whitelist = whitelist diff --git a/src/Test/TestContent.py b/src/Test/TestContent.py new file mode 100644 index 00000000..7e7ca1a5 --- /dev/null +++ b/src/Test/TestContent.py @@ -0,0 +1,273 @@ +import json +import time +import io + +import pytest + +from Crypt import CryptBitcoin +from Content.ContentManager import VerifyError, SignError +from util.SafeRe import UnsafePatternError + + +@pytest.mark.usefixtures("resetSettings") +class TestContent: + privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" + + def testInclude(self, site): + # Rules defined in parent content.json + rules = site.content_manager.getRules("data/test_include/content.json") + + assert rules["signers"] == ["15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo"] # Valid signer + assert rules["user_name"] == "test" # Extra data + assert rules["max_size"] == 20000 # Max size of files + assert not rules["includes_allowed"] # Don't allow more includes + assert rules["files_allowed"] == "data.json" # Allowed file pattern + + # Valid signers for "data/test_include/content.json" + valid_signers = site.content_manager.getValidSigners("data/test_include/content.json") + assert "15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo" in valid_signers # Extra valid signer defined in parent content.json + assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in valid_signers # The site itself + assert len(valid_signers) == 2 # No more + + # Valid signers for "data/users/content.json" + valid_signers = site.content_manager.getValidSigners("data/users/content.json") + assert "1LSxsKfC9S9TVXGGNSM3vPHjyW82jgCX5f" in valid_signers # Extra valid signer defined in parent content.json + assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in valid_signers # The site itself + assert len(valid_signers) == 2 + + # Valid signers for root content.json + assert site.content_manager.getValidSigners("content.json") == ["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"] + + def testInlcudeLimits(self, site, crypt_bitcoin_lib): + # Data validation + res = [] + data_dict = { + "files": { + "data.json": { + "sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", + "size": 505 + } + }, + "modified": time.time() + } + + # Normal data + data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)} + data_json = json.dumps(data_dict).encode() + data = io.BytesIO(data_json) + assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False) + + # Reset + del data_dict["signs"] + + # Too large + data_dict["files"]["data.json"]["size"] = 200000 # Emulate 2MB sized data.json + data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)} + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False) + assert "Include too large" in str(err.value) + + # Reset + data_dict["files"]["data.json"]["size"] = 505 + del data_dict["signs"] + + # Not allowed file + data_dict["files"]["notallowed.exe"] = data_dict["files"]["data.json"] + data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)} + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False) + assert "File not allowed" in str(err.value) + + # Reset + del data_dict["files"]["notallowed.exe"] + del data_dict["signs"] + + # Should work again + data_dict["signs"] = {"1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey)} + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False) + + @pytest.mark.parametrize("inner_path", ["content.json", "data/test_include/content.json", "data/users/content.json"]) + def testSign(self, site, inner_path): + # Bad privatekey + with pytest.raises(SignError) as err: + site.content_manager.sign(inner_path, privatekey="5aaa3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMnaa", filewrite=False) + assert "Private key invalid" in str(err.value) + + # Good privatekey + content = site.content_manager.sign(inner_path, privatekey=self.privatekey, filewrite=False) + content_old = site.content_manager.contents[inner_path] # Content before the sign + assert not content_old == content # Timestamp changed + assert site.address in content["signs"] # Used the site's private key to sign + if inner_path == "content.json": + assert len(content["files"]) == 17 + elif inner_path == "data/test-include/content.json": + assert len(content["files"]) == 1 + elif inner_path == "data/users/content.json": + assert len(content["files"]) == 0 + + # Everything should be same as before except the modified timestamp and the signs + assert ( + {key: val for key, val in content_old.items() if key not in ["modified", "signs", "sign", "zeronet_version"]} + == + {key: val for key, val in content.items() if key not in ["modified", "signs", "sign", "zeronet_version"]} + ) + + def testSignOptionalFiles(self, site): + for hash in list(site.content_manager.hashfield): + site.content_manager.hashfield.remove(hash) + + assert len(site.content_manager.hashfield) == 0 + + site.content_manager.contents["content.json"]["optional"] = "((data/img/zero.*))" + content_optional = site.content_manager.sign(privatekey=self.privatekey, filewrite=False, remove_missing_optional=True) + + del site.content_manager.contents["content.json"]["optional"] + content_nooptional = site.content_manager.sign(privatekey=self.privatekey, filewrite=False, remove_missing_optional=True) + + assert len(content_nooptional.get("files_optional", {})) == 0 # No optional files if no pattern + assert len(content_optional["files_optional"]) > 0 + assert len(site.content_manager.hashfield) == len(content_optional["files_optional"]) # Hashed optional files should be added to hashfield + assert len(content_nooptional["files"]) > len(content_optional["files"]) + + def testFileInfo(self, site): + assert "sha512" in site.content_manager.getFileInfo("index.html") + assert site.content_manager.getFileInfo("data/img/domain.png")["content_inner_path"] == "content.json" + assert site.content_manager.getFileInfo("data/users/hello.png")["content_inner_path"] == "data/users/content.json" + assert site.content_manager.getFileInfo("data/users/content.json")["content_inner_path"] == "data/users/content.json" + assert not site.content_manager.getFileInfo("notexist") + + # Optional file + file_info_optional = site.content_manager.getFileInfo("data/optional.txt") + assert "sha512" in file_info_optional + assert file_info_optional["optional"] is True + + # Not exists yet user content.json + assert "cert_signers" in site.content_manager.getFileInfo("data/users/unknown/content.json") + + # Optional user file + file_info_optional = site.content_manager.getFileInfo("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert "sha512" in file_info_optional + assert file_info_optional["optional"] is True + + def testVerify(self, site, crypt_bitcoin_lib): + inner_path = "data/test_include/content.json" + data_dict = site.storage.loadJson(inner_path) + data = io.BytesIO(json.dumps(data_dict).encode("utf8")) + + # Re-sign + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + assert site.content_manager.verifyFile(inner_path, data, ignore_same=False) + + # Wrong address + data_dict["address"] = "Othersite" + del data_dict["signs"] + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(inner_path, data, ignore_same=False) + assert "Wrong site address" in str(err.value) + + # Wrong inner_path + data_dict["address"] = "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" + data_dict["inner_path"] = "content.json" + del data_dict["signs"] + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(inner_path, data, ignore_same=False) + assert "Wrong inner_path" in str(err.value) + + # Everything right again + data_dict["address"] = "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" + data_dict["inner_path"] = inner_path + del data_dict["signs"] + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(inner_path, data, ignore_same=False) + + def testVerifyInnerPath(self, site, crypt_bitcoin_lib): + inner_path = "content.json" + data_dict = site.storage.loadJson(inner_path) + + for good_relative_path in ["data.json", "out/data.json", "Any File [by none] (1).jpg", "árvzítűrő/tükörfúrógép.txt"]: + data_dict["files"] = {good_relative_path: {"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", "size": 505}} + + if "sign" in data_dict: + del data_dict["sign"] + del data_dict["signs"] + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(inner_path, data, ignore_same=False) + + for bad_relative_path in ["../data.json", "data/" * 100, "invalid|file.jpg", "con.txt", "any/con.txt"]: + data_dict["files"] = {bad_relative_path: {"sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", "size": 505}} + + if "sign" in data_dict: + del data_dict["sign"] + del data_dict["signs"] + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), self.privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(inner_path, data, ignore_same=False) + assert "Invalid relative path" in str(err.value) + + @pytest.mark.parametrize("key", ["ignore", "optional"]) + def testSignUnsafePattern(self, site, key): + site.content_manager.contents["content.json"][key] = "([a-zA-Z]+)*" + with pytest.raises(UnsafePatternError) as err: + site.content_manager.sign("content.json", privatekey=self.privatekey, filewrite=False) + assert "Potentially unsafe" in str(err.value) + + + def testVerifyUnsafePattern(self, site, crypt_bitcoin_lib): + site.content_manager.contents["content.json"]["includes"]["data/test_include/content.json"]["files_allowed"] = "([a-zA-Z]+)*" + with pytest.raises(UnsafePatternError) as err: + with site.storage.open("data/test_include/content.json") as data: + site.content_manager.verifyFile("data/test_include/content.json", data, ignore_same=False) + assert "Potentially unsafe" in str(err.value) + + site.content_manager.contents["data/users/content.json"]["user_contents"]["permission_rules"]["([a-zA-Z]+)*"] = {"max_size": 0} + with pytest.raises(UnsafePatternError) as err: + with site.storage.open("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json") as data: + site.content_manager.verifyFile("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", data, ignore_same=False) + assert "Potentially unsafe" in str(err.value) + + def testPathValidation(self, site): + assert site.content_manager.isValidRelativePath("test.txt") + assert site.content_manager.isValidRelativePath("test/!@#$%^&().txt") + assert site.content_manager.isValidRelativePath("ÜøßÂŒƂÆÇ.txt") + assert site.content_manager.isValidRelativePath("тест.текст") + assert site.content_manager.isValidRelativePath("𝐮𝐧𝐢𝐜𝐨𝐝𝐞𝑖𝑠𝒂𝒘𝒆𝒔𝒐𝒎𝒆") + + # Test rules based on https://stackoverflow.com/questions/1976007/what-characters-are-forbidden-in-windows-and-linux-directory-names + + assert not site.content_manager.isValidRelativePath("any\\hello.txt") # \ not allowed + assert not site.content_manager.isValidRelativePath("/hello.txt") # Cannot start with / + assert not site.content_manager.isValidRelativePath("\\hello.txt") # Cannot start with \ + assert not site.content_manager.isValidRelativePath("../hello.txt") # Not allowed .. in path + assert not site.content_manager.isValidRelativePath("\0hello.txt") # NULL character + assert not site.content_manager.isValidRelativePath("\31hello.txt") # 0-31 (ASCII control characters) + assert not site.content_manager.isValidRelativePath("any/hello.txt ") # Cannot end with space + assert not site.content_manager.isValidRelativePath("any/hello.txt.") # Cannot end with dot + assert site.content_manager.isValidRelativePath(".hello.txt") # Allow start with dot + assert not site.content_manager.isValidRelativePath("any/CON") # Protected names on Windows + assert not site.content_manager.isValidRelativePath("CON/any.txt") + assert not site.content_manager.isValidRelativePath("any/lpt1.txt") + assert site.content_manager.isValidRelativePath("any/CONAN") + assert not site.content_manager.isValidRelativePath("any/CONOUT$") + assert not site.content_manager.isValidRelativePath("a" * 256) # Max 255 characters allowed diff --git a/src/Test/TestContentUser.py b/src/Test/TestContentUser.py new file mode 100644 index 00000000..8e91dd3e --- /dev/null +++ b/src/Test/TestContentUser.py @@ -0,0 +1,390 @@ +import json +import io + +import pytest + +from Crypt import CryptBitcoin +from Content.ContentManager import VerifyError, SignError + + +@pytest.mark.usefixtures("resetSettings") +class TestContentUser: + def testSigners(self, site): + # File info for not existing user file + file_info = site.content_manager.getFileInfo("data/users/notexist/data.json") + assert file_info["content_inner_path"] == "data/users/notexist/content.json" + file_info = site.content_manager.getFileInfo("data/users/notexist/a/b/data.json") + assert file_info["content_inner_path"] == "data/users/notexist/content.json" + valid_signers = site.content_manager.getValidSigners("data/users/notexist/content.json") + assert valid_signers == ["14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet", "notexist", "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"] + + # File info for exsitsing user file + valid_signers = site.content_manager.getValidSigners("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json") + assert '1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT' in valid_signers # The site address + assert '14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet' in valid_signers # Admin user defined in data/users/content.json + assert '1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C' in valid_signers # The user itself + assert len(valid_signers) == 3 # No more valid signers + + # Valid signer for banned user + user_content = site.storage.loadJson("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json") + user_content["cert_user_id"] = "bad@zeroid.bit" + + valid_signers = site.content_manager.getValidSigners("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert '1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT' in valid_signers # The site address + assert '14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet' in valid_signers # Admin user defined in data/users/content.json + assert '1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C' not in valid_signers # The user itself + + def testRules(self, site): + # We going to manipulate it this test rules based on data/users/content.json + user_content = site.storage.loadJson("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json") + + # Known user + user_content["cert_auth_type"] = "web" + user_content["cert_user_id"] = "nofish@zeroid.bit" + rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert rules["max_size"] == 100000 + assert "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C" in rules["signers"] + + # Unknown user + user_content["cert_auth_type"] = "web" + user_content["cert_user_id"] = "noone@zeroid.bit" + rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert rules["max_size"] == 10000 + assert "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C" in rules["signers"] + + # User with more size limit based on auth type + user_content["cert_auth_type"] = "bitmsg" + user_content["cert_user_id"] = "noone@zeroid.bit" + rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert rules["max_size"] == 15000 + assert "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C" in rules["signers"] + + # Banned user + user_content["cert_auth_type"] = "web" + user_content["cert_user_id"] = "bad@zeroid.bit" + rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C" not in rules["signers"] + + def testRulesAddress(self, site): + user_inner_path = "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json" + user_content = site.storage.loadJson(user_inner_path) + + rules = site.content_manager.getRules(user_inner_path, user_content) + assert rules["max_size"] == 10000 + assert "1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9" in rules["signers"] + + users_content = site.content_manager.contents["data/users/content.json"] + + # Ban user based on address + users_content["user_contents"]["permissions"]["1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9"] = False + rules = site.content_manager.getRules(user_inner_path, user_content) + assert "1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9" not in rules["signers"] + + # Change max allowed size + users_content["user_contents"]["permissions"]["1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9"] = {"max_size": 20000} + rules = site.content_manager.getRules(user_inner_path, user_content) + assert rules["max_size"] == 20000 + + def testVerifyAddress(self, site): + privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" # For 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT + user_inner_path = "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json" + data_dict = site.storage.loadJson(user_inner_path) + users_content = site.content_manager.contents["data/users/content.json"] + + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + + # Test error on 15k data.json + data_dict["files"]["data.json"]["size"] = 1024 * 15 + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + assert "Include too large" in str(err.value) + + # Give more space based on address + users_content["user_contents"]["permissions"]["1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9"] = {"max_size": 20000} + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + + def testVerify(self, site): + privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" # For 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT + user_inner_path = "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json" + data_dict = site.storage.loadJson(user_inner_path) + users_content = site.content_manager.contents["data/users/content.json"] + + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + + # Test max size exception by setting allowed to 0 + rules = site.content_manager.getRules(user_inner_path, data_dict) + assert rules["max_size"] == 10000 + assert users_content["user_contents"]["permission_rules"][".*"]["max_size"] == 10000 + + users_content["user_contents"]["permission_rules"][".*"]["max_size"] = 0 + rules = site.content_manager.getRules(user_inner_path, data_dict) + assert rules["max_size"] == 0 + data = io.BytesIO(json.dumps(data_dict).encode()) + + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + assert "Include too large" in str(err.value) + users_content["user_contents"]["permission_rules"][".*"]["max_size"] = 10000 # Reset + + # Test max optional size exception + # 1 MB gif = Allowed + data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 1024 * 1024 + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + assert site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + + # 100 MB gif = Not allowed + data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 100 * 1024 * 1024 + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + assert "Include optional files too large" in str(err.value) + data_dict["files_optional"]["peanut-butter-jelly-time.gif"]["size"] = 1024 * 1024 # Reset + + # hello.exe = Not allowed + data_dict["files_optional"]["hello.exe"] = data_dict["files_optional"]["peanut-butter-jelly-time.gif"] + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + assert "Optional file not allowed" in str(err.value) + del data_dict["files_optional"]["hello.exe"] # Reset + + # Includes not allowed in user content + data_dict["includes"] = {"other.json": {}} + del data_dict["signs"] # Remove signs before signing + data_dict["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(data_dict, sort_keys=True), privatekey) + } + data = io.BytesIO(json.dumps(data_dict).encode()) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile(user_inner_path, data, ignore_same=False) + assert "Includes not allowed" in str(err.value) + + def testCert(self, site): + # user_addr = "1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C" + user_priv = "5Kk7FSA63FC2ViKmKLuBxk9gQkaQ5713hKq8LmFAf4cVeXh6K6A" + # cert_addr = "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" + cert_priv = "5JusJDSjHaMHwUjDT3o6eQ54pA6poo8La5fAgn1wNc3iK59jxjA" + + # Check if the user file is loaded + assert "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json" in site.content_manager.contents + user_content = site.content_manager.contents["data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json"] + rules_content = site.content_manager.contents["data/users/content.json"] + + # Override valid cert signers for the test + rules_content["user_contents"]["cert_signers"]["zeroid.bit"] = [ + "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet", + "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" + ] + + # Check valid cert signers + rules = site.content_manager.getRules("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + assert rules["cert_signers"] == {"zeroid.bit": [ + "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet", + "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" + ]} + + # Sign a valid cert + user_content["cert_sign"] = CryptBitcoin.sign("1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C#%s/%s" % ( + user_content["cert_auth_type"], + user_content["cert_user_id"].split("@")[0] + ), cert_priv) + + # Verify cert + assert site.content_manager.verifyCert("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_content) + + # Verify if the cert is valid for other address + assert not site.content_manager.verifyCert("data/users/badaddress/content.json", user_content) + + # Sign user content + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + + # Test user cert + assert site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + + # Test banned user + cert_user_id = user_content["cert_user_id"] # My username + site.content_manager.contents["data/users/content.json"]["user_contents"]["permissions"][cert_user_id] = False + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Valid signs: 0/1" in str(err.value) + del site.content_manager.contents["data/users/content.json"]["user_contents"]["permissions"][cert_user_id] # Reset + + # Test invalid cert + user_content["cert_sign"] = CryptBitcoin.sign( + "badaddress#%s/%s" % (user_content["cert_auth_type"], user_content["cert_user_id"]), cert_priv + ) + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Invalid cert" in str(err.value) + + # Test banned user, signed by the site owner + user_content["cert_sign"] = CryptBitcoin.sign("1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C#%s/%s" % ( + user_content["cert_auth_type"], + user_content["cert_user_id"].split("@")[0] + ), cert_priv) + cert_user_id = user_content["cert_user_id"] # My username + site.content_manager.contents["data/users/content.json"]["user_contents"]["permissions"][cert_user_id] = False + + site_privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" # For 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT + del user_content["signs"] # Remove signs before signing + user_content["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(user_content, sort_keys=True), site_privatekey) + } + assert site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(user_content).encode()), ignore_same=False + ) + + def testMissingCert(self, site): + user_priv = "5Kk7FSA63FC2ViKmKLuBxk9gQkaQ5713hKq8LmFAf4cVeXh6K6A" + cert_priv = "5JusJDSjHaMHwUjDT3o6eQ54pA6poo8La5fAgn1wNc3iK59jxjA" + + user_content = site.content_manager.contents["data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json"] + rules_content = site.content_manager.contents["data/users/content.json"] + + # Override valid cert signers for the test + rules_content["user_contents"]["cert_signers"]["zeroid.bit"] = [ + "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet", + "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" + ] + + # Sign a valid cert + user_content["cert_sign"] = CryptBitcoin.sign("1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C#%s/%s" % ( + user_content["cert_auth_type"], + user_content["cert_user_id"].split("@")[0] + ), cert_priv) + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + + assert site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + + # Test invalid cert_user_id + user_content["cert_user_id"] = "nodomain" + user_content["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(user_content, sort_keys=True), user_priv) + } + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Invalid domain in cert_user_id" in str(err.value) + + # Test removed cert + del user_content["cert_user_id"] + del user_content["cert_auth_type"] + del user_content["signs"] # Remove signs before signing + user_content["signs"] = { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": CryptBitcoin.sign(json.dumps(user_content, sort_keys=True), user_priv) + } + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Missing cert_user_id" in str(err.value) + + + def testCertSignersPattern(self, site): + user_priv = "5Kk7FSA63FC2ViKmKLuBxk9gQkaQ5713hKq8LmFAf4cVeXh6K6A" + cert_priv = "5JusJDSjHaMHwUjDT3o6eQ54pA6poo8La5fAgn1wNc3iK59jxjA" # For 14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet + + user_content = site.content_manager.contents["data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json"] + rules_content = site.content_manager.contents["data/users/content.json"] + + # Override valid cert signers for the test + rules_content["user_contents"]["cert_signers_pattern"] = "14wgQ[0-9][A-Z]" + + # Sign a valid cert + user_content["cert_user_id"] = "certuser@14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" + user_content["cert_sign"] = CryptBitcoin.sign("1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C#%s/%s" % ( + user_content["cert_auth_type"], + "certuser" + ), cert_priv) + signed_content = site.content_manager.sign( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", user_priv, filewrite=False + ) + + assert site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + + # Cert does not matches the pattern + rules_content["user_contents"]["cert_signers_pattern"] = "14wgX[0-9][A-Z]" + + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Invalid cert signer: 14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" in str(err.value) + + # Removed cert_signers_pattern + del rules_content["user_contents"]["cert_signers_pattern"] + + with pytest.raises(VerifyError) as err: + site.content_manager.verifyFile( + "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + io.BytesIO(json.dumps(signed_content).encode()), ignore_same=False + ) + assert "Invalid cert signer: 14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" in str(err.value) + + + def testNewFile(self, site): + privatekey = "5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv" # For 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT + inner_path = "data/users/1NEWrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json" + + site.storage.writeJson(inner_path, {"test": "data"}) + site.content_manager.sign(inner_path, privatekey) + assert "test" in site.storage.loadJson(inner_path) + + site.storage.delete(inner_path) diff --git a/src/Test/TestCryptBitcoin.py b/src/Test/TestCryptBitcoin.py new file mode 100644 index 00000000..2bc087b5 --- /dev/null +++ b/src/Test/TestCryptBitcoin.py @@ -0,0 +1,48 @@ +from Crypt import CryptBitcoin + + +class TestCryptBitcoin: + def testSign(self, crypt_bitcoin_lib): + privatekey = "5K9S6dVpufGnroRgFrT6wsKiz2mJRYsC73eWDmajaHserAp3F1C" + privatekey_bad = "5Jbm9rrusXyApAoM8YoM4Rja337zMMoBUMRJ1uijiguU2aZRnwC" + + # Get address by privatekey + address = crypt_bitcoin_lib.privatekeyToAddress(privatekey) + assert address == "1MpDMxFeDUkiHohxx9tbGLeEGEuR4ZNsJz" + + address_bad = crypt_bitcoin_lib.privatekeyToAddress(privatekey_bad) + assert address_bad != "1MpDMxFeDUkiHohxx9tbGLeEGEuR4ZNsJz" + + # Text signing + data_len_list = list(range(0, 300, 10)) + data_len_list += [1024, 2048, 1024 * 128, 1024 * 1024, 1024 * 2048] + for data_len in data_len_list: + data = data_len * "!" + sign = crypt_bitcoin_lib.sign(data, privatekey) + + assert crypt_bitcoin_lib.verify(data, address, sign) + assert not crypt_bitcoin_lib.verify("invalid" + data, address, sign) + + # Signed by bad privatekey + sign_bad = crypt_bitcoin_lib.sign("hello", privatekey_bad) + assert not crypt_bitcoin_lib.verify("hello", address, sign_bad) + + def testVerify(self, crypt_bitcoin_lib): + sign_uncompressed = b'G6YkcFTuwKMVMHI2yycGQIFGbCZVNsZEZvSlOhKpHUt/BlADY94egmDAWdlrbbFrP9wH4aKcEfbLO8sa6f63VU0=' + assert crypt_bitcoin_lib.verify("1NQUem2M4cAqWua6BVFBADtcSP55P4QobM#web/gitcenter", "19Bir5zRm1yo4pw9uuxQL8xwf9b7jqMpR", sign_uncompressed) + + sign_compressed = b'H6YkcFTuwKMVMHI2yycGQIFGbCZVNsZEZvSlOhKpHUt/BlADY94egmDAWdlrbbFrP9wH4aKcEfbLO8sa6f63VU0=' + assert crypt_bitcoin_lib.verify("1NQUem2M4cAqWua6BVFBADtcSP55P4QobM#web/gitcenter", "1KH5BdNnqxh2KRWMMT8wUXzUgz4vVQ4S8p", sign_compressed) + + def testNewPrivatekey(self): + assert CryptBitcoin.newPrivatekey() != CryptBitcoin.newPrivatekey() + assert CryptBitcoin.privatekeyToAddress(CryptBitcoin.newPrivatekey()) + + def testNewSeed(self): + assert CryptBitcoin.newSeed() != CryptBitcoin.newSeed() + assert CryptBitcoin.privatekeyToAddress( + CryptBitcoin.hdPrivatekey(CryptBitcoin.newSeed(), 0) + ) + assert CryptBitcoin.privatekeyToAddress( + CryptBitcoin.hdPrivatekey(CryptBitcoin.newSeed(), 2**256) + ) diff --git a/src/Test/TestCryptConnection.py b/src/Test/TestCryptConnection.py new file mode 100644 index 00000000..46d2affc --- /dev/null +++ b/src/Test/TestCryptConnection.py @@ -0,0 +1,23 @@ +import os + +from Config import config +from Crypt import CryptConnection + + +class TestCryptConnection: + def testSslCert(self): + # Remove old certs + if os.path.isfile("%s/cert-rsa.pem" % config.data_dir): + os.unlink("%s/cert-rsa.pem" % config.data_dir) + if os.path.isfile("%s/key-rsa.pem" % config.data_dir): + os.unlink("%s/key-rsa.pem" % config.data_dir) + + # Generate certs + CryptConnection.manager.loadCerts() + + assert "tls-rsa" in CryptConnection.manager.crypt_supported + assert CryptConnection.manager.selectCrypt(["tls-rsa", "unknown"]) == "tls-rsa" # It should choose the known crypt + + # Check openssl cert generation + assert os.path.isfile("%s/cert-rsa.pem" % config.data_dir) + assert os.path.isfile("%s/key-rsa.pem" % config.data_dir) diff --git a/src/Test/TestCryptHash.py b/src/Test/TestCryptHash.py new file mode 100644 index 00000000..b91dbcca --- /dev/null +++ b/src/Test/TestCryptHash.py @@ -0,0 +1,31 @@ +import base64 + +from Crypt import CryptHash + +sha512t_sum_hex = "2e9466d8aa1f340c91203b4ddbe9b6669879616a1b8e9571058a74195937598d" +sha512t_sum_bin = b".\x94f\xd8\xaa\x1f4\x0c\x91 ;M\xdb\xe9\xb6f\x98yaj\x1b\x8e\x95q\x05\x8at\x19Y7Y\x8d" +sha256_sum_hex = "340cd04be7f530e3a7c1bc7b24f225ba5762ec7063a56e1ae01a30d56722e5c3" + + +class TestCryptBitcoin: + + def testSha(self, site): + file_path = site.storage.getPath("dbschema.json") + assert CryptHash.sha512sum(file_path) == sha512t_sum_hex + assert CryptHash.sha512sum(open(file_path, "rb")) == sha512t_sum_hex + assert CryptHash.sha512sum(open(file_path, "rb"), format="digest") == sha512t_sum_bin + + assert CryptHash.sha256sum(file_path) == sha256_sum_hex + assert CryptHash.sha256sum(open(file_path, "rb")) == sha256_sum_hex + + with open(file_path, "rb") as f: + hash = CryptHash.Sha512t(f.read(100)) + hash.hexdigest() != sha512t_sum_hex + hash.update(f.read(1024 * 1024)) + assert hash.hexdigest() == sha512t_sum_hex + + def testRandom(self): + assert len(CryptHash.random(64)) == 64 + assert CryptHash.random() != CryptHash.random() + assert bytes.fromhex(CryptHash.random(encoding="hex")) + assert base64.b64decode(CryptHash.random(encoding="base64")) diff --git a/src/Test/TestDb.py b/src/Test/TestDb.py new file mode 100644 index 00000000..67f383a3 --- /dev/null +++ b/src/Test/TestDb.py @@ -0,0 +1,137 @@ +import io + + +class TestDb: + def testCheckTables(self, db): + tables = [row["name"] for row in db.execute("SELECT name FROM sqlite_master WHERE type='table'")] + assert "keyvalue" in tables # To store simple key -> value + assert "json" in tables # Json file path registry + assert "test" in tables # The table defined in dbschema.json + + # Verify test table + cols = [col["name"] for col in db.execute("PRAGMA table_info(test)")] + assert "test_id" in cols + assert "title" in cols + + # Add new table + assert "newtest" not in tables + db.schema["tables"]["newtest"] = { + "cols": [ + ["newtest_id", "INTEGER"], + ["newtitle", "TEXT"], + ], + "indexes": ["CREATE UNIQUE INDEX newtest_id ON newtest(newtest_id)"], + "schema_changed": 1426195822 + } + db.checkTables() + tables = [row["name"] for row in db.execute("SELECT name FROM sqlite_master WHERE type='table'")] + assert "test" in tables + assert "newtest" in tables + + def testQueries(self, db): + # Test insert + for i in range(100): + db.execute("INSERT INTO test ?", {"test_id": i, "title": "Test #%s" % i}) + + assert db.execute("SELECT COUNT(*) AS num FROM test").fetchone()["num"] == 100 + + # Test single select + assert db.execute("SELECT COUNT(*) AS num FROM test WHERE ?", {"test_id": 1}).fetchone()["num"] == 1 + + # Test multiple select + assert db.execute("SELECT COUNT(*) AS num FROM test WHERE ?", {"test_id": [1, 2, 3]}).fetchone()["num"] == 3 + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"test_id": [1, 2, 3], "title": "Test #2"} + ).fetchone()["num"] == 1 + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"test_id": [1, 2, 3], "title": ["Test #2", "Test #3", "Test #4"]} + ).fetchone()["num"] == 2 + + # Test multiple select using named params + assert db.execute("SELECT COUNT(*) AS num FROM test WHERE test_id IN :test_id", {"test_id": [1, 2, 3]}).fetchone()["num"] == 3 + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE test_id IN :test_id AND title = :title", + {"test_id": [1, 2, 3], "title": "Test #2"} + ).fetchone()["num"] == 1 + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE test_id IN :test_id AND title IN :title", + {"test_id": [1, 2, 3], "title": ["Test #2", "Test #3", "Test #4"]} + ).fetchone()["num"] == 2 + + # Large ammount of IN values + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"not__test_id": list(range(2, 3000))} + ).fetchone()["num"] == 2 + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"test_id": list(range(50, 3000))} + ).fetchone()["num"] == 50 + + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"not__title": ["Test #%s" % i for i in range(50, 3000)]} + ).fetchone()["num"] == 50 + + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"title__like": "%20%"} + ).fetchone()["num"] == 1 + + # Test named parameter escaping + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE test_id = :test_id AND title LIKE :titlelike", + {"test_id": 1, "titlelike": "Test%"} + ).fetchone()["num"] == 1 + + def testEscaping(self, db): + # Test insert + for i in range(100): + db.execute("INSERT INTO test ?", {"test_id": i, "title": "Test '\" #%s" % i}) + + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"title": "Test '\" #1"} + ).fetchone()["num"] == 1 + + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"title": ["Test '\" #%s" % i for i in range(0, 50)]} + ).fetchone()["num"] == 50 + + assert db.execute( + "SELECT COUNT(*) AS num FROM test WHERE ?", + {"not__title": ["Test '\" #%s" % i for i in range(50, 3000)]} + ).fetchone()["num"] == 50 + + + def testUpdateJson(self, db): + f = io.BytesIO() + f.write(""" + { + "test": [ + {"test_id": 1, "title": "Test 1 title", "extra col": "Ignore it"} + ] + } + """.encode()) + f.seek(0) + assert db.updateJson(db.db_dir + "data.json", f) is True + assert db.execute("SELECT COUNT(*) AS num FROM test_importfilter").fetchone()["num"] == 1 + assert db.execute("SELECT COUNT(*) AS num FROM test").fetchone()["num"] == 1 + + def testUnsafePattern(self, db): + db.schema["maps"] = {"[A-Za-z.]*": db.schema["maps"]["data.json"]} # Only repetition of . supported + f = io.StringIO() + f.write(""" + { + "test": [ + {"test_id": 1, "title": "Test 1 title", "extra col": "Ignore it"} + ] + } + """) + f.seek(0) + assert db.updateJson(db.db_dir + "data.json", f) is False + assert db.execute("SELECT COUNT(*) AS num FROM test_importfilter").fetchone()["num"] == 0 + assert db.execute("SELECT COUNT(*) AS num FROM test").fetchone()["num"] == 0 diff --git a/src/Test/TestDbQuery.py b/src/Test/TestDbQuery.py new file mode 100644 index 00000000..597bc950 --- /dev/null +++ b/src/Test/TestDbQuery.py @@ -0,0 +1,31 @@ +import re + +from Db.DbQuery import DbQuery + + +class TestDbQuery: + def testParse(self): + query_text = """ + SELECT + 'comment' AS type, + date_added, post.title AS title, + keyvalue.value || ': ' || comment.body AS body, + '?Post:' || comment.post_id || '#Comments' AS url + FROM + comment + LEFT JOIN json USING (json_id) + LEFT JOIN json AS json_content ON (json_content.directory = json.directory AND json_content.file_name='content.json') + LEFT JOIN keyvalue ON (keyvalue.json_id = json_content.json_id AND key = 'cert_user_id') + LEFT JOIN post ON (comment.post_id = post.post_id) + WHERE + post.date_added > 123 + ORDER BY + date_added DESC + LIMIT 20 + """ + query = DbQuery(query_text) + assert query.parts["LIMIT"] == "20" + assert query.fields["body"] == "keyvalue.value || ': ' || comment.body" + assert re.sub("[ \r\n]", "", str(query)) == re.sub("[ \r\n]", "", query_text) + query.wheres.append("body LIKE '%hello%'") + assert "body LIKE '%hello%'" in str(query) diff --git a/src/Test/TestDebug.py b/src/Test/TestDebug.py new file mode 100644 index 00000000..e3eb20b3 --- /dev/null +++ b/src/Test/TestDebug.py @@ -0,0 +1,52 @@ +from Debug import Debug +import gevent +import os +import re + +import pytest + + +class TestDebug: + @pytest.mark.parametrize("items,expected", [ + (["@/src/A/B/C.py:17"], ["A/B/C.py line 17"]), # basic test + (["@/src/Db/Db.py:17"], ["Db.py line 17"]), # path compression + (["%s:1" % __file__], ["TestDebug.py line 1"]), + (["@/plugins/Chart/ChartDb.py:100"], ["ChartDb.py line 100"]), # plugins + (["@/main.py:17"], ["main.py line 17"]), # root + (["@\\src\\Db\\__init__.py:17"], ["Db/__init__.py line 17"]), # Windows paths + ([":1"], []), # importlib builtins + ([":1"], []), # importlib builtins + (["/home/ivanq/ZeroNet/src/main.py:13"], ["?/src/main.py line 13"]), # best-effort anonymization + (["C:\\ZeroNet\\core\\src\\main.py:13"], ["?/src/main.py line 13"]), + (["/root/main.py:17"], ["/root/main.py line 17"]), + (["{gevent}:13"], ["/__init__.py line 13"]), # modules + (["{os}:13"], [" line 13"]), # python builtin modules + (["src/gevent/event.py:17"], ["/event.py line 17"]), # gevent-overriden __file__ + (["@/src/Db/Db.py:17", "@/src/Db/DbQuery.py:1"], ["Db.py line 17", "DbQuery.py line 1"]), # mutliple args + (["@/src/Db/Db.py:17", "@/src/Db/Db.py:1"], ["Db.py line 17", "1"]), # same file + (["{os}:1", "@/src/Db/Db.py:17"], [" line 1", "Db.py line 17"]), # builtins + (["{gevent}:1"] + ["{os}:3"] * 4 + ["@/src/Db/Db.py:17"], ["/__init__.py line 1", "...", "Db.py line 17"]) + ]) + def testFormatTraceback(self, items, expected): + q_items = [] + for item in items: + file, line = item.rsplit(":", 1) + if file.startswith("@"): + file = Debug.root_dir + file[1:] + file = file.replace("{os}", os.__file__) + file = file.replace("{gevent}", gevent.__file__) + q_items.append((file, int(line))) + assert Debug.formatTraceback(q_items) == expected + + def testFormatException(self): + try: + raise ValueError("Test exception") + except Exception: + assert re.match(r"ValueError: Test exception in TestDebug.py line [0-9]+", Debug.formatException()) + try: + os.path.abspath(1) + except Exception: + assert re.search(r"in TestDebug.py line [0-9]+ > <(posixpath|ntpath)> line ", Debug.formatException()) + + def testFormatStack(self): + assert re.match(r"TestDebug.py line [0-9]+ > <_pytest>/python.py line [0-9]+", Debug.formatStack()) diff --git a/src/Test/TestDiff.py b/src/Test/TestDiff.py new file mode 100644 index 00000000..622951a1 --- /dev/null +++ b/src/Test/TestDiff.py @@ -0,0 +1,58 @@ +import io + +from util import Diff + + +class TestDiff: + def testDiff(self): + assert Diff.diff( + [], + ["one", "two", "three"] + ) == [("+", ["one", "two","three"])] + + assert Diff.diff( + ["one", "two", "three"], + ["one", "two", "three", "four", "five"] + ) == [("=", 11), ("+", ["four", "five"])] + + assert Diff.diff( + ["one", "two", "three", "six"], + ["one", "two", "three", "four", "five", "six"] + ) == [("=", 11), ("+", ["four", "five"]), ("=", 3)] + + assert Diff.diff( + ["one", "two", "three", "hmm", "six"], + ["one", "two", "three", "four", "five", "six"] + ) == [("=", 11), ("-", 3), ("+", ["four", "five"]), ("=", 3)] + + assert Diff.diff( + ["one", "two", "three"], + [] + ) == [("-", 11)] + + def testUtf8(self): + assert Diff.diff( + ["one", "\xe5\xad\xa6\xe4\xb9\xa0\xe4\xb8\x8b", "two", "three"], + ["one", "\xe5\xad\xa6\xe4\xb9\xa0\xe4\xb8\x8b", "two", "three", "four", "five"] + ) == [("=", 20), ("+", ["four", "five"])] + + def testDiffLimit(self): + old_f = io.BytesIO(b"one\ntwo\nthree\nhmm\nsix") + new_f = io.BytesIO(b"one\ntwo\nthree\nfour\nfive\nsix") + actions = Diff.diff(list(old_f), list(new_f), limit=1024) + assert actions + + old_f = io.BytesIO(b"one\ntwo\nthree\nhmm\nsix") + new_f = io.BytesIO(b"one\ntwo\nthree\nfour\nfive\nsix"*1024) + actions = Diff.diff(list(old_f), list(new_f), limit=1024) + assert actions is False + + def testPatch(self): + old_f = io.BytesIO(b"one\ntwo\nthree\nhmm\nsix") + new_f = io.BytesIO(b"one\ntwo\nthree\nfour\nfive\nsix") + actions = Diff.diff( + list(old_f), + list(new_f) + ) + old_f.seek(0) + assert Diff.patch(old_f, actions).getvalue() == new_f.getvalue() diff --git a/src/Test/TestEvent.py b/src/Test/TestEvent.py new file mode 100644 index 00000000..8bdafaaa --- /dev/null +++ b/src/Test/TestEvent.py @@ -0,0 +1,65 @@ +import util + + +class ExampleClass(object): + def __init__(self): + self.called = [] + self.onChanged = util.Event() + + def increment(self, title): + self.called.append(title) + + +class TestEvent: + def testEvent(self): + test_obj = ExampleClass() + test_obj.onChanged.append(lambda: test_obj.increment("Called #1")) + test_obj.onChanged.append(lambda: test_obj.increment("Called #2")) + test_obj.onChanged.once(lambda: test_obj.increment("Once")) + + assert test_obj.called == [] + test_obj.onChanged() + assert test_obj.called == ["Called #1", "Called #2", "Once"] + test_obj.onChanged() + test_obj.onChanged() + assert test_obj.called == ["Called #1", "Called #2", "Once", "Called #1", "Called #2", "Called #1", "Called #2"] + + def testOnce(self): + test_obj = ExampleClass() + test_obj.onChanged.once(lambda: test_obj.increment("Once test #1")) + + # It should be called only once + assert test_obj.called == [] + test_obj.onChanged() + assert test_obj.called == ["Once test #1"] + test_obj.onChanged() + test_obj.onChanged() + assert test_obj.called == ["Once test #1"] + + def testOnceMultiple(self): + test_obj = ExampleClass() + # Allow queue more than once + test_obj.onChanged.once(lambda: test_obj.increment("Once test #1")) + test_obj.onChanged.once(lambda: test_obj.increment("Once test #2")) + test_obj.onChanged.once(lambda: test_obj.increment("Once test #3")) + + assert test_obj.called == [] + test_obj.onChanged() + assert test_obj.called == ["Once test #1", "Once test #2", "Once test #3"] + test_obj.onChanged() + test_obj.onChanged() + assert test_obj.called == ["Once test #1", "Once test #2", "Once test #3"] + + def testOnceNamed(self): + test_obj = ExampleClass() + # Dont store more that one from same type + test_obj.onChanged.once(lambda: test_obj.increment("Once test #1/1"), "type 1") + test_obj.onChanged.once(lambda: test_obj.increment("Once test #1/2"), "type 1") + test_obj.onChanged.once(lambda: test_obj.increment("Once test #2"), "type 2") + + assert test_obj.called == [] + test_obj.onChanged() + assert test_obj.called == ["Once test #1/1", "Once test #2"] + test_obj.onChanged() + test_obj.onChanged() + assert test_obj.called == ["Once test #1/1", "Once test #2"] diff --git a/src/Test/TestFileRequest.py b/src/Test/TestFileRequest.py new file mode 100644 index 00000000..3fabc271 --- /dev/null +++ b/src/Test/TestFileRequest.py @@ -0,0 +1,124 @@ +import io + +import pytest +import time + +from Connection import ConnectionServer +from Connection import Connection +from File import FileServer + + +@pytest.mark.usefixtures("resetSettings") +@pytest.mark.usefixtures("resetTempSettings") +class TestFileRequest: + def testGetFile(self, file_server, site): + file_server.ip_incoming = {} # Reset flood protection + client = ConnectionServer(file_server.ip, 1545) + + connection = client.getConnection(file_server.ip, 1544) + file_server.sites[site.address] = site + + # Normal request + response = connection.request("getFile", {"site": site.address, "inner_path": "content.json", "location": 0}) + assert b"sign" in response["body"] + + response = connection.request("getFile", {"site": site.address, "inner_path": "content.json", "location": 0, "file_size": site.storage.getSize("content.json")}) + assert b"sign" in response["body"] + + # Invalid file + response = connection.request("getFile", {"site": site.address, "inner_path": "invalid.file", "location": 0}) + assert "File read error" in response["error"] + + # Location over size + response = connection.request("getFile", {"site": site.address, "inner_path": "content.json", "location": 1024 * 1024}) + assert "File read error" in response["error"] + + # Stream from parent dir + response = connection.request("getFile", {"site": site.address, "inner_path": "../users.json", "location": 0}) + assert "File read exception" in response["error"] + + # Invalid site + response = connection.request("getFile", {"site": "", "inner_path": "users.json", "location": 0}) + assert "Unknown site" in response["error"] + + response = connection.request("getFile", {"site": ".", "inner_path": "users.json", "location": 0}) + assert "Unknown site" in response["error"] + + # Invalid size + response = connection.request("getFile", {"site": site.address, "inner_path": "content.json", "location": 0, "file_size": 1234}) + assert "File size does not match" in response["error"] + + # Invalid path + for path in ["../users.json", "./../users.json", "data/../content.json", ".../users.json"]: + for sep in ["/", "\\"]: + response = connection.request("getFile", {"site": site.address, "inner_path": path.replace("/", sep), "location": 0}) + assert response["error"] == 'File read exception' + + connection.close() + client.stop() + + def testStreamFile(self, file_server, site): + file_server.ip_incoming = {} # Reset flood protection + client = ConnectionServer(file_server.ip, 1545) + connection = client.getConnection(file_server.ip, 1544) + file_server.sites[site.address] = site + + buff = io.BytesIO() + response = connection.request("streamFile", {"site": site.address, "inner_path": "content.json", "location": 0}, buff) + assert "stream_bytes" in response + assert b"sign" in buff.getvalue() + + # Invalid file + buff = io.BytesIO() + response = connection.request("streamFile", {"site": site.address, "inner_path": "invalid.file", "location": 0}, buff) + assert "File read error" in response["error"] + + # Location over size + buff = io.BytesIO() + response = connection.request( + "streamFile", {"site": site.address, "inner_path": "content.json", "location": 1024 * 1024}, buff + ) + assert "File read error" in response["error"] + + # Stream from parent dir + buff = io.BytesIO() + response = connection.request("streamFile", {"site": site.address, "inner_path": "../users.json", "location": 0}, buff) + assert "File read exception" in response["error"] + + connection.close() + client.stop() + + def testPex(self, file_server, site, site_temp): + file_server.sites[site.address] = site + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + connection = client.getConnection(file_server.ip, 1544) + + # Add new fake peer to site + fake_peer = site.addPeer(file_server.ip_external, 11337, return_peer=True) + # Add fake connection to it + fake_peer.connection = Connection(file_server, file_server.ip_external, 11337) + fake_peer.connection.last_recv_time = time.time() + assert fake_peer in site.getConnectablePeers() + + # Add file_server as peer to client + peer_file_server = site_temp.addPeer(file_server.ip, 1544) + + assert "%s:11337" % file_server.ip_external not in site_temp.peers + assert peer_file_server.pex() + assert "%s:11337" % file_server.ip_external in site_temp.peers + + # Should not exchange private peers from local network + fake_peer_private = site.addPeer("192.168.0.1", 11337, return_peer=True) + assert fake_peer_private not in site.getConnectablePeers(allow_private=False) + fake_peer_private.connection = Connection(file_server, "192.168.0.1", 11337) + fake_peer_private.connection.last_recv_time = time.time() + + assert "192.168.0.1:11337" not in site_temp.peers + assert not peer_file_server.pex() + assert "192.168.0.1:11337" not in site_temp.peers + + + connection.close() + client.stop() diff --git a/src/Test/TestFlag.py b/src/Test/TestFlag.py new file mode 100644 index 00000000..12fd8165 --- /dev/null +++ b/src/Test/TestFlag.py @@ -0,0 +1,39 @@ +import os + +import pytest + +from util.Flag import Flag + +class TestFlag: + def testFlagging(self): + flag = Flag() + @flag.admin + @flag.no_multiuser + def testFn(anything): + return anything + + assert "admin" in flag.db["testFn"] + assert "no_multiuser" in flag.db["testFn"] + + def testSubclassedFlagging(self): + flag = Flag() + class Test: + @flag.admin + @flag.no_multiuser + def testFn(anything): + return anything + + class SubTest(Test): + pass + + assert "admin" in flag.db["testFn"] + assert "no_multiuser" in flag.db["testFn"] + + def testInvalidFlag(self): + flag = Flag() + with pytest.raises(Exception) as err: + @flag.no_multiuser + @flag.unknown_flag + def testFn(anything): + return anything + assert "Invalid flag" in str(err.value) diff --git a/src/Test/TestHelper.py b/src/Test/TestHelper.py new file mode 100644 index 00000000..07644ec0 --- /dev/null +++ b/src/Test/TestHelper.py @@ -0,0 +1,79 @@ +import socket +import struct +import os + +import pytest +from util import helper +from Config import config + + +@pytest.mark.usefixtures("resetSettings") +class TestHelper: + def testShellquote(self): + assert helper.shellquote("hel'lo") == "\"hel'lo\"" # Allow ' + assert helper.shellquote('hel"lo') == '"hello"' # Remove " + assert helper.shellquote("hel'lo", 'hel"lo') == ('"hel\'lo"', '"hello"') + + def testPackAddress(self): + for port in [1, 1000, 65535]: + for ip in ["1.1.1.1", "127.0.0.1", "0.0.0.0", "255.255.255.255", "192.168.1.1"]: + assert len(helper.packAddress(ip, port)) == 6 + assert helper.unpackAddress(helper.packAddress(ip, port)) == (ip, port) + + for ip in ["1:2:3:4:5:6:7:8", "::1", "2001:19f0:6c01:e76:5400:1ff:fed6:3eca", "2001:4860:4860::8888"]: + assert len(helper.packAddress(ip, port)) == 18 + assert helper.unpackAddress(helper.packAddress(ip, port)) == (ip, port) + + assert len(helper.packOnionAddress("boot3rdez4rzn36x.onion", port)) == 12 + assert helper.unpackOnionAddress(helper.packOnionAddress("boot3rdez4rzn36x.onion", port)) == ("boot3rdez4rzn36x.onion", port) + + with pytest.raises(struct.error): + helper.packAddress("1.1.1.1", 100000) + + with pytest.raises(socket.error): + helper.packAddress("999.1.1.1", 1) + + with pytest.raises(Exception): + helper.unpackAddress("X") + + def testGetDirname(self): + assert helper.getDirname("data/users/content.json") == "data/users/" + assert helper.getDirname("data/users") == "data/" + assert helper.getDirname("") == "" + assert helper.getDirname("content.json") == "" + assert helper.getDirname("data/users/") == "data/users/" + assert helper.getDirname("/data/users/content.json") == "data/users/" + + def testGetFilename(self): + assert helper.getFilename("data/users/content.json") == "content.json" + assert helper.getFilename("data/users") == "users" + assert helper.getFilename("") == "" + assert helper.getFilename("content.json") == "content.json" + assert helper.getFilename("data/users/") == "" + assert helper.getFilename("/data/users/content.json") == "content.json" + + def testIsIp(self): + assert helper.isIp("1.2.3.4") + assert helper.isIp("255.255.255.255") + assert not helper.isIp("any.host") + assert not helper.isIp("1.2.3.4.com") + assert not helper.isIp("1.2.3.4.any.host") + + def testIsPrivateIp(self): + assert helper.isPrivateIp("192.168.1.1") + assert not helper.isPrivateIp("1.1.1.1") + assert helper.isPrivateIp("fe80::44f0:3d0:4e6:637c") + assert not helper.isPrivateIp("fca5:95d6:bfde:d902:8951:276e:1111:a22c") # cjdns + + def testOpenLocked(self): + locked_f = helper.openLocked(config.data_dir + "/locked.file") + assert locked_f + with pytest.raises(BlockingIOError): + locked_f_again = helper.openLocked(config.data_dir + "/locked.file") + locked_f_different = helper.openLocked(config.data_dir + "/locked_different.file") + + locked_f.close() + locked_f_different.close() + + os.unlink(locked_f.name) + os.unlink(locked_f_different.name) diff --git a/src/Test/TestMsgpack.py b/src/Test/TestMsgpack.py new file mode 100644 index 00000000..5a0b6d4d --- /dev/null +++ b/src/Test/TestMsgpack.py @@ -0,0 +1,88 @@ +import io +import os + +import msgpack +import pytest + +from Config import config +from util import Msgpack +from collections import OrderedDict + + +class TestMsgpack: + test_data = OrderedDict( + sorted({"cmd": "fileGet", "bin": b'p\x81zDhL\xf0O\xd0\xaf', "params": {"site": "1Site"}, "utf8": b'\xc3\xa1rv\xc3\xadzt\xc5\xb1r\xc5\x91'.decode("utf8"), "list": [b'p\x81zDhL\xf0O\xd0\xaf', b'p\x81zDhL\xf0O\xd0\xaf']}.items()) + ) + + def testPacking(self): + assert Msgpack.pack(self.test_data) == b'\x85\xa3bin\xc4\np\x81zDhL\xf0O\xd0\xaf\xa3cmd\xa7fileGet\xa4list\x92\xc4\np\x81zDhL\xf0O\xd0\xaf\xc4\np\x81zDhL\xf0O\xd0\xaf\xa6params\x81\xa4site\xa51Site\xa4utf8\xad\xc3\xa1rv\xc3\xadzt\xc5\xb1r\xc5\x91' + assert Msgpack.pack(self.test_data, use_bin_type=False) == b'\x85\xa3bin\xaap\x81zDhL\xf0O\xd0\xaf\xa3cmd\xa7fileGet\xa4list\x92\xaap\x81zDhL\xf0O\xd0\xaf\xaap\x81zDhL\xf0O\xd0\xaf\xa6params\x81\xa4site\xa51Site\xa4utf8\xad\xc3\xa1rv\xc3\xadzt\xc5\xb1r\xc5\x91' + + def testUnpackinkg(self): + assert Msgpack.unpack(Msgpack.pack(self.test_data)) == self.test_data + + @pytest.mark.parametrize("unpacker_class", [msgpack.Unpacker, msgpack.fallback.Unpacker]) + def testUnpacker(self, unpacker_class): + unpacker = unpacker_class(raw=False) + + data = msgpack.packb(self.test_data, use_bin_type=True) + data += msgpack.packb(self.test_data, use_bin_type=True) + + messages = [] + for char in data: + unpacker.feed(bytes([char])) + for message in unpacker: + messages.append(message) + + assert len(messages) == 2 + assert messages[0] == self.test_data + assert messages[0] == messages[1] + + def testStreaming(self): + bin_data = os.urandom(20) + f = Msgpack.FilePart("%s/users.json" % config.data_dir, "rb") + f.read_bytes = 30 + + data = {"cmd": "response", "body": f, "bin": bin_data} + + out_buff = io.BytesIO() + Msgpack.stream(data, out_buff.write) + out_buff.seek(0) + + data_packb = { + "cmd": "response", + "body": open("%s/users.json" % config.data_dir, "rb").read(30), + "bin": bin_data + } + + out_buff.seek(0) + data_unpacked = Msgpack.unpack(out_buff.read()) + assert data_unpacked == data_packb + assert data_unpacked["cmd"] == "response" + assert type(data_unpacked["body"]) == bytes + + def testBackwardCompatibility(self): + packed = {} + packed["py3"] = Msgpack.pack(self.test_data, use_bin_type=False) + packed["py3_bin"] = Msgpack.pack(self.test_data, use_bin_type=True) + for key, val in packed.items(): + unpacked = Msgpack.unpack(val) + type(unpacked["utf8"]) == str + type(unpacked["bin"]) == bytes + + # Packed with use_bin_type=False (pre-ZeroNet 0.7.0) + unpacked = Msgpack.unpack(packed["py3"], decode=True) + type(unpacked["utf8"]) == str + type(unpacked["bin"]) == bytes + assert len(unpacked["utf8"]) == 9 + assert len(unpacked["bin"]) == 10 + with pytest.raises(UnicodeDecodeError) as err: # Try to decode binary as utf-8 + unpacked = Msgpack.unpack(packed["py3"], decode=False) + + # Packed with use_bin_type=True + unpacked = Msgpack.unpack(packed["py3_bin"], decode=False) + type(unpacked["utf8"]) == str + type(unpacked["bin"]) == bytes + assert len(unpacked["utf8"]) == 9 + assert len(unpacked["bin"]) == 10 + diff --git a/src/Test/TestNoparallel.py b/src/Test/TestNoparallel.py new file mode 100644 index 00000000..6fc4f57d --- /dev/null +++ b/src/Test/TestNoparallel.py @@ -0,0 +1,167 @@ +import time + +import gevent +import pytest + +import util +from util import ThreadPool + + +@pytest.fixture(params=['gevent.spawn', 'thread_pool.spawn']) +def queue_spawn(request): + thread_pool = ThreadPool.ThreadPool(10) + if request.param == "gevent.spawn": + return gevent.spawn + else: + return thread_pool.spawn + + +class ExampleClass(object): + def __init__(self): + self.counted = 0 + + @util.Noparallel() + def countBlocking(self, num=5): + for i in range(1, num + 1): + time.sleep(0.1) + self.counted += 1 + return "counted:%s" % i + + @util.Noparallel(queue=True, ignore_class=True) + def countQueue(self, num=5): + for i in range(1, num + 1): + time.sleep(0.1) + self.counted += 1 + return "counted:%s" % i + + @util.Noparallel(blocking=False) + def countNoblocking(self, num=5): + for i in range(1, num + 1): + time.sleep(0.01) + self.counted += 1 + return "counted:%s" % i + + +class TestNoparallel: + def testBlocking(self, queue_spawn): + obj1 = ExampleClass() + obj2 = ExampleClass() + + # Dont allow to call again until its running and wait until its running + threads = [ + queue_spawn(obj1.countBlocking), + queue_spawn(obj1.countBlocking), + queue_spawn(obj1.countBlocking), + queue_spawn(obj2.countBlocking) + ] + assert obj2.countBlocking() == "counted:5" # The call is ignored as obj2.countBlocking already counting, but block until its finishes + gevent.joinall(threads) + assert [thread.value for thread in threads] == ["counted:5", "counted:5", "counted:5", "counted:5"] + obj2.countBlocking() # Allow to call again as obj2.countBlocking finished + + assert obj1.counted == 5 + assert obj2.counted == 10 + + def testNoblocking(self): + obj1 = ExampleClass() + + thread1 = obj1.countNoblocking() + thread2 = obj1.countNoblocking() # Ignored + + assert obj1.counted == 0 + time.sleep(0.1) + assert thread1.value == "counted:5" + assert thread2.value == "counted:5" + assert obj1.counted == 5 + + obj1.countNoblocking().join() # Allow again and wait until finishes + assert obj1.counted == 10 + + def testQueue(self, queue_spawn): + obj1 = ExampleClass() + + queue_spawn(obj1.countQueue, num=1) + queue_spawn(obj1.countQueue, num=1) + queue_spawn(obj1.countQueue, num=1) + + time.sleep(0.3) + assert obj1.counted == 2 # No multi-queue supported + + obj2 = ExampleClass() + queue_spawn(obj2.countQueue, num=10) + queue_spawn(obj2.countQueue, num=10) + + time.sleep(1.5) # Call 1 finished, call 2 still working + assert 10 < obj2.counted < 20 + + queue_spawn(obj2.countQueue, num=10) + time.sleep(2.0) + + assert obj2.counted == 30 + + def testQueueOverload(self): + obj1 = ExampleClass() + + threads = [] + for i in range(1000): + thread = gevent.spawn(obj1.countQueue, num=5) + threads.append(thread) + + gevent.joinall(threads) + assert obj1.counted == 5 * 2 # Only called twice (no multi-queue allowed) + + def testIgnoreClass(self, queue_spawn): + obj1 = ExampleClass() + obj2 = ExampleClass() + + threads = [ + queue_spawn(obj1.countQueue), + queue_spawn(obj1.countQueue), + queue_spawn(obj1.countQueue), + queue_spawn(obj2.countQueue), + queue_spawn(obj2.countQueue) + ] + s = time.time() + time.sleep(0.001) + gevent.joinall(threads) + + # Queue limited to 2 calls (every call takes counts to 5 and takes 0.05 sec) + assert obj1.counted + obj2.counted == 10 + + taken = time.time() - s + assert 1.2 > taken >= 1.0 # 2 * 0.5s count = ~1s + + def testException(self, queue_spawn): + class MyException(Exception): + pass + + @util.Noparallel() + def raiseException(): + raise MyException("Test error!") + + with pytest.raises(MyException) as err: + raiseException() + assert str(err.value) == "Test error!" + + with pytest.raises(MyException) as err: + queue_spawn(raiseException).get() + assert str(err.value) == "Test error!" + + def testMultithreadMix(self, queue_spawn): + obj1 = ExampleClass() + with ThreadPool.ThreadPool(10) as thread_pool: + s = time.time() + t1 = queue_spawn(obj1.countBlocking, 5) + time.sleep(0.01) + t2 = thread_pool.spawn(obj1.countBlocking, 5) + time.sleep(0.01) + t3 = thread_pool.spawn(obj1.countBlocking, 5) + time.sleep(0.3) + t4 = gevent.spawn(obj1.countBlocking, 5) + threads = [t1, t2, t3, t4] + for thread in threads: + assert thread.get() == "counted:5" + + time_taken = time.time() - s + assert obj1.counted == 5 + assert 0.5 < time_taken < 0.7 diff --git a/src/Test/TestPeer.py b/src/Test/TestPeer.py new file mode 100644 index 00000000..f57e046e --- /dev/null +++ b/src/Test/TestPeer.py @@ -0,0 +1,159 @@ +import time +import io + +import pytest + +from File import FileServer +from File import FileRequest +from Crypt import CryptHash +from . import Spy + + +@pytest.mark.usefixtures("resetSettings") +@pytest.mark.usefixtures("resetTempSettings") +class TestPeer: + def testPing(self, file_server, site, site_temp): + file_server.sites[site.address] = site + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + connection = client.getConnection(file_server.ip, 1544) + + # Add file_server as peer to client + peer_file_server = site_temp.addPeer(file_server.ip, 1544) + + assert peer_file_server.ping() is not None + + assert peer_file_server in site_temp.peers.values() + peer_file_server.remove() + assert peer_file_server not in site_temp.peers.values() + + connection.close() + client.stop() + + def testDownloadFile(self, file_server, site, site_temp): + file_server.sites[site.address] = site + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + connection = client.getConnection(file_server.ip, 1544) + + # Add file_server as peer to client + peer_file_server = site_temp.addPeer(file_server.ip, 1544) + + # Testing streamFile + buff = peer_file_server.getFile(site_temp.address, "content.json", streaming=True) + assert b"sign" in buff.getvalue() + + # Testing getFile + buff = peer_file_server.getFile(site_temp.address, "content.json") + assert b"sign" in buff.getvalue() + + connection.close() + client.stop() + + def testHashfield(self, site): + sample_hash = list(site.content_manager.contents["content.json"]["files_optional"].values())[0]["sha512"] + + site.storage.verifyFiles(quick_check=True) # Find what optional files we have + + # Check if hashfield has any files + assert site.content_manager.hashfield + assert len(site.content_manager.hashfield) > 0 + + # Check exsist hash + assert site.content_manager.hashfield.getHashId(sample_hash) in site.content_manager.hashfield + + # Add new hash + new_hash = CryptHash.sha512sum(io.BytesIO(b"hello")) + assert site.content_manager.hashfield.getHashId(new_hash) not in site.content_manager.hashfield + assert site.content_manager.hashfield.appendHash(new_hash) + assert not site.content_manager.hashfield.appendHash(new_hash) # Don't add second time + assert site.content_manager.hashfield.getHashId(new_hash) in site.content_manager.hashfield + + # Remove new hash + assert site.content_manager.hashfield.removeHash(new_hash) + assert site.content_manager.hashfield.getHashId(new_hash) not in site.content_manager.hashfield + + def testHashfieldExchange(self, file_server, site, site_temp): + server1 = file_server + server1.sites[site.address] = site + site.connection_server = server1 + + server2 = FileServer(file_server.ip, 1545) + server2.sites[site_temp.address] = site_temp + site_temp.connection_server = server2 + site.storage.verifyFiles(quick_check=True) # Find what optional files we have + + # Add file_server as peer to client + server2_peer1 = site_temp.addPeer(file_server.ip, 1544) + + # Check if hashfield has any files + assert len(site.content_manager.hashfield) > 0 + + # Testing hashfield sync + assert len(server2_peer1.hashfield) == 0 + assert server2_peer1.updateHashfield() # Query hashfield from peer + assert len(server2_peer1.hashfield) > 0 + + # Test force push new hashfield + site_temp.content_manager.hashfield.appendHash("AABB") + server1_peer2 = site.addPeer(file_server.ip, 1545, return_peer=True) + with Spy.Spy(FileRequest, "route") as requests: + assert len(server1_peer2.hashfield) == 0 + server2_peer1.sendMyHashfield() + assert len(server1_peer2.hashfield) == 1 + server2_peer1.sendMyHashfield() # Hashfield not changed, should be ignored + + assert len(requests) == 1 + + time.sleep(0.01) # To make hashfield change date different + + site_temp.content_manager.hashfield.appendHash("AACC") + server2_peer1.sendMyHashfield() # Push hashfield + + assert len(server1_peer2.hashfield) == 2 + assert len(requests) == 2 + + site_temp.content_manager.hashfield.appendHash("AADD") + + assert server1_peer2.updateHashfield(force=True) # Request hashfield + assert len(server1_peer2.hashfield) == 3 + assert len(requests) == 3 + + assert not server2_peer1.sendMyHashfield() # Not changed, should be ignored + assert len(requests) == 3 + + server2.stop() + + def testFindHash(self, file_server, site, site_temp): + file_server.sites[site.address] = site + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Add file_server as peer to client + peer_file_server = site_temp.addPeer(file_server.ip, 1544) + + assert peer_file_server.findHashIds([1234]) == {} + + # Add fake peer with requred hash + fake_peer_1 = site.addPeer(file_server.ip_external, 1544) + fake_peer_1.hashfield.append(1234) + fake_peer_2 = site.addPeer("1.2.3.5", 1545) + fake_peer_2.hashfield.append(1234) + fake_peer_2.hashfield.append(1235) + fake_peer_3 = site.addPeer("1.2.3.6", 1546) + fake_peer_3.hashfield.append(1235) + fake_peer_3.hashfield.append(1236) + + res = peer_file_server.findHashIds([1234, 1235]) + assert sorted(res[1234]) == sorted([(file_server.ip_external, 1544), ("1.2.3.5", 1545)]) + assert sorted(res[1235]) == sorted([("1.2.3.5", 1545), ("1.2.3.6", 1546)]) + + # Test my address adding + site.content_manager.hashfield.append(1234) + + res = peer_file_server.findHashIds([1234, 1235]) + assert sorted(res[1234]) == sorted([(file_server.ip_external, 1544), ("1.2.3.5", 1545), (file_server.ip, 1544)]) + assert sorted(res[1235]) == sorted([("1.2.3.5", 1545), ("1.2.3.6", 1546)]) diff --git a/src/Test/TestRateLimit.py b/src/Test/TestRateLimit.py new file mode 100644 index 00000000..fafa5f1a --- /dev/null +++ b/src/Test/TestRateLimit.py @@ -0,0 +1,100 @@ +import time + +import gevent + +from util import RateLimit + + +# Time is around limit +/- 0.05 sec +def around(t, limit): + return t >= limit - 0.05 and t <= limit + 0.05 + + +class ExampleClass(object): + def __init__(self): + self.counted = 0 + self.last_called = None + + def count(self, back="counted"): + self.counted += 1 + self.last_called = back + return back + + +class TestRateLimit: + def testCall(self): + obj1 = ExampleClass() + obj2 = ExampleClass() + + s = time.time() + assert RateLimit.call("counting", allowed_again=0.1, func=obj1.count) == "counted" + assert around(time.time() - s, 0.0) # First allow to call instantly + assert obj1.counted == 1 + + # Call again + assert not RateLimit.isAllowed("counting", 0.1) + assert RateLimit.isAllowed("something else", 0.1) + assert RateLimit.call("counting", allowed_again=0.1, func=obj1.count) == "counted" + assert around(time.time() - s, 0.1) # Delays second call within interval + assert obj1.counted == 2 + time.sleep(0.1) # Wait the cooldown time + + # Call 3 times async + s = time.time() + assert obj2.counted == 0 + threads = [ + gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)), # Instant + gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)), # 0.1s delay + gevent.spawn(lambda: RateLimit.call("counting", allowed_again=0.1, func=obj2.count)) # 0.2s delay + ] + gevent.joinall(threads) + assert [thread.value for thread in threads] == ["counted", "counted", "counted"] + assert around(time.time() - s, 0.2) + + # Wait 0.1s cooldown + assert not RateLimit.isAllowed("counting", 0.1) + time.sleep(0.11) + assert RateLimit.isAllowed("counting", 0.1) + + # No queue = instant again + s = time.time() + assert RateLimit.isAllowed("counting", 0.1) + assert RateLimit.call("counting", allowed_again=0.1, func=obj2.count) == "counted" + assert around(time.time() - s, 0.0) + + assert obj2.counted == 4 + + def testCallAsync(self): + obj1 = ExampleClass() + obj2 = ExampleClass() + + s = time.time() + RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #1").join() + assert obj1.counted == 1 # First instant + assert around(time.time() - s, 0.0) + + # After that the calls delayed + s = time.time() + t1 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #2") # Dumped by the next call + time.sleep(0.03) + t2 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #3") # Dumped by the next call + time.sleep(0.03) + t3 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #4") # Will be called + assert obj1.counted == 1 # Delay still in progress: Not called yet + t3.join() + assert t3.value == "call #4" + assert around(time.time() - s, 0.1) + + # Only the last one called + assert obj1.counted == 2 + assert obj1.last_called == "call #4" + + # Just called, not allowed again + assert not RateLimit.isAllowed("counting async", 0.1) + s = time.time() + t4 = RateLimit.callAsync("counting async", allowed_again=0.1, func=obj1.count, back="call #5").join() + assert obj1.counted == 3 + assert around(time.time() - s, 0.1) + assert not RateLimit.isAllowed("counting async", 0.1) + time.sleep(0.11) + assert RateLimit.isAllowed("counting async", 0.1) diff --git a/src/Test/TestSafeRe.py b/src/Test/TestSafeRe.py new file mode 100644 index 00000000..429bde50 --- /dev/null +++ b/src/Test/TestSafeRe.py @@ -0,0 +1,24 @@ +from util import SafeRe + +import pytest + + +class TestSafeRe: + def testSafeMatch(self): + assert SafeRe.match( + "((js|css)/(?!all.(js|css))|data/users/.*db|data/users/.*/.*|data/archived|.*.py)", + "js/ZeroTalk.coffee" + ) + assert SafeRe.match(".+/data.json", "data/users/1J3rJ8ecnwH2EPYa6MrgZttBNc61ACFiCj/data.json") + + @pytest.mark.parametrize("pattern", ["([a-zA-Z]+)*", "(a|aa)+*", "(a|a?)+", "(.*a){10}", "((?!json).)*$", r"(\w+\d+)+C"]) + def testUnsafeMatch(self, pattern): + with pytest.raises(SafeRe.UnsafePatternError) as err: + SafeRe.match(pattern, "aaaaaaaaaaaaaaaaaaaaaaaa!") + assert "Potentially unsafe" in str(err.value) + + @pytest.mark.parametrize("pattern", ["^(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)(.*a)$"]) + def testUnsafeRepetition(self, pattern): + with pytest.raises(SafeRe.UnsafePatternError) as err: + SafeRe.match(pattern, "aaaaaaaaaaaaaaaaaaaaaaaa!") + assert "More than" in str(err.value) diff --git a/src/Test/TestSite.py b/src/Test/TestSite.py new file mode 100644 index 00000000..05bb2ed9 --- /dev/null +++ b/src/Test/TestSite.py @@ -0,0 +1,70 @@ +import shutil +import os + +import pytest +from Site import SiteManager + +TEST_DATA_PATH = "src/Test/testdata" + +@pytest.mark.usefixtures("resetSettings") +class TestSite: + def testClone(self, site): + assert site.storage.directory == TEST_DATA_PATH + "/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" + + # Remove old files + if os.path.isdir(TEST_DATA_PATH + "/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL"): + shutil.rmtree(TEST_DATA_PATH + "/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + assert not os.path.isfile(TEST_DATA_PATH + "/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL/content.json") + + # Clone 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT to 15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc + new_site = site.clone( + "159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL", "5JU2p5h3R7B1WrbaEdEDNZR7YHqRLGcjNcqwqVQzX2H4SuNe2ee", address_index=1 + ) + + # Check if clone was successful + assert new_site.address == "159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL" + assert new_site.storage.isFile("content.json") + assert new_site.storage.isFile("index.html") + assert new_site.storage.isFile("data/users/content.json") + assert new_site.storage.isFile("data/zeroblog.db") + assert new_site.storage.verifyFiles()["bad_files"] == [] # No bad files allowed + assert new_site.storage.query("SELECT * FROM keyvalue WHERE key = 'title'").fetchone()["value"] == "MyZeroBlog" + + # Optional files should be removed + + assert len(new_site.storage.loadJson("content.json").get("files_optional", {})) == 0 + + # Test re-cloning (updating) + + # Changes in non-data files should be overwritten + new_site.storage.write("index.html", b"this will be overwritten") + assert new_site.storage.read("index.html") == b"this will be overwritten" + + # Changes in data file should be kept after re-cloning + changed_contentjson = new_site.storage.loadJson("content.json") + changed_contentjson["description"] = "Update Description Test" + new_site.storage.writeJson("content.json", changed_contentjson) + + changed_data = new_site.storage.loadJson("data/data.json") + changed_data["title"] = "UpdateTest" + new_site.storage.writeJson("data/data.json", changed_data) + + # The update should be reflected to database + assert new_site.storage.query("SELECT * FROM keyvalue WHERE key = 'title'").fetchone()["value"] == "UpdateTest" + + # Re-clone the site + site.log.debug("Re-cloning") + site.clone("159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + + assert new_site.storage.loadJson("data/data.json")["title"] == "UpdateTest" + assert new_site.storage.loadJson("content.json")["description"] == "Update Description Test" + assert new_site.storage.read("index.html") != "this will be overwritten" + + # Delete created files + new_site.storage.deleteFiles() + assert not os.path.isdir(TEST_DATA_PATH + "/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + + # Delete from site registry + assert new_site.address in SiteManager.site_manager.sites + SiteManager.site_manager.delete(new_site.address) + assert new_site.address not in SiteManager.site_manager.sites diff --git a/src/Test/TestSiteDownload.py b/src/Test/TestSiteDownload.py new file mode 100644 index 00000000..cd0a4c9f --- /dev/null +++ b/src/Test/TestSiteDownload.py @@ -0,0 +1,562 @@ +import time + +import pytest +import mock +import gevent +import gevent.event +import os + +from Connection import ConnectionServer +from Config import config +from File import FileRequest +from File import FileServer +from Site.Site import Site +from . import Spy + + +@pytest.mark.usefixtures("resetTempSettings") +@pytest.mark.usefixtures("resetSettings") +class TestSiteDownload: + def testRename(self, file_server, site, site_temp): + assert site.storage.directory == config.data_dir + "/" + site.address + assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address + + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + + site_temp.addPeer(file_server.ip, 1544) + + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + assert site_temp.storage.isFile("content.json") + + # Rename non-optional file + os.rename(site.storage.getPath("data/img/domain.png"), site.storage.getPath("data/img/domain-new.png")) + + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + + content = site.storage.loadJson("content.json") + assert "data/img/domain-new.png" in content["files"] + assert "data/img/domain.png" not in content["files"] + assert not site_temp.storage.isFile("data/img/domain-new.png") + assert site_temp.storage.isFile("data/img/domain.png") + settings_before = site_temp.settings + + with Spy.Spy(FileRequest, "route") as requests: + site.publish() + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) # Wait for download + assert "streamFile" not in [req[1] for req in requests] + + content = site_temp.storage.loadJson("content.json") + assert "data/img/domain-new.png" in content["files"] + assert "data/img/domain.png" not in content["files"] + assert site_temp.storage.isFile("data/img/domain-new.png") + assert not site_temp.storage.isFile("data/img/domain.png") + + assert site_temp.settings["size"] == settings_before["size"] + assert site_temp.settings["size_optional"] == settings_before["size_optional"] + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + def testRenameOptional(self, file_server, site, site_temp): + assert site.storage.directory == config.data_dir + "/" + site.address + assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address + + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + + site_temp.addPeer(file_server.ip, 1544) + + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + assert site_temp.settings["optional_downloaded"] == 0 + + site_temp.needFile("data/optional.txt") + + assert site_temp.settings["optional_downloaded"] > 0 + settings_before = site_temp.settings + hashfield_before = site_temp.content_manager.hashfield.tobytes() + + # Rename optional file + os.rename(site.storage.getPath("data/optional.txt"), site.storage.getPath("data/optional-new.txt")) + + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv", remove_missing_optional=True) + + content = site.storage.loadJson("content.json") + assert "data/optional-new.txt" in content["files_optional"] + assert "data/optional.txt" not in content["files_optional"] + assert not site_temp.storage.isFile("data/optional-new.txt") + assert site_temp.storage.isFile("data/optional.txt") + + with Spy.Spy(FileRequest, "route") as requests: + site.publish() + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) # Wait for download + assert "streamFile" not in [req[1] for req in requests] + + content = site_temp.storage.loadJson("content.json") + assert "data/optional-new.txt" in content["files_optional"] + assert "data/optional.txt" not in content["files_optional"] + assert site_temp.storage.isFile("data/optional-new.txt") + assert not site_temp.storage.isFile("data/optional.txt") + + assert site_temp.settings["size"] == settings_before["size"] + assert site_temp.settings["size_optional"] == settings_before["size_optional"] + assert site_temp.settings["optional_downloaded"] == settings_before["optional_downloaded"] + assert site_temp.content_manager.hashfield.tobytes() == hashfield_before + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + + def testArchivedDownload(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Download normally + site_temp.addPeer(file_server.ip, 1544) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + bad_files = site_temp.storage.verifyFiles(quick_check=True)["bad_files"] + + assert not bad_files + assert "data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json" in site_temp.content_manager.contents + assert site_temp.storage.isFile("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json") + assert len(list(site_temp.storage.query("SELECT * FROM comment"))) == 2 + + # Add archived data + assert "archived" not in site.content_manager.contents["data/users/content.json"]["user_contents"] + assert not site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", time.time()-1) + + site.content_manager.contents["data/users/content.json"]["user_contents"]["archived"] = {"1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q": time.time()} + site.content_manager.sign("data/users/content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + + date_archived = site.content_manager.contents["data/users/content.json"]["user_contents"]["archived"]["1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q"] + assert site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived-1) + assert site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived) + assert not site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived+1) # Allow user to update archived data later + + # Push archived update + assert not "archived" in site_temp.content_manager.contents["data/users/content.json"]["user_contents"] + site.publish() + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) # Wait for download + + # The archived content should disappear from remote client + assert "archived" in site_temp.content_manager.contents["data/users/content.json"]["user_contents"] + assert "data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json" not in site_temp.content_manager.contents + assert not site_temp.storage.isDir("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q") + assert len(list(site_temp.storage.query("SELECT * FROM comment"))) == 1 + assert len(list(site_temp.storage.query("SELECT * FROM json WHERE directory LIKE '%1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q%'"))) == 0 + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + def testArchivedBeforeDownload(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Download normally + site_temp.addPeer(file_server.ip, 1544) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + bad_files = site_temp.storage.verifyFiles(quick_check=True)["bad_files"] + + assert not bad_files + assert "data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json" in site_temp.content_manager.contents + assert site_temp.storage.isFile("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json") + assert len(list(site_temp.storage.query("SELECT * FROM comment"))) == 2 + + # Add archived data + assert not "archived_before" in site.content_manager.contents["data/users/content.json"]["user_contents"] + assert not site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", time.time()-1) + + content_modification_time = site.content_manager.contents["data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json"]["modified"] + site.content_manager.contents["data/users/content.json"]["user_contents"]["archived_before"] = content_modification_time + site.content_manager.sign("data/users/content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + + date_archived = site.content_manager.contents["data/users/content.json"]["user_contents"]["archived_before"] + assert site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived-1) + assert site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived) + assert not site.content_manager.isArchived("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json", date_archived+1) # Allow user to update archived data later + + # Push archived update + assert not "archived_before" in site_temp.content_manager.contents["data/users/content.json"]["user_contents"] + site.publish() + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) # Wait for download + + # The archived content should disappear from remote client + assert "archived_before" in site_temp.content_manager.contents["data/users/content.json"]["user_contents"] + assert "data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json" not in site_temp.content_manager.contents + assert not site_temp.storage.isDir("data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q") + assert len(list(site_temp.storage.query("SELECT * FROM comment"))) == 1 + assert len(list(site_temp.storage.query("SELECT * FROM json WHERE directory LIKE '%1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q%'"))) == 0 + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + + # Test when connected peer has the optional file + def testOptionalDownload(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = ConnectionServer(file_server.ip, 1545) + site_temp.connection_server = client + site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + site_temp.addPeer(file_server.ip, 1544) + + # Download site + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + # Download optional data/optional.txt + site.storage.verifyFiles(quick_check=True) # Find what optional files we have + optional_file_info = site_temp.content_manager.getFileInfo("data/optional.txt") + assert site.content_manager.hashfield.hasHash(optional_file_info["sha512"]) + assert not site_temp.content_manager.hashfield.hasHash(optional_file_info["sha512"]) + + assert not site_temp.storage.isFile("data/optional.txt") + assert site.storage.isFile("data/optional.txt") + site_temp.needFile("data/optional.txt") + assert site_temp.storage.isFile("data/optional.txt") + + # Optional user file + assert not site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + optional_file_info = site_temp.content_manager.getFileInfo( + "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif" + ) + assert site.content_manager.hashfield.hasHash(optional_file_info["sha512"]) + assert not site_temp.content_manager.hashfield.hasHash(optional_file_info["sha512"]) + + site_temp.needFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert site_temp.content_manager.hashfield.hasHash(optional_file_info["sha512"]) + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + # Test when connected peer does not has the file, so ask him if he know someone who has it + def testFindOptional(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init full source server (has optional files) + site_full = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") + file_server_full = FileServer(file_server.ip, 1546) + site_full.connection_server = file_server_full + + def listen(): + ConnectionServer.start(file_server_full) + ConnectionServer.listen(file_server_full) + + gevent.spawn(listen) + time.sleep(0.001) # Port opening + file_server_full.sites[site_full.address] = site_full # Add site + site_full.storage.verifyFiles(quick_check=True) # Check optional files + site_full_peer = site.addPeer(file_server.ip, 1546) # Add it to source server + hashfield = site_full_peer.updateHashfield() # Update hashfield + assert len(site_full.content_manager.hashfield) == 8 + assert hashfield + assert site_full.storage.isFile("data/optional.txt") + assert site_full.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert len(site_full_peer.hashfield) == 8 + + # Remove hashes from source server + for hash in list(site.content_manager.hashfield): + site.content_manager.hashfield.remove(hash) + + # Init client server + site_temp.connection_server = ConnectionServer(file_server.ip, 1545) + site_temp.addPeer(file_server.ip, 1544) # Add source server + + # Download normal files + site_temp.log.info("Start Downloading site") + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + # Download optional data/optional.txt + optional_file_info = site_temp.content_manager.getFileInfo("data/optional.txt") + optional_file_info2 = site_temp.content_manager.getFileInfo("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert not site_temp.storage.isFile("data/optional.txt") + assert not site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + assert not site.content_manager.hashfield.hasHash(optional_file_info["sha512"]) # Source server don't know he has the file + assert not site.content_manager.hashfield.hasHash(optional_file_info2["sha512"]) # Source server don't know he has the file + assert site_full_peer.hashfield.hasHash(optional_file_info["sha512"]) # Source full peer on source server has the file + assert site_full_peer.hashfield.hasHash(optional_file_info2["sha512"]) # Source full peer on source server has the file + assert site_full.content_manager.hashfield.hasHash(optional_file_info["sha512"]) # Source full server he has the file + assert site_full.content_manager.hashfield.hasHash(optional_file_info2["sha512"]) # Source full server he has the file + + site_temp.log.info("Request optional files") + with Spy.Spy(FileRequest, "route") as requests: + # Request 2 file same time + threads = [] + threads.append(site_temp.needFile("data/optional.txt", blocking=False)) + threads.append(site_temp.needFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif", blocking=False)) + gevent.joinall(threads) + + assert len([request for request in requests if request[1] == "findHashIds"]) == 1 # findHashids should call only once + + assert site_temp.storage.isFile("data/optional.txt") + assert site_temp.storage.isFile("data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif") + + assert site_temp.storage.deleteFiles() + file_server_full.stop() + [connection.close() for connection in file_server.connections] + site_full.content_manager.contents.db.close("FindOptional test end") + + def testUpdate(self, file_server, site, site_temp): + assert site.storage.directory == config.data_dir + "/" + site.address + assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address + + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Don't try to find peers from the net + site.announce = mock.MagicMock(return_value=True) + site_temp.announce = mock.MagicMock(return_value=True) + + # Connect peers + site_temp.addPeer(file_server.ip, 1544) + + # Download site from site to site_temp + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + assert len(site_temp.bad_files) == 1 + + # Update file + data_original = site.storage.open("data/data.json").read() + data_new = data_original.replace(b'"ZeroBlog"', b'"UpdatedZeroBlog"') + assert data_original != data_new + + site.storage.open("data/data.json", "wb").write(data_new) + + assert site.storage.open("data/data.json").read() == data_new + assert site_temp.storage.open("data/data.json").read() == data_original + + site.log.info("Publish new data.json without patch") + # Publish without patch + with Spy.Spy(FileRequest, "route") as requests: + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + site.publish() + time.sleep(0.1) + site.log.info("Downloading site") + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + assert len([request for request in requests if request[1] in ("getFile", "streamFile")]) == 1 + + assert site_temp.storage.open("data/data.json").read() == data_new + + # Close connection to avoid update spam limit + list(site.peers.values())[0].remove() + site.addPeer(file_server.ip, 1545) + list(site_temp.peers.values())[0].ping() # Connect back + time.sleep(0.1) + + # Update with patch + data_new = data_original.replace(b'"ZeroBlog"', b'"PatchedZeroBlog"') + assert data_original != data_new + + site.storage.open("data/data.json-new", "wb").write(data_new) + + assert site.storage.open("data/data.json-new").read() == data_new + assert site_temp.storage.open("data/data.json").read() != data_new + + # Generate diff + diffs = site.content_manager.getDiffs("content.json") + assert not site.storage.isFile("data/data.json-new") # New data file removed + assert site.storage.open("data/data.json").read() == data_new # -new postfix removed + assert "data/data.json" in diffs + assert diffs["data/data.json"] == [('=', 2), ('-', 29), ('+', [b'\t"title": "PatchedZeroBlog",\n']), ('=', 31102)] + + # Publish with patch + site.log.info("Publish new data.json with patch") + with Spy.Spy(FileRequest, "route") as requests: + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + + event_done = gevent.event.AsyncResult() + site.publish(diffs=diffs) + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + assert [request for request in requests if request[1] in ("getFile", "streamFile")] == [] + + assert site_temp.storage.open("data/data.json").read() == data_new + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] + + def testBigUpdate(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Connect peers + site_temp.addPeer(file_server.ip, 1544) + + # Download site from site to site_temp + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + assert list(site_temp.bad_files.keys()) == ["data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json"] + + # Update file + data_original = site.storage.open("data/data.json").read() + data_new = data_original.replace(b'"ZeroBlog"', b'"PatchedZeroBlog"') + assert data_original != data_new + + site.storage.open("data/data.json-new", "wb").write(data_new) + + assert site.storage.open("data/data.json-new").read() == data_new + assert site_temp.storage.open("data/data.json").read() != data_new + + # Generate diff + diffs = site.content_manager.getDiffs("content.json") + assert not site.storage.isFile("data/data.json-new") # New data file removed + assert site.storage.open("data/data.json").read() == data_new # -new postfix removed + assert "data/data.json" in diffs + + content_json = site.storage.loadJson("content.json") + content_json["description"] = "BigZeroBlog" * 1024 * 10 + site.storage.writeJson("content.json", content_json) + site.content_manager.loadContent("content.json", force=True) + + # Publish with patch + site.log.info("Publish new data.json with patch") + with Spy.Spy(FileRequest, "route") as requests: + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + assert site.storage.getSize("content.json") > 10 * 1024 # Make it a big content.json + site.publish(diffs=diffs) + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + file_requests = [request for request in requests if request[1] in ("getFile", "streamFile")] + assert len(file_requests) == 1 + + assert site_temp.storage.open("data/data.json").read() == data_new + assert site_temp.storage.open("content.json").read() == site.storage.open("content.json").read() + + # Test what happened if the content.json of the site is bigger than the site limit + def testHugeContentSiteUpdate(self, file_server, site, site_temp): + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Connect peers + site_temp.addPeer(file_server.ip, 1544) + + # Download site from site to site_temp + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + site_temp.settings["size_limit"] = int(20 * 1024 *1024) + site_temp.saveSettings() + + # Raise limit size to 20MB on site so it can be signed + site.settings["size_limit"] = int(20 * 1024 *1024) + site.saveSettings() + + content_json = site.storage.loadJson("content.json") + content_json["description"] = "PartirUnJour" * 1024 * 1024 + site.storage.writeJson("content.json", content_json) + changed, deleted = site.content_manager.loadContent("content.json", force=True) + + # Make sure we have 2 differents content.json + assert site_temp.storage.open("content.json").read() != site.storage.open("content.json").read() + + # Generate diff + diffs = site.content_manager.getDiffs("content.json") + + # Publish with patch + site.log.info("Publish new content.json bigger than 10MB") + with Spy.Spy(FileRequest, "route") as requests: + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + assert site.storage.getSize("content.json") > 10 * 1024 * 1024 # verify it over 10MB + time.sleep(0.1) + site.publish(diffs=diffs) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + assert site_temp.storage.getSize("content.json") < site_temp.getSizeLimit() * 1024 * 1024 + assert site_temp.storage.open("content.json").read() == site.storage.open("content.json").read() + + def testUnicodeFilename(self, file_server, site, site_temp): + assert site.storage.directory == config.data_dir + "/" + site.address + assert site_temp.storage.directory == config.data_dir + "-temp/" + site.address + + # Init source server + site.connection_server = file_server + file_server.sites[site.address] = site + + # Init client server + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + site_temp.addPeer(file_server.ip, 1544) + + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) + + site.storage.write("data/img/árvíztűrő.png", b"test") + + site.content_manager.sign("content.json", privatekey="5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv") + + content = site.storage.loadJson("content.json") + assert "data/img/árvíztűrő.png" in content["files"] + assert not site_temp.storage.isFile("data/img/árvíztűrő.png") + settings_before = site_temp.settings + + with Spy.Spy(FileRequest, "route") as requests: + site.publish() + time.sleep(0.1) + assert site_temp.download(blind_includes=True, retry_bad_files=False).get(timeout=10) # Wait for download + assert len([req[1] for req in requests if req[1] == "streamFile"]) == 1 + + content = site_temp.storage.loadJson("content.json") + assert "data/img/árvíztűrő.png" in content["files"] + assert site_temp.storage.isFile("data/img/árvíztűrő.png") + + assert site_temp.settings["size"] == settings_before["size"] + assert site_temp.settings["size_optional"] == settings_before["size_optional"] + + assert site_temp.storage.deleteFiles() + [connection.close() for connection in file_server.connections] diff --git a/src/Test/TestSiteStorage.py b/src/Test/TestSiteStorage.py new file mode 100644 index 00000000..f11262bf --- /dev/null +++ b/src/Test/TestSiteStorage.py @@ -0,0 +1,25 @@ +import pytest + + +@pytest.mark.usefixtures("resetSettings") +class TestSiteStorage: + def testWalk(self, site): + # Rootdir + walk_root = list(site.storage.walk("")) + assert "content.json" in walk_root + assert "css/all.css" in walk_root + + # Subdir + assert list(site.storage.walk("data-default")) == ["data.json", "users/content-default.json"] + + def testList(self, site): + # Rootdir + list_root = list(site.storage.list("")) + assert "content.json" in list_root + assert "css/all.css" not in list_root + + # Subdir + assert set(site.storage.list("data-default")) == set(["data.json", "users"]) + + def testDbRebuild(self, site): + assert site.storage.rebuildDb() diff --git a/src/Test/TestThreadPool.py b/src/Test/TestThreadPool.py new file mode 100644 index 00000000..5e95005e --- /dev/null +++ b/src/Test/TestThreadPool.py @@ -0,0 +1,163 @@ +import time +import threading + +import gevent +import pytest + +from util import ThreadPool + + +class TestThreadPool: + def testExecutionOrder(self): + with ThreadPool.ThreadPool(4) as pool: + events = [] + + @pool.wrap + def blocker(): + events.append("S") + out = 0 + for i in range(10000000): + if i == 3000000: + events.append("M") + out += 1 + events.append("D") + return out + + threads = [] + for i in range(3): + threads.append(gevent.spawn(blocker)) + gevent.joinall(threads) + + assert events == ["S"] * 3 + ["M"] * 3 + ["D"] * 3 + + res = blocker() + assert res == 10000000 + + def testLockBlockingSameThread(self): + lock = ThreadPool.Lock() + + s = time.time() + + def unlocker(): + time.sleep(1) + lock.release() + + gevent.spawn(unlocker) + lock.acquire(True) + lock.acquire(True, timeout=2) + + unlock_taken = time.time() - s + + assert 1.0 < unlock_taken < 1.5 + + def testLockBlockingDifferentThread(self): + lock = ThreadPool.Lock() + + def locker(): + lock.acquire(True) + time.sleep(0.5) + lock.release() + + with ThreadPool.ThreadPool(10) as pool: + threads = [ + pool.spawn(locker), + pool.spawn(locker), + gevent.spawn(locker), + pool.spawn(locker) + ] + time.sleep(0.1) + + s = time.time() + + lock.acquire(True, 5.0) + + unlock_taken = time.time() - s + + assert 1.8 < unlock_taken < 2.2 + + gevent.joinall(threads) + + def testMainLoopCallerThreadId(self): + main_thread_id = threading.current_thread().ident + with ThreadPool.ThreadPool(5) as pool: + def getThreadId(*args, **kwargs): + return threading.current_thread().ident + + t = pool.spawn(getThreadId) + assert t.get() != main_thread_id + + t = pool.spawn(lambda: ThreadPool.main_loop.call(getThreadId)) + assert t.get() == main_thread_id + + def testMainLoopCallerGeventSpawn(self): + main_thread_id = threading.current_thread().ident + with ThreadPool.ThreadPool(5) as pool: + def waiter(): + time.sleep(1) + return threading.current_thread().ident + + def geventSpawner(): + event = ThreadPool.main_loop.call(gevent.spawn, waiter) + + with pytest.raises(Exception) as greenlet_err: + event.get() + assert str(greenlet_err.value) == "cannot switch to a different thread" + + waiter_thread_id = ThreadPool.main_loop.call(event.get) + return waiter_thread_id + + s = time.time() + waiter_thread_id = pool.apply(geventSpawner) + assert main_thread_id == waiter_thread_id + time_taken = time.time() - s + assert 0.9 < time_taken < 1.2 + + def testEvent(self): + with ThreadPool.ThreadPool(5) as pool: + event = ThreadPool.Event() + + def setter(): + time.sleep(1) + event.set("done!") + + def getter(): + return event.get() + + pool.spawn(setter) + t_gevent = gevent.spawn(getter) + t_pool = pool.spawn(getter) + s = time.time() + assert event.get() == "done!" + time_taken = time.time() - s + gevent.joinall([t_gevent, t_pool]) + + assert t_gevent.get() == "done!" + assert t_pool.get() == "done!" + + assert 0.9 < time_taken < 1.2 + + with pytest.raises(Exception) as err: + event.set("another result") + + assert "Event already has value" in str(err.value) + + def testMemoryLeak(self): + import gc + thread_objs_before = [id(obj) for obj in gc.get_objects() if "threadpool" in str(type(obj))] + + def worker(): + time.sleep(0.1) + return "ok" + + def poolTest(): + with ThreadPool.ThreadPool(5) as pool: + for i in range(20): + pool.spawn(worker) + + for i in range(5): + poolTest() + new_thread_objs = [obj for obj in gc.get_objects() if "threadpool" in str(type(obj)) and id(obj) not in thread_objs_before] + #print("New objs:", new_thread_objs, "run:", num_run) + + # Make sure no threadpool object left behind + assert not new_thread_objs diff --git a/src/Test/TestTor.py b/src/Test/TestTor.py new file mode 100644 index 00000000..0252d73a --- /dev/null +++ b/src/Test/TestTor.py @@ -0,0 +1,153 @@ +import time + +import pytest +import mock + +from File import FileServer +from Crypt import CryptRsa +from Config import config + +@pytest.mark.usefixtures("resetSettings") +@pytest.mark.usefixtures("resetTempSettings") +class TestTor: + def testDownload(self, tor_manager): + for retry in range(15): + time.sleep(1) + if tor_manager.enabled and tor_manager.conn: + break + assert tor_manager.enabled + + def testManagerConnection(self, tor_manager): + assert "250-version" in tor_manager.request("GETINFO version") + + def testAddOnion(self, tor_manager): + # Add + address = tor_manager.addOnion() + assert address + assert address in tor_manager.privatekeys + + # Delete + assert tor_manager.delOnion(address) + assert address not in tor_manager.privatekeys + + def testSignOnion(self, tor_manager): + address = tor_manager.addOnion() + + # Sign + sign = CryptRsa.sign(b"hello", tor_manager.getPrivatekey(address)) + assert len(sign) == 128 + + # Verify + publickey = CryptRsa.privatekeyToPublickey(tor_manager.getPrivatekey(address)) + assert len(publickey) == 140 + assert CryptRsa.verify(b"hello", publickey, sign) + assert not CryptRsa.verify(b"not hello", publickey, sign) + + # Pub to address + assert CryptRsa.publickeyToOnion(publickey) == address + + # Delete + tor_manager.delOnion(address) + + @pytest.mark.slow + def testConnection(self, tor_manager, file_server, site, site_temp): + file_server.tor_manager.start_onions = True + address = file_server.tor_manager.getOnion(site.address) + assert address + print("Connecting to", address) + for retry in range(5): # Wait for hidden service creation + time.sleep(10) + try: + connection = file_server.getConnection(address + ".onion", 1544) + if connection: + break + except Exception as err: + continue + assert connection.handshake + assert not connection.handshake["peer_id"] # No peer_id for Tor connections + + # Return the same connection without site specified + assert file_server.getConnection(address + ".onion", 1544) == connection + # No reuse for different site + assert file_server.getConnection(address + ".onion", 1544, site=site) != connection + assert file_server.getConnection(address + ".onion", 1544, site=site) == file_server.getConnection(address + ".onion", 1544, site=site) + site_temp.address = "1OTHERSITE" + assert file_server.getConnection(address + ".onion", 1544, site=site) != file_server.getConnection(address + ".onion", 1544, site=site_temp) + + # Only allow to query from the locked site + file_server.sites[site.address] = site + connection_locked = file_server.getConnection(address + ".onion", 1544, site=site) + assert "body" in connection_locked.request("getFile", {"site": site.address, "inner_path": "content.json", "location": 0}) + assert connection_locked.request("getFile", {"site": "1OTHERSITE", "inner_path": "content.json", "location": 0})["error"] == "Invalid site" + + def testPex(self, file_server, site, site_temp): + # Register site to currently running fileserver + site.connection_server = file_server + file_server.sites[site.address] = site + # Create a new file server to emulate new peer connecting to our peer + file_server_temp = FileServer(file_server.ip, 1545) + site_temp.connection_server = file_server_temp + file_server_temp.sites[site_temp.address] = site_temp + + # We will request peers from this + peer_source = site_temp.addPeer(file_server.ip, 1544) + + # Get ip4 peers from source site + site.addPeer("1.2.3.4", 1555) # Add peer to source site + assert peer_source.pex(need_num=10) == 1 + assert len(site_temp.peers) == 2 + assert "1.2.3.4:1555" in site_temp.peers + + # Get onion peers from source site + site.addPeer("bka4ht2bzxchy44r.onion", 1555) + assert "bka4ht2bzxchy44r.onion:1555" not in site_temp.peers + + # Don't add onion peers if not supported + assert "onion" not in file_server_temp.supported_ip_types + assert peer_source.pex(need_num=10) == 0 + + file_server_temp.supported_ip_types.append("onion") + assert peer_source.pex(need_num=10) == 1 + + assert "bka4ht2bzxchy44r.onion:1555" in site_temp.peers + + def testFindHash(self, tor_manager, file_server, site, site_temp): + file_server.ip_incoming = {} # Reset flood protection + file_server.sites[site.address] = site + file_server.tor_manager = tor_manager + + client = FileServer(file_server.ip, 1545) + client.sites = {site_temp.address: site_temp} + site_temp.connection_server = client + + # Add file_server as peer to client + peer_file_server = site_temp.addPeer(file_server.ip, 1544) + + assert peer_file_server.findHashIds([1234]) == {} + + # Add fake peer with requred hash + fake_peer_1 = site.addPeer("bka4ht2bzxchy44r.onion", 1544) + fake_peer_1.hashfield.append(1234) + fake_peer_2 = site.addPeer("1.2.3.5", 1545) + fake_peer_2.hashfield.append(1234) + fake_peer_2.hashfield.append(1235) + fake_peer_3 = site.addPeer("1.2.3.6", 1546) + fake_peer_3.hashfield.append(1235) + fake_peer_3.hashfield.append(1236) + + res = peer_file_server.findHashIds([1234, 1235]) + + assert sorted(res[1234]) == [('1.2.3.5', 1545), ("bka4ht2bzxchy44r.onion", 1544)] + assert sorted(res[1235]) == [('1.2.3.5', 1545), ('1.2.3.6', 1546)] + + # Test my address adding + site.content_manager.hashfield.append(1234) + + res = peer_file_server.findHashIds([1234, 1235]) + assert sorted(res[1234]) == [('1.2.3.5', 1545), (file_server.ip, 1544), ("bka4ht2bzxchy44r.onion", 1544)] + assert sorted(res[1235]) == [('1.2.3.5', 1545), ('1.2.3.6', 1546)] + + def testSiteOnion(self, tor_manager): + with mock.patch.object(config, "tor", "always"): + assert tor_manager.getOnion("address1") != tor_manager.getOnion("address2") + assert tor_manager.getOnion("address1") == tor_manager.getOnion("address1") diff --git a/src/Test/TestTranslate.py b/src/Test/TestTranslate.py new file mode 100644 index 00000000..348a65a6 --- /dev/null +++ b/src/Test/TestTranslate.py @@ -0,0 +1,61 @@ +from Translate import Translate + +class TestTranslate: + def testTranslateStrict(self): + translate = Translate() + data = """ + translated = _("original") + not_translated = "original" + """ + data_translated = translate.translateData(data, {"_(original)": "translated"}) + assert 'translated = _("translated")' in data_translated + assert 'not_translated = "original"' in data_translated + + def testTranslateStrictNamed(self): + translate = Translate() + data = """ + translated = _("original", "original named") + translated_other = _("original", "original other named") + not_translated = "original" + """ + data_translated = translate.translateData(data, {"_(original, original named)": "translated"}) + assert 'translated = _("translated")' in data_translated + assert 'not_translated = "original"' in data_translated + + def testTranslateUtf8(self): + translate = Translate() + data = """ + greeting = "Hi again árvztűrőtökörfúrógép!" + """ + data_translated = translate.translateData(data, {"Hi again árvztűrőtökörfúrógép!": "Üdv újra árvztűrőtökörfúrógép!"}) + assert data_translated == """ + greeting = "Üdv újra árvztűrőtökörfúrógép!" + """ + + def testTranslateEscape(self): + _ = Translate() + _["Hello"] = "Szia" + + # Simple escaping + data = "{_[Hello]} {username}!" + username = "Hacker" + data_translated = _(data) + assert 'Szia' in data_translated + assert '<' not in data_translated + assert data_translated == "Szia Hacker<script>alert('boom')</script>!" + + # Escaping dicts + user = {"username": "Hacker"} + data = "{_[Hello]} {user[username]}!" + data_translated = _(data) + assert 'Szia' in data_translated + assert '<' not in data_translated + assert data_translated == "Szia Hacker<script>alert('boom')</script>!" + + # Escaping lists + users = [{"username": "Hacker"}] + data = "{_[Hello]} {users[0][username]}!" + data_translated = _(data) + assert 'Szia' in data_translated + assert '<' not in data_translated + assert data_translated == "Szia Hacker<script>alert('boom')</script>!" diff --git a/src/Test/TestUiWebsocket.py b/src/Test/TestUiWebsocket.py new file mode 100644 index 00000000..d2d23d03 --- /dev/null +++ b/src/Test/TestUiWebsocket.py @@ -0,0 +1,11 @@ +import sys +import pytest + +@pytest.mark.usefixtures("resetSettings") +class TestUiWebsocket: + def testPermission(self, ui_websocket): + res = ui_websocket.testAction("ping") + assert res == "pong" + + res = ui_websocket.testAction("certList") + assert "You don't have permission" in res["error"] diff --git a/src/Test/TestUpnpPunch.py b/src/Test/TestUpnpPunch.py new file mode 100644 index 00000000..f17c77bd --- /dev/null +++ b/src/Test/TestUpnpPunch.py @@ -0,0 +1,274 @@ +import socket +from urllib.parse import urlparse + +import pytest +import mock + +from util import UpnpPunch as upnp + + +@pytest.fixture +def mock_socket(): + mock_socket = mock.MagicMock() + mock_socket.recv = mock.MagicMock(return_value=b'Hello') + mock_socket.bind = mock.MagicMock() + mock_socket.send_to = mock.MagicMock() + + return mock_socket + + +@pytest.fixture +def url_obj(): + return urlparse('http://192.168.1.1/ctrlPoint.xml') + + +@pytest.fixture(params=['WANPPPConnection', 'WANIPConnection']) +def igd_profile(request): + return """ + urn:schemas-upnp-org:service:{}:1 + urn:upnp-org:serviceId:wanpppc:pppoa + /upnp/control/wanpppcpppoa + /upnp/event/wanpppcpppoa + /WANPPPConnection.xml +""".format(request.param) + + +@pytest.fixture +def httplib_response(): + class FakeResponse(object): + def __init__(self, status=200, body='OK'): + self.status = status + self.body = body + + def read(self): + return self.body + return FakeResponse + + +class TestUpnpPunch(object): + def test_perform_m_search(self, mock_socket): + local_ip = '127.0.0.1' + + with mock.patch('util.UpnpPunch.socket.socket', + return_value=mock_socket): + result = upnp.perform_m_search(local_ip) + assert result == 'Hello' + assert local_ip == mock_socket.bind.call_args_list[0][0][0][0] + assert ('239.255.255.250', + 1900) == mock_socket.sendto.call_args_list[0][0][1] + + def test_perform_m_search_socket_error(self, mock_socket): + mock_socket.recv.side_effect = socket.error('Timeout error') + + with mock.patch('util.UpnpPunch.socket.socket', + return_value=mock_socket): + with pytest.raises(upnp.UpnpError): + upnp.perform_m_search('127.0.0.1') + + def test_retrieve_location_from_ssdp(self, url_obj): + ctrl_location = url_obj.geturl() + parsed_location = urlparse(ctrl_location) + rsp = ('auth: gibberish\r\nlocation: {0}\r\n' + 'Content-Type: text/html\r\n\r\n').format(ctrl_location) + result = upnp._retrieve_location_from_ssdp(rsp) + assert result == parsed_location + + def test_retrieve_location_from_ssdp_no_header(self): + rsp = 'auth: gibberish\r\nContent-Type: application/json\r\n\r\n' + with pytest.raises(upnp.IGDError): + upnp._retrieve_location_from_ssdp(rsp) + + def test_retrieve_igd_profile(self, url_obj): + with mock.patch('urllib.request.urlopen') as mock_urlopen: + upnp._retrieve_igd_profile(url_obj) + mock_urlopen.assert_called_with(url_obj.geturl(), timeout=5) + + def test_retrieve_igd_profile_timeout(self, url_obj): + with mock.patch('urllib.request.urlopen') as mock_urlopen: + mock_urlopen.side_effect = socket.error('Timeout error') + with pytest.raises(upnp.IGDError): + upnp._retrieve_igd_profile(url_obj) + + def test_parse_igd_profile_service_type(self, igd_profile): + control_path, upnp_schema = upnp._parse_igd_profile(igd_profile) + assert control_path == '/upnp/control/wanpppcpppoa' + assert upnp_schema in ('WANPPPConnection', 'WANIPConnection',) + + def test_parse_igd_profile_no_ctrlurl(self, igd_profile): + igd_profile = igd_profile.replace('controlURL', 'nope') + with pytest.raises(upnp.IGDError): + control_path, upnp_schema = upnp._parse_igd_profile(igd_profile) + + def test_parse_igd_profile_no_schema(self, igd_profile): + igd_profile = igd_profile.replace('Connection', 'nope') + with pytest.raises(upnp.IGDError): + control_path, upnp_schema = upnp._parse_igd_profile(igd_profile) + + def test_create_open_message_parsable(self): + from xml.parsers.expat import ExpatError + msg, _ = upnp._create_open_message('127.0.0.1', 8888) + try: + upnp.parseString(msg) + except ExpatError as e: + pytest.fail('Incorrect XML message: {}'.format(e)) + + def test_create_open_message_contains_right_stuff(self): + settings = {'description': 'test desc', + 'protocol': 'test proto', + 'upnp_schema': 'test schema'} + msg, fn_name = upnp._create_open_message('127.0.0.1', 8888, **settings) + assert fn_name == 'AddPortMapping' + assert '127.0.0.1' in msg + assert '8888' in msg + assert settings['description'] in msg + assert settings['protocol'] in msg + assert settings['upnp_schema'] in msg + + def test_parse_for_errors_bad_rsp(self, httplib_response): + rsp = httplib_response(status=500) + with pytest.raises(upnp.IGDError) as err: + upnp._parse_for_errors(rsp) + assert 'Unable to parse' in str(err.value) + + def test_parse_for_errors_error(self, httplib_response): + soap_error = ('' + '500' + 'Bad request' + '') + rsp = httplib_response(status=500, body=soap_error) + with pytest.raises(upnp.IGDError) as err: + upnp._parse_for_errors(rsp) + assert 'SOAP request error' in str(err.value) + + def test_parse_for_errors_good_rsp(self, httplib_response): + rsp = httplib_response(status=200) + assert rsp == upnp._parse_for_errors(rsp) + + def test_send_requests_success(self): + with mock.patch( + 'util.UpnpPunch._send_soap_request') as mock_send_request: + mock_send_request.return_value = mock.MagicMock(status=200) + upnp._send_requests(['msg'], None, None, None) + + assert mock_send_request.called + + def test_send_requests_failed(self): + with mock.patch( + 'util.UpnpPunch._send_soap_request') as mock_send_request: + mock_send_request.return_value = mock.MagicMock(status=500) + with pytest.raises(upnp.UpnpError): + upnp._send_requests(['msg'], None, None, None) + + assert mock_send_request.called + + def test_collect_idg_data(self): + pass + + @mock.patch('util.UpnpPunch._get_local_ips') + @mock.patch('util.UpnpPunch._collect_idg_data') + @mock.patch('util.UpnpPunch._send_requests') + def test_ask_to_open_port_success(self, mock_send_requests, + mock_collect_idg, mock_local_ips): + mock_collect_idg.return_value = {'upnp_schema': 'schema-yo'} + mock_local_ips.return_value = ['192.168.0.12'] + + result = upnp.ask_to_open_port(retries=5) + + soap_msg = mock_send_requests.call_args[0][0][0][0] + + assert result is True + + assert mock_collect_idg.called + assert '192.168.0.12' in soap_msg + assert '15441' in soap_msg + assert 'schema-yo' in soap_msg + + @mock.patch('util.UpnpPunch._get_local_ips') + @mock.patch('util.UpnpPunch._collect_idg_data') + @mock.patch('util.UpnpPunch._send_requests') + def test_ask_to_open_port_failure(self, mock_send_requests, + mock_collect_idg, mock_local_ips): + mock_local_ips.return_value = ['192.168.0.12'] + mock_collect_idg.return_value = {'upnp_schema': 'schema-yo'} + mock_send_requests.side_effect = upnp.UpnpError() + + with pytest.raises(upnp.UpnpError): + upnp.ask_to_open_port() + + @mock.patch('util.UpnpPunch._collect_idg_data') + @mock.patch('util.UpnpPunch._send_requests') + def test_orchestrate_soap_request(self, mock_send_requests, + mock_collect_idg): + soap_mock = mock.MagicMock() + args = ['127.0.0.1', 31337, soap_mock, 'upnp-test', {'upnp_schema': + 'schema-yo'}] + mock_collect_idg.return_value = args[-1] + + upnp._orchestrate_soap_request(*args[:-1]) + + assert mock_collect_idg.called + soap_mock.assert_called_with( + *args[:2] + ['upnp-test', 'UDP', 'schema-yo']) + assert mock_send_requests.called + + @mock.patch('util.UpnpPunch._collect_idg_data') + @mock.patch('util.UpnpPunch._send_requests') + def test_orchestrate_soap_request_without_desc(self, mock_send_requests, + mock_collect_idg): + soap_mock = mock.MagicMock() + args = ['127.0.0.1', 31337, soap_mock, {'upnp_schema': 'schema-yo'}] + mock_collect_idg.return_value = args[-1] + + upnp._orchestrate_soap_request(*args[:-1]) + + assert mock_collect_idg.called + soap_mock.assert_called_with(*args[:2] + [None, 'UDP', 'schema-yo']) + assert mock_send_requests.called + + def test_create_close_message_parsable(self): + from xml.parsers.expat import ExpatError + msg, _ = upnp._create_close_message('127.0.0.1', 8888) + try: + upnp.parseString(msg) + except ExpatError as e: + pytest.fail('Incorrect XML message: {}'.format(e)) + + def test_create_close_message_contains_right_stuff(self): + settings = {'protocol': 'test proto', + 'upnp_schema': 'test schema'} + msg, fn_name = upnp._create_close_message('127.0.0.1', 8888, ** + settings) + assert fn_name == 'DeletePortMapping' + assert '8888' in msg + assert settings['protocol'] in msg + assert settings['upnp_schema'] in msg + + @mock.patch('util.UpnpPunch._get_local_ips') + @mock.patch('util.UpnpPunch._orchestrate_soap_request') + def test_communicate_with_igd_success(self, mock_orchestrate, + mock_get_local_ips): + mock_get_local_ips.return_value = ['192.168.0.12'] + upnp._communicate_with_igd() + assert mock_get_local_ips.called + assert mock_orchestrate.called + + @mock.patch('util.UpnpPunch._get_local_ips') + @mock.patch('util.UpnpPunch._orchestrate_soap_request') + def test_communicate_with_igd_succeed_despite_single_failure( + self, mock_orchestrate, mock_get_local_ips): + mock_get_local_ips.return_value = ['192.168.0.12'] + mock_orchestrate.side_effect = [upnp.UpnpError, None] + upnp._communicate_with_igd(retries=2) + assert mock_get_local_ips.called + assert mock_orchestrate.called + + @mock.patch('util.UpnpPunch._get_local_ips') + @mock.patch('util.UpnpPunch._orchestrate_soap_request') + def test_communicate_with_igd_total_failure(self, mock_orchestrate, + mock_get_local_ips): + mock_get_local_ips.return_value = ['192.168.0.12'] + mock_orchestrate.side_effect = [upnp.UpnpError, upnp.IGDError] + with pytest.raises(upnp.UpnpError): + upnp._communicate_with_igd(retries=2) + assert mock_get_local_ips.called + assert mock_orchestrate.called diff --git a/src/Test/TestUser.py b/src/Test/TestUser.py new file mode 100644 index 00000000..e5ec5c8c --- /dev/null +++ b/src/Test/TestUser.py @@ -0,0 +1,50 @@ +import pytest + +from Crypt import CryptBitcoin + + +@pytest.mark.usefixtures("resetSettings") +class TestUser: + def testAddress(self, user): + assert user.master_address == "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc" + address_index = 1458664252141532163166741013621928587528255888800826689784628722366466547364755811 + assert user.getAddressAuthIndex("15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc") == address_index + + # Re-generate privatekey based on address_index + def testNewSite(self, user): + address, address_index, site_data = user.getNewSiteData() # Create a new random site + assert CryptBitcoin.hdPrivatekey(user.master_seed, address_index) == site_data["privatekey"] + + user.sites = {} # Reset user data + + # Site address and auth address is different + assert user.getSiteData(address)["auth_address"] != address + # Re-generate auth_privatekey for site + assert user.getSiteData(address)["auth_privatekey"] == site_data["auth_privatekey"] + + def testAuthAddress(self, user): + # Auth address without Cert + auth_address = user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") + assert auth_address == "1MyJgYQjeEkR9QD66nkfJc9zqi9uUy5Lr2" + auth_privatekey = user.getAuthPrivatekey("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") + assert CryptBitcoin.privatekeyToAddress(auth_privatekey) == auth_address + + def testCert(self, user): + cert_auth_address = user.getAuthAddress("1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz") # Add site to user's registry + # Add cert + user.addCert(cert_auth_address, "zeroid.bit", "faketype", "fakeuser", "fakesign") + user.setCert("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr", "zeroid.bit") + + # By using certificate the auth address should be same as the certificate provider + assert user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == cert_auth_address + auth_privatekey = user.getAuthPrivatekey("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") + assert CryptBitcoin.privatekeyToAddress(auth_privatekey) == cert_auth_address + + # Test delete site data + assert "1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" in user.sites + user.deleteSiteData("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") + assert "1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr" not in user.sites + + # Re-create add site should generate normal, unique auth_address + assert not user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == cert_auth_address + assert user.getAuthAddress("1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr") == "1MyJgYQjeEkR9QD66nkfJc9zqi9uUy5Lr2" diff --git a/src/Test/TestWeb.py b/src/Test/TestWeb.py new file mode 100644 index 00000000..2ce66c98 --- /dev/null +++ b/src/Test/TestWeb.py @@ -0,0 +1,105 @@ +import urllib.request + +import pytest + +try: + from selenium.webdriver.support.ui import WebDriverWait + from selenium.webdriver.support.expected_conditions import staleness_of, title_is + from selenium.common.exceptions import NoSuchElementException +except: + pass + + +class WaitForPageLoad(object): + def __init__(self, browser): + self.browser = browser + + def __enter__(self): + self.old_page = self.browser.find_element_by_tag_name('html') + + def __exit__(self, *args): + WebDriverWait(self.browser, 10).until(staleness_of(self.old_page)) + + +def getContextUrl(browser): + return browser.execute_script("return window.location.toString()") + + +def getUrl(url): + content = urllib.request.urlopen(url).read() + assert "server error" not in content.lower(), "Got a server error! " + repr(url) + return content + +@pytest.mark.usefixtures("resetSettings") +@pytest.mark.webtest +class TestWeb: + def testFileSecurity(self, site_url): + assert "Not Found" in getUrl("%s/media/sites.json" % site_url) + assert "Forbidden" in getUrl("%s/media/./sites.json" % site_url) + assert "Forbidden" in getUrl("%s/media/../config.py" % site_url) + assert "Forbidden" in getUrl("%s/media/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../sites.json" % site_url) + assert "Forbidden" in getUrl("%s/media/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/..//sites.json" % site_url) + assert "Forbidden" in getUrl("%s/media/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../../zeronet.py" % site_url) + + assert "Not Found" in getUrl("%s/raw/sites.json" % site_url) + assert "Forbidden" in getUrl("%s/raw/./sites.json" % site_url) + assert "Forbidden" in getUrl("%s/raw/../config.py" % site_url) + assert "Forbidden" in getUrl("%s/raw/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../sites.json" % site_url) + assert "Forbidden" in getUrl("%s/raw/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/..//sites.json" % site_url) + assert "Forbidden" in getUrl("%s/raw/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../../zeronet.py" % site_url) + + assert "Forbidden" in getUrl("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../sites.json" % site_url) + assert "Forbidden" in getUrl("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/..//sites.json" % site_url) + assert "Forbidden" in getUrl("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/../../zeronet.py" % site_url) + + assert "Forbidden" in getUrl("%s/content.db" % site_url) + assert "Forbidden" in getUrl("%s/./users.json" % site_url) + assert "Forbidden" in getUrl("%s/./key-rsa.pem" % site_url) + assert "Forbidden" in getUrl("%s/././././././././././//////sites.json" % site_url) + + def testLinkSecurity(self, browser, site_url): + browser.get("%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/test/security.html" % site_url) + WebDriverWait(browser, 10).until(title_is("ZeroHello - ZeroNet")) + assert getContextUrl(browser) == "%s/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/test/security.html" % site_url + + # Switch to inner frame + browser.switch_to.frame(browser.find_element_by_id("inner-iframe")) + assert "wrapper_nonce" in getContextUrl(browser) + assert browser.find_element_by_id("script_output").text == "Result: Works" + browser.switch_to.default_content() + + # Clicking on links without target + browser.switch_to.frame(browser.find_element_by_id("inner-iframe")) + with WaitForPageLoad(browser): + browser.find_element_by_id("link_to_current").click() + assert "wrapper_nonce" not in getContextUrl(browser) # The browser object back to default content + assert "Forbidden" not in browser.page_source + # Check if we have frame inside frame + browser.switch_to.frame(browser.find_element_by_id("inner-iframe")) + with pytest.raises(NoSuchElementException): + assert not browser.find_element_by_id("inner-iframe") + browser.switch_to.default_content() + + # Clicking on link with target=_top + browser.switch_to.frame(browser.find_element_by_id("inner-iframe")) + with WaitForPageLoad(browser): + browser.find_element_by_id("link_to_top").click() + assert "wrapper_nonce" not in getContextUrl(browser) # The browser object back to default content + assert "Forbidden" not in browser.page_source + browser.switch_to.default_content() + + # Try to escape from inner_frame + browser.switch_to.frame(browser.find_element_by_id("inner-iframe")) + assert "wrapper_nonce" in getContextUrl(browser) # Make sure we are inside of the inner-iframe + with WaitForPageLoad(browser): + browser.execute_script("window.top.location = window.location") + assert "wrapper_nonce" in getContextUrl(browser) # We try to use nonce-ed html without iframe + assert " 0.1: + line_marker = "!" + elif since_last > 0.02: + line_marker = "*" + elif since_last > 0.01: + line_marker = "-" + else: + line_marker = " " + + since_start = time.time() - time_start + record.since_start = "%s%.3fs" % (line_marker, since_start) + + self.time_last = time.time() + return True + +log = logging.getLogger() +fmt = logging.Formatter(fmt='%(since_start)s %(thread_marker)s %(levelname)-8s %(name)s %(message)s %(thread_title)s') +[hndl.addFilter(TimeFilter()) for hndl in log.handlers] +[hndl.setFormatter(fmt) for hndl in log.handlers] + +from Site.Site import Site +from Site import SiteManager +from User import UserManager +from File import FileServer +from Connection import ConnectionServer +from Crypt import CryptConnection +from Crypt import CryptBitcoin +from Ui import UiWebsocket +from Tor import TorManager +from Content import ContentDb +from util import RateLimit +from Db import Db +from Debug import Debug + +gevent.get_hub().NOT_ERROR += (Debug.Notify,) + +def cleanup(): + Db.dbCloseAll() + for dir_path in [config.data_dir, config.data_dir + "-temp"]: + if os.path.isdir(dir_path): + for file_name in os.listdir(dir_path): + ext = file_name.rsplit(".", 1)[-1] + if ext not in ["csr", "pem", "srl", "db", "json", "tmp"]: + continue + file_path = dir_path + "/" + file_name + if os.path.isfile(file_path): + os.unlink(file_path) + +atexit_register(cleanup) + +@pytest.fixture(scope="session") +def resetSettings(request): + open("%s/sites.json" % config.data_dir, "w").write("{}") + open("%s/filters.json" % config.data_dir, "w").write("{}") + open("%s/users.json" % config.data_dir, "w").write(""" + { + "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc": { + "certs": {}, + "master_seed": "024bceac1105483d66585d8a60eaf20aa8c3254b0f266e0d626ddb6114e2949a", + "sites": {} + } + } + """) + + +@pytest.fixture(scope="session") +def resetTempSettings(request): + data_dir_temp = config.data_dir + "-temp" + if not os.path.isdir(data_dir_temp): + os.mkdir(data_dir_temp) + open("%s/sites.json" % data_dir_temp, "w").write("{}") + open("%s/filters.json" % data_dir_temp, "w").write("{}") + open("%s/users.json" % data_dir_temp, "w").write(""" + { + "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc": { + "certs": {}, + "master_seed": "024bceac1105483d66585d8a60eaf20aa8c3254b0f266e0d626ddb6114e2949a", + "sites": {} + } + } + """) + + def cleanup(): + os.unlink("%s/sites.json" % data_dir_temp) + os.unlink("%s/users.json" % data_dir_temp) + os.unlink("%s/filters.json" % data_dir_temp) + request.addfinalizer(cleanup) + + +@pytest.fixture() +def site(request): + threads_before = [obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet)] + # Reset ratelimit + RateLimit.queue_db = {} + RateLimit.called_db = {} + + site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") + + # Always use original data + assert "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT" in site.storage.getPath("") # Make sure we dont delete everything + shutil.rmtree(site.storage.getPath(""), True) + shutil.copytree(site.storage.getPath("") + "-original", site.storage.getPath("")) + + # Add to site manager + SiteManager.site_manager.get("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") + site.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + def cleanup(): + site.delete() + site.content_manager.contents.db.close("Test cleanup") + site.content_manager.contents.db.timer_check_optional.kill() + SiteManager.site_manager.sites.clear() + db_path = "%s/content.db" % config.data_dir + os.unlink(db_path) + del ContentDb.content_dbs[db_path] + gevent.killall([obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet) and obj not in threads_before]) + request.addfinalizer(cleanup) + + site.greenlet_manager.stopGreenlets() + site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") # Create new Site object to load content.json files + if not SiteManager.site_manager.sites: + SiteManager.site_manager.sites = {} + SiteManager.site_manager.sites["1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT"] = site + site.settings["serving"] = True + return site + + +@pytest.fixture() +def site_temp(request): + threads_before = [obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet)] + with mock.patch("Config.config.data_dir", config.data_dir + "-temp"): + site_temp = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") + site_temp.settings["serving"] = True + site_temp.announce = mock.MagicMock(return_value=True) # Don't try to find peers from the net + + def cleanup(): + site_temp.delete() + site_temp.content_manager.contents.db.close("Test cleanup") + site_temp.content_manager.contents.db.timer_check_optional.kill() + db_path = "%s-temp/content.db" % config.data_dir + os.unlink(db_path) + del ContentDb.content_dbs[db_path] + gevent.killall([obj for obj in gc.get_objects() if isinstance(obj, gevent.Greenlet) and obj not in threads_before]) + request.addfinalizer(cleanup) + site_temp.log = logging.getLogger("Temp:%s" % site_temp.address_short) + return site_temp + + +@pytest.fixture(scope="session") +def user(): + user = UserManager.user_manager.get() + if not user: + user = UserManager.user_manager.create() + user.sites = {} # Reset user data + return user + + +@pytest.fixture(scope="session") +def browser(request): + try: + from selenium import webdriver + print("Starting chromedriver...") + options = webdriver.chrome.options.Options() + options.add_argument("--headless") + options.add_argument("--window-size=1920x1080") + options.add_argument("--log-level=1") + browser = webdriver.Chrome(executable_path=CHROMEDRIVER_PATH, service_log_path=os.path.devnull, options=options) + + def quit(): + browser.quit() + request.addfinalizer(quit) + except Exception as err: + raise pytest.skip("Test requires selenium + chromedriver: %s" % err) + return browser + + +@pytest.fixture(scope="session") +def site_url(): + try: + urllib.request.urlopen(SITE_URL).read() + except Exception as err: + raise pytest.skip("Test requires zeronet client running: %s" % err) + return SITE_URL + + +@pytest.fixture(params=['ipv4', 'ipv6']) +def file_server(request): + if request.param == "ipv4": + return request.getfixturevalue("file_server4") + else: + return request.getfixturevalue("file_server6") + + +@pytest.fixture +def file_server4(request): + time.sleep(0.1) + file_server = FileServer("127.0.0.1", 1544) + file_server.ip_external = "1.2.3.4" # Fake external ip + + def listen(): + ConnectionServer.start(file_server) + ConnectionServer.listen(file_server) + + gevent.spawn(listen) + # Wait for port opening + for retry in range(10): + time.sleep(0.1) # Port opening + try: + conn = file_server.getConnection("127.0.0.1", 1544) + conn.close() + break + except Exception as err: + print("FileServer6 startup error", Debug.formatException(err)) + assert file_server.running + file_server.ip_incoming = {} # Reset flood protection + + def stop(): + file_server.stop() + request.addfinalizer(stop) + return file_server + + +@pytest.fixture +def file_server6(request): + try: + sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) + sock.connect(("::1", 80, 1, 1)) + has_ipv6 = True + except OSError: + has_ipv6 = False + if not has_ipv6: + pytest.skip("Ipv6 not supported") + + + time.sleep(0.1) + file_server6 = FileServer("::1", 1544) + file_server6.ip_external = 'fca5:95d6:bfde:d902:8951:276e:1111:a22c' # Fake external ip + + def listen(): + ConnectionServer.start(file_server6) + ConnectionServer.listen(file_server6) + + gevent.spawn(listen) + # Wait for port opening + for retry in range(10): + time.sleep(0.1) # Port opening + try: + conn = file_server6.getConnection("::1", 1544) + conn.close() + break + except Exception as err: + print("FileServer6 startup error", Debug.formatException(err)) + assert file_server6.running + file_server6.ip_incoming = {} # Reset flood protection + + def stop(): + file_server6.stop() + request.addfinalizer(stop) + return file_server6 + + +@pytest.fixture() +def ui_websocket(site, user): + class WsMock: + def __init__(self): + self.result = gevent.event.AsyncResult() + + def send(self, data): + logging.debug("WsMock: Set result (data: %s) called by %s" % (data, Debug.formatStack())) + self.result.set(json.loads(data)["result"]) + + def getResult(self): + logging.debug("WsMock: Get result") + back = self.result.get() + logging.debug("WsMock: Got result (data: %s)" % back) + self.result = gevent.event.AsyncResult() + return back + + ws_mock = WsMock() + ui_websocket = UiWebsocket(ws_mock, site, None, user, None) + + def testAction(action, *args, **kwargs): + ui_websocket.handleRequest({"id": 0, "cmd": action, "params": list(args) if args else kwargs}) + return ui_websocket.ws.getResult() + + ui_websocket.testAction = testAction + return ui_websocket + + +@pytest.fixture(scope="session") +def tor_manager(): + try: + tor_manager = TorManager(fileserver_port=1544) + tor_manager.start() + assert tor_manager.conn is not None + tor_manager.startOnions() + except Exception as err: + raise pytest.skip("Test requires Tor with ControlPort: %s, %s" % (config.tor_controller, err)) + return tor_manager + + +@pytest.fixture() +def db(request): + db_path = "%s/zeronet.db" % config.data_dir + schema = { + "db_name": "TestDb", + "db_file": "%s/zeronet.db" % config.data_dir, + "maps": { + "data.json": { + "to_table": [ + "test", + {"node": "test", "table": "test_importfilter", "import_cols": ["test_id", "title"]} + ] + } + }, + "tables": { + "test": { + "cols": [ + ["test_id", "INTEGER"], + ["title", "TEXT"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX test_id ON test(test_id)"], + "schema_changed": 1426195822 + }, + "test_importfilter": { + "cols": [ + ["test_id", "INTEGER"], + ["title", "TEXT"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX test_importfilter_id ON test_importfilter(test_id)"], + "schema_changed": 1426195822 + } + } + } + + if os.path.isfile(db_path): + os.unlink(db_path) + db = Db.Db(schema, db_path) + db.checkTables() + + def stop(): + db.close("Test db cleanup") + os.unlink(db_path) + + request.addfinalizer(stop) + return db + + +@pytest.fixture(params=["sslcrypto", "sslcrypto_fallback", "libsecp256k1"]) +def crypt_bitcoin_lib(request, monkeypatch): + monkeypatch.setattr(CryptBitcoin, "lib_verify_best", request.param) + CryptBitcoin.loadLib(request.param) + return CryptBitcoin + +@pytest.fixture(scope='function', autouse=True) +def logCaseStart(request): + global time_start + time_start = time.time() + logging.debug("---- Start test case: %s ----" % request._pyfuncitem) + yield None # Wait until all test done + + +# Workaround for pytest bug when logging in atexit/post-fixture handlers (I/O operation on closed file) +def workaroundPytestLogError(): + import _pytest.capture + write_original = _pytest.capture.EncodedFile.write + + def write_patched(obj, *args, **kwargs): + try: + write_original(obj, *args, **kwargs) + except ValueError as err: + if str(err) == "I/O operation on closed file": + pass + else: + raise err + + def flush_patched(obj, *args, **kwargs): + try: + obj.buffer.flush(*args, **kwargs) + except ValueError as err: + if str(err).startswith("I/O operation on closed file"): + pass + else: + raise err + + _pytest.capture.EncodedFile.write = write_patched + _pytest.capture.EncodedFile.flush = flush_patched + + +workaroundPytestLogError() + +@pytest.fixture(scope='session', autouse=True) +def disableLog(): + yield None # Wait until all test done + logging.getLogger('').setLevel(logging.getLevelName(logging.CRITICAL)) + diff --git a/src/Test/coverage.ini b/src/Test/coverage.ini new file mode 100644 index 00000000..ec34d0fc --- /dev/null +++ b/src/Test/coverage.ini @@ -0,0 +1,15 @@ +[run] +branch = True +concurrency = gevent +omit = + src/lib/* + src/Test/* + +[report] +exclude_lines = + pragma: no cover + if __name__ == .__main__.: + if config.debug: + if config.debug_socket: + if self.logging: + def __repr__ diff --git a/src/Test/pytest.ini b/src/Test/pytest.ini new file mode 100644 index 00000000..556389a2 --- /dev/null +++ b/src/Test/pytest.ini @@ -0,0 +1,6 @@ +[pytest] +python_files = Test*.py +addopts = -rsxX -v --durations=6 --no-print-logs --capture=fd +markers = + slow: mark a tests as slow. + webtest: mark a test as a webtest. diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/content.json new file mode 100644 index 00000000..786db098 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/content.json @@ -0,0 +1,133 @@ +{ + "address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT", + "background-color": "white", + "description": "Blogging platform Demo", + "domain": "Blog.ZeroNetwork.bit", + "files": { + "css/all.css": { + "sha512": "65ddd3a2071a0f48c34783aa3b1bde4424bdea344630af05a237557a62bd55dc", + "size": 112710 + }, + "data-default/data.json": { + "sha512": "3f5c5a220bde41b464ab116cce0bd670dd0b4ff5fe4a73d1dffc4719140038f2", + "size": 196 + }, + "data-default/users/content-default.json": { + "sha512": "0603ce08f7abb92b3840ad0cf40e95ea0b3ed3511b31524d4d70e88adba83daa", + "size": 679 + }, + "data/data.json": { + "sha512": "0f2321c905b761a05c360a389e1de149d952b16097c4ccf8310158356e85fb52", + "size": 31126 + }, + "data/img/autoupdate.png": { + "sha512": "d2b4dc8e0da2861ea051c0c13490a4eccf8933d77383a5b43de447c49d816e71", + "size": 24460 + }, + "data/img/direct_domains.png": { + "sha512": "5f14b30c1852735ab329b22496b1e2ea751cb04704789443ad73a70587c59719", + "size": 16185 + }, + "data/img/domain.png": { + "sha512": "ce87e0831f4d1e95a95d7120ca4d33f8273c6fce9f5bbedf7209396ea0b57b6a", + "size": 11881 + }, + "data/img/memory.png": { + "sha512": "dd56515085b4a79b5809716f76f267ec3a204be3ee0d215591a77bf0f390fa4e", + "size": 12775 + }, + "data/img/multiuser.png": { + "sha512": "88e3f795f9b86583640867897de6efc14e1aa42f93e848ed1645213e6cc210c6", + "size": 29480 + }, + "data/img/progressbar.png": { + "sha512": "23d592ae386ce14158cec34d32a3556771725e331c14d5a4905c59e0fe980ebf", + "size": 13294 + }, + "data/img/slides.png": { + "sha512": "1933db3b90ab93465befa1bd0843babe38173975e306286e08151be9992f767e", + "size": 14439 + }, + "data/img/slots_memory.png": { + "sha512": "82a250e6da909d7f66341e5b5c443353958f86728cd3f06e988b6441e6847c29", + "size": 9488 + }, + "data/img/trayicon.png": { + "sha512": "e7ae65bf280f13fb7175c1293dad7d18f1fcb186ebc9e1e33850cdaccb897b8f", + "size": 19040 + }, + "dbschema.json": { + "sha512": "2e9466d8aa1f340c91203b4ddbe9b6669879616a1b8e9571058a74195937598d", + "size": 1527 + }, + "img/loading.gif": { + "sha512": "8a42b98962faea74618113166886be488c09dad10ca47fe97005edc5fb40cc00", + "size": 723 + }, + "index.html": { + "sha512": "c4039ebfc4cb6f116cac05e803a18644ed70404474a572f0d8473f4572f05df3", + "size": 4667 + }, + "js/all.js": { + "sha512": "034c97535f3c9b3fbebf2dcf61a38711dae762acf1a99168ae7ddc7e265f582c", + "size": 201178 + } + }, + "files_optional": { + "data/img/zeroblog-comments.png": { + "sha512": "efe4e815a260e555303e5c49e550a689d27a8361f64667bd4a91dbcccb83d2b4", + "size": 24001 + }, + "data/img/zeroid.png": { + "sha512": "b46d541a9e51ba2ddc8a49955b7debbc3b45fd13467d3c20ef104e9d938d052b", + "size": 18875 + }, + "data/img/zeroname.png": { + "sha512": "bab45a1bb2087b64e4f69f756b2ffa5ad39b7fdc48c83609cdde44028a7a155d", + "size": 36031 + }, + "data/img/zerotalk-mark.png": { + "sha512": "a335b2fedeb8d291ca68d3091f567c180628e80f41de4331a5feb19601d078af", + "size": 44862 + }, + "data/img/zerotalk-upvote.png": { + "sha512": "b1ffd7f948b4f99248dde7efe256c2efdfd997f7e876fb9734f986ef2b561732", + "size": 41092 + }, + "data/img/zerotalk.png": { + "sha512": "54d10497a1ffca9a4780092fd1bd158c15f639856d654d2eb33a42f9d8e33cd8", + "size": 26606 + }, + "data/optional.txt": { + "sha512": "c6f81db0e9f8206c971c9e5826e3ba823ffbb1a3a900f8047652a8bf78ea98fd", + "size": 6 + } + }, + "ignore": "((js|css)/(?!all.(js|css))|data/.*db|data/users/.*/.*|data/test_include/.*)", + "includes": { + "data/test_include/content.json": { + "added": 1424976057, + "files_allowed": "data.json", + "includes_allowed": false, + "max_size": 20000, + "signers": ["15ik6LeBWnACWfaika1xqGapRZ1zh3JpCo"], + "signers_required": 1, + "user_id": 47, + "user_name": "test" + }, + "data/users/content.json": { + "signers": ["1LSxsKfC9S9TVXGGNSM3vPHjyW82jgCX5f"], + "signers_required": 1 + } + }, + "inner_path": "content.json", + "modified": 1503257990, + "optional": "(data/img/zero.*|data/optional.*)", + "signers_sign": "HDNmWJHM2diYln4pkdL+qYOvgE7MdwayzeG+xEUZBgp1HtOjBJS+knDEVQsBkjcOPicDG2it1r6R1eQrmogqSP0=", + "signs": { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G4Uq365UBliQG66ygip1jNGYqW6Eh9Mm7nLguDFqAgk/Hksq/ruqMf9rXv78mgUfPBvL2+XgDKYvFDtlykPFZxk=" + }, + "signs_required": 1, + "title": "ZeroBlog", + "zeronet_version": "0.5.7" +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/css/all.css b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/css/all.css new file mode 100644 index 00000000..c2ad65fc --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/css/all.css @@ -0,0 +1,385 @@ + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/Comments.css ---- */ + + +.comments { margin-bottom: 60px } +.comment { background-color: white; padding: 25px 0px; margin: 1px; border-top: 1px solid #EEE } +.comment .user_name { font-size: 14px; font-weight: bold } +.comment .added { color: #AAA } +.comment .reply { color: #CCC; opacity: 0; -webkit-transition: opacity 0.3s; -moz-transition: opacity 0.3s; -o-transition: opacity 0.3s; -ms-transition: opacity 0.3s; transition: opacity 0.3s ; border: none } +.comment:hover .reply { opacity: 1 } +.comment .reply .icon { opacity: 0.3 } +.comment .reply:hover { border-bottom: none; color: #666 } +.comment .reply:hover .icon { opacity: 1 } +.comment .info { font-size: 12px; color: #AAA; margin-bottom: 7px } +.comment .info .score { margin-left: 5px } +.comment .comment-body { line-height: 1.5em; margin-top: 0.5em; margin-bottom: 0.5em } +.comment .comment-body p { margin-bottom: 0px; margin-top: 0.5em; } +.comment .comment-body p:first-child { margin: 0px; margin-top: 0px; } +.comment .comment-body.editor { margin-top: 0.5em !important; margin-bottom: 0.5em !important } +.comment .comment-body h1, .comment .body h2, .comment .body h3 { font-size: 110% } +.comment .comment-body blockquote { padding: 1px 15px; border-left: 2px solid #E7E7E7; margin: 0px; margin-top: 30px } +.comment .comment-body blockquote:first-child { margin-top: 0px } +.comment .comment-body blockquote p { margin: 0px; color: #999; font-size: 90% } +.comment .comment-body blockquote a { color: #333; font-weight: normal; border-bottom: 0px } +.comment .comment-body blockquote a:hover { border-bottom: 1px solid #999 } +.comment .editable-edit { margin-top: -5px } + +.comment-new { margin-bottom: 5px; border-top: 0px } +.comment-new .button-submit { + margin: 0px; font-weight: normal; padding: 5px 15px; display: inline-block; + background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; font-size: 15px; line-height: 30px +} +.comment-new h2 { margin-bottom: 25px } + +/* Input */ +.comment-new textarea { + line-height: 1.5em; width: 100%; padding: 10px; font-family: 'Roboto', sans-serif; font-size: 16px; + -webkit-transition: border 0.3s; -moz-transition: border 0.3s; -o-transition: border 0.3s; -ms-transition: border 0.3s; transition: border 0.3s ; border: 2px solid #eee; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; overflow-y: auto +} +input.text:focus, textarea:focus { border-color: #5FC0EA; outline: none; background-color: white } + +.comment-nocert textarea { opacity: 0.5; pointer-events: none } +.comment-nocert .info { opacity: 0.1; pointer-events: none } +.comment-nocert .button-submit-comment { opacity: 0.1; pointer-events: none } +.comment-nocert .button.button-certselect { display: inherit } +.button.button-certselect { + position: absolute; left: 50%; white-space: nowrap; -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); transform: translateX(-50%) ; z-index: 99; + margin-top: 13px; background-color: #007AFF; color: white; border-bottom-color: #3543F9; display: none +} +.button.button-certselect:hover { background-color: #3396FF; color: white; border-bottom-color: #5D68FF; } +.button.button-certselect:active { position: absolute; -webkit-transform: translateX(-50%) translateY(1px); -moz-transform: translateX(-50%) translateY(1px); -o-transform: translateX(-50%) translateY(1px); -ms-transform: translateX(-50%) translateY(1px); transform: translateX(-50%) translateY(1px) ; top: auto; } + +.user-size { font-size: 11px; margin-top: 6px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; text-transform: uppercase; display: inline-block; color: #AAA } +.user-size-used { position: absolute; color: #B10DC9; overflow: hidden; width: 40px; white-space: nowrap } + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/ZeroBlog.css ---- */ + + +/* Design based on medium */ + +body { background-color: white; color: #333332; margin: 10px; padding: 0px; font-family: 'Roboto', sans-serif; height: 15000px; overflow: hidden } +body.loaded { height: auto; overflow: auto } +h1, h2, h3, h4 { font-family: 'Roboto', sans-serif; font-weight: normal; margin: 0px; padding: 0px } +h1 { font-size: 32px; line-height: 1.2em; font-weight: bold; letter-spacing: -0.5px; margin-bottom: 5px } +h2 { margin-top: 3em } +h3 { font-size: 24px; margin-top: 2em } +h1 + h2, h2 + h3 { margin-top: inherit } + +p { margin-top: 0.9em; margin-bottom: 0.9em } +hr { margin: 20px 0px; border: none; border-bottom: 1px solid #eee; margin-left: auto; margin-right: auto; width: 120px; } +small { font-size: 80%; color: #999; } + +a { border-bottom: 1px solid #3498db; text-decoration: none; color: black; font-weight: bold } +a.nolink { border-bottom: none } +a:hover { color: #3498db } + +.button { + padding: 5px 10px; margin-left: 10px; background-color: #DDE0E0; border-bottom: 2px solid #999998; background-position: left center; + -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; text-decoration: none; -webkit-transition: all 0.5s ease-out; -moz-transition: all 0.5s ease-out; -o-transition: all 0.5s ease-out; -ms-transition: all 0.5s ease-out; transition: all 0.5s ease-out ; color: #333 +} +.button:hover { background-color: #FFF400; border-color: white; border-bottom: 2px solid #4D4D4C; -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none ; color: inherit } +.button:active { position: relative; top: 1px } + +/*.button-delete { background-color: #e74c3c; border-bottom-color: #A83F34; color: white }*/ +.button-outline { background-color: white; color: #DDD; border: 1px solid #eee } + +.button-delete:hover { background-color: #FF5442; border: 1px solid #FF5442; color: white } +.button-ok:hover { background-color: #27AE60; border: 1px solid #27AE60; color: white } + +.button.loading { + color: rgba(0,0,0,0); background: #999 url(../img/loading.gif) no-repeat center center; + -webkit-transition: all 0.5s ease-out; -moz-transition: all 0.5s ease-out; -o-transition: all 0.5s ease-out; -ms-transition: all 0.5s ease-out; transition: all 0.5s ease-out ; pointer-events: none; border-bottom: 2px solid #666 +} + +.cancel { margin-left: 10px; font-size: 80%; color: #999; } + + +.template { display: none } + +/* Editable */ +.editable { outline: none } +.editable-edit:hover { opacity: 1; border: none; color: #333 } +.editable-edit { + opacity: 0; float: left; margin-top: 0px; margin-left: -40px; padding: 8px 20px; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; width: 0px; display: inline-block; padding-right: 0px; + color: rgba(100,100,100,0.5); text-decoration: none; font-size: 18px; font-weight: normal; border: none; +} +/*.editing { white-space: pre-wrap; z-index: 1; position: relative; outline: 10000px solid rgba(255,255,255,0.9) !important; } +.editing p { margin: 0px; padding: 0px }*/ /* IE FIX */ +.editor { width: 100%; display: block; overflow :hidden; resize: none; border: none; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; z-index: 900; position: relative } +.editor:focus { border: 0px; outline-offset: 0px } + + +/* -- Editbar -- */ + +.bottombar { + display: none; position: fixed; padding: 10px 20px; opacity: 0; background-color: rgba(255,255,255,0.9); + right: 30px; bottom: 0px; z-index: 999; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; transform: translateY(50px) +} +.bottombar.visible { -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); -ms-transform: translateY(0px); transform: translateY(0px) ; opacity: 1 } +.publishbar { z-index: 990} +.publishbar.visible { display: inline-block; } +.editbar { -webkit-perspective: 900px ; -moz-perspective: 900px ; -o-perspective: 900px ; -ms-perspective: 900px ; perspective: 900px } +.markdown-help { + position: absolute; bottom: 30px; -webkit-transform: translateX(0px) rotateY(-40deg); -moz-transform: translateX(0px) rotateY(-40deg); -o-transform: translateX(0px) rotateY(-40deg); -ms-transform: translateX(0px) rotateY(-40deg); transform: translateX(0px) rotateY(-40deg) ; transform-origin: right; right: 0px; + list-style-type: none; background-color: rgba(255,255,255,0.9); padding: 10px; opacity: 0; -webkit-transition: all 0.6s; -moz-transition: all 0.6s; -o-transition: all 0.6s; -ms-transition: all 0.6s; transition: all 0.6s ; display: none +} +.markdown-help.visible { -webkit-transform: none; -moz-transform: none; -o-transform: none; -ms-transform: none; transform: none ; opacity: 1 } +.markdown-help li { margin: 10px 0px } +.markdown-help code { font-size: 100% } +.icon-help { border: 1px solid #EEE; padding: 2px; display: inline-block; width: 17px; text-align: center; font-size: 13px; margin-right: 6px; vertical-align: 1px } +.icon-help.active { background-color: #EEE } + +/* -- Left -- */ + +.left { float: left; position: absolute; width: 170px; padding-left: 60px; padding-right: 20px; margin-top: 60px; text-align: right } +.right { float: left; padding-left: 60px; margin-left: 240px; max-width: 650px; padding-right: 60px; padding-top: 60px } + +.left .avatar { + background-color: #F0F0F0; width: 60px; height: 60px; -webkit-border-radius: 100%; -moz-border-radius: 100%; -o-border-radius: 100%; -ms-border-radius: 100%; border-radius: 100% ; margin-bottom: 10px; + background-position: center center; background-size: 70%; display: inline-block; +} +.left h1 a.nolink { font-family: Tinos; display: inline-block; padding: 1px } +.left h1 a.editable-edit { float: none } +.left h2 { font-size: 15px; font-family: Tinos; line-height: 1.6em; color: #AAA; margin-top: 14px; letter-spacing: 0.2px } +.left ul, .left li { padding: 0px; margin: 0px; list-style-type: none; line-height: 2em } +.left hr { margin-left: 100px; margin-right: 0px; width: auto } +.left .links { width: 230px; margin-left: -60px } +.left .links.editor { text-align: left !important } + +/* -- Post -- */ + +.posts .new { display: none; position: absolute; top: -50px; margin-left: 0px; left: 50%; -webkit-transform: translateX(-50%) ; -moz-transform: translateX(-50%) ; -o-transform: translateX(-50%) ; -ms-transform: translateX(-50%) ; transform: translateX(-50%) } + +.posts, .post-full { display: none; position: relative; } +.page-main .posts { display: block } +.page-post.loaded .post-full { display: block; border-bottom: none } + + +.post { margin-bottom: 50px; padding-bottom: 50px; border-bottom: 1px solid #eee; min-width: 500px } +.post .title a { text-decoration: none; color: inherit; display: inline-block; border-bottom: none; font-weight: inherit } +.posts .title a:visited { color: #666969 } +.post .details { color: #BBB; margin-top: 5px; margin-bottom: 20px } +.post .details .comments-num { border: none; color: #BBB; font-weight: normal; } +.post .details .comments-num .num { border-bottom: 1px solid #eee; color: #000; } +.post .details .comments-num:hover .num { border-bottom: 1px solid #D6A1DE; } +.post .body { font-size: 21.5px; line-height: 1.6; font-family: Tinos; margin-top: 20px } + +.post .body h1 { text-align: center; margin-top: 50px } +.post .body h1:before { content: " "; border-top: 1px solid #EEE; width: 120px; display: block; margin-left: auto; margin-right: auto; margin-bottom: 50px; } + +.post .body p + ul { margin-top: -0.5em } +.post .body li { margin-top: 0.5em; margin-bottom: 0.5em } +.post .body hr:first-of-type { display: none } + +.post .body a img { margin-bottom: -8px } +.post .body img { max-width: 100% } + +code { + background-color: #f5f5f5; border: 1px solid #ccc; padding: 0px 5px; overflow: auto; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; display: inline-block; + color: #444; font-weight: normal; font-size: 60%; vertical-align: text-bottom; border-bottom-width: 2px; +} +.post .body pre { table-layout: fixed; width: auto; display: table; white-space: normal; } +.post .body pre code { padding: 10px 20px; white-space: pre; max-width: 850px } + +blockquote { border-left: 3px solid #333; margin-left: 0px; padding-left: 1em } +/*.post .more { + display: inline-block; border: 1px solid #eee; padding: 10px 25px; -webkit-border-radius: 26px; -moz-border-radius: 26px; -o-border-radius: 26px; -ms-border-radius: 26px; border-radius: 26px ; font-size: 11px; color: #AAA; font-weight: normal; + left: 50%; position: relative; -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); transform: translateX(-50%) ; +}*/ + +.post .more { border: 2px solid #333; padding: 10px 20px; font-size: 15px; margin-top: 30px; display: none; -webkit-transition: all 0.3s ; -moz-transition: all 0.3s ; -o-transition: all 0.3s ; -ms-transition: all 0.3s ; transition: all 0.3s } +.post .more .readmore { } +.post .more:hover { color: white; -webkit-box-shadow: inset 150px 0px 0px 0px #333; -moz-box-shadow: inset 150px 0px 0px 0px #333; -o-box-shadow: inset 150px 0px 0px 0px #333; -ms-box-shadow: inset 150px 0px 0px 0px #333; box-shadow: inset 150px 0px 0px 0px #333 ; } +.post .more:active { color: white; -webkit-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -moz-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -o-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -ms-box-shadow: inset 150px 0px 0px 0px #AF3BFF; box-shadow: inset 150px 0px 0px 0px #AF3BFF ; -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none ; border-color: #AF3BFF } + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/fonts.css ---- */ + + +/* Base64 encoder: http://www.motobit.com/util/base64-decoder-encoder.asp */ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 21, 2015 */ + +@font-face { + font-family: 'Tinos'; + src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAIfEABMAAAABK6AAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAABqAAAABwAAAAcafTEEEdERUYAAAHEAAAAJAAAACYAJwFhR1BPUwAAAegAAAJ1AAAHzLT7y6ZHU1VCAAAEYAAAAIIAAADSeGF8IE9TLzIAAATkAAAAYAAAAGD/Bgk2Y21hcAAABUQAAAJGAAADdg18Ei5jdnQgAAAHjAAAADIAAAAyDwsIvWZwZ20AAAfAAAABsQAAAmVTtC+nZ2FzcAAACXQAAAAIAAAACAAAABBnbHlmAAAJfAAAceQAAQSsvLBIQGhlYWQAAHtgAAAAMwAAADYI0lERaGhlYQAAe5QAAAAhAAAAJA+wBn9obXR4AAB7uAAAAioAAATsC2JNKGxvY2EAAH3kAAACcAAAAnjTQBTGbWF4cAAAgFQAAAAgAAAAIAJYAbZuYW1lAACAdAAAAxwAAAd009XuX3Bvc3QAAIOQAAADlQAABiya+85BcHJlcAAAhygAAACUAAAAz1AoMgx3ZWJmAACHvAAAAAYAAAAGNWtUwAAAAAEAAAAA0MoNVwAAAADIRNDOAAAAANDl5ep42mNgZGBg4AFiMQY5BiYGRgZGRisgyQIUYQJiRggGAAysAIp42uVUv2tTURg9372vbSqaHyWUUkymh6i0Kg1SE4o4XEpaMsVGk/AGqwSDqcUGEbSlgyCIy4MiIuLgX5BBMjg4iDg5iJtCFwen4uDg0MnreTcZ/NmtRZFw3ne/75xz73fvzXsQAPuwgDV4l262lzB+ud1o4VCzcbGNqaXF68s4DY8aWItI+/ux/FBXrUZ7GfGri+0W0swFMT5jbqSgqR3AIIYwTPYgjuIUZtnBFdzDfaqi2e666OEBnuINtvrZtqTlhJR6mdTlhmxIp589l/fyRSVdFlNZVVCBWldP1Ev1UQ+66gG9Xx/WRl/Qa/qh7uq3+pMX83zvjBc4XnlV7xb749jbYJeCESIe7cvtKkJUTRNJYuy7eo9T5MYci1+43fDtBrfXe9jJt9ecxijGkXU3/zP7ryn+pnP9v7nonhTvafSPN7WzQpRyX9cRHIPBPK5hHY/RwSuJS1Fuywt5LR/cb0s+88vq2xDTdhN5okDM2G70BvI5DO24DPJft8kF5Axqtok6Y2CNTJLTSJBJET6ZIXq69BjOZ+hp0pOjNqTWsK+ITdCVInxWBqi9Q21AbUhtSG2HvWt2kqA7SU2KMWMfIUvWp3KKnLErmCWKRMk+Q5mxwniOscpYZwyIeG8m9u9mYsxwtizhc2zYRZEosYcy8wpjlQhY6zvpSnLdFGOGvWcJn6xhH0WixG7LjBXGKhHQnejt0q2Z6a9p6DR9Z47OHJ0hnTmcZX2B9SpRY64wZzdlEis8mwRnTNp3XD3EvKuWyCfsKiurEJngPqIzbXLfIc5HCo6jt1zzP+bjCI4jh5OYRh4FzGAOFdRQRyATMvkNmAz7ZgAAAHjaY2BkYGDgYghiyGFgSa4symGQSi9KzWZQyUhNKmIwyEksyWOwYWABqmH4/x9IwFiMKGxGFHGm5OTcAgY+MCkC5DOCRUGYmYGDQYBBgoENLAaiQeI6UHknoDxQN1CFCFiWAa4PohdECwGxFMQWIMnE4MPgC1XBxtALNtUHAMqqFmYAAAADBB0BkAAFAAQFmgUzAAABJQWaBTMAAAOgAGQBpAEFAgIGAwUEBQIDBOAACv9QAHj/AAAAIQAAAABNT05PAEAADSX8Bmb+ZgAAB9oClWAAAb/f9wAAA6wFPQAAACAABHjarZPpU81RGMc/z68FUaK0y6+oaN/rhsoeiksia7asWbNky9jXsQuhSZSkYgYzzRgaXvgTTJYX947/gGG8yD3O3HsnZpjxxpk55zzPmXM+58z3+R7AA1ePQPSIVOlMnLmnWPVspRAv/PGllrs084CHdPKULp7zlm8SIHGSIGmSI0VSImVSKdVSa4Qbb4z3xkfTxww0w8xIM9qMNVPMPLPCbI+KjulVSpN9MWnUxFZN7HATu+nhuwRJvCRLplikWKxSLhukxghxEzH9zRAzwk20/CKqr+qTeq1eqW71Ur1QXeqZeqIeq0eqU7WrNtWqWlSzalKNqkHVqzrHD0epo9BRYI+wB9sD7QF2f7uv3cvWa+uxnbUFf8h3qfFfm7fh41SYP9iC4Y6MfzBcJz3w1DXxph/9GYAPAxmk1fRjsK7TEIYSQCDDCCKYEEIJI1xXcziRjNCKRxHNSEYRQyxxjGYM8SSQSBLJpJBKGulkkEkW2eSQi4U8xjKO8eRToL0wgYlMYjJTmMo0ipjODGZSTAmzmK3dMoe5lDKPMuazgHIWsojFLGEpy6hgOSv0+3ewk93s4RDHOcMFznORy1ziCnVc5xo3qOcWN7lNg3ZIE3eczrunnXJf+6/NqcFqKrUc6To6x0bWiYUq1upsFyf61FrzFwWv0sIWVv22sp7NksFKtlLNMT7zRbsvQVIkVRIlybmjQ/z0XbmSJdl9hUiWND1tZy/b2EcNB/T/OMh+jnBUrx/mFKc5yTsJlXD3iTA2uaKffxyhPwAAAAADrAU9AFAALQA1AFYAWgBoAKYAaQCmALQAwQDRAGYAXwCEAI8AYQCaAJYAXABEBREAAHjaXVG7TltBEN0NDwOBxNggOdoUs5mQxnuhBQnE1Y1iZDuF5QhpN3KRi3EBH0CBRA3arxmgoaRImwYhF0h8Qj4hEjNriKI0Ozuzc86ZM0vKkap36WvPU+ckkMLdBs02/U5ItbMA96Tr642MtIMHWmxm9Mp1+/4LBpvRlDtqAOU9bykPGU07gVq0p/7R/AqG+/wf8zsYtDTT9NQ6CekhBOabcUuD7xnNussP+oLV4WIwMKSYpuIuP6ZS/rc052rLsLWR0byDMxH5yTRAU2ttBJr+1CHV83EUS5DLprE2mJiy/iQTwYXJdFVTtcz42sFdsrPoYIMqzYEH2MNWeQweDg8mFNK3JMosDRH2YqvECBGTHAo55dzJ/qRA+UgSxrxJSjvjhrUGxpHXwKA2T7P/PJtNbW8dwvhZHMF3vxlLOvjIhtoYEWI7YimACURCRlX5hhrPvSwG5FL7z0CUgOXxj3+dCLTu2EQ8l7V1DjFWCHp+29zyy4q7VrnOi0J3b6pqqNIpzftezr7HA54eC8NBY8Gbz/v+SoH6PCyuNGgOBEN6N3r/orXqiKu8Fz6yJ9O/sVoAAAAAAQAB//8AD3ja5L0JfFTluTh83nNmTWY7s2bWzJLJwpAMmckQIhACsomIioiIFkEpm+IKoqKiIiKiIq5IqSuipak9ZzKgorWo127WWv8W1Kq11npt7rVqe71WgRy+53nfcyaTZJKgvf3u//t9+iM5mSzzPvv+vBzPTeY4frH+dE7gjFyTTLj0uLxR5/trRjbo3x2XF3h45GQBX9bjy3mjoerIuDzB17NiTEzGxNhkPqrUkG3KMv3ph344WfcqB3+Se+foh+RV/XiukrNz53F5M8elCoKJE3WpvIXnUkRypCXuYMFgw5fUT102A2dKFewV3DZdSrKnCzb6JIskJds50SlZ2iSbKJuFtjbJ4JSsbZxsEeBlW9uo5taW0dmM1+M2JOK1rqyQeGdqNjt1SkvLFMvv2xecnZ06Nds8fbreeWQ6nG2dcDb/MpwNYe7g8vBKStJl8XhmeF9DhkimtCQcLPAV3Gh4gXfIRgJnpF/JZjiMkRedMtG1tXGjmvHNCPxb93L7DDIZPujHK9XkA6Wao3hIcpzwDrxXkKsmZ3D5AOAh7/H6s9ls3gjvmzdVWuC5wJGA0Zrq4sVQuMaXlTlTd5fbVxWs8WUKeh39luCIVOO39PAtg7nCCt8iUjQtBQ7K/opuyU8PKZsquvNGU0Wqq8OoM6ckLiOZHLIXvuGBb3i8+A2PHb7hzEgeh1wJ37BUdMsxkpJGB/a1f/hFhPOkKva1/8cXE/FBCji6+IDRBe9OPxrwI7xVl9lvggevo6vCWwkPHkeX1WOBH3DQjyL96MaP+DM++jPwW1X0t+BvBrW/E9L+Thh/piui/WQ1vi50OHgBQXWIiItQOFLd1O8/qSOAJMhlXYlcDCiB/7KeBPyLCQkX/muNuWLJ/ccdIpaZy04kuZnLZu7c2/aZcmTWslnKr05aPusakmtTXiG7lpDsUnKfshz/LVVeXaLMJ7vwH7wOdBS4eUcXCy/oX+HquVFcK/cTLl8LlJQNQrfUnMnXGhCxtUlzKh9HAruQoxxZOWjolpoyeVcQv+0SzakuX1I0AfOPSUvWg3KDuVsi0YOixmgNDjlJUnmDozGTyRRqKrgTQFqcwWb4SqpxyC1AJV9Gjpq7C17Gi21AvwYrSIDQJrfUwOcqEAlDLTxwbZJP3EOsoWhja42vTQo6pYY2ySVKHpQVMeuLEJ/YpMu1jG7NZT1en5ioayJ1IrwMImT0JHJNxOXGn7ER0k5yLbV18ybFq3905pqFM1vDr+6eff/2ieHIle3nPHbLm0/NPv/j9XUzFiw+n8QuvHzR+izp+GnDCXp+dEP6uFnfbb9jr+36dYak0r0zNEKnJOLju2768ZvWW2/mR+rEsaeNryPPWlccflm88bIFV2U4PTf16EeGxfrZnJnzcH6uBrB9O0eRKnmzcj2guykth+GTEfAmW+HBlZZ5+ITS0IwqRa4ArFY4ZAfgRg+PeoccgMckPCYdcgoeAYFyBj47KkRnl5H3+gFBcioJX/jC8Sr4gpON9fBVIJpM4bdcYfhCX+Hg4AtgNkcM9IwjFq9tdXuzmdGAm0Tc4CJZM2EqqP+3ppJpDz6m7H34oe+dMnf+nNPOOuPk5ULhoiMn8rFHdj24U3nq4Yd3aN8QPiQXPf2Ucuvze3du3LJj220bDi/XLzm0nVyY/wm8vPn5p9SXgR9nHf3E4AY81XCN3BjueoYjud7QnQ/jQ0jfLbnTEugLDzyNykij06A3u4nURnGUtIISSYKylZssFC8tqAks3fJx8LkJUCHp2qQWsWCO16ccyD8WpzQC8OIOic49OgcnVlPMjPaAHrQY2hAtLe2ktTanamEbMZLRrXW5mMfIG6uJJ1ZnIwkVLa3EBrzla+dzLYCdWdOvvum+/XuffPr4q7aQXYsMt5Nfbp655s+PKU/8cNmHG7/6+t9+8ODb9yvW5Qse2r7o9NTe5WeTxYtuPS97554t99y+adalZ4xRrvvZY8FcLqj8Q/qtP/e978x+4cWtO+4nv2zczn/30VU1UxbP2L+QI9xc4WwSpDo/zjS+qu6JpCvR9bKepFSdPldV5fC785WZ/DL9bZzI1XGSLQ2/QSQnxaPZ2g2mDaXbbAOtqsvILvYHWpyjWz02wosOp9fnaSL8/GV/+MVVdxw/9d5Lfvb+cvLpp+Tkr1bMmfqO8q5ySDmivPK7iXOWf01ORZtBuEnwfqdo7yemJTN7P91B2Qrvp7Pi++lAm0im4vu1E6fo4GvrchHi9Lh5g3HSJfdOPf6Oq37xh2XwxspDEw+QHBGIgdS8M3XO+f9Q5E8/VX781fns/Rbzs4QHADci/J/XU+vsTGt/uZG06oWskPRZiTHpSrj0i8l05ekOMja1I03GdygFMrNDeSm9I6W8LJx73uItL5JpyjPP33buotueU54l01+Cv7+Ee0VXrdsAvsBsTuLSkjErExNIZibPEYSFqwDFSSgaiWCGd7ekpYqDEp+RzWDZdJm8uYKi2Ag/VmHGxwrOnJKt7IC5mAieiCcmJsQl5ImlZLcydym/egl+XqLMJbsZjLOUl8k67g3OwTVx4HvIHAoD4JY/WLBWcFFQtDzFK+8ALc3x8Fayk/59H4pxXZGzDcZZUiQ5eXKu4+QH7/x0zMXuqCvRMbrt7KmbnhmB7zOT3Msv5NPAZ/UIa4GYuCA4OOwTMpvMgS8h2DhTL7eBmMzk3eTe++9nZ90IvtOV3AHAV66v51TyTJHU34FSUVLqC23U/CDNB4K/zx39hG/TT4UzRkEW0GARSnQd/Yt86dk8JEvIm+cqKbd+/qFdIDegd4Q86J0KzstN4vImVDY2AZWNLCBKfVQuKkGrVDqo42YArVIFn8VK0BUmcN1Ai9jg0cBRteFwZjPAurE4rz3yiTg/6613f/euMv13bz296robr77qphsu5XeSk8gi5VHlxz3TyWIyR+lU/pMkyFQyiYSULxjeCmCoN+inw9mmMLhkAsrPnMkbKHiVSG3ZZO7Om3gktQnZjqfOEs8x6bWgCwXOnWRA1y6bS4r6XDIr6j0F4lL+Rja2EGcuqJu6KPeHw6ZgDt9zPrznFv1MLsRdyd6zEKCkzovwnrIZ9LFZpMxrRcYOpyUbZTg091aHbID3c4NMu6kD4Q7BgQxufDQgg0cQfWDe82JVoA0RF0AnmLRJZlE2uMEJhq/sbXjOVtSmaGzsJCEWVbDBGPPM39f1xAmX35S7OJWYtHfdu++dUfjtmYv5/F0/+P6Lv9lww83hqp2ETz31+MU/f1meedZ2hsdzgcYSwDSCe4rL1yMe9UJ3Xl+PB9MTOGMYYXMDbO4wPXeVOVWwWurD1hSaZCKl0pL/YKGKgtlFwO1LFTgGM0oEe6pyyCa0y9T+SNVozkV4FtNytaU7L1bjHxYtgIWRyDxVorPA68Pxemqe9WCewR5JFlFKtklWpxRvk9yiVN0mhZ1SANkKHRxmgdMEsEN6sdNOslERxJh6Ool43bmTGuu2tH//3lu2btlyyQWrr8utGpmYdN4d08iT99+6t/OrD5/fTZqf80bveOLGTUbTbLPhuhs2rqVYC4jK3s2PuT2P37Pn1ynq6wOqhD/qJwOoNi3myfNoarhKM2+lMQZn4sJqjGEHxX5QsmSQIyUhkzdRzWYyAH7NlCnNyAPoxpjMAC4PcFeq9OdFCH5QcZCsCO4uaD6IwxL1/JbL9u7tVILkIz2p2yBsO3LpFuVtUreFf5TRdQ2l63guwj3B5UNFuoaKdHXgYV1MY3ktIQfQ0wtUttC4wWJDDq5OS/aDBXcFdzHwuNtOye8ElUnc9nJUdjMq+0EJRLUoLtImuwmFSDKJXXqbN8SIGqLfQ6L62ySvU3L3IWQTOBDGBFX0Re1Wt2ZS48i1Yx64p+PWy886YyH/RE/+grV/+fDLj56/B4hWFblHvnrduCr+/vuVOVXPv/Srt1MsJpsHeHgJ+Bv9S/CcfIgJ8CnzOmRrCwKsowCbgK3FhE8HaBCNwNZJqtsCwKX2DIQxFCK3pbvL5I4C7EbmQdSihxkAj9GiE33oOplEyQzgJcCLlDkqtSJIrayzUDXDfIVsxudBDxxUn1CEjmlE5kXOu/bDe+7cOikRu7jxzkdNj+6U973x8z999vQtm6+8YOnFm/h73yLH7Ux8vMkZVD5SPp/78+de/5AsJFOU15R3vr9n551oU4A3MeY1YcSr13R+wUiJ3cXpCYYlZmoATBQQUO2UH8EgyxVgC2RipIEGHBiIAKo3ZtwotPfsvp4/sacroePI+JMOO3Q7dzLflNoIL/haTdzFXN6DGA6AlYim5VqIiUaqzmiaItQHCDWg/CfgweeQw4BBJzw24GvolI7CMCcBnqdZ8ASidsotiGLZCTZEqhVlO2YERva6oqNbm0ivwWaSHnWVuuslz7OuW3nGylf273v1/LMuvebgn5Q5hctv2LDumo03rmpYvPLi5ResXLGUrNjw44b6bRft2rvn8Qvvrx/Rdd3z+8m1P7hp886H7thEPtp85dpNt9xwLeWtSQB7J/BWFcC+nukAWQTeEql0i2AF8gKyWUyAKC5kFlDEkLcSFBUgJ10WPyZBVBsBYb0bwr5IhtrRGhQlK814gL7bYxYFbyhG0SGiiqhsk0NeEQVHiomagUU0gFXlQFpyTJicLkPRF0drO+lPv/nogPLpV4/ePDERvaD1oU7ztu/Lrzx9xbXXr79y4yFh56/+oOxVHlJ+rHwv/pc77FXET8TT33jm/jtB+5BqhPkR8FfuEl4Af8XHje3rsdgJPHtUj6UKYQSNp3orklN7kv0D/Bax5PmRqdnM1CnZlilTWrJTpmayU89GlwZ8GSEMH5rBsWFyvQJ8vB1wDgdY4wVc3k2YNca30jy+cInHBzHjAKcPjHJBZKcDS4QGmBeB0dwBzfzKFVZE6wCv0FVy3hVytGbylJaOUx68a4x2ZHAVPVFnfOLotrOmgauoW188OfrH+8A/vpczcByodI+ZeJYIzxx5U2jgt2TIgaXKlcqVSxE+cG911cITNG8VQO+SutHgUupN3ZizwtyU6k8S+Id/ZJrwDHliyRKyfckSZgOWwXvF2Hu15swQFHiWCQ3wXs/sW0o2ko1LlVSG4fLoh0Ib8DHK8LtcPsoVccn41wVq0iXQvIYX7QLlXzUvIXlpaqlQQTMYXWKlz5YqhBlWtciccTNmnaz6F87AZJNNsjgk237Z7PhaMu7vMpkxR2RxdFktNlcqDx+jt0RvSRjAd2wDWwnKqI2DH7JYMQ9Eik9SR4DIPpQCD3gDoiy42trkCvQ9A1GkoQv1hr4C9IUggilFbI2mDoGdCAlB8xTspA89H9hEnnh4e5v1lMCWubNW3HTx7MRqjSV1CSWldD76s6hVOUJmhcVbb7rryuadR9pUDqW4XKmsNfxdP4dr507g9nPS2LTcAkoQ3FFntpA0cQmwthNNXDVgZ0paDgJJIxlUkTpk2BkUr6PM3Ej49iiH7AG8TqigPzzBITcQandiIEInqjm8O/++mabupjTZpMn79XJE/NomVe/n5OrJiKdI9eQpRTw1TBCdT+kqnfGRLWPGUj1S2QLoaR0D6EmijyFPmQg/YeQ88YZRE+xq/sPJxaKc6OZ1iXiupZUG9rmWdmEsyfgEG+haVK3OXAsXi+t40e3UwZetPgP8dA2fdOMXrrq4gV95mDxLbOQUcsmLyt6uiaYznjh++snjL3r8oRtqakddarInk6v2X6z8Qvm0W9n85vdI7S/u/npD7Dblg10fKD94lh97ypi7xl/WfMOPl5MVJER+TXjleeUPzyvyr7KZE884c+VZaz6U1jYaej5NXOpP+h8l8e1HSNWHymnK4ZeU3/7wpHOyF57zEzLvsXvaW3iP7kzlK0onN8fpn4b4wc45uYnMm6exqr47bzDbMpkMZf2CxcGh2rag2nalUT9zEDgA3ng98JrgAN5zMq8cFKTPE8u1CjHB54EP7m3kl8+Td3b3/LKwoefzjQU7eeOvEE98hcFELkjWK9cEc3wjvxkkfOzRQ7q/g712cWGultvM5V1oSTDT5c6wZ3osFMVaI/Uf6bNO312IhF0GOF8Ez1dHYx4IMYCn8jwNLXg1MQyumR9dMlu3FEdLa7Z1y/XwQtyNSR0vCkuYpxGGFBEx9V7rBEeGwiXW5WLRom3VxZKtqjlNkZz2MLazk/8uRJpb1+/5mfLfRzllzspbdvxw93Ovff7OI/dv/9FrAPcDgdx9Oy/fFXL96OYXfm6Yb9h6/23r5193x9qLQU/NOfqJ7iPQP0H00PxFK+qnVtSjWdFKobvL6BfQdwlRA2oDaGyl+XrJ4JC8mGP1sC89aS15im6GEbRJXnD7aXQl+gFacNiMoszZkJKgNSQ9ZXkulvG5qIMWxZQOwDiBZAVwKrg5ZAGZ9/rnhkmRqc8sVI5+8o9PLv3V2OREw7s9yj7lbn4LmU/OyyrvPJlKK/9HeUl5V/l1a9MvlJcnkPOYzRp79Ih+NdDZCrbzFC5v1ahsy7DnIpV9falMrSmQ1malALsAGCQgGlLZh2QrJRUH9p8RCT2BWAJps4hcRpYojys/UOIvXPHYl93K68rHBUYUZY9SUCRll26BicTJKDD4cWo7xnKc7hpay/iJGl97jN3FQFvL4PiBOHrqScM39RpTWt2cHsNDeM1t1aKGvJVypNUO5tfE6VUyAlQegMoCDOspCc6xYOEEJWfPFERGS5EGF6rjLRkpPxcCvdQ1iRQPQFCaGPewoKOIFjFRB3wqxlqz8BQTY1GkKaBG+HRS9OLfvUNWVHd0VCv3EhPhT2mb5FJx89O3bT1fPKQsfqTnPcdXygMaXhoALz7uIfA6KF703eDdUBdbNgHI9IEDNDjMbgJocMBrDuoROmwY7zlovFcJaNC5qScOxPUelEVAgymTF2n8JbrgJ700meBFjAD0NkBHZaYkn6DD3BJDAMq2zko5mJMdHnjwtrFsWV+wqYISx2pAb64eP75aWf1+zwsP6k0M2tcptF+iitJReEE29RtBNqPc97l8RJNNTSALXl+EurWAA3+myxih4hkrFU9QmXLQ2p0PUvIHkWPctEbiBl+iyxB0m3qpmtYKb3GMtlBeK4UIyCtS1QSgeZHIwTbZGMH4qozcin3kllLeYxTBbKHwLiKnf/Hh8cEpL5x/lPvrF5/NeXpUJ/ls/apDd6jSu5B8Z5zyx13NOQilfqa8rbxWHyLXBEaPDigza1vIQk6TC/1mKhcPq1bDxayG0xNAq4FCIFmzKAd5o8WOxR1zFRUHM+poxvJ+Rms/TU35g2ZMEuR5f6kA+GkpT6rIIGOUcAUqC5Ux3PCVJYPcz8lV1CaJgBEdRAdgmNp6eR8wEFM/MwZARkC14O/k13TyVZ2dPX/p7NnUyZg+F+j5G2/Hz4fPRTbgcz2vYPoLYJ8BSuxcWuedVpJzq8gUJV8yZmiuklez5bzG6hQ+c2n2jWUve0/o88zopGfRToHvDu+ZOvoJj7bRza1U7aIBvFGDiybOeGCmSnzvCnhvK7y3Jy2R0lou5iPscBI7TbLYMSIz2bV8IK2V0gygC0tpLlZKqxBZjVkNoHLq+dzo+6QmRVxTR9zayeu2zX586XUVX2z2BZ4XPsXjHnnxpl+uVvkjD+f1Y1aohD9kZ5XGHRaVOyrRzSBSgOLLx1jCR1HmAymBj5gD532lWAsirXVIa7OnL4UJ/WRGH4QYe+l7wway83vKaH78VuXpnv/as79I45v5K/Cz0tETBz9k11ZlLMtxon5bBue3azlOmtfsr/etmt7XiO7oT3R69lKKS2YHEh3r/KPVOr/NSl0ODmIZliLSiTTpUMK3mVYX1dP8uNeI6cDi9onOIn8scxOfsk49s+EDOHMVd4t6Zpsry6TS6vAVpdJE8Q78SiQ/Pa63ojvvpcf1VuFxvaXH9bKUtgVAslB5s5gxZAQNbaGyCHaMFhtFLya4TehUIGHyRidQphcIM+mVO5IgjDLkXlIg75LrQPL+WOjpTige1Rof0QlHNMHTNR9ep7v+8GtFuui3UR9xo8pXNgohmh4KXQWFTjZbkKfcFD4R4BP5oj3hxVL4RNZEYIOfsRnxGzYL/IzRRvsJAFSMPmSjSBNXkk2kdGIAWh2lABKVVL2w8fkC+WXnoiMva0BVC3dSijl1ew9vp7qEp3blMrArWFuY3FtboDlU2V1SXbAVqwt6W2l1gS9WF/RqdUH1faJcaXVhDij2yWQmuDj7lRcU6fW3/v2j37/97x+/yT/EdyqPKT9WdiuPkO+QM5SfKH8AB+h4MpEElY9Ufw1kIUZloYq7nMtb8IxWpvHoMauMmB1kz2jwTQ4Lb6VOAOUwGxUIyZHJm22aIszbzBqu0S83M/uos3YjL3GyiSV85CoLLctSG44Ba4qoLOQqutzkEPnk6+77DvS88uALy37w8Pa956INX/2bg8okZr17rtr+5GO3U1wrBf1Omqeq4RZzeS8tGmu4joMD6kjLlSbEc8Gq576D6RuW/vTbaLNJtYp8THdWg+Pcxbu9Rkx36kXJAVQIYRhkbJPiYl9a6FGDYmk0EW8idehB96fMJDJL+X5m3tXjZvvWpaddePH6mlHKT5U8pdI7f/73t/gH+CeBSj9SPHe2X7hAN6kimF66S0fOIacBvf5IImQKUCyofFikl/40oJeHi3C3cXknSkllVnaBWFQ4MiqhIFSSPCVEs3mdSDQbEq06LbkPosGQvJm8nTosdtFcmvtGotlZl4HeyvLcATvwoBUUAKLDAuiwuVA/u8EWR5yad5KLsdQR1c+JAcTkjz/y+Z3Xk/O3AvQb//ZKz4EHX5C77rvn2R8CTXc/d9NLtT1/AS09U9GppH16wwP3X09t8qajnwhfAG0buSvU2Cmu+WcVhmLA1ESzcSEwu2aIGYsuZBKO7zXDT3mTpmLTUxrlnsNYSWSxUhxjpRA6YV2c6A0j4SuwIwuzKnot7YiuF2ZYPe6IgWVS6sTefL5h0+cHHnl+YmLJvTfdN/68dRvWnTf+0z9e8PvTJyaSe+bd+v3x51274drzxgtfPrQ3pXTvnLFy4cS540emx561fuGLB2pjZPSe9PQt105fMLGxaczcdRTuJMjmC9QvuFiNpGwgmZWqHy4a0Jp2cVZwsCUhSx0DjpYy1EKFHYCsANVeQSlbgarPXqH5CJi4KvGuvSiZHGqaCnsby4lTP7MolJhDSup2TA5GfnVF84Geew5ke74T1PFkrPLy68bKw+dTot3nfp1j/ox+B7VVV6jxg9HEYgb0GoEh8wL1GqkG8R1ELsvrqQ+gF+CQPj31D1CH6x2Yq2dKvkIzSfkKUQOIMmmFnuaI4fxGOL+jqo0xI+hrRwwoozk3ukS0JiemwP8i5+1/FdW38o8jyn8r/wD+A9/mHeWuvV1CA/Vz3v/b5397T2hBWHxHP9BjjcnGjWQ0YHCYVDiMFRQOexqzgHACa68woKdC3xpMoo+PFMAg3iORwl09H2V73mfvmRTewfc79F96K74Xf/QD4yZK7/OYHyjZs+ztKtW3q7DSt/OkqeM8OrBv3F8/WUrTY/YmGyYbTcavJfN+sDVmm5pGtNm19BgcD6Q2rzeIbW29R8wWT2mGg4LKeJlMIMsbydlk1OvkudXKjJyyU/leTpnMjnyy8MiRBYLMji3sOLIYjw5nbwS99AiNGcapttvNvBOXl8YMBpX6enjJpFI/lGaOvR6dvYoq1eCaNTev19vDF32exrvJL5S19/ENu4mXtO4iT92tbCSvbut5c7fykHLVLnDjF/Ad1OE7l1D3SanomUfde1PPV9QkIz3hnHdRHM/j8g4a6+lpdqIcWUGinKxJxerUAvu8k4b7TofqXFudakzKieVor7lFPr61QK4nF+4GDlCmogApDRSjPffw51NvNa500KzZPv7PWLMG2b8MzulE2af+XiX4qJXUNa10oI+POkBA9ceZUP250pLxoKrf8gbq7RgqMCqhCWo1xUAtscOAcVQlq9w5sTuskpVhQddVUBoQlHasTZIYpjezwrn854f+8Z3qKcLWnkoSX/VZ89ipwQW6Te43yPi5h1d6KwmnbGb43aZ8yi/U38YZuTQHwa5s0HVLQlrmdTSjjwZXbwZpp3DosUCBXTEszQ/vpxf1nm1A5TdJg/Kp4cF0wyGxIU3/bp8eDwHlkBusx0PMksS55M3F+qmHdrGYDs7kLDkTx86kU89EDsoGOBOhPQsEzyRoZ/IlxWQuJsZmwHnehHON+bBB/1lD+utF9O+GyQZhF9DIgH1GrOUE/rqJQUOyKFFh0tlMOpcqj4AHtkF4+sh0LE7A7x79XPlK5zi6AODxcXgYztSN/2hHDQPDGPPEHLro4T8+sgRr3bpzeIf+Dk6PfTj6dIE3cTZ0YgwUfsHGVQD8RpQmXk+pydpIPYk1B/6tVX9+Uvk8Rv2H6WBLLxFeADlNcjex/l05AtqZOkweXXfeQTAeAvuqJnFAyxZ0iYDDCp8E7jJ8z1pKx5AZc1pSyIH5mjga2zR8QXtv9RnZbe6W64DZYiHMcDiw30Nyi7KvCq1twgMOlpurirEMfEs7qBy1TpHI0ToFig14U3EXTbCLRhuZfsJD226bNmPxafExj6zdvnW1orgulf+2a8vk8zLrbzqH6BasnSjo7lp0dnr1q4lrb+jZ4G9ccCmJSNVVZJZOv4DCztE6LvahhbnlqkXFrg8jghwA5xArUMgUkbTkOCg7AUA+k3dQ0XegOXI6ZB8aHEs39Rd9IPqy0UqddFT8jjYpgCIkGVERSJwoiQCeCAzkNrLqC099BldvsdZI0obF2/a/+sGBua/N2jVn9S1XX3fT2FUB/cJGRRp9x6zuT3qUr2ur9b7DFY63Dj5d8Fho7xfAMUt4GaKKhWot2g4UFBCKCiBcBS1jVRixjMUCDIsFSFXMIgOtaIxhtKADZPdQB8juoWl+qUIERYbVJGd/vwd8dKywoqsbndX99saHWlOnrVK+ePSHd17Q3DlfaSXv/WdPtXJoV1pZ9rs9sXE1DRTnM+CsHwPOMe+/ivmrsg9Oa6OBhk49NnjqkjktV6jIhyO74cgso4/cZAH59NOY1I9hGyLfj2l9wdmGDRay3YEwhLC3yMJh6AYcDPCYWDsCQFA7HvWxylWsdN4qAkwzfv+7Cy4yPEAmr1K+slxyn7KucN2Nl8w/81LlCHn1H4T4Yhu+qGo89Iy/cep88sHzz9bxH4vMDz8F4JoKNPBwIW6JmrWxaFQIYNbQ6KJZQ7VKCyCZLOhzYwO7T60YYj3WZ0IqWFxt1LlWIbG4GDsZMSbF3hFOpUVU9MTA/USXkwUdta4YZaRTfvNTsrzn+fHrlo6+e9Sox+a+88pecufZ5yy7iLz35d+VJbOdt9x/irNyTHXTJ+TUrvufoPprAgCyW/8I6IIruXwVQuDX0bBAJEwy1LIKyESeR5NuTWOHeN5KNaW1wszy2wHa2ugx0zDQE6A9+S5M7nh8YKcCNOcd4PCFQJU5xUw+toEx8uRaadEZ+0UQjjDBBiBmNCc88tg9J01qboyPmtBy6NArim6zMK+5btJv/+h6da3n4u075hz5MtbYGAMXVuDmKVOFt3VBro5r4To4ictnsMIbNnEBnNBAeNoFptwg7pNTQCDfmAw2BPmQQBNp75IhI+eARhyWV+rN3BjQaTmHPFbtimlyjzWBPgO9NgleyZmRbEaq18aKHWa7xR+OJFMZ2iLjdlK7mkkBi8awpyOMSR/J55QN8AvSGFE2QtghtTvzTreZOmM+1uOhdRz7Wn1GtSXICMSOsQa4RGkjdgy7jnsVybzpC9tmPfDAS/uSq6rfS2w+/sW9s6dOEKaPJt5td63+08P7f3nb1dc9vmfqNOXuEblJC5evPGvBsuXnvplbOsV1di4/4+3tT9grLkrdceKdj+yyrxcjN65avuP0y9fOPfHqi9o6ai4SQjdecc26DZdcymw8uPTCRyDTYe4+ZkEwTxPUYSaqCn09EzYquGkhuFSlhg7KPqZSfSEtA5gPUb8/RNkjFAAd61NzUuZiTgorCiUJKRR+0UfZB/RuEIt7oTbaloQ61ymF1bKA29hONFMCzNSSiGs5KjfJGKc/NeGqqy9Vzr9m14L165TFa1DjLl/W1DDu9o099/obG/38gs5wjwuf9Dy6GiArTohBsY//Ii0zrKP5TKvaZeYCTtMjp1HHwkvTU0YmFUZeSznleaOWoVJLl0aIcWzdUkWaqgU6imN1aak2yVhS3/F5SEkVP/XQBpJ6WLmjY2RjR0fjyI5GvxD1Nx7Z7m/Uvc9e6YCI4mVlJtkE50abdzVYCzxrkJ21glp6gMFOa/N5HY0TdQTFmiphbHpDw05YGg1IIlUBLBYNFrQpTji6M02J4kQ3Xgfho2zBQMwTpEDYAQg0g8asj3IrhYRydmlLwth0MJYZO+42kr3vzvbT/pOeHuB6Z2Xo2luF/QBW40u/chqu1+AiIOecjgMe9HMXsGwPBhc+4EGL3U3jDQROTwlU5MFAWqo6KLsYD7qqaLMHll6raKa9ipKkygssRlPQeh/ND1ShNeHAZZb8KmP1CUyIxlR1pJlcfy6ZuVr5gsxboqybqyhrFyvrkLGOjCEPBhsbfcqnPZ/6gKHIPRuVv6uchfIElhJ8u9uAt6b14SzqC+LBKzReKs9ImDWv1LLm/Tim4aGHyNSH8a2YHaPxOccZ/GC7mrnfaXXPJOaSdd0Ft6+mblSNL0OZQ3JkCyNNlAWCmRLWztDjpOE4aXqcdDMeJ12aeU07aO09AT+ToH22CRwmqk/gY30t/EzCQX0QIEYZSiANsvDdNAqDwQjSXU/9qgSIRhS+qhJlRzVy10haEgJpkXQiaGNradLWR8WffvSTog6w8cZelVDLdEJqzRriMp34RMeU1eGTXpv8+ZXK6bc+FJgyZYJHvE2ZtPn00+etv41J18zUcS1tqUnKf6o6Yl6nqcKqGz1R+/K0M8M9fkAygUiDEz4AHIdQR9J42EExnLc7g8ifiN+Cj+rIEszSdi45AEgJUMwGsIOaD5RiNsCK4zb4GRvFlg2jQZdNG8miTkWgiDgXIo4D1YKIslFEyYJxAJr6oyR9ySXEYj7pyeOYkjz19Pnr16koGNlWVJHzTjuH6kitjx7g7Z/rpv6Q+9t00pefPpr11rsHf4+d9IU119943bU3rV9N3vn0yD/+SxGVv334k397960X91H/LKbMFCQ4j4+LcbdyebvasZk343mqwVHT4YMAcuZjAaEH4v04DQYxdDFgJctNtBpuntBEKQGHBh2ikDpdlEDXgNCwXwqJstlOPWnsqiPYGBvAAECqxjlPWfBp7bGlWMeAoM4bphlTgJGhP7bmfGLiR9x2QuHlN1+5ZIlhp9JBQmeuOHLNutWzlLVVujf8ja01Iw/9x2fKIe/0BqUqzXMi2bX/2Rj1twHud4S3wd+OcNeW+NuUDtgUjIpRqkzLFh2OEtB8cK+7bQV3O5BhMwXW4kyBlVYWrZXAXJgMthY9b5Mo66m/6rQgCUH85DASk3O0FT3v1qzGWq3FplXmer/9+sUXzZ+6TLnk+orzHwbPe92GsZeFqev9xt/A9U4d2leVTlcR/aKpp5GPf7rfbeX/Khb15TagrZu7tERfulShstGW9KJQ5W00cWij8woeKl8Q2OWdVL7A/QL5cpYqUszpODXx4WRbsWw3QGzGEvBZIYRDLQsaxGke9+o4e+q4zKbMw0xUVmfOVi4MensmodplfQb8G3DueuwBov52FAgSpeovGsYeoHIhXAPNawczBauZm8xy2tg6AP62PAKpgewWqW3D0sQeE9iraBJdUA9EpnoEIFpF+wloYOfpH9h5tIQ29jioKe0cNdS5ljRp4uf84I6l30uPyF166uknzbpr/oSE/KOpPxjV2HziFS/ef+Z3z87w+67eUv3qyvQpk9tmBTJNx8+dcOsdYefH6yfvuqolHJt8nuovAtyNuutBM1yociRGSpRAJhZkmFiQQSijER0SheNY+Oo5KJvNbGrKU6y6emiFyYMDBahBzB51oMDiZA1eJlbgduUmQDiBAUUxdI3X5kT3Nd+d8OabY0cdd1rixjELzxHmNdYdODCnZ93ESY6JVdWXLuXvYucOgk57T+iEc1/BIryC3sTVAG8Vg1dCWFWSU4WJnVcA/vII2gkloeg+lfhOLAIXaGG+N4LVW9GdhUdMHmj9LW6MVbXoFUHwkyCJPHT1BbeT7BrlU9O0fRM+F9Y19izsrOY/Zh7gzLo24uaXsLyZjgMYSvLXRE106obIX4t989dk7z3ESQz3kLPnKxtnKNfA2zUGe9bwm8EMeI7cIFzFsfz1J/rn4b3c4Fn05q+Jmr/W9c9fs3y0bBKL2eggyQa196zEbDT56Y73P5zzpwPbyZJlysuz/vLRDOVZ9t4b+O/23Mdfz96fv6DnbvUMwF7Cx3CGvnloXW8emqh5aN0x5qGDfdy9SvjkXElyyucXkd3X7Pnt9WT2BcpXJHehMveat5XrGx1kG9kKhwoqfycOPJyyW2nygO9HTlJkTyPjKz/Eql/BGUPYlTmQHFiqRJXtowk4n5sNWqFdBzvOujGBPWR9ZQneGNJsPOuKB2ZvJ63ETwp3K1/eRRacq2yduHDVibNmpmPVrS3zTmhVtjMsXsTfRTF41mN3zHC+stA37vJtwsX0jK2AxzlwRhe3RtWxFtBLFpq3tWC9kBpSAS08lUXBhMd0pyXTQWx1Ap9Rm9uvZDEOWPyCkyWfsOouYojAW4DTnSLtTbGwWSCWuKnU0tA44pRjeWjsZmvlde+NWeauTvN7e44QV9u1gWza3yikXY6Nh5qPHAi6X1aeYzjep3wqhMGnjnNzOSQwZjZYHICRllHHRhSqD2Ku12vGzpq8l85oeYNsELWGMqgfAxlwNSUiyiKavAoIcWwM8RDLtIxGIwAKFCewPBECn730FdAyLbX73rxh/cb2s05aNu/MpSed1b7x2o3L+YZG3V9I7W3b0itXKHvP2eQSPBsXKfkVK9PbbyV1q1fTs29XphKMbTA3rGa4ZaGim/5TRyzFrLh9iTLVOO2rZ8rAG2cuTYCBLaZlpwqvjg5oRcw0y6OL0Hgvjr13Krx0IkAfATj94M6Y6Ege7Z0d1eyjwRvO1zcRBI62xoLf6PaBWvXQ+v0+gHXJ/HnLANabb7jhzQvO33jNzR+uXEFmLdroEVy3LCAzAM5ttym//4uuUbfqcuXtzd+jZ28jX+r8wiyI5abS+WAuC+8NR0zLgglzzDRy44p7IXCo0QqoCKJSRQIJIupOLzaFGVyUNsz1Z2myLJUKnEUCi+7ccPmYNSfOPS0xZZZrqdixYvaKzTMW1Z40y0q+fPb7x02Y3rx80w23zLxyQtvKG1me7x1lCXmVzoLYAbPUQhfM6vzH4Cs/rGzlh7XPyg/rwJUfdrpxoyQOBg3oegfHW3HM1dK+oF2Yrg5WHD4Vxx/omdaBbK7Tj+cCXBS7gXDei856FTw2HO6SIlnZY8JYHfxbR3R/WjJk5WqB8ng1NUvVNHXHWhiD4PkFWUpSiGQy2E18ApZSQFNjf1AFiK2ZiW0cOcSGI/JOzF5VFzPFMm/S5pS05QtYGacGl+1eAA/eJxrWvfGz2RvXtKYmzffdeUHi9sWzX/tV4cI1H/Gd7/VUdu42VCmHHqupOPJBbFwoZdy3z/rVX/N7qgRPmPLIlQDzC/qZXJLbw3o0MYuBc6m4dUS2GyCwovGwHesVHIkYrbQrjROYZ19Lx82xzVBHk0o6DPbjog5oVVXB3Qh/pypOQ08PTQKEWT8qcFqhkhXOsJYR14nOPB9MYkagCsdoXF6WfjZSxz8YAfpWU9Mdb5PthG0dMLKimiuX1XJ7rIsABCfmidGGiRhaFjqAc+W641//7ZjL10xMfGfxR2HiVQ45pp/B54/sm74l5uVXz96x+Ym99pCi7MwpX256YPbK8WfePmP76o6rr0mfO5rpAfCbBAV4o4a7Q8vp6qm0D6xvFkLhKgJoErM0/+7KFGJxfEHWW7JZHOiSbBnaJRM4iANbHmu/BC/wU98cLwSrUiyjpnmxkcYTwBSKnm9jm2VKTVXWEzN6AHAPNau5GPxfF8tlweS/vP6zL9eSU5Yp//iL8t8W4lO6sXdT6SY+u/LVvytf962abp0d3jj7Yyycfjz7+sRs/iLAwATdFH6F3kbnt3IcTgF66DYcj452W7MndXxLNgBYBqZUnNZudXKrVCSTJc8T2utGjBkzomEc+e5xI/BpxHG63SOOg+ex4xrY53ZO3a8CvpB+NmiNam4M9pdjZ1XBTSto+RGoRRJ67gl8pjmREXXAtqPTlhFW+KTnfgvfSI+muZUMIDWULtbe6L6LgoM1eTjozGahkQUGjQ5cAyLVZQpZlrerzUhZmmZRRyDpNoxMo+jcY3GHErrRGCdkRTnZgtybHg382tImjRALJkdVFJeDSAmnlGSBXE02o8NFDHTqpZUOwdQ4cy18TSKu432IoWqixhKOWAZMtRHRNe9ZMn7fs6TjmT3KT5/fp+x/eurjpHrX4yT6xG7lT48/rvzxsffeeO2y+3XNrtmX33Udsd42w9usu/qBl97jH/gJmbj3aeWFnzyjvPTc06Rj3+PK+489Br/4BInvhOfO138XeXZ5dvdzyqPj1vy87gDVi6u5GcKTwhzOwFnp5FlWcCXUT6vJrFM//PDUE8nJp/75z6eSJyeRxcpaZS1ZrD5wfXcdcP12GOj60DPHtXMf96VoO3pxuWwhzogahS/zNfj9TNYSBZEaMQpEKgPGOJUpjG7Cl5DMN+j60HZCP9q2AOXSbFJqdCafbinm2lporq0FWSNKc21A2EKSVSySfSjeARQ/Ls0ormvEaXMchBrZJlU58w0jUrT015QFVdYATCCNprSvp7RvPzbaJ7WuLxcEk8KArq/hOYDYyIwdD86fd2DOqx/Nv1TZtfDm41ecNfeyCcOywK8bLltx0sUh5VUxRb6jvC+mUiIvKdKMhWeeALTcoTuHz2n1cq5/vVxXrJfLOo6OAVP95Mp6yI5/O6A8oDsnRhxJbQ/DFmUm74DIwg3eFSa76WIID5jVg7IdonAayghOUZ3w1gb161qzxaH8Ld6Z3nGjT5neMNd51tLNF8xsVzqN5rGNze2G+2eb551w9oVe5N/ZwL+bNf5tdQlZAo4v+zQbufZkRSYnABeTWUp+BtlANig7Jik7ig+s51SZJyTAX8E5x//g8gHUNFE2MwpRlw3spI0qa5tYnHLUcnJ6Vh4+gQ4ZdYmGsC1V8LEpR19am3c0FD15ZK8BI4+8Q9JpI4/wRZfA61wpyexg4495+LLM1KOgM5rY1KP2RKf5wj7gS5sHjK1Br847YscKdmOiF4KBcxR8EL1aP5tAXFmXUR3Yw7jfkIiW1kvmPLz9OAudeLzgxotnJybdfZcyj9RNaclMQ/9qzsO/iFqJTsnjyOPdVzTvVFK6z5unT8uAK4b6nM7SGf4A8u/hqoacpvP2TtP506zltWSazku3WpWZpqPNGmTgTJ3zwL+1Kg+XGawzPINNHUeu4zf3PZ9zmPM5hjzfENN+dVQ+ys38TUSZKTf499+qGGnne5/2GQeHPJ+/93xaYF5yPj/NZpXDnwsRmNSXGUuc9PsDb49RvlC+0JdBo/5HMSIqn8WeeoqhsnjWPJy1lmvA3RKDnrVOOysE6JjNx7DXR3eI+LCWGU8XnOzFOM0xxh0odCOwu6RQy2x0XUaqpb22hSDzsnGjV62DRQoBsaNCJ5grbXanKcxWhZSgok7EJWiyLwyfo+VQArwf4WkIBPzfBFEQuOOugeiZbC+MOvWE46OpUeYWfJx+fCxa5zWScsja//dULpWZ/Df4WNWYObISMKZT8bWW8l6EG4HZzeG5DzsH6rMFL3PL4hm6ZcXF5obUfuwk+GO4LcXvoo0qtjYadWD6I+ks6MyVJrE/SrhBubeSDOLSlePnPw9088pxNzmnv+un4WJLERebBsWFFKd+dylK6tOsX4RiolDNdHE17WEu+FlchvhIVosAv+AMedFQ+8W8GXNofTARYnIs1wsYpvjbhsdJaZGlHE6+v2bOnDX475QZzaNOnJ7NTi+LEgv7oTVzWqZNzWVxYJzOIRv2QkySAHn6gG1qwRgfhy1D6tCNHI4DWkhoiInLaE0IR8yiRhy+DGnDl6UTlyE6cVmXliIHpWRGG7qMUHsX0WFgF8EQ5RvNXdaXn7vM85EYhoE1UQyHcSbNYoIfqlXxPHAaM0unMelkGuDeFRPdN/MbdwofToxd/LtNxB/p6IgoH+8l/CnHTXQead2mLH7tgXPJ+YDiXc4BM5olCH+E2fyZ6mzxKO5HQ08X47rB6t4h4+bSKUasKqTM4KIe27wxrhyMgx3vMFcKoj+UrKtvwh16Rmx6MbmRHf3Ap12hZD3drWdsAqxxttq2Y51EJuUcqaHHk8lf+vtZQw0s93ynjA9GZ4LBjga5GPfLf9lUcPx/aCoYC5BO8IXykWrKjt9mQphQz2PwOeGeEeCBlB8WZi4I1x9vv/6/Am/VmWNDXSjyT6AOPaIhUHeB6hiVwR36HdQ30nD3PuCuhnv1X4a75P8Qz9X28lxCQ1zeHI2rM8zfCHnUYxscf0de1jy3wXHIfDfqtzE8ruWwCzDL9fyLMImIbM4WqpnjkgLHpWVQzHaFPLwJ1CR8qwyOu1xikw1MjJVa/ib4NBTec7jKtB5DIteg7CrrLepSqyExP4grNAQhjpT1iMqpBF9/n4jnRuNMNegGPSdyp3J5A50I0tNsYp/JZidWj0pnmUU6/a2NMxvMdFYcu1/sJtXR4bQ2d1IyZT0aQ6Y8G7VmKurQaX1GrrFPAj6sgDNVwplOG2LS21lm0ls22DP9Z73pwgpsG7CJbW39pr6ZmlBnv5WLenUCO05RE+C5nPBhO+gCE3hNJ6v7thA/rkzexquzmQ42mlJ5EDOWeWel1smAg5qVNNCoZHO8rJmhkjaFqQkOKnFiyeGcmoix4/WKVH+cCbRfeAXIF+ZVE9h7UZwWxZ5hPJ2DnhQzrrFixjUIp62hk6Ie3NLrsYFAcFZajTPAC1X0hQi4+jipZwMPviCYLQ507eUIqJmC0+sL0qVgfdOyrhIYhHIp2koG0PMavxY585CzFDDt5XZW78mp+0tErpq7UZ0RcAh0BJk+27X9JcF+W2o4YjVYU1KI1RwibJm5g7ZGA5Wwgc5J67nOCC4mLM4UyDoICLTBAtx4EqO76bAOZ/axOmO2ZOdJApNrxb0nuD0wl+/kx5G14BHuVfJKRWfnC1c89o+/KG8qrz1CrlQ28qtn83Ugpj9SnlMeV36sywX5ZE+3ifhJmsRITc+fZ/fOlW6DmNcFMcubw05fS7E01l8wsg3G6M4LgEqqTWM4hy/W0jHzWlq6Th3TnLYbFN0IFhKPcGCtG8OfOAt/hp7hxohohJvNcEdE2Rtr6zvFLQdj8M2aQaa5ywbJ/Ua855cPkMtPfvcLkVFu6Bw46BrsjQthj2eZSfBwuUnwiNod12XifQEa6w4/DM7U4WAj4S+Aahx6LJx/S/Xp/l8+N1OSg52bzEKtOfTJya+LelQ7+/v07NWDnD1a7uyxkrMHjxnnqmId7PhXa0p2eAhK/BkGQ57C0Ih9pANgAMVaiDCRi9TQMDcGEtWQLvjZiw00AmzwmbX5aA1aH5aNmIA10pmtQpx9Fe/FBA5Jx7BaZLK5/XxNX1zIEdzPXzcETsoJ1mD4ubK8hA2Drff7SRrWaRjO1lKc4bbOleWwBoQfmcX1fx5aJdMWd/biRg6Dyg47aJDQAI8NvVjB5Z24+7QLsMIfK38M4nANho7HBnpbwwjt6IFFSOSfX+ov018EPkUAcLFEtddhDRNVgranEzwK2QXAu9gOWDBDOAuD2zldaIjsWOaPint0FhvvRZmQzAAwbY+sAkw8xRnNNlHniWv3CUR9ELF7KRrqjInWWpfbR2oRDdRwtdQh2MKDay/bvZtC3rP9yjW7O1+fyL9ywZ8+fnP1ivc/+n0HgnvJ3a/m4QcA4Au3viqR+T1bhUWblI+O/PEmBPyLLdRu0Vlz0FFVXATnG4acNq/+Z6fNo+q0ed7tD9GE27FMnLP4uszcOXHhaOZgw+fklWJs/X8/jEmqvMvBuAf19qBA/rQYAzMY3wcYY8PCGP9nYUz0whg+ZhhbNSVfBsyPihWGISBVNbugwrqW7ioZVdyxVh5aBLYpWwgxXVXPbgUZDnrclVYNaouljuWUlSb1hsZJRk0sy0b3sWJkMLVWBkH/GKjRBuf8hgHKjGdz+yADbtBl5w4/uR/EyX3Jk+k3vI/zSyXz+yF1fh8wyRbSDz3Dz7i83CQ/eaPI5uXm+TU2x/lrdd+OCzyq9SVxp7NP3JkPqVPYBYebM1tpCKJNh4gQKpncmUyJO01Xj/X3qKvYZifWN+pQ8wMhN60s0Q1qffdQebJsCY8HfGKtej/9wQd5S+dtdAlPZ+eyXTsflM/VYqcu3MPzXDBH5j8q775X6/MWntY/wjVzD6pbyLG/vdig30SnR7XxoWYzmKHm4pmb6cBQwcZaWdRstNuMUwmSGdd50sx0GnvB6WhQfTPwZwinKW1ilyFci7lnKeXM+6LYnoU3CmC7JoukpECb3BTFnT5md5AaKYSaMaxNoM3vpLf5nW5Ea6mtoyu3W7Ee4hHdt+7penZ34zkzm08+a+6c++9u3xRvjPlOzt576hmnnX7t1XPPf7HRL7z/3Au/69ZbayYdd8JFHePvXbZpc8Czf0GodtepV4xt23LeBTd5Hr/7yOHdrD+IzuHr76D50hR3lzqJXzPsJH5Dn0n8kdRvibNJ/HjpJD74cXW9k/iNmKvH3vIQ6DupTixUOgKRGBtV7fJVVUepI9OgjuXXDT+Wz3IuwwznX455mN8MOaGvX0eL2D8smdMvxU0ScHPrt9xSMPIYtxQ0qlsK9gBOammtQnKLgJSGERQp32ZXAeskGXpjwTLUGMOtLeA/7u1D0fCyleaJm7j7VbzUDYuXkX3wwnzdJMNLshQvSQdOlGh4GaUNl1CeSYoQQksjKJYi1QmGpbyvKk715kgVSSOOgXNUKzrcZodpmkmtG5KBdJcVy/clTKThajHgKsON475QcZUbFlfHleAKA6kEC6QSDXSIEScXm4ohVxNtoG4KYXQ1nmI1S7HalcliE3CIITaULmTYU7YU2VmHPKaIbNRydVhlU7sCatOFOtYO0A5UGAOSW0CBbSiiPUHRfpyK9jGYLHOY2V61RAN8HjkcGcr2BgxDkvGD5EGGJtBNfVsGtpWIOsRrjE42mrNv5sZzL6mUGjEspdKllEqmpbHFnHwOHIB2So96Ro9QPadm4etLSVDvQOEvIcEYNDQZ+LFMGpDeLU9AtQmqQa5EQ5MR8w7zCLQuY5zqIpO0SoDGEgIMg/jSFGYR36UZ+fK4X6E5UOM0bDdojtQgeH9e9aKObNIwLmR6+xQY3l+hOhbx/vNvpWVBmcg5CKjHpuUGNO3tQ+ncWrDvGdbTkKEaWNaPyVDcF0ay5gbEd6ZWw3dMLJgjjjRl+pHOMqtjiiw/Nge/M7K27dgV9CCND0Or7MiAFojh9Ldw84B2CKab9E7hZW4ENxowv4/LJzHb2pBF5EuNGbalwp1FzEtjM6XIb/Un3VZQJFm5VcCZOA3jKYbxVCnGU6wdGLg7AN9tpZPDY3DhiIUxNs565J11acrQYt4doY6TzynH4ojoCN6aF8f2ki4uVpdGIrTSixkR6bLNWR7ZPsRrmMQ8TLnQiTsN9a1NZDwB5CdjA3H9+NR5O34s9/wHnz1/3ui7R2V2nPbvZ299ATB/2fVmJ6Cet5FlZ5x1zhl9ET5j1m9/NXv+1avGOivHRBuvvx4QP1lcOOohwLz8w4fvRn97ljJT3ZVDvSzcllOI6bgHdWWnLUHj45Sw5jyoe3Nw93Yt4LC2zwod9BvCFtH5lFDh8UXjCcqntXRhi5EtpwigJk61SR5wJ6KJWuTYihiOxzrbyi0WLF2wU7aLtNzWnf/q3/EwYA2Psn9AmwPwIN1fAz6WBzRAnLuk/wYbcNwLIbbBJlRME9ENNiE6rRnuvfNCNqGT4PXRNSd7BIuryk9zRHpn2WU2oSGX2ahdkIOstHkIHcrCIHttdHehK9nzK9xuUwpfCOC7YLgNPYlBNvTUqBt6EK5wdZwtBO2yO6LsmppvvqeHuYaDbuu5gnqFZVf2kDtLfUEG31a6BzSJm1v7wpcA+KoZfNUIX20RvmoKX1SFr06lXx5ioDaW5aMUDDMKAqSBUBlIq4cmoubiDUbHom/XOggthY2aV8foqVPhtQG8Ma6ea8G+ur4Q1wLEcQYxrnutTkuZLKbB0SEYCYoyV8RAPNPlNaFDEMJ91CzJC7joSusTJjXdm5bTYP5HY/YX95e5BGxbktJs9ynuzUIkxMWhkFBq5xkeSo38QJxcoBn4GSpOgkX7PgA7/0c17T1PIF+815vz5Tkv3VODfe92bo5Wa9fRPEkl1Xc4CeighXYrRODqaD/mgtSBf4NZWx1OZ9ZM6mR1Bd6WZW3rV24Hy+pFmeyiu2jYmrnDD/duomG1Rdydk4AzmdmZSnfn9K6+cAy944Qty6FnwhU5lBDlFuSwRCRbjUOFqWQtTm9TP3/0LfiwEOTHxDnxTKzOjsOSmbyNsOluulOx8iAYPPCEaJHdgf0glQ6twg4frWZ1p6JaZJetFVRORjUXG5JdxcPVa2wfpOfD8zAm74My4eghOFuSzi8ht6/V6uw6elcK3c3lwHnztFRdLLL7WVq0d57Jpi1XsRWXq6jrQixmdWlIl9dlY1JARSCEw9h+ulbFYaXt9QDEwIJ7v3K7QWPbZgpT14CxqMPrSiiwu0+tnd2rtpMLcLXYTUCn1SK0qIUjFria0Zqm/Zy9Y4roNXot7GKXIIdVGLPFiroqJu4VjHq7s6oCv/I6ZZHanpoI23hPrS3l5i6jXXSqYSqa3to6fa61ti7n9SU9Rq+zmpTZOLJy3qjNytt/Xrpqz02k4sX7dur4kg0kN1xOnnv/k0T+xs6F62fUzBp55o4Fl12lbDiaUEZ9+qc3ntz7yi+6djN46U4YiElDXJb7z2PeCiONSBdqWMBZMwIpWFNnRscbox18MU3HltNhjEJbht0f0xUO8BCbqhNiwy2T6aq3ueCn69Re9XShnvk+2IvkykJUaqiormF5kt4NMxVsVYZcMwJw3zjcphlSLhItt35GOVw+/Bx8LY3u0v4FQu0uvzu4Cnqr2ilqddAt9PoFWk2b3t7JPAGDuqtPRE+nEofWfWLBZBUcNgp6wF1ua42WIyuzu+aHqDMfH7DARnc99WCu7t1jU3peb8l5+27WCZfbrKPV4AsmwedHGy4ZRDkQPLYtO8xLGbhr507qnvRfuEN2aopVO+9WOK+Lq+bmq+f1Cb0baLS6u7pyJqCeFyXbjZ5IJduFGEAM2wQnPTmrQXJsJKgMpos5pTLIXqlpXfsAhAuri25GL9I1GBYDDDGukduhwpDUYEiBbqoqTnY46foWJyhYnAGxshfD1JaGK3vr7nFwMGJxTAtVMmGqTBdixZI7qDMsVgAesLs6rm4or49j8d3qrAoLlM/wTncKveysUsdgSrFQPqVTBiNLygtSYCB+bu4jQD3LNSTpVBzZinX2S1UsBYTeCALXQYzM4kKevnV2iEC7Kn3ogeGFQOoNmQB7V4MhDC8m4MVEGh0xVmwXQWkLpkC0957MgRzQJ6vSC3Kpy1UE/37NZAWLAM8o+lpF0PdrPtZ8jcs/K62tTz3aKTwtKGpt/VJ1w5S2YAlr63RDBo0shIOyy1Ksrlst2GXIqus4nUGczO822UUDq65bnbK5krI7W54nVYl7SKVVoBV2XBuAizN9rexOSVprRyTUGdU6u0HdL1s3dd2at96957tzlq1drUzfumjuKWFyT/vV61dPH7fqxuuq5+SvIdynRzqufHLdl4o4di2ffvgsftKcfT2/nvlv7971HbBXdP8N6B7UPBuOcQNO+Ng34KCGEnCdAGZ2cPO+y0+DDcni/IbrcJiqHbAU5zhQs+UX4/B6VlzvC+N1/xoYcctPl0tVwhaMHgOssehYwWN1xwHgERG1cXkAv+6NFTUYt9JOqFuOEcboscMYU+mY91VVtxUpGWGUBGiD4W8EbbHOPgDgWk2TDwqz1jwlqDDbVO30+DFBXbYvaAAWunyCx8Q6hMriA6/9pFf99tNjaLtwZjVBF5U2aDzO0aXFDq+2k78sfw9SaB+AoXkDy+zlcUUml6mx071EIAuYMTnmzUQAYc033kzEOHqo/UQkqDL3YFuKvu6tqdtw1x/dBVrD3c4x6uLdL7iHVo6zTTI+Gj0VV4Em8UZ3ucbcLfN4a0oN7ZOrwSjJT/vo/DTk9HuBnDVsGBHcK3Y5TA3ON9nobjj0RlyovEI4lizFcXFR7yJaf79FtCXL/tQuXmaljDaSNvRZ97fmsTNXXH3VldesnkUXgY+5o8+6v3SVYc9hnfjamy89zfo0Gd1sQDfMjGw+NsphSiiTxdnwkgxJ+CDlWj6TD9O1FGGOrepswGWcakYEm99wsUkDEDqIWRFn3mgy0HrUN+KBwZh6KK7YVJa/B2ORgUyuzfaO4uzgn3q56UNMqrqLY5mAO9FEN1hiU8WAgVNv2XFkXFo1YNS2hl/VU26WW//SypVHVtDxY612qfsTFwR93YC9FLQyEx+2MlNXWpnB2Wk89AjqckVZgSBaWiCI0u4grdybKi33yslombX9dWrtJXns1S5EwzBVxZMBJx8OXULcBNi5p7RuqNHxZaBjmItyW4egY6RIx2Aat1Ljckj1dkYH7pvO0E1IjoMls0/YHVvVe0ujCGydt9togtQn7tUJZlOQtkxIVSjxAxii7DB2VttGxZLBA1gjPMNxyZw5F4sz9PfeeNO9leUG/l8+fvr049ffc//hj9nMP6vhrQE+aeCyWEeifDJyWD5pLuUTCOqjDCnROrqIEkdkE2yqCRhnBLCGJQwKZESfal4Wu/TTRe7pqnGnIbRJMAwm0oWa3pmlBAZ1Dl8d1RDNKgulj52F+iJuGGY6pw8WJw/de7JZxecRZz/eUlYW702u4VYMMcENMmbo7rNSIUlHtwN0Fwu1FwFMq1XQ64e5MOaSA+gkyZY4DhHrvW3DLF2ACAZB97DS0GAD6ySeTq30VU87ftyYyYsvuqLcZPah23PLR8aWNcw42dvRdBnTM8pK4RH1LpBWbu8xVoDBTsijAOp+7TZjjq3dRqrFNodGhp82bL1BnYOKRmrExoYGqnGc8ogcvaF+FGCptjGDL0bEvLsBy++0BpznqmJtx17wHYjGYe4TSfZB6HB13p7f9EUuz+57Vudh1x/bjc/xb3rjc0K98bkguP2haupkf6s7n9XRi6FvfqbBxlDj1LoFpTEHvaNEjavOH+6WkvAgt5RE1FtK9gh2T/8k1je7sISBWPbakigrufWrmmJfkeZfMlqy+dxjpGXym9KytpSW0X+OlmwUZehJ+YuLEynDkLQ4j6LRlMWRlw1H0+ggNMVoEXd99kaLSF01XjTg9Q3flLbF9F858l6owVmWwhpwGo230z6krcdCYyAxZuBdqPvqS6kdonsRujGtdyyEb1B7jLpwi0INIzdbn4AXk1LKD0Px0oGSoWW4Q7srYkii/0G7ZaGX5jNpHH1tCc0DPFss5dINsrY6UUp/OlJjoyM1JaxQo0bFXRV2j8BAp30T31C0S3N85QR8ngb1QBb4r15Q/zfkPPbPyHlWn8x6hMQwcr5yDLEQy5i3DwxFcv1FIAUx5bN+Mn7JPyvjss9flPBApFqV8OC3kHAV2HL0XaVBOIC8+htVsHA3AM71Am2tAFkUb4il07y80A0BAHsm2mRvtO9kLw0P1NurfUy8cU4XAwMfHfi20wRA3uF1URc3ytPJ/GLZS53cLcIgFMd38c7nReQyskR5XPmBEn9SA+TnVzz2ZbfyuvKxermwskcpKJKyS2d4ngF0SDaROBlF/CSOsM04+onepL+d3rE1intyqFu28hGsMFaz1YPsxi26wqB52Eu3kMTgcBSaKrgsNsQ20YbYiDnVxSXq1fmRAXdy0Rs7bAPu5qqGZ1N9U1vbsPdzJXPtfK6lic9pQj74hV38W8efUhtOhFtTmUlbBr2965IJ9hGj6kR/qK66tmHWxJWb/n888413sx3R30b9/y2q919d6v1Trqmhd7NJzixetis5MngLmE1X7CkKYU+Y2s5Zydo5cQ+BO1ZcoBGjCzRitGEihg0T2r2AshAoTS/UoFsPsWFftqCbYXMxj3otWLnr25S/EhdwxKZNg13idknVnB1VjR/MOfxpv4vctN0ro2iu5bf/qo0hWi4m+j+0giWmLqXKmyPVA9euHOMSEMDpEAs/XuVXDbJz5aWVK7X+M92fOA/nB316af9urIjQXQiwbqyAwBKwpm5t5TQ2YQVoG1pQbUOL92kjDIrFC/GwflDlp2ZSa7sKDNl2RfNug7Sdncav6vlssI6z769c2VPAXjONJ5gv+Od/3RaZUvdxCLYo8SePnUPQq3TG/6eXxQyx6egxzckaZC1MY9HT0noXZ9LezHruqhLeiaJXWVviVfbv02zo16eJleMEICfR27I5QhvQtrgC6FXSi7zUYovGQ17xGDo1h2zXU/s1l/b6luV6NnlnqS89Vlmpu4bekdzIffVN+QqH32oNx77uqWk4piok2MJg0OgJh7rQFdfd2LOIzUE5CxsTEtgUaXPRRJbJSdc/pZgekqtqaaarFhdrJerb2M0J1bi61TP8Sij9gCzN4BynXNA/5VWG7fYNyHmdoqws3tvZxN2p1gWjOu7SEpaTRqblOkNfzksP5LxCDcNgTS/zYaGvBpivYBECLpoi9olybCRVZQW7o04dKnPVAX7CNZjsko1R1ll7jDzZD0GDcub3+yawyrLnkSv74afvLrLf/H9nF1l1okbbRdZljsbiajT5TZbgMe98KJOo+eeDqLjntWhjYH/26n+2P1v2VhW7s/3hCOvOLmAnwbdoz9YCkcHs5IkaoBcN1mq/jYHKmrO12Fm/EfgmyjVwO9kNDTR21gLmAt4whbIEmsyf6TJGaPg8ojR8xj7aoLU7H6TsEkQOU+s0XuAcQ9Bt6uWCtBpo07IV9rPtqRQisZo6Rve8KVlLYzGvSPukZGNETaX0D67FPsG1tlEKY87STNoicvoXHx4fnPLC+Ue5v37x2ZynR3WSz9avOnQHDbEvKkmlLSTfGaf8cVdzTnlN+ZnytvJafYhcExg9OqDMrG0hC3WLenNOOnZnLfBIHURt47kTsIIztv+ttdNKbq1twVtrJ44t3lo7Q7u1tl27tbaZKaR2hzxZvbW21T1ZvbX2RHil3YzJVGOgvmEUYmqy2GFhF9eOSKVbxqp31+adI5so9sa2lL+/dqJ6f+20b35/bTFXJ3zri2wXF/v5vvmNtvpHi9vN3ip3ua3Gxy8DHzfhLsZj4mMwF4Ukq6ElRyLDJnELT32x303lb3XLzuhiy1+hgX3V8C15f5TaI1ioFMTISKoHigzv+xYM36fSNhzX396n0jY86+uvVKtt6n0KlPfXAO/nuEncLOyH7ujP+zNLeL8NeX9qh8r7UjaNN5MixkdmEU0j67EnGjB+siYTx2syMZrKRFfD8WbAYT3DYX1aw/3xDvkEgr+K0lIYRV/sGuc+QRWaUwDFx/de9Syf0IALby12XyQ5MgvcQ+dx6WXPHW3lhWWqKiwzv4Ww9Ct9fluJWdmHVOFvLjaGZ1XaHZowUGo0mdkOMjMS9w8fm8ywrnYa/zT2kxK5Dh7rvqVQNOHvx2g+PSL+8zLRJ7k+pETw00qy68PZgQ964wJNFmaqd5fPxFt5S28vn4xB0QwWFA17k/lJQ9xkPhFQMw1QO63cpeaz+l1qDko+w5T8Xks4mRrTTq3DWFGO2Nv+V244L43HvtVt52dp9PnG156Tt/rWCZSZ+o1AryjXzHWW4XepOV3e3cmUMjpWb5squlkmleZQpVhGavqWbI87UZoS2CktRirLs/2xsPvoPslW43Asn70iPiLemspOXHz18EzfM6Em5/N6YvHakScdN+/8ZAnvv6by/qm4ezLT3w4Mxe+zh+N3wPC0iYjhaTMBw5Mz5bn/tEG5P59M4Y4o4Pw9oPXHWNqZk/S/wf4Q8YErz/8TInD24qs1in1zIfgj0KyEhL17Qzer8eLzaqeMi3XKOD30xk29utMK4sO8ke60KpiraJhoVhtmeHbrgymT99OpJX9QXWnkLw0M/Q5cZ4ut83iNm+gtLj+yZfJeuvzI66b7gmlU6Oe1zSVesStSHcf1hXiZYZSuB62iDVu4th8XIcmCo610FZIYK26WpQv7xZLrRbBm4+/k19Ddsj1/6ezZ1Lmn75LqXKDnb7xdWy+bC/K5nldKrxlheHNDkPiR0ciFuVqs2ATUfatBXXfe6qhCvGH3KvarJYCZtbbVurQUOij72A32Pnpbgg/1Q4huAgvRptUQ3jziY4NAWMKxUNxYbPBjokXb/EUH6HwhusWbzraKYpcpGkuq7ffxGjonFMSO7VBbSU9ruF9Pq1i8WF3DVrF9200yxulPTWATXLsWrF+nLF7jL+5JW9ioLF/W1DCuOLS1oJPObOFN9bcVUcX461Z6d0QdJ6v8FWT8FcA7IzJ5M/KXmJVN8FKlw0VZjk5werLAdEK37KsFlquJUparQZaj+VbUGTFrt2ypgV+IUb6LJeiG6TwfK/KdKSPF6Dpa2ZbMZCibuoFN6eIXP159F6E8Su+VcGQw7cpB7I7Mpd25ISZy2RzbsBVTP6ulDI21YrnY2M4f/rCXr370I5Wz4OueTbmgsHL2+8hP77OPs4/c1ctX/Pt/YLu3kJ/0t3FJ7gfMImHBphq4SXSHECWoSAtVjJviaUmflRMGLGYVWas2LUUPSjUZOYhN0Qb4lWCU2h89MlUQr6eOUisUpVwWxYW/QQe9y5UOyHqKA7Ieh3ZDIE1feILquG4VbpdzRGl1kBZIMVmP/w/OTIg74CPiUv46gJc2bQIm+mDOueW5SOecs4POPsCHLYZRnMDZIcrI69BW69neOGQc5BqpkmHBxKaQDQfZ0jhDcWkcsISBZrMMOnY3rMguCcRaQ8kW6iC/qudZdYv2SytXHhrfb+f40T/Dh3m6P8FZrLhznJ1FR3Ng9DZdk3pHLR7ERg9SCZitpAfBSeO8oVI7BXw0AX7tyG8mvXpjrtB7IDhOCI7zBhs0Xr1y5eHNpVPZeE/8Sv5ckKtK0ECbBt1/LgXTstcAx4mUXYNe1X8NOt7/ZUEj7GINftg47+JZzt0syg7aueVFhvBjl3jegt3zbRJh+fm+W9MHJoO1DepLy2R+GZYH5ntTAKcbfDUzrebs7Dt9Xo2edZJ51sVxW39adhs0LYED6VI8UzKTjrvO+4+lI9gVCLbIfA+jQw7Z8IYjWocRAQF5a3VSzZDb/DRD7oYXK0SvmiHHIrmk6z/NPhAFpU6wOuV+WR9shDUnt5fcfZCiP6q5smwH/rkQt+E+90WD84AnXbCrkVoV1ZxgYoETsDzeywzUXvfZiO/XNuLbPQM34peAoVH15r4VJHU7e2/diNA9Ak6hE2g5c7AtAhXHtEWgEsWmzPYAhtESQaF7SYVx4N+4QU7UW+Blg6E7b6Dj0gYeFwKU3mEAgkIOFnjmnvM0dV16owFKsXqdAa5YQPkw8Tge5vHRlRt2UQoBdxhcbGy9gt1j36qtJdT2b6KrWEylpSZFXFNH3NrJ67bNfnzpdcdpNrbii82+wPPCp3S35os3/XK1/oU+PsjRl5WZ/CL9Vk7kAtxyjg6fy2bAqD2NdjOvo+fUEez0CdJrEwnr6SVlx8D+n96uBrit6kq/+57+LEuW3tO/JUuWZNmxHUe2FMc2xsQB19CQZvlJUygQXEJCBgib0rSwZUtKIYSUFggsUNoAKZtl25R2JFmh5WdKgKbDwLCUoYFt2TaU0mGz7FCWMt2BRK97z7nvT9KTJQ/MeiaxLcm27jnfvffce875PshTYg2D5EOglzx+DKVdMNmpuVkv4/CIHTtAGJeoiBGwNpLJbDSZmzz52yR/752nnOtXB/L61tj13xIOUZ8MPfu8ZCPGur1JehYr0XUswg1oXQAs/ixKYTX6dCnRZzuUbhcGsiopfYhFnSFeDaTo/3YATMi4pilFP330JBGDEnkuBtd7nTlkno/B6cobwCk9gDzzCKxiW6B6PTOoyBOYAb6ak5YSV35jJ9n/PXkFP7VH/lnlLwcP9ekHLC26vIW/Fj7L05UU3f8f3iNPRkflW+vOVjzXJ6+xcNgXNcDdzWFZBwTiIRoVuDx+iAqwV9WKkwjv4pVYgFon/CrQR0CY6QtrDBJhBH0YJ1IYeqN8C5rGx7pX+0ABmWJ6AE+nYYzEOVFrjzJYZnSMqDt/rX36yAi54RKy5svyB+S8zfKO9bJ83aXyjmuO6gai4cCJcfJgdGgoJL9beTdEowBy9y75fRZUfnhajYVYrmuLoun4bWVFabPV57rcaq5LFQUJ1u6GCJqqjbDNW3QDnyk7nYeUtbDkFQMwJ9xiSfL54asOFAEvtrEkVcEiVrOyisncmM8gNMSf/BJxHLn0lFXSiZeqdES2+ElI3mGQEqHj66f/DdttyLtydtWKWbBkwe1NWVdgHVcpV4ouz8RCpCv9+/aR2e/LuxjpipVnlVfWI3odNZ2rli10rnq4bu6fW7d3oTur1uA1M7kEFaUUjBJoMHJSCKNyqDo1+AJqTdxdqhQ7Wp/rZiSxzbxgMmc1f1R+WD9VFa/UT07qG9CUpXOzja69X6r2TWdWc0+0qXtorFEIQbepy0kDyWwxREfvguWLc4lMLycGmx3XifK0pt6rGZXix3v14ejeNFlm1HmEfk2BOntTvxa68irPMbDZlL1Yjoglwy34mJ44yt2sCDGAJ5QAcNlwAXrsnXd3Bxyao6G82B1gfMcd3WLVRCtaDKwCZvOtpuywytXyo4ZKwxpfC3fVFRiijU6nwWjMehv1t4H3mUUvSPrSzkoymeOxKa2rFd/DCQCS4WAND/K8eJxgDY+fNZ9zRSeeRoGPxdIO91u4KRv9L9SO9XQEwIxhjDoAhLdM6id1/0eBLaPVeV32ReBMXvYpwWWsJfd7gQGIBtfBqkkNdUDuYNWk1jwNDViCY8LMzdW1TQYPb6kLRpl7+d9p8ShbX3+KczgA6grGOexDKhCf5lF1z2jmTuBo93Ycgw2DK/p017lrKrWqSZjYlM3pob/qLsPbZfEz+inE7VI4593US/hFgHopgPfNAbF2t6NBfxBrWt0sXHLj1ZsbvBPEY3EQjkD+XMFdpQ0N8b8I79s5UZDEgg/IsQLYLkvX1yKnFLqqDskErIpTYPcffBKdkZdfVBxy/E+PkIfntvLXYQT0l9KGUuUVdMholPxCuf/gs9QXIqhmYdmzB0/Wmv0ltTKXnqnhsKLQeAEmFXIvC94lAiESi1aLdofhPYpj2oWg/yA196FD35cj++ibuox/PTxUmd62YVvlNQg1yHO6ntLvOR+Nvm5tqqdEYNFvQSVpYSUkqKaEppGSzR/C2IJNBIMWkrkGkk+NLoyiR7fr4UWdxNGP9T2dcVoxzoD9LXNaqWv9QkxVTcmpcIHvhMjERudIwSfOOxWKxg71nlcnpbIwUqomZFQCWsKMfWqJziVnSjVl4JbDM8l3kOO/B/KhzbS0erLqLXgz94OcW5K+JggXlFwwyqZdshku4D4cs0E2uhHalY2QA/2e+EQL6KiPeow4ubA27KlFi3nMkJXXCH8QDlPcDKkxQytcaENZtbKxGXTgaD1ATZIAzjQu0QP8TNDF3ARTWSOmigMJ1prjY0cYyxDYqqNvojmQaoxmBqmVxgirEbDMYke2thxFDYlW1pauT2BtietrS2Qxa4tgKKwzwmZTdTFdLWgMxXTqGrOHjhZvt1teY3o/gTWmT8HDvM3ehQ1MsMx092TYMlNKphgT+2IXGq3e0JTp7kPVOI1xYd2m9zYxzath5OLqhFvuesUroK5wHFPucWolz2IGybNIy5JnyUAj+aqb+O1NlLvexB4C5BCzvEnfdwd93xco71tSGcTC9H23Z6FmUn3fHtexgoflHIAyDt63R6PkC4hFhzCBZHGs5SgsmZPFASWFCSvatfz2ynP1FGi3bt1a2azznlVr4qW4T5sqy6XNzNyjmPkgqOJ1dS9CWy5Akguq4z2y95D8Oumj//9HaxJ56mZlqeFDTGleqGZETJsxIvbUMCL+FBkRlS3Ypm7BjcgRYTyCkaqtmnLwARhSUnPHGTC2Kt4+GIDG2qczELIavo9sj1pnuDiN0F/kSlEcjyo2n6IDU8opwnSqW7Bmw36skGGcDsU+4VjZ5YsphA4ln0tdCkoun5pInbfHDOWriQ5UWgJz+N2YTfKj02kwWfayi2BvTXMo8MiUI3oFaw/sMzGsJYOKDeCDcECve0Gt7S1yCbWAw9pAWt6q4AYao1L8OgqUM4nIX2UmMF9ZJ78jPyE/+vJrb6+dzl349mv8PnIuOdteV9JMPkvOplj7L6fl7nb5HYUb0boD9+1+bhjq5/FWsTOPTaJBVfMHkAOEGX2gOJ8rD7QHwZ4DACXWadjl0vT1oH10IAfthWCJNgqsnNLBQbHHWgmtUPw8SDcaT1AR94E7Zq44QE9885wUxqvzPiOhulr4HKxioVeqK6bIMvqAzcrqn9c++9xzGy/+BTmv8odbdudvHczuW/vbL2z8t6efKV+y9YuXWy+/8qov8HPk78/93NwmAOAtt0Ap9HM/Qsr5G2+svP/Goef+PfpS4Yk9hb0/4FQdauu5dI2A2u8euHmFfsxCe77oo1uyE/imcKWIU9QFlK8567FyR1DiqZU6lKoIP0ohQ7rJ41fVkEt+j1pVX+BysBYCfabVzaipOumhhR47E8kexlNecim7UwcgqM0Pqo2SLnDFIhO8kVbz0T5V+WmMHQn40068d+cN5Io98lPyrv95oXLkwaeL8/fe/cSPtil6VweevPnZ3sp/Rkf5NbIFstKWByo/2/nAfTc8b4iH4Zz8MF1jQLvrK4Zzsk/ZuDtYJae6cZc6UKCsw60kHugeLtH9WeJVneMSLxkvKGEbkHggo7UHgkxutEO7yKvbjCdJIN2XsunRfv811xCp7eQXT/YMnpTbnfv+b/VI/8u5C+WrosHKqcYAX/XvUfRvH/dAI//21fo3oft3iebfxML+TSv+hUSix682AqTFg25HpFNtBCi5orEaR/c1cbTWBKB63MTXa9Uw5DLmdHN/k1+xSOTEh+B3TcMaubW7uO0Gbu1YruRTAjXwt8qzXQrhwhoKgr/jSLkdpf6O4qkcCw/ao0ZRa4jso3CX5YCkMQRfTkyAF9wi8gti/6wyOjO3S+qwnq3xvBpTqXTcBvcjjnfTvfIDOq+HuLzGD5BS6/6cNo0UAJmT6GiBYb0cZ2u+m0nxBdvoq4IZh7oXIEOSnYOqfDGybDivUJyM5GBcqQjbFeziPCcGcZFzAgm7iXZECirDbIqImciyhXAEUbbV3e8deejnq9Kb77n53qmNO3bu2Dj17htX/vazq9KZg+d96/6pjdfvvH7jFLkIKff+uu/RQfnY/tVb51atn1qanbzgxrlnjvQmyYqD2TNuv/6MDauGlo2v38H7q/hR+Ffo/F7CLeNuUXi8YRfoxsxRN3jQlD4Aq+ML0VzZzVTf3Ez1LWAUn4r3TgDT/nSbQxDD3Zn+QRR6C0jzduvSIcYIy7hwkUogUEslEFCNA/WYusZbECTesmSZEl2t++Edl30vOzB69dmf/czauz6/Ml388ewPh4dGzrz2mfvO33Rh7jfIffP4P96eeHFr9qyZibWduWWnrV/5rTu6pLdvnHn4q8u7kjMbyTvGGIRh5SjFyooFsTK2CKyMG7EyslzBSi7/SWFFy8O2BJcrNTbO1hGj521XI2ZgjRgBhbck2Kef2qcfa6/6e9uU2k+foMVg3jZWQtsGZUrlIMNMkIUN8TaQw8Eq2CCUcTqYrs0gBQ4vuER7Z7IfgROnB9gOtmr0M1lweqArtsVZnhq5yLQOlZYAtFq1wrImGNLZ/uULFgYSw4+8RvjAuobi51TuIYaf8riiW6NAqDCdLY7oVCSnmSNpOTXJFLXOVANQQaPQ8rgoTbc7KaxSA8vGJk6CvoZiZkpkMjaRERplLRs7aQoetU9DMCoizTvCS2odXmaaNi1B7c1akZsWIXfcVy99w+q3+VdoDLuEm4KaQlivyvnGmkCT2eJSTdyqermC26JxatxxfeVaqaxc8/HefrBYISuCab108VqaWz46CQ+NS0WxB9c1CPMDUtFuRRW9SWrxKaB7nu/PjaKomzMPVGeB6EStYlDThc3M2M3WufNr7dxszTsxXm/g/4e1LzeqrH355Z/c2qeEDC0B8ptqCNEiEIWM3hvK9su36Nq3hK5931zEfplrvF/mDahDCUt9y1w6PMK2zJLdOsQYaj7ejqkSDzUBk0NjHmoCIv6E4a4vI6+xPG2domeFfu4xhYulA2s0Uee3KNowv9aXheuheYubOGiknFeO4mU/A5Ef86JFp5vaz6MqHJc8TrUEq+D0FnogaU7jTChx7KGfnN6ihR7KBf1QDuF2KRBHRkKnWA4nupPQX1q09GBozRXd1I7zgTget4oWaOl2ehKMvURMYpfFoKodDOSExGxKZix7Z6Lx568dASHhfOWiKMnXTkILTyblwy/b249fgRH3vf6XPzpgNu/8dF0bstyAWme72alE1TrDs5WD2o7D9mK4OuVRdE7XOwu8WgjlQF+XbqSlQJtG+t2mCaCh5FlbgJ60+M5uJkbZJZYkPGQWeim+XIwGWOqkdlEUz2BDXUnyWPOsETqlekdF0wXK/7VNK197bXL4pHPTN43PXWypW/fPG+o7cmRdZceqU72rwomrL+PvOr7OdI3PcJzlaaVu79sNcWQAUHxRAArkagCTUM9noS62N4ahnrMU6WQHMwvc8zk9DbGhzao6PBxWp5EJDPgnNd4u0F4+3fqv1Pf93PcUBijoNjdxPMFSRGIB2XCsCsfSA8QDzqPAqyoK2gJaHr4aEEAf0ceqDrDuazoWalOqv9gtToCdv2MiKgVyRYdLpXo1R0Mdz1MNEsjNhnIEExT8S33VhaopP8yFWc3FQirrEToPHExK5eNJy8d1afnoIqTlkwET0fT3+O0NRdKPbN2qc/tb3sSb/5tbY7k35AJapfiP1Ug1AI89cvtH2H1LSyT2dJB1hPV5fnsDgnoPDFD14WHqw16usLAPe7LQNQY3C13I4d4VoePpzmHXTDOn6pwSkBLqpt8l2XfJZg6HRhoQJSnZ/T0tO7y61drE9SRc1bPbEAbkNa2rWtV5uIZioQfq61rBQipbjjKbRVN43QIlc0BkllHBUQjnqvFRDjHLhLLmYJmPu+w0bkvoDB1xQI4n1bLaQZVx6iCztsoyDfQ9RL3ZXGAYskcohnq4YYj4F0JRKltcIqBYfUy5rm4FOxmma5vB0yiMHb5LNMMOXHSDqM+8355iPB4aeIrLltCvEpGFYdRAxtYMUNvqxGsbg2quVrVW1dN4QdHTeLxVPQ2QZQQ2nU6FQqeBmgYwh4PFzAHVhYDqZy/pp7OcqQWjOJCAohpFO0Cssxs7MeuFNYpLQVS4K9SixIbRlHXwe6jOjg0WsO/WS/+qWLT9nmIRcgO7FsQizsKPtx31KtvRQWCIZnkBUSxCxNbaQpUxZB/NUJXRM48N4fRUdc5RqNLcScHtT0uKNOnWt6seXZEmxrpuHvVFOqNd8RTrbyx5vImJiUVq0qhmqEPEWboNFhTjUQxA3Sxvse6lZ5wwN8CVGALKMcZAZbIgLclCqx4W5beyEnWzFqTuZsiACv3uCAQq9hg74ZS6MkvQKmm69BR6UWk+0g1tS0UOOkXt3vBEs+Wopl3JDDK/rupXaoiaj86t46aKylstRHiE4mYJN9/aCtSbLSZtjDeuRfAo21eImTGULcdZKxvQyoVAr8sKjHpxO0hCMH0MFz1HIuuZLwmQi+NxyCrOu5jOEy5EC4Gr3mz1Uk9Hq4xmDrPjb1RZTOBCHGe9y3YdPQMBM8f9XMmLTAWs+xGR5lCQxjRi6BFoIA9NoqAI05NDYg5J6YaUNJ1YCWs+JSi6jrolxyDSeAWyQFkwn8QH+tzHkIYDmLnmBT4MWapiMoqnZvokFJrYFdVITtTTVNAEwpRilINRG2kgERPix8rkBnLVAVK+S56Fk5LcTwbrtWEQXJW7+SuwajQlT6MkwuP8W6S/Tv6I4usSemaE2g6Jzky1Jr/ddqzUjuXL7VAZ5ICzowBXWJwDrrAi2YL9VeWOqmTDyimbsw1T/F46GRmFGSZpvTY6br7dF2RrMPIH2IGHhOA9lROTlARFDETgsKQBkNb4cQn/3kf/e1HiU8KeSjtJbf/zyORstHIAkhIbLLv9r5Cp9ce3BtsJJ99qaADhuTG62K6j6yzUoH5VGY9LOFZy4XigP4D1nQpwN4fnO8EB90ydIA8MFBMgZWjH06IdWvzsWn0vkDxDtaloh0G5/MgNohT5AvEzHVSxTVDaUnFYNhBnYONifGswrjHe8rvxLf5Eln+0coL4Jq7vzGcjcgATsELW59310ciJI1H/YfnJqvpK5qfvUj/Ftd7VBf1UiGXLQaXKPNHYY1AJFuk4BkwDBucBFZvPBhO/nU58bwRiWX6i1ofm3jNg1tSHBbVku9aPhr5H1Y9rUFHzu+Z+DPGMMwM6WU192t3Yp8A30kmH3VnlXtTjhAjB5kI1TjjOM465RfnZGFaZertfq1qv8fjRKs4V5vOj1OfRVudmrKW52WWYm+FFzk3lzsbMtSdeV+9t6lz7c+NdMPPtHqzl3LmIOdrVwJ+RXM00xcJNB/WjP8BoHnhXEJU0JGkx01UZqqkPK6u1esVqH2pFisZ81incAZOcQOGUrJoWWGmeFoBwf5KGM8OTUNA7PEoHuyxXmGyQL5imDw4D619iAMlbyk4xkkKRgYyS1TqFjnccczCQOpD01MFi81q1DVStJdtDevVvi0mEj9436fHUc1kTai6rhVxCYSJLCifVpxPg7m4FtfHgCrDx4DB9ZX+usELPM0xW5eUHxYMsswV2W4HZ1JRYFB0ThqRWeILaOQ/clZhykJSUw6JyWbWsRE0yD88bWImaJbBCJjbVcxAZ7r7GOYhM1nB93Gt+fQzcAaY3yPT/mHaPHHJChW7NjTJUHodgciYg1ZDBL5reI9disT69cJtuHLPEwm4Te+h5hT7uOy3fLWN+oS+LtU4tXClH2um5jUIP9Re5SByl2bDsSb1M7hGLLrxMlvroA0mkEfFMFBwLXizXYqfmXnnEMAtNcgv5GmsQTrJcrNQ2DXIFDohUyryD64DIog0hYO3g7NR7Tugi4jml21IrKpDUcgG9HECpF7GM8gnrC8jFMMuBNINHwLBagJuTMP5qF7sBcWGfKyx0n1barCQXlH0JYJuAp7bctu5KY3f9TRBnclcBY91Ax3op9fsWruDOlu1M3NqOBwA7bKVSFkaPMtisOo+DvSmE75YJWUOBBrWFonoNda9FZxBq5d3Ix+3GkKLIa9VqZiLWkrledb28O33Pa8g9/ByfpacfDo4Ua3g/uee++z7Wc397nxywdPBeeA4oVjosMXJg82btOYfxOYf+HHdYmCV/ta7jvFxh+qsWWzt9jSTaOoSOH1wgWO4/X7B0S+TPEvmVRA5J5HaJzEnU5mTLNomslIhXIkclUpDIDomcZXhFFp+irxt/SSL7ql+UkMh7EnlKInfg6xL4OseGi/Dji/Bx9dWG767Wv+NWDg6KXF6UyIQYyo8Mq2xjwZACoMN77y7Ee0+bGZ06R3h712NDa8e3Bbr86VUrxj+HYy0LM+RP1nPoWKn9MK3Xq026ciGemYGffFCY+cz4Nn+3Lz29YuJzZ+5+jNmpJB8mf+RegZ8N1fyovaT97J3vVv3ogBIXCrPCGNo4SeamP0QrB0IxQeTEVNofuP98v18IJRJGq0+mSU+a+NPknTR5PU1eSpNCmuxPk39Kk5vS5II0mUmTaJq0p8nlx9PkrTT5dZqU02R7mlyaJpP4nCVNPkiTF9LkR/hj9PHl+EuPq7/0F/gj9Kkr0mSd4Tee9Gt8TvtTZ+Jv1N7OC/hj9L1cZ/jJdvy97H3Qv/d1w1sZTJNEmnjShL/4Iv3ji+rH1erHhvpnGz2nICEfzubFfHYQEAGQMEdFpvaBSxSYLJ8+i+zXv66BzAWz1d9SP64XZoRBxE/SBEHW2gfWa7AgEvty+u/q0DWgf3vhLIKN/h35sDCIWEuaoC1T+4D+d+4k+7U/VAvF6r8zAJj+EinxnxeAW4czrsNfum3T5ttu27zpNv5h+Ez/0ZXjN3/7o72PO4Jrf5rjxhrcehi//s1sPj/7qeXLP8X/pP6rC/Ozs/mRM84YqfkM72snt5rPCOs4G1iZRva+9E6y9py33jqH/ORUcql8nXwdm5OG1435hDwJkJ3worVyaTXZSXbKe0+V98LrEn/7b+EPNK4fht+Xp5YbS4/mJY6+0QRBnsmUzZ4MJClGQvQTxsxMwirF9SUu5/nLtyUI98rqey+zzPiHvnLyHfdIZIP8AM+TS+SH/A9+/TM39EZOs/yg/Cu5kiB/PWdUmg2dTdyED8RP7BzMHn3j7JnQuHjOm6+PDz0ov7uSdJwAH8/xEfuN2H+5lK3mrF/CECWxsmAfDRjUnl6C3Wpz/OF+79L7u3bI/7AjcWdO5N/fsoV0fEAc8ubN8v4r5Zdj8h+3Wq755S+/5qys9w4OevlHXF+rPEQ/F7z9lcf40/u9lbPw8bnKJv7+ygPeQWojuPh/RHgE9ogRGrTB1yfW/R+MGzfMeNpjYGRgYGC0esg7O/dTPL/NVwZ5DgYQuPD06SsY/f/oPzcOPnZJIJeDgQkkCgC13g87AHjaY2BkYGC/9TebgYGD4f/R/zc4+BiAIsiA0RoAmVcGQQAAAHjajZMxaBRREIbndje3qSyOxXAch1gc8Vg1lcpxhRJCIkdYRJZDAoqEIJJgIUFCKguREDDYSrBKGVKFVFZaxFTWUSxjaSGWNvH7X97Ksd6JCz//vJ15M2/+Ny/4bjPGFxTYta/hjD2PzFrgXnXXZqsdyypPrY9vAUzzfyl6YY+Iz1jPwxtBx4z/GTgAC2ARXAJrygM2vH+a2B2wrBwej8MtW44f2JOxI0vG+tYFOXY3OgGrrI/O1tTrhU1LC1/cdD7n/xPXd3s28bdYK3Yi3rIAviKb/4vkeaMzu3wfrBnZ6Q/sNc5xmzMarLP24Dv8v+l7SNiTBp3TQ+xJ7DbapNhTvreL2kN8mzPm+BPWDeWjbgDXQJ2cN8Jje1fZtm1xlFun0B6/tF8HgepWE1f3mXSWDb8Fr/l3lzy502sI0EU65k6/AbD3unoGNeUn9lqh3wikJUygrTRKpNUwUFecSbtBoMd5r99n8MtrVmhXxqzXbhB1cE6sHl2tMtOzao9k9XrZeupbdyVNdLZR7OaKu/8Hd6VFwWjaoLdvTmP16lkzq7nxcZPuLpifQQ5v2Zxbv3frVPPj46eGsOpnBXPfuiv1qTtue67pHWgWPfdKa81Hy80pHK64eprnxn+we0ea5b+4lNvP2qY4fGUW13lfnoP7ZpWP4OoZ7ARegZfce5gvwPv8OQ6wD8EB2KeW6vWF4JOtjpt90V58LwXl5awX4mN7GO6Z/QYKROv8AAB42mNgYNCBwiqGDYxTmDyY7jCXME9iPsXCxGLEUsKyguUUyy9WCdY01gVsXGzL2L6xV7F/4dDiWMGpxJnGeYjzGucPLh6uTdxt3Gd4fHgO8IrxLuKT4lvEr8Afxb9JQEggR+CeoJvgDME/QgVCr4TThA+JaIjEiewRFRBNET0g+kaMS8xMLEQsR2yCOJ94kfgJCROJaRJ/JDdJ6Uh1SH2RjpKeJOMis0eWRbZB9pOcn9wpeTX5Dvl9CgwKQQpLFFkUkxRrFG8paQBhkdIb5QYVJhUXlX+qcqo6aixqWmpxag3qOuo16meACnZpOmie0qrSVtDeoxOl80/3lJ6IXoLeOn0F/TkGXgbLDFkM04wYjNqMfhhnGd8xCTJ5Yxpgus8sxOyReZ4Fi8UNyylWQdYc1lNsWGxKbN7YNtieshOxS7K7Zu/nIOCQ4XDAUclxi5OJ0zJnCecuFxaXeS6/XKvcBNyS3L64l3koeUzzdPE84qXltc5bxnuFj5zPAl8e3yo/Kb9p/hL+WwKUAi4F+gUJBC0IdgneExIWqhB6JWxXeFSEUcSNyB1RIVEvomtiOGL8YqbEcsROi30XpxE3Le5HfFuCWEJbwrnEkMRdST5Ju5LNkvuS/6S4pOxIdUq9klaU9iq9Kv1ahkHGjEymzA1ZTlmnso2yD+Xo5ezKdcm9kpeSL5R/qCCo4EFhXRFLUU0xW3FF8YuSulKu0jVlAWWXyoPK31W0VcpVtlV+qsqqelMdUX2mpqJWqXZVnUFdTN2yegYckK9epl6r3qLerX5P/a36Hw13GgUaXRqjGicA4ZLGHY07mpiavJrCABnq3TkAAQAAATsAUgAFAAAAAAACAAEAAgAWAAABAAFgAAAAAHjapVVNTxNRFL2FUgWVFTGGuBhdKbEFSkiMcWMADQaIESKJcTPt9EumM7Uz0NSFaxf+BuPKX8HCJerexMSla5fGpeeed1umILowkzc9792vcz/eVERm5KeMSy4/KSIplsM5mcLO4TGZlleGx2VB3hjOy6wcGp6QK/LFcAG2Pwyfk/fyy/B5mcu9NTwpV3NHhqfGDnPfDV+Qu/l3hi/K6/w3w5fk2URgeFp2Jj4YPpLLhRnDH2WhMGf4k0jhqeHPMjXAX8dlthDIqrSkgZVivZSaBOJh+dj7QFWJpSN96VKriVNPbuD0Jn7LyH8Rq2iojLMH0I+hGcKTJyvAXdjr22eEWCIpyQ5QBJzIY+g1ZB/6PnQ2KY+h2YeVeliXNiQN6jewL2IdWx8j74SnJ9h1ce4iemBXAr+lM2xbfGu+KZkGsG7Tzx7OYqmfymwdtlX4VKuINVP9Pn4rlHfJRv2mZOLq2iKXKk+0vm7/HKy71A3wrg7rlMD/vysyYLLNSAfU2WS1dZ/QPptrD7KEPa6xPg1IHLsK+f/Nj2e2PrH6VK8H1lu1uWW51/lOMDEDngmzbrGW2dha8yY9DPrQhjSlbhXnIZ6+TWIbNXCxKtaHHie3aVPRpl9PtvDb40zErFZ07Tp7la2DdrVuU+LRtgMcM4uA8gjTliCuZlIjU0U+b0cFFiFjO25NTovP7tWsmykzSDIzokyVdYcnRVlj52N21tV0F3O28UeProJpxpv2JCTfJOM7IttgmKOrtmqFFsllHHKe94b9qfOWuooG9FY8o+Z11ia1qDEZBXhcx91sxbDdZz8icnbfgPRU5XzWNza7Dm9valzavAFNTmBH7sg8nh6fEmSj96I1citKxvx/bOflEZkFyKPKbLdZuwN2VTOdxzw5D6sjd6kLzSYse5xf7dqG2UTcae/22UPX10Hn7rHSVduN2ui9OvlNK4Prwhk5+hlfJVazAWk44lMz2MD3YwVzuAXOa/ySq89dSCvDPruvpztV7g9tVss4V9ltxC7LMt5L0Br8LywzquN6f+hpW14g9xYkOi3hbzqdRMN42m3SV2xbVRzH8e+vda5bu+nee+8RO4mTdLuJs5ombVJ3pPPGubHdOnZxfEtbRkECIabghWfGEyD2kkCCFxB7if0AD0wxn9nF8T2qXcSV7vmcc6T///zPYAyl79ISBvmfT1uK/xiNZSw+qrDwM47xBAgygWomMonJTGEq05jODGYyi9nMYS7zmM8CFrKIxSxhKctYzgpWsorVrGEt61jPBjayiRpChKmljnoiNNBIE5vZwla2sZ0d7CTKLpppIUYrbbTTQSe76WIP3fSwl3300sd+4hzgIIc4TD9HOMoxjnOCk9jy8SA3cTP3che385CquI07+ZKHeYBHeYPXeIwBEtxdPIW3cHidN3mPt3mHd/mBIT7kfT7gcZLcwyd8xMek+IlfuJVTpDnNMBmy3EeOqzhDnhFcCpzlan7kHBc4zzVcx7Xcz0Wu5wZu5Gd+5QVZ8mucxiugIH/zjyaoWhM1iUtCkzVFUyVN03TN0EzN0mzN0VzN03x+43ct0EIt0mIt0VIt03Kt0Eqt0mr+4FOt0Vqt03pt0EZtUo1CCqtWdXzF16pXRA1qVJM2a4u2apu28wRPaod2KqpdalaLYmrlT/7iG75Vm9rVoU7tVpf2qFs92qt96lWf9vOi4jqggzrEd3yvw+rXER3lM77gcx3TcZ3QSdkaUEKDcjSkpFJK6xRP8TTP8Tyv8AzP8iq38IhO8xIvK6Nh7lDWSmbOn0mF/G42XVNT0+IZrTG2+KPDdiKfy/ptTys6kHfOOpZdwh/NJXNZ57Tf9gw2J9L5hDs8lHHOBRPlfqB5MFewEwknWwgkLnetloQ9mnLQo6WY3y74Y2ZBxzMQK4c6l7v+mFnY8bRiXg6nRLCtooxkRRlt5VzJcq7RrYbCYWNtsL0iOlXu+9oH7LwvVWz8HabGtLHDVJM2x9BZkeFUue+tUBsxNlhddsItOFamhJndZWy2urw9ZUr4uooF+zLFxur2orIVUXX1xojV7UVlS/h7TIU5z+qelJtN2nl3OGO7hepc5cjq9fLmPXq9PHmPPm9ypESwr2J/I//dX8ScZKTW2u8FF7xa4qYW1zyluPeU3BJV8Xw6m6xyR9vq+BVVupUjf9yctWtuvt+r7EKJQH/5hi9cecPhUKOxyRg1lk48XHz9xpAxbKw11hnrjRFjg7HR2GSMeoZM3lAoMJROunln0B5JeVPhVs/6Vl/MzedKg/rW5n8BNmipUQAAAHja28H4v3UDYy+D9waOgIiNjIx9kRvd2LQjFDcIRHpvEAkCMhoiZTewacdEMGxgVnDdwKztsoFVwXUTswOTNpjDAuSwqkM5bCCZ/VAOO5DDVgTlcAA57NYQDuMGTqhJXEBRTmEm7Y3MbmVALreC6y4Gzvr/DHARHqAC7gA4lxfI5dGGc/mAXF45GDdyg4g2ABjbO40AAVTANWoAAA==) format('woff'); + font-weight: normal; + font-style: normal; + +} + + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: + local('Roboto Light'), + url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'), + url('../font/Roboto-Light.woff') format('woff'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: bold; + src: + local('Roboto Medium'), + url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'), + url(../font/Roboto-Medium.woff) format('woff'); +} + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/github.css ---- */ + + +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + -webkit-text-size-adjust: none; +} + +.hljs-comment, +.diff .hljs-header, +.hljs-javadoc { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #008080; +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-phpdoc, +.hljs-dartdoc, +.tex .hljs-formula { + color: #d14; +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #900; + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rules .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body { + color: #008080; +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/icons.css ---- */ + + +.icon { display: inline-block; vertical-align: text-bottom; background-repeat: no-repeat; } +.icon-profile { font-size: 6px; top: 0em; -webkit-border-radius: 0.7em 0.7em 0 0; -moz-border-radius: 0.7em 0.7em 0 0; -o-border-radius: 0.7em 0.7em 0 0; -ms-border-radius: 0.7em 0.7em 0 0; border-radius: 0.7em 0.7em 0 0 ; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px } +.icon-profile:before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; -webkit-border-radius: 50%; -moz-border-radius: 50%; -o-border-radius: 50%; -ms-border-radius: 50%; border-radius: 50% ; background: #FFFFFF; } + +.icon-comment { width: 16px; height: 10px; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; background: #B10DC9; margin-top: 0px; display: inline-block; position: relative; top: -2px; } +.icon-comment:after { left: 9px; border: 2px solid transparent; border-top-color: #B10DC9; border-left-color: #B10DC9; background: transparent; content: ""; display: block; margin-top: 10px; width: 0px; margin-left: 7px; } + +.icon-edit { + width: 16px; height: 16px; background-repeat: no-repeat; background-position: 20px center; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAOVBMVEUAAAC9w8e9w8e9w8e9w8e/xMi9w8e9w8e+w8e9w8e9w8e9w8e9w8e9w8e9w8e+w8e/xMi9w8e9w8fvY4+KAAAAEnRSTlMASPv3WQbwOTCkt4/psX4YDMWr+RRCAAAAUUlEQVQY06XLORKAMAxDUTs7kA3d/7AYGju0UfffjIgoHkxm0vB5bZyxKHx9eX0FJw0Y4bcXKQ4/CTtS5yqp5GFFOjGpVGl00k1pNDIb3Nv9AHC7BOZC4ZjvAAAAAElFTkSuQmCC+d0ckOwyAMRVGHUOO0gUyd+P8f7WApz4Iki9wFmyOEATrXLZcFp5LrGogPOxKp6zfFf9fZ1/I/cY7YZSS3U6S3XFZJmGBwL+FuJX/F1K0wUUlZyZGlXgXESthTEs4B8fh7xoVUDPGYJnsfkCRarKAgz8cAKbpD6pqDPz3XB8K6HdUEeN9NAAAAAElFTkSuQmCC); +} +.icon-reply { + width: 16px; height: 16px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAABmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYs5FxxAAAAC3RSTlMAgBFwYExAMHgoCDJmUTYAAAA3SURBVAjXY8APGGEMQZgAjCEoKBwEEQCCAoiIh6AQVM1kMaguJhGYOSJQjexiUMbiAChDCclCAOHqBBdHpwQTAAAAAElFTkSuQmCC); +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/data.json new file mode 100644 index 00000000..41392501 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/data.json @@ -0,0 +1,10 @@ +{ + "title": "MyZeroBlog", + "description": "My ZeroBlog.", + "links": "- [Source code](https://github.com/HelloZeroNet)", + "next_post_id": 1, + "demo": false, + "modified": 1432515193, + "post": [ + ] +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/users/content-default.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/users/content-default.json new file mode 100644 index 00000000..06bfc9cd --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data-default/users/content-default.json @@ -0,0 +1,25 @@ +{ + "files": {}, + "ignore": ".*", + "modified": 1432466966.003, + "signs": { + "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8": "HChU28lG4MCnAiui6wDAaVCD4QUrgSy4zZ67+MMHidcUJRkLGnO3j4Eb1N0AWQ86nhSBwoOQf08Rha7gRyTDlAk=" + }, + "user_contents": { + "cert_signers": { + "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ] + }, + "permission_rules": { + ".*": { + "files_allowed": "data.json", + "max_size": 10000 + }, + "bitid/.*@zeroid.bit": { "max_size": 40000 }, + "bitmsg/.*@zeroid.bit": { "max_size": 15000 } + }, + "permissions": { + "banexample@zeroid.bit": false, + "nofish@zeroid.bit": { "max_size": 20000 } + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/data.json new file mode 100644 index 00000000..af289e8f --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/data.json @@ -0,0 +1,244 @@ +{ + "title": "ZeroBlog", + "description": "Demo for decentralized, self publishing blogging platform.", + "links": "- [Source code](https://github.com/HelloZeroNet)\n- [Create new blog](?Post:3:How+to+have+a+blog+like+this)", + "next_post_id": 42, + "demo": false, + "modified": 1433033806, + "post": [ + { + "post_id": 41, + "title": "Changelog: May 31, 2015", + "date_published": 1433033779.604, + "body": " - rev194\n - Ugly OpenSSL memory leak fix\n - Added Docker and Vargant files (thanks to n3r0-ch)\n\nZeroBlog\n - Comment editing, Deleting, Replying added\n\nNew official site: http://zeronet.io/" + }, + { + "post_id": 40, + "title": "Trusted authorization providers", + "date_published": 1432549828.319, + "body": "What is it good for?\n\n - It allows you to have multi-user sites without need of a bot that listen to new user registration requests.\n - You can use the same username across sites\n - The site owner can give you (or revoke) permissions based on your ZeroID username\n\nHow does it works?\n\n - You visit an authorization provider site (eg zeroid.bit)\n - You enter the username you want to register and sent the request to the authorization provider site owner (zeroid supports bitmessage and simple http request).\n - The authorization provider process your request and it he finds everything all right (unique username, other anti-spam methods) he sends you a certificate for the username registration.\n - If a site trust your authorization provider you can post your own content (comments, topics, upvotes, etc.) using this certificate without ever contacting the site owner.\n\nWhat sites currently supports ZeroID?\n\n - You can post comments to ZeroBlog using your ZeroID\n - Later, if everyone is updated to 0.3.0 a new ZeroTalk is also planned that supports ZeroID certificates\n\nWhy is it necessary?\n\n - To have some kind of control over the users of your site. (eg. remove misbehaving users)\n\nOther info\n\n - ZeroID is a standard site, anyone can clone it and have his/her own one\n - You can stop seeding ZeroID site after you got your cert" + }, + { + "post_id": 39, + "title": "Changelog: May 25, 2015", + "date_published": 1432511642.167, + "body": "- Version 0.3.0, rev187\n- Trusted authorization provider support: Easier multi-user sites by allowing site owners to define tusted third-party user certificate signers. (more info about it in the next days)\n- `--publish` option to siteSign to publish automatically after the new files signed.\n- `cryptSign` command line command to sign message using private key.\n- New, more stable OpenSSL layer that also works on OSX.\n- New json table format support.\n- DbCursor SELECT parameters bugfix.\n- Faster multi-threaded peer discovery from trackers.\n- New http trackers added.\n- Wait for dbschema.json file to execute query.\n- Handle json import errors.\n- More compact json writeJson storage command output.\n- Workaround to make non target=_top links work.\n- Cleaner UiWebsocket command router.\n- Notify other local users on local file changes.\n- Option to wait file download before execute query.\n- fileRules, certAdd, certSelect, certSet websocket API commands.\n- Allow more file errors on big sites.\n- On stucked downloads skip worker's current file instead of stopping it.\n- NoParallel parameter bugfix.\n- RateLimit interval bugfix.\n- Updater skips non-writeable files.\n- Try to close OpenSSL dll before update.\n\nZeroBlog:\n- Rewritten to use SQL database\n- Commenting on posts (**Please note: The comment publishing and distribution can be slow until most of the clients is not updated to version 0.3.0**)\n\n![comments](data/img/zeroblog-comments.png)\n\nZeroID\n- Sample Trusted authorization provider site with Bitmessage registration support\n\n![comments](data/img/zeroid.png)" + }, + { + "post_id": 38, + "title": "Status report: Trusted authorization providers", + "date_published": 1431286381.226, + "body": "Currently working on a new feature that allows to create multi-user sites more easily. For example it will allows us to have comments on ZeroBlog (without contacting the site owner).\n\nCurrent status:\n\n - Sign/verification process: 90%\n - Sample trusted authorization provider site: 70%\n - ZeroBlog modifications: 30%\n - Authorization UI enhacements: 10%\n - Total progress: 60%\n \nEta.: 1-2weeks\n\n### Update: May 18, 2015:\n\nThings left:\n - More ZeroBlog modifications on commenting interface\n - Bitmessage support in Sample trusted authorization provider site\n - Test everything on multiple platform/browser and machine\n - Total progress: 80%\n\nIf no major flaw discovered it should be out this week." + }, + { + "post_id": 37, + "title": "Changelog: May 3, 2015", + "date_published": 1430652299.794, + "body": " - rev134\n - Removed ZeroMQ dependencies and support (if you are on pre 0.2.0 version please, upgrade)\n - Save CPU and memory on file requests by streaming content directly to socket without loading to memory and encoding with msgpack.\n - Sites updates without re-download all content.json by querying the modified files from peers.\n - Fix urllib memory leak\n - SiteManager testsuite\n - Fix UiServer security testsuite\n - Announce to tracker on site resume\n\nZeroBoard:\n\n - Only last 100 messages loaded by default\n - Typo fix" + }, + { + "post_id": 36, + "title": "Changelog: Apr 29, 2015", + "date_published": 1430388168.315, + "body": " - rev126\n - You can install the \"127.0.0.1:43110-less\" extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/zeronet-protocol/cpkpdcdljfbnepgfejplkhdnopniieop). (thanks to g0ld3nrati0!)\n - You can disable the use of openssl using `--use_openssl False`\n - OpenSSL disabled on OSX because of possible segfault. You can enable it again using `zeronet.py --use_openssl True`,
please [give your feedback](https://github.com/HelloZeroNet/ZeroNet/issues/94)!\n - Update on non existent file bugfix\n - Save 20% memory using Python slots\n\n![Memory save](data/img/slots_memory.png)" + }, + { + "post_id": 35, + "title": "Changelog: Apr 27, 2015", + "date_published": 1430180561.716, + "body": " - Revision 122\n - 40x faster signature verification by using OpenSSL if available\n - Added OpenSSL benchmark: beat my CPU at http://127.0.0.1:43110/Benchmark :)\n - Fixed UiServer socket memory leak" + }, + { + "post_id": 34, + "title": "Slides about ZeroNet", + "date_published": 1430081791.43, + "body": "Topics:\n - ZeroNet cryptography\n - How site downloading works\n - Site updates\n - Multi-user sites\n - Current status of the project / Future plans\n\n\n\n[Any feedback is welcome!](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:18@2/Presentation+about+how+ZeroNet+works) \n\nThanks! :)" + }, + { + "post_id": 33, + "title": "Changelog: Apr 24, 2014", + "date_published": 1429873756.187, + "body": " - Revision 120\n - Batched publishing to avoid update flood: Only send one update in every 7 seconds\n - Protection against update flood by adding update queue: Only allows 1 update in every 10 second for the same file\n - Fix stucked notification icon\n - Fix websocket error when writing to not-owned sites" + }, + { + "post_id": 32, + "title": "Changelog: Apr 20, 2014", + "date_published": 1429572874, + "body": " - Revision 115\n - For faster pageload times allow browser cache on css/js/font files\n - Support for experimental chrome extension that allows to browse zeronet sites using `http://talk.zeronetwork.bit` and/or `http://zero/1Name2NXVi1RDPDgf5617UoW7xA6YrhM9F`\n - Allow to browse memory content in /Stats\n - Peers uses Site's logger to save some memory\n - Give not-that-good peers on initial PEX if required\n - Allows more than one `--ui_restrict` ip address\n - Disable ssl monkey patching to avoid ssl error in Debian Jessie\n - Fixed websocket error when writing not-allowed files\n - Fixed bigsite file not found error\n - Fixed loading screen stays on screen even after index.html loaded\n\nZeroHello:\n\n - Site links converted to 127.0.0.1:43110 -less if using chrome extension\n\n![direct domains](data/img/direct_domains.png)" + }, + { + "post_id": 31, + "title": "Changelog: Apr 17, 2014", + "date_published": 1429319617.201, + "body": " - Revision 101\n - Revision numbering between version\n - Allow passive publishing\n - Start Zeronet when Windows starts option to system tray icon\n - Add peer ping time to publish timeout\n - Passive connected peers always get the updates\n - Pex count bugfix\n - Changed the topright button hamburger utf8 character to more supported one and removed click anim\n - Passive peers only need 3 connection\n - Passive connection store on tracker bugfix\n - Not exits file bugfix\n - You can compare your computer speed (bitcoin crypto, sha512, sqlite access) to mine: http://127.0.0.1:43110/Benchmark :)\n\nZeroTalk:\n\n - Only quote the last message\n - Message height bugfix\n\nZeroHello:\n\n - Changed the burger icon to more supported one\n - Added revision display" + }, + { + "post_id": 30, + "title": "Changelog: Apr 16, 2015", + "date_published": 1429135541.581, + "body": "Apr 15:\n\n - Version 0.2.9\n - To get rid of dead ips only send peers over pex that messaged within 2 hour\n - Only ask peers from 2 sources using pex every 20 min\n - Fixed mysterious notification icon disappearings\n - Mark peers as bad if publish is timed out (5s+)" + }, + { + "post_id": 29, + "title": "Changelog: Apr 15, 2015", + "date_published": 1429060414.445, + "body": " - Sexy system tray icon with statistics instead of ugly console. (sorry, Windows only yet)\n - Total sent/received bytes stats\n - Faster connections and publishing by don't send passive peers using PEX and don't store them on trackers\n\n![Tray icon](data/img/trayicon.png)" + }, + { + "post_id": 28, + "title": "Changelog: Apr 14, 2015", + "date_published": 1428973199.042, + "body": " - Experimental socks proxy support (Tested using Tor)\n - Tracker-less peer exchange between peers\n - Http bittorrent tracker support\n - Option to disable udp connections (udp tracker)\n - Other stability/security fixes\n\nTo use ZeroNet over Tor network start it with `zeronet.py --proxy 127.0.0.1:9050 --disable_udp`\n\nIt's still an experimental feature, there is lot work/fine tuning needed to make it work better and more secure (eg. by supporting hidden service peer addresses to allow connection between Tor clients). \nIn this mode you can only access to sites where there is at least one peer with peer exchange support. (client updated to latest commit)\n\nIf no more bug found i'm going to tag it as 0.2.9 in the next days." + }, + { + "post_id": 27, + "title": "Changelog: Apr 9, 2015", + "date_published": 1428626164.266, + "body": " - Packaged windows dependencies for windows to make it easier to install: [ZeroBundle](https://github.com/HelloZeroNet/ZeroBundle)\n - ZeroName site downloaded at startup, so first .bit domain access is faster.\n - Fixed updater bug. (argh)" + }, + { + "post_id": 26, + "title": "Changelog: Apr 7, 2015", + "date_published": 1428454413.286, + "body": " - Fix for big sites confirmation display\n - Total objects in memory stat\n - Memory optimizations\n - Retry bad files in every 20min\n - Load files to db when executing external siteSign command\n - Fix for endless reconnect bug\n \nZeroTalk:\n \n - Added experimental P2P new bot\n - Bumped size limit to 20k for every user :)\n - Reply button\n\nExperimenting/researching possibilities of i2p/tor support (probably using DHT)\n\nAny help/suggestion/idea greatly welcomed: [github issue](https://github.com/HelloZeroNet/ZeroNet/issues/60)" + }, + { + "post_id": 25, + "title": "Changelog: Apr 2, 2015", + "date_published": 1428022346.555, + "body": " - Better passive mode by making sure to keep 5 active connections\n - Site connection and msgpack unpacker stats\n - No more sha1 hash added to content.json (it was only for backward compatibility with old clients)\n - Keep connection logger object to prevent some exception\n - Retry upnp port opening 3 times\n - Publish received content updates to more peers to make sure the better distribution\n\nZeroTalk: \n\n - Changed edit icon to more clear pencil\n - Single line breaks also breaks the line" + }, + { + "post_id": 24, + "title": "Changelog: Mar 29, 2015", + "date_published": 1427758356.109, + "body": " - Version 0.2.8\n - Namecoin (.bit) domain support!\n - Possible to disable backward compatibility with old version to save some memory\n - Faster content publishing (commenting, posting etc.)\n - Display error on internal server errors\n - Better progress bar\n - Crash and bugfixes\n - Removed coppersurfer tracker (its down atm), added eddie4\n - Sorry, the auto updater broken for this version: please overwrite your current `update.py` file with the [latest one from github](https://raw.githubusercontent.com/HelloZeroNet/ZeroNet/master/update.py), run it and restart ZeroNet.\n - Fixed updater\n\n![domain](data/img/domain.png)\n\nZeroName\n\n - New site for resolving namecoin domains and display registered ones\n\n![ZeroName](data/img/zeroname.png)\nZeroHello\n\n - Automatically links to site's domain names if its specificed in content.json `domain` field\n\n" + }, + { + "post_id": 22, + "title": "Changelog: Mar 23, 2015", + "date_published": 1427159576.994, + "body": " - Version 0.2.7\n - Plugin system: Allows extend ZeroNet without modify the core source\n - Comes with 3 plugin:\n - Multiuser: User login/logout based on BIP32 master seed, generate new master seed on visit (disabled by default to enable it just remove the disabled- from the directory name)\n - Stats: /Stats url moved to separate plugin for demonstration reasons\n - DonationMessage: Puts a little donation link to the bottom of every page (disabled by default)\n - Reworked module import system\n - Lazy user auth_address generatation\n - Allow to send prompt dialog to user from server-side\n - Update script remembers plugins enabled/disabled status\n - Multiline notifications\n - Cookie parser\n\nZeroHello in multiuser mode:\n\n - Logout button\n - Identicon generated based on logined user xpub address\n\n![Multiuser](data/img/multiuser.png)" + }, + { + "post_id": 21, + "title": "Changelog: Mar 19, 2015", + "date_published": 1426818095.915, + "body": " - Version 0.2.6\n - SQL database support that allows easier site development and faster page load times\n - Updated [ZeroFrame API Reference](http://zeronet.readthedocs.org/en/latest/site_development/zeroframe_api_reference/)\n - Added description of new [dbschema.json](http://zeronet.readthedocs.org/en/latest/site_development/dbschema_json/) file\n - SiteStorage class for file operations\n - Incoming connection firstchar errorfix\n - dbRebuild and dbQuery commandline actions\n - [Goals donation page](http://zeronet.readthedocs.org/en/latest/zeronet_development/donate/)\n\nZeroTalk\n\n - Rewritten to use SQL queries (falls back nicely to use json files on older version)" + }, + { + "post_id": 20, + "title": "Changelog: Mar 14, 2015", + "date_published": 1426386779.836, + "body": "\n - Save significant amount of memory by remove unused msgpack unpackers\n - Log unhandled exceptions\n - Connection checker error bugfix\n - Working on database support, you can follow the progress on [reddit](http://www.reddit.com/r/zeronet/comments/2yq7e8/a_json_caching_layer_for_quicker_development_and/)\n\n![memory usage](data/img/memory.png)" + }, + { + "post_id": 19, + "title": "Changelog: Mar 10, 2015", + "date_published": 1426041044.008, + "body": " - Fixed ZeroBoard and ZeroTalk registration: It was down last days, sorry, I haven't tested it after recent modifications, but I promise I will from now :)\n - Working hard on documentations, after trying some possibilities, I chosen readthedocs.org: http://zeronet.readthedocs.org\n - The API reference is now up-to-date, documented demo sites working method and also updated other parts\n\n[Please, tell me what you want to see in the docs, Thanks!](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topic:14@2/New+ZeroNet+documentation)" + }, + { + "post_id": 18, + "title": "Changelog: Mar 8, 2015", + "date_published": 1425865493.306, + "body": " - [Better uPnp Puncher](https://github.com/HelloZeroNet/ZeroNet/blob/master/src/util/UpnpPunch.py), if you have problems with port opening please try this.\n\nZeroTalk: \n - Comment upvoting\n - Topic groups, if you know any other article about ZeroNet please, post [here](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topics:8@2/Articles+about+ZeroNet)" + }, + { + "post_id": 17, + "title": "Changelog: Mar 5, 2015", + "date_published": 1425606285.111, + "body": " - Connection pinging and timeout\n - Request timeout\n - Verify content at signing (size, allowed files)\n - Smarter coffeescript recompile\n - More detailed stats\n\nZeroTalk: \n - Topic upvote\n - Even more source code realign\n\n![ZeroTalk upvote](data/img/zerotalk-upvote.png)" + }, + { + "post_id": 16, + "title": "Changelog: Mar 1, 2015", + "date_published": 1425259087.503, + "body": "ZeroTalk: \n - Reordered source code to allow more more feature in the future\n - Links starting with http://127.0.0.1:43110/ automatically converted to relative links (proxy support)\n - Comment reply (by clicking on comment's creation date)" + }, + { + "post_id": 15, + "title": "Changelog: Feb 25, 2015", + "date_published": 1424913197.035, + "body": " - Version 0.2.5\n - Pure-python upnp port opener (Thanks to sirMackk!)\n - Site download progress bar\n - We are also on [Gitter chat](https://gitter.im/HelloZeroNet/ZeroNet)\n - More detailed connection statistics (ping, buff, idle, delay, sent, received)\n - First char failed bugfix\n - Webebsocket disconnect on slow connection bugfix\n - Faster site update\n\n![Progressbar](data/img/progressbar.png)\n\nZeroTalk: \n\n - Sort after 100ms idle\n - Colored usernames\n - Limit reload rate to 500ms\n\nZeroHello\n\n - [iframe render fps test](/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/test/render.html) ([more details on ZeroTalk](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topic:7@2/Slow+rendering+in+Chrome))\n" + }, + { + "post_id": 14, + "title": "Changelog: Feb 24, 2015", + "date_published": 1424734437.473, + "body": " - Version 0.2.4\n - New, experimental network code and protocol\n - peerPing and peerGetFile commands\n - Connection share and reuse between sites\n - Don't retry bad file more than 3 times in 20 min\n - Multi-threaded include file download\n - Really shuffle peers before publish\n - Simple internal stats page: http://127.0.0.1:43110/Stats\n - Publish bugfix for sites with more then 10 peers\n\n_If someone on very limited resources its recommended to wait some time until most of the peers is updates to new network code, because the backward compatibility is a little bit tricky and using more memory._" + }, + { + "post_id": 13, + "title": "Changelog: Feb 19, 2015", + "date_published": 1424394659.345, + "body": " - Version 0.2.3\n - One click source code download from github, auto unpack and restart \n - Randomize peers before publish and work start\n - Switched to upnpc-shared.exe it has better virustotal reputation (4/53 vs 19/57)\n\n![Autoupdate](data/img/autoupdate.png)\n\nZeroTalk:\n\n - Topics also sorted by topic creation date\n\n_New content and file changes propagation is a bit broken yet. Already working on better network code that also allows passive content publishing. It will be out in 1-2 weeks._" + }, + { + "post_id": 12, + "title": "Changelog: Feb 16, 2015", + "date_published": 1424134864.167, + "body": "Feb 16: \n - Version 0.2.2\n - LocalStorage support using WrapperAPI\n - Bugfix in user management\n\nZeroTalk: \n - Topics ordered by date of last post\n - Mark updated topics since your last visit\n\n![Mark](data/img/zerotalk-mark.png)" + }, + { + "post_id": 11, + "title": "Changelog: Feb 14, 2015", + "date_published": 1423922572.778, + "body": " - Version 0.2.1\n - Site size limit: Default 10MB, asks permission to store more, test it here: [ZeroNet windows requirement](/1ZeroPYmW4BGwmT6Z54jwPgTWpbKXtTra)\n - Browser open wait until UiServer started\n - Peer numbers stored in sites.json for faster warmup\n - Silent WSGIHandler error\n - siteSetLimit WrapperAPI command\n - Grand ADMIN permission to wrapperframe\n\nZeroHello: \n\n - Site modify time also include sub-file changes (ZeroTalk last comment)\n - Better changetime date format" + }, + { + "post_id": 10, + "title": "Changelog: Feb 11, 2015", + "date_published": 1423701015.643, + "body": "ZeroTalk:\n - Link-type posts\n - You can Edit or Delete your previous Comments and Topics\n - [Uploaded source code to github](https://github.com/HelloZeroNet/ZeroTalk)" + }, + { + "post_id": 9, + "title": "Changelog: Feb 10, 2015", + "date_published": 1423532194.094, + "body": " - Progressive publish timeout based on file size\n - Better tracker error log\n - Viewport support in content.json and ZeroFrame API to allow better mobile device layout\n - Escape ZeroFrame notification messages to avoid js injection\n - Allow select all data in QueryJson\n\nZeroTalk:\n - Display topic's comment number and last comment time (requires ZeroNet today's commits from github)\n - Mobile device optimized layout" + }, + { + "post_id": 8, + "title": "Changelog: Feb 9, 2015", + "date_published": 1423522387.728, + "body": " - Version 0.2.0\n - New bitcoin ECC lib (pybitcointools)\n - Hide notify errors\n - Include support for content.json\n - File permissions (signer address, filesize, allowed filenames)\n - Multisig ready, new, Bitcoincore compatible sign format\n - Faster, multi threaded content publishing\n - Multiuser, ready, BIP32 based site auth using bitcoin address/privatekey\n - Simple json file query language\n - Websocket api fileGet support\n\nZeroTalk: \n - [Decentralized forum demo](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Home)\n - Permission request/username registration\n - Everyone has an own file that he able to modify, sign and publish decentralized way, without contacting the site owner\n - Topic creation\n - Per topic commenting\n\n![ZeroTalk screenshot](data/img/zerotalk.png)" + }, + { + "post_id": 7, + "title": "Changelog: Jan 29, 2015", + "date_published": 1422664081.662, + "body": "The default tracker (tracker.pomf.se) is down since yesterday and its resulting some warning messages. To make it disappear please update to latest version from [GitHub](https://github.com/HelloZeroNet/ZeroNet).\n\nZeroNet:\n- Added better tracker error handling\n- Updated alive [trackers list](https://github.com/HelloZeroNet/ZeroNet/blob/master/src/Site/SiteManager.py) (if anyone have more, please [let us know](http://www.reddit.com/r/zeronet/comments/2sgjsp/changelog/co5y07h))\n\nIf you want to stay updated about the project status:
\nWe have created a [@HelloZeronet](https://twitter.com/HelloZeroNet) Twitter account" + }, + { + "post_id": 6, + "title": "Changelog: Jan 27, 2015", + "date_published": 1422394676.432, + "body": "ZeroNet\n* You can use `start.py` to start zeronet and open in browser automatically\n* Send timeout 50sec (workaround for some strange problems until we rewrite the network code without zeromq)\n* Reworked Websocket API to make it unified and allow named and unnamed parameters\n* Reload `content.json` when changed using fileWrite API command\n* Some typo fix\n\nZeroBlog\n* Allow edit post on mainpage\n* Also change blog title in `content.json` when modified using inline editor\n\nZeroHello\n* Update failed warning changed to No peers found when seeding own site." + }, + { + "post_id": 4, + "title": "Changelog: Jan 25, 2015", + "date_published": 1422224700.583, + "body": "ZeroNet\n- Utf-8 site titles fixed\n- Changes in DebugMedia merger to allow faster, node.js based coffeescript compiler\n\nZeroBlog\n- Inline editor rewritten to simple textarea, so copy/paste, undo/redo now working correctly\n- Read more button to folded posts with `---`\n- ZeroBlog running in demo mode, so anyone can try the editing tools\n- Base html tag fixed\n- Markdown cheat-sheet\n- Confirmation if you want to close the browser tab while editing\n\nHow to update your running blog?\n- Backup your `content.json` and `data.json` files\n- Copy the files in the `data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8` directory to your site.\n" + }, + { + "post_id": 3, + "title": "How to have a blog like this", + "date_published": 1422140400, + "body": "* Stop ZeroNet\n* Create a new site using `python zeronet.py siteCreate` command\n* Copy all file from **data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8** to **data/[Your new site address displayed when executed siteCreate]** directory\n* Delete **data** directory and rename **data-default** to **data** to get a clean, empty site\n* Rename **data/users/content-default.json** file to **data/users/content.json**\n* Execute `zeronet.py siteSign [yoursiteaddress] --inner_path data/users/content.json` to sign commenting rules\n* Start ZeroNet\n* Add/Modify content\n* Click on the `Sign & Publish new content` button\n* Congratulations! Your site is ready to access.\n\n_Note: You have to start commands with `..\\python\\python zeronet.py...` if you downloaded ZeroBundle package_" + }, + { + "post_id": 2, + "title": "Changelog: Jan 24, 2015", + "date_published": 1422105774.057, + "body": "* Version 0.1.6\n* Only serve .html files with wrapper frame\n* Http parameter support in url\n* Customizable background-color for wrapper in content.json\n* New Websocket API commands (only allowed on own sites):\n - fileWrite: Modify site's files in hdd from javascript\n - sitePublish: Sign new content and Publish to peers\n* Prompt value support in ZeroFrame (used for prompting privatekey for publishing in ZeroBlog)\n\n---\n\n## Previous changes:\n\n### Jan 20, 2014\n- Version 0.1.5\n- Detect computer wakeup from sleep and acts as startup (check open port, site changes)\n- Announce interval changed from 10min to 20min\n- Delete site files command support\n- Stop unfinished downloads on pause, delete\n- Confirm dialog support to WrapperApi\n\nZeroHello\n- Site Delete menuitem\n- Browser back button doesn't jumps to top\n\n### Jan 19, 2014:\n- Version 0.1.4\n- WIF compatible new private addresses\n- Proper bitcoin address verification, vanity address support: http://127.0.0.1:43110/1ZEro9ZwiZeEveFhcnubFLiN3v7tDL4bz\n- No hash error on worker kill\n- Have you secured your private key? confirmation\n\n### Jan 18, 2014:\n- Version 0.1.3\n- content.json hashing changed from sha1 to sha512 (trimmed to 256bits) for better security, keep hasing to sha1 for backward compatiblility yet\n- Fixed fileserver_port argument parsing\n- Try to ping peer before asking any command if no communication for 20min\n- Ping timeout / retry\n- Reduce websocket bw usage\n- Separate wrapper_key for websocket auth and auth_key to identify user\n- Removed unnecessary from wrapper iframe url\n\nZeroHello:\n- Compatiblilty with 0.1.3 websocket changes while maintaining backward compatibility\n- Better error report on file update fail\n\nZeroBoard:\n- Support for sha512 hashed auth_key, but keeping md5 key support for older versions yet\n\n### Jan 17, 2014:\n- Version 0.1.2\n- Better error message logging\n- Kill workers on download done\n- Retry on socket error\n- Timestamping console messages\n\n### Jan 16:\n- Version to 0.1.1\n- Version info to websocket api\n- Add publisher's zeronet version to content.json\n- Still chasing network publish problems, added more debug info\n\nZeroHello:\n- Your and the latest ZeroNet version added to top right corner (please update if you dont see it)\n" + }, + { + "post_id": 1, + "title": "ZeroBlog features", + "date_published": 1422105061, + "body": "Initial version (Jan 24, 2014):\n\n* Site avatar generated by site address\n* Distraction-free inline edit: Post title, date, body, Site title, description, links\n* Post format using [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)\n* Code block [syntax highlight](#code-highlight-demos) using [highlight.js](https://highlightjs.org/)\n* Create & Delete post\n* Sign & Publish from web\n* Fold blog post: Content after first `---` won't appear at listing\n* Shareable, friendly post urls\n\n\nTodo:\n\n* ~~Better content editor (contenteditable seemed like a good idea, but tricky support of copy/paste makes it more pain than gain)~~\n* Image upload to post & blog avatar\n* Paging\n* Searching\n* ~~Quick cheat-sheet using markdown~~\n\n---\n\n## Code highlight demos\n### Server-side site publishing (UiWebsocket.py):\n```py\ndef actionSitePublish(self, to, params):\n\tsite = self.site\n\tif not site.settings[\"own\"]: return self.response(to, \"Forbidden, you can only modify your own sites\")\n\n\t# Signing\n\tsite.loadContent(True) # Reload content.json, ignore errors to make it up-to-date\n\tsigned = site.signContent(params[0]) # Sign using private key sent by user\n\tif signed:\n\t\tself.cmd(\"notification\", [\"done\", \"Private key correct, site signed!\", 5000]) # Display message for 5 sec\n\telse:\n\t\tself.cmd(\"notification\", [\"error\", \"Site sign failed: invalid private key.\"])\n\t\tself.response(to, \"Site sign failed\")\n\t\treturn\n\tsite.loadContent(True) # Load new content.json, ignore errors\n\n\t# Publishing\n\tif not site.settings[\"serving\"]: # Enable site if paused\n\t\tsite.settings[\"serving\"] = True\n\t\tsite.saveSettings()\n\t\tsite.announce()\n\n\tpublished = site.publish(5) # Publish to 5 peer\n\n\tif published>0: # Successfuly published\n\t\tself.cmd(\"notification\", [\"done\", \"Site published to %s peers.\" % published, 5000])\n\t\tself.response(to, \"ok\")\n\t\tsite.updateWebsocket() # Send updated site data to local websocket clients\n\telse:\n\t\tif len(site.peers) == 0:\n\t\t\tself.cmd(\"notification\", [\"info\", \"No peers found, but your site is ready to access.\"])\n\t\t\tself.response(to, \"No peers found, but your site is ready to access.\")\n\t\telse:\n\t\t\tself.cmd(\"notification\", [\"error\", \"Site publish failed.\"])\n\t\t\tself.response(to, \"Site publish failed.\")\n```\n\n\n### Client-side site publish (ZeroBlog.coffee)\n```coffee\n# Sign and Publish site\npublish: =>\n\tif not @server_info.ip_external # No port open\n\t\t@cmd \"wrapperNotification\", [\"error\", \"To publish the site please open port #{@server_info.fileserver_port} on your router\"]\n\t\treturn false\n\t@cmd \"wrapperPrompt\", [\"Enter your private key:\", \"password\"], (privatekey) => # Prompt the private key\n\t\t$(\".publishbar .button\").addClass(\"loading\")\n\t\t@cmd \"sitePublish\", [privatekey], (res) =>\n\t\t\t$(\".publishbar .button\").removeClass(\"loading\")\n\t\t\t@log \"Publish result:\", res\n\n\treturn false # Ignore link default event\n```\n\n" + } + ] +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/autoupdate.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/autoupdate.png new file mode 100644 index 0000000000000000000000000000000000000000..7fa439cc6823746e82ce1a3dff48e3f050d3a1ee GIT binary patch literal 24460 zcmb@tbyS-{vpAemhe8W2q*$Ry@j%gHr9e~M9Rd_98iHGp3Ka-Wf#M~&7k6lJcMnn= zLV)5*L&l$pR#4jxe>LmxG&FTBuu?n0q>QScri@SD#pG>bmGE zDTEbl0T>MeiAi`kn3&mGxX_zgSX$eQGi=o~Fwk3@i!Yis&LSS-41e*80PV|eZU*|lATGAz z4F4cXS4ov#8sTI?F8~qbGUIv5PcI}4c`6_%BrL>9&kHBHH77^eR;o+tK z=Z689&B^?Yi2BP{|C|eW5@)b-ad8mg=5}{?hq&`W5KfldPlbhrxp{cGd3m`22rg$& zdlwTAE_-Lje_?oO;cVt)?cidKu&2MoXkv|BBdI)6>C%TiwDL;p$`tY}^~h%c&ehq@65G zTo6v02!!3gR#DXo;ev3sLO9S%OaEOpdR854dvk=lGuz)WN=hPf_RcOQ_GT7xFU1)E zED&pJa}lYhyik5AK7OfZ!u(I4LiwKw@$pMT`JM?$3h?s1d?xs>u`dy3u5b%`mw$~l z|F5wE|8eZ4IKUl%nO|BsS-V-7zj8vr>Ho4VV*Q_K;r);J{yEnCKhwhZAIEY7#Bg73 z?tk0te{}&8blLp3=mHP_7JdtRK;oSM(Z0}4Mgk`Wq^hV1rJI_)*l+1Yd*`n7UR<0{ z?e&fhm2Piu`$aZo&Kk2c*ALVs93LO&b4>FDS%Sy=%U*);w7nXz$j)Pr{# z%b$FWKR7su(c{@{4%@vrJO7POD7H)wBwhH8kDhPD9~sxy)f4mY0{|5`yji z_lt}1ewfnP!;S6&d{Ix&$;CN-ENy2WFDzp7=k#!N#UGT=iVeY+1mQCi<9pxXi)*_E z3dkM5H@E$n8OP&0o9n;T^;Bnmy4bV(+~kPE8YuyX?aQU($OFM zf&9tINi`<%XYzxp^0KKs^_j_rPmLXZIRj^BXA1rbziJ$Bs7aI*6dWENHblY%OKo&O zI)FyAFSS^2YRXSfT>&Tzee4^R)792`y6`qHtL#U1b=|N9epPy>SK{h>dHj*KhMGz+ z3bl7+TwhhLC@=pBqyhCv&&$q~vXvAwjodk$C{D{?UtdRmVZ#5>K$kQ$ck~3!)-Kk8 zbAn0j;dUZoD%zk=GU5*kUHL(vPi?BIJ#~*37Z(;T|Nrp~v=-L?;G5R*r>Cd*ndi$( zz~A!j?(P<@Yk7I;;9!4oY4KqHU}bf6ANU*`?Ck99?d~ltEn%_PmDLsCvwyI^ySE24 zS65dL_V?Ct>$`iqTU%Q=9L~eteRXB^&!0cI4VqOD+u3>D)7vvKK3>_toWZ-}l9Hp5%TJ|Ev zHO8B(dLk~g`19Fp7i=b$&$;*ZqLcEDSZ7BAACxLR1C z11V@P6XpMfK+7Km`fhCafQEdI0Ynb~;rK!deX27dST*DTOUeBLvbR@U)ewiNKD@{| zkt^*?%J$yjtb-LZyNaWZqxtQ(Uh`DRK3GL=)^U^d@lLwWB1hfKukl#H_BvGTjgMa_ zi4jqr{uBq`epJdnSl+NaM~ZPAA6nW=z5;z{gyx*PFJ0Z{gx-8Lev2Msm`1pBP%`64 zcvwo_(iTEq_$`_lGMRrhb)({jbC(;0_^o2=0(zsut{mmo6KF=kfi01K6|Z9t=B;)e z_IbC6$8aUsz2$TWCqZpeT9D&T=FLc2CLX7%Sxz&UyR2uu-mKX&Vqko0=QzOCmsdo1 z5NLLTV>k~<7vU}P>&k9}z|8T3JNQu#%Sk4?-MM6ZY1MJS?y?Mm95Q+FA}dIHF#1~9 zHe}Fbp!4Rum)!vW()ZZ?Z~}p+O8dJg=rP{QvQB_ag3(F7JyVTMwhw%N9xp3q6&5i* zbwm-c-h*Fi^mxgF)}nB9yBCUN@i{-r?C4u_liI$ySp}_JjXsq!=MVgOi(V8~>T}9h zQ)c2~HlRhMO%q@K^7^ZA*_UlR;8w7*Ens@HswhlPVX3-yc_VTP?x(3 zNa5O#)jTz~fH8p*W{zm(@$4sBYM}|c4G4S9E2UqSIU<)lRi`GLm%MOavC=-(bpS%50H^PV^)l0D~ zIQ9H%rOwI=fy~uQvey}GGhh#N9D{Ee`aienJzf!I4DW(`eXR7d71~QCeBS3i`o%&( zo94k-yo`7Jm~Q-v-{h3o%(sFd5o#(C+o?kQg&OHYc*Fj?{-0LNE7bH0hQQv4-+d;) zs3jBs!?~r1IcK|Cx7W7ekh>mYN^1SxYh;u&bCfOi%Qx$b3VXNc)wNcE7(-UU+#;;c z@^Wx}&u5k6oHEZ~8y|T-PMiFb-yd?cS8UCDTn}%7;l`9$2K~Y-#Xq4H31v0)YV?Gz zsWvr6y!n;m_B9l{{>+om@R*U@SI6l_BTW~2g7-$o_;b7_paM1l1*rl#KQq-*g}@Rc z%cQf*!7JVuhnvg$HadjGo9vW3@M)x`vfFMV^f)p{cpz7j@dhCF?$^&DwKoCwu9i596t*H#`p}gQMA|$`Xm2 z?%TKvsl=)NCLO_zl?*v&+o+*T;ZJp^jygj~zdG-7KFO zJ9LK4vr<7eAn#LQ=x&b$sd2r+c-Aw%pr~GrOokl~^k@(hnLni#^xI2{;?SA#TIT{e z3{FjQe>sw@T8+f$%!p!pitfH?_|jbXr}O%l?_nw^Oi9dnv~wf*D@5OOv{=ZP^7Q*F z;WbI{_H@!lH`RLY2p*>u%zZVgf4nGI!0ZY=(!sd)T5qNs1dsB!mA#X*=*P%F0JvlOeD{|!Pg^*s~0i?pCKTb}H>7^9Y@CSb*&!u`x zds0aCK4sKQu7n?y@a^D)Q?(6r^436J`Ni5@+Zmf<*D@m}-@KUx#hiWZ zc!N9=`PGrlHSXFgpbv52j6$FNW&zV0+3vN+NcCQa*o4DKVn@)!VLRP#hu8qyX2*eo z3b*r}mRbYGP(vmuKGd>#I zCB$NoaRG${0omk`fYjLF!q?p5f^;@4e=6uy0vswoOEwip=a-y~I3bvD^=*k!D0DX36H; z08613(js~8N$=%?P$syUzl0Q3?wUsOI3CX=(|*yeC@a;Jxm!C#HNDPs6upEtwAk4l zi6~C6>%a;yLU47>uM)f%!Q6M)Gh&)E{a#mEm1UEztR#sIkuk$bxacZNXu-5%-<nB5>=fZEZ50y`*r@r*RFf|TfA9!X>@|Imf;AGd)riXPI)<2(9*XTOTv}>A#t0S zS`fz;;Jzu~mweW6}wI+oXrK22)$p&+3=^3Q)_lnkLK)71a|+88)dpB6P;MGC-u)we$UZ=zBJxm$Bqy7nI5WDiG z;T3M0rCHbZg0o@(i-C7NYle!r4nggu*uhN)cf;E21JAcT){zHeb+oyL!8qqV$3G+c zpI(vp{%EpTkThUFr2%g^hqK3Ftb66?SL&uVgR5@(I6Hp~O!8Au#9{5mi&B3X{>U|p znL~?zzOMWs=7;iy@w1k>VwLseL#&={##z+Kj_YhGBKKG*xJcnEyY#&DO_l?H?Ldf| z?W-wV!M)!MeY`@DYN<97<)=MD9I&L1ZZQ6Nsl=RGq9epzZFs?nUWp==FTiWCI};LbV}kRe2qv%*m`U~wQN}?ig7W#ZqsCt!R@g%o zpZB=57!*$S&3pX$Ww>eA23>mZvy*y8OFG@nHBqAy3r|j9(cv89pcx*-RJi8{1r1Bt z@=4liHMzw0*QatddbsvR_#j+YMJDQdj}|*34;v09ZTs8{LT-+fbAo#+8qssJWWUtU z67b?PLK}AJ^TZ}pnc4!dHimkUxPs^nL3Yb+Rj^*yXwW^^7!5zZ`9^Q8LtX-=IwCDy zi|Z@Cez_54SBv`Qa$bl+$nXU`xjHuQBAa`(+oKU(8VHt#;L6!C`*i=5yMp*(7W?Y{ zgAswvEx3;ElFCzV{4hte4$>kvuH^TtOlw6r4mUgbN&V&(T%pxrZ`L!RM_@^rs)Y|9 zJO_fg@s=x+Pc3(>GhX42WT7gfol+F#D3WN=FIiS?AvxGpzZ`r>bUdz0T&c*~XJ)cY zM)1)#C+F-y|DTXEy+H=`@uxa{VlG*=u+_mpluh21x$s`6A*fJmomL4FFNJrl;7nVN z10=W;ioPZa=l83Z$f}cFm%hobovpmYAPR|?zbEyB7F=eT8w2z2EV* z213^R%tbaZRVgqnB_&5$eI#R|09t}5r1%}8grx)W^f-TLax zv#_Y;l)5SrLJ?iE0UytXpszG{zMww&%@Cq8bQ^_NlDAyYOwN-fTJ^LfUsN-8mOa8y zE*ydEzDae&{08+E(mKoLaT*# zRZwNNME4SK+?;}y9wNrhK?EL!J0CiFW7_uuVcTXpn={f&1>9~MRufu!=Zz^l;ufD_ zod#H3#`>q68yh6sv%VPUDal3*&7@z}Sr(y z+0UsQ;|+H*bqz1RF{oqiRc`fSp{I~ezxET+1bm@;>ktZs>x@WEB8}pH5{lXpf2V=1 zTy3mmIZ~w#%F27@e4sQ2GogmCLY$gVq&cnb4N=vGm};q!;RL3sO4&^*zx(SeU0xdX z)SgT0R4X5Q!AC46kXYlHc8OdrBNi`eeHNJw>d@7|c&#j0=5<|3WS zH~bD0&q;1>ge%%Qj|tYfJK)RDPiLp`Av1qe<)lZfqXS=hFs;;`7MxTIxraVqjQFCZ z5_Gc}8guSjTX-F_qcWda6lF8^^rYx~dPfAJo~{`^a_r`*Gz4Yj1jjDTCONz`7i*qo_o$g4CVEx-?5taTWZWL->#xy)bgVy#3OZmw<{t}n zJbyZEq~+MK#z3iMO-Du44G4HBik?k|oqE4{KTsj&$)P^MS_xGfS|*KK_IyPpFfW%@ zM0IGY{6OJ+OAAliXeU~@X7ihm=NWQC-stG=B!0?{&;P_|mQp1%eI*7_!B1QPGk1ME z(eX@fbw59(g2?rcAU;F%Vs>mS=tyD2ZDDg}Lz>!gj{K1N+)BA2!H!8{i1PRM(EcM= znFO1bH=6{;8@%|7XOQ=r3C5HI0;Te~I(|;}A^D`+v%eBPEFqoKsI-&c*rZL_kA&ml zkwjl#(SYkNPRikh2&CZ!xA}0ts$rF}VrSt&o8WrQQA4fSd3Z?KXAxjsG(D) zOZ?NU7A-uRtF$b)M~pPGX&hQ+v)Ln_ji(l`EoZsK*C82im1x8Gq$*6i_O;oruNk{l z+6`5!t^};10g-U%Dfx-P+HcT-CDjG(i=Sk;W0UVLFF&Jlly5jHa*s?2cMmFGFE2jF z*aeS6M3}}z@vc3BY^l-kldj`~yU6UL9A=at_5FI# zt9}VbQYOYhFMF{F9ldgv`rI8?0ZTjkkld>ppmpM49KtcKU_EEKej(4i#tMJD(lydM zX2-FWfT`N>?h`xBOz?7tw@o^QpB&F<_4*y2r7{5N^y*I$V-=Lt!VnRfB4II}!?uIv z4GZyEPlS7Tyn9xbL*@=t{?;CNi#7zumYd*v^r!JCW4|0l5asAl{dCJv1+%{%^2!bj zAF{1KFF#^oIoO!CRI2l-PdY3wQ|#fC&@G6`E;Q}HU{{U{SMs=W#rpLRjCzkp<7{d^ zl%v>b^$&?(ZXSPH+vB$NGW0(l5q3GPg|>Lf6>S93HU1puw24hsxd|(O^7X zOdaB{>GYekY7Rinj3(gSLe=6E5Qs|n>`a~TsnOvR7oIVjHxgqO`(dK4b-o54g*XXT zjY(+jdo+T_Rvy7euF?rDKDsm9E;?=f7stg$;f(JoxWVHz*tlW4wQvS#RQR2vD*U!v zF$nwt7;$z`(cmS`dC%Ezo8zg0_u0Xi>BreX;RdgTU?Jag+ij(Sebj6qcf&1t);1@# zQ=64?{K$qhu6ao(;n)J8{d{C!M4SW*#1_Tr_-{n#C?U9y}mrHMF|08-*(qUnxbW~W74qx zMrmOXPo=Pj)f^DNI)u+#w&D+HEC-FG{c0&H$904KWxx2#vTpd>fzPoY>3UBGoVmq> z5Hq`dJxHUoc%iM2bmE7pD=oF2625aE=_K%G+Z%1WN%(=?K5>aHpmn+(>i2Bx*b`{Y z)zSr)F`LeaJ>C6$nF4qzC9cx$Hb5=mJy!*Ou+tW5ruTLy@9gG?W17LsoDU8#s!#84Bu0 zHpj(@h=}a$G|OmcaMp=X!N)-TT?}Ltylb)ri~u4Z6Lc*oVgd-MU*Ny7Rs~;X-OB?- zcBIz60H{{!$d{OzKLPo7I;&0vNsTY4=RCgvv=!`x;o%MgE@0R-o}-7mEc>4OS$(nv zj~FFd^2T%eyq7<0xrch~kO+8A9@dzJ))s1)me(AF_kFD^%xIo(kTC7>TEs?XfB&d6 zgurcm&Io^Jo74 zS1F7F?milaWhyg{#q5M%fuh30y*#pko-Ds-yq&J$XS&RZWVTfMi{Z9f{UzA*@koOL zH$#^V37Ua;H=%5V(*}&AOqJXyh96*oiQT%9r>Mbw0nIYI^=S9*?3mgRts66> zobAa=MuGi$!!iSlvG#;G15Q2I@Yk3pN|m=>-`Yvb3CKP`H#A6>f#pj0^Su^TOgAHC zXu#s0pKpCisBCu$xBafAlk7sw^&=Ws!cS7nO4>z1B9mn*zQ(7o^sxFY5D^B=g-WYB z+obV~t<#0nNJ10=0kA7PM^y(ZIi}0j-0EOKotHZCn2Afx=(K8^<{ad5Vq%a_KT5Mj6HPq zHn0GtY`Cj~jsx{akhuiUjcpHaoIdQ@ThvJlG(c%Acj0trCY~l##aDFj+jt}}yMr3O z(n>|l62UZc0c#_=JQ%&u)0az}>JW-ERw-Iy(2cx0tA?zkI!k`j1qKj|{~qK-jmfEC zus7-G`N`gu7agg`fih*#f`(1gZRp*U`e(+zM(&vX+{G24Jw@9(#1~KFK@F#rIQ=C~ zr74AZ-L}KY1*GWSvsCcI^;@85gGcak8b+7FDcCo^q9gQkLZUXY6WuwXM;>`U{t((S zuO)Je9}uU1U#B}VGr3@Py7oCFu)Gy81v|&N+T{AcJ@EA@YHEZ0tzg=kXr$Sd zpVZ(0R+*d9$6)-x$vp|kajKDA3)JRV=#iCMGh+k!q(Ci33ie>HJ1k=tv#{N|W1mDx z0IIK)U4;ffso9K$?g{vrjku!YmV;4K^zBdkg(6D9+nfTRRY@3Aj^QL{CttZ;Ts)E1 zLKw!#yan2$UDvBUyl>WswGuO<01bws3f!wZgUW4381{z0Va^=YN|wGqt=5t&2a8*b zj8>~ac;+WgLDFIn^><-d-mZotwl?V9TN6j~=tiwjte$B)w}8RiK+K~W-zcNh(?tTt z8M$jbE(;8l_YBb+49~SB^ixFZvozdB*DGaj=jerUSI<0hbD91o6JMwzSf3T|ErK``}Z_@`rJ1qDCiC{q+wDOjN+LKGW z@tXk#95bN&+6cXTykxWzU;uao&I({(VAp_0K;Z*W|2wd3%1r+7umr?L{-FNJ+vm;$ z)3epO7anW2A3w&3GaVho5E4m1d@okoF0!J9RE}kxP3Be}4W1QZj7~np9eta6rSg35 z6h#z|Ke&7MyiI10;v*e?(hS>1+#@1aB$b%3>sX~WS3*ZdH(R?WScbI_;>YA>8J=b8 zFVSUwS@6)L!8|C6j@(m7b_j8it+Mj6m3GzC(5ZSp8UqQ0=VTSTX^B@bg*FnLucF@! zK?lid(`p>Em7z<;rgWMN+lT(~&+eH$Be$Ihzs&j4lr5m>4Ga1L5 zHJLEZo}Gr~otmhRaZ%xfOWt+z&T}gla%X1^F}Eq}_P86RxeZTJ8s8KZ#P2EKcgj*$ z&>6kaS)a>CGwPkxj4aCBja@DLW%@%M2UhAJ5h;N|Rydwzgv1`MMb3~(=X|FkK1%O- z+KRaM8a%WE>TZC^dI{xZ(kL#+7t5bH_ZktEp$HrF+~dcMuFDu}IEDk$7)NH`;R3_= zV`V3@m`1@68=HLPDIHpF5C1FKscanHXJ$QgI*vWlF*&c7v$-W`HW_S3x`r)FD1yGR zu*4-+$_BpbK3Z%um)Eut5v#`CXh1D`Z!n}JX8NP1(u_~yCarE&Wn~Lc$@UwBD33xt zov*rU8A=7byKq)3X@mN4ETC(&6b9hxw4pvF1;TnTmkRyiykIkd2h&`+uXF0!$$F+; z2ia%O;zVU|uL3hC*3p?s(|1N$MzaGP)SDSBzlc)x>ryl6|#b_X^#C>p1gx4iv1-r{snLiso*bUFjR`h<%_ zO^}b665PVhMXF_2;MgPA5309 z?1Tw(R1460yxWanANcfaDi@-D^ImYd-G1{6CH+tEcvk*?I*6A|U`1Wl#BI0D`n~yO zZi&U0l4F^6-0Uuss5G1Bz+3`;$^sN?Dj4NiP4V*?kx7MF-|orzbVRN%zmRp+$}+c~ zT~?(PDn~$zrPjr*4(p1*jK@Q;!@sl}<84JT??3RoeeR&PTY}&J#=agJE7?75^DT_f z2=`dBV;;@T@qr(6Zsjzi;L6ccxw@&4d>)27#TST6Gwn&-mC*Xu?-vT3O4Ql{THVT7Da`H8Wc?|i;XDH+69 zFDt{=Qw(RZhPfPm4V~6L>apBEVh}IX3+8n)+{0B^ToT1@=CmUS>CFhB^t( zGYAlzJVow>J!m#lhAoEFxGgXs9b8JD7J7Czxr;6oZ2THGzQ}xI*)Uqlw|SC`d&4BK zc_Q)L$-M;I~4#d!*Q&_$HaNU_SG1-DtfCC{I6GA4rTfxcUtFz5`+wjgS` zanc0s>5&xj6cDA8dn#yOp1I$bxoIyrW)0b6InrEx+K#BF?9ua)h?`a-Zx6|!2Wx#g zO+n_~2_k9s>VoD3Y72;anAk=vfL0B`jtINtnk=Tcp!_Qk^%63wEVw5>Q>!A&9C{xv z7i}LglbbdUf>5C$>IdI2U(?h_BE}3LlX0ATYVnW0|GMQc@ZDh`1Ixs2GePzn%?0mx z&>#1ZKhYocm963vr)Jx$!soxyk~?SUyUW@i9bfyXV)k3hH4lJ^KWg1{B>jy}Ip-Ak zr=I`k*Iy$r$MA1k5Q}BlCkVSnvT)gzC1Ln=?4Ahc?Z0N?d>P&Q=Wztw;IDZYR)NSn z?S9$1K?=L3*VaHRa-#^=)f>{GOZ`hYFVltEP%}>bPkUrKiIS)&pnzM`4+<&rcUi2 z%jM}426zT{tijAapZ8DR#$;xL)jqGiis#}sKRlrweXPLY`B~s+n44Ox7erR(H91%N zT{&Z~{9v+CrnDUI$MtGjr9X~0WO$Y~Ma!N82AOu3POhUP+NpBvUBx(mYbyiV*HC7*u0P6hBvNAP&18NTw>I zy^iKlok?tNl0k&b{vF`DS60Or*Ttp%7^=AD0+IfEz?HOr1ll0LRr*(`4LC@DJ*@wy zpMIxJOj5v4-`WBAuPO|MSn*e<1_S{Q&rLmPfoL+U(#l7RUrAq|FPBEJtn&lAg5`)< zO88Y4#Tw49V%Jf z=zBosFJNCMdH+6V<>^x_cLsG5ETN;TtObl00OWJ%S`oeI+ziVk6i|jv8}gp!fT)WC zX@;w-Xleen_Wig7O9_P@%s8hN}ydDsp^`M!9rHqmQY8J_7LCV_7b0K29P| zu&aB%r1Ga&Pq+WDdfiw z+~{=O`>9_PVxF6+*yEzc3B8Jx2M3sSblC#>j1r4(vYt5`&~*FW;@dh9(#v0sub{Ed zB7r+7a|;YXM}L0kCpk=m#LeV{Ld#KF1$X38_;V%T4dx#veqDR4T^*7U-%oJ& z5wOAmsPZ)D-L_Gi%vRot;$o-I_bvTPGb;N|5EE*86S3fEeZ!Bk`A+r`<&?=NmqvKJ z*Kah53~I#nQi&wINnIuBb8IOOlxDLoo-Eka=Mc!(8~_2fwaCT(LKjh$SujMxY?`T8 zp6$!TIv}s`l9^Uc9Wz%--&U^apT6u2*b$~+gLjbP(DZ6kR9#JNsx~nvE9J=m=teWt zf~^%-na@8^&fBMN;3DuOYx~t$T8=_oM4I*r{8NYMy@a?~Xi?yw<@FcfC|z=16^|iJ z^oP`@%3Jh&u&<*%bk%hhGBOULis-gHisk(d_1r&5b~k<=fd*6_W{@ECSv$0vFi!V) zNJ;z3#vmXdAlL(2rG@2CE|U=k!*ea@5}MhFOI7BI@$JXU!;`7lf$jmmpc0D5<$GK;TP z$Eae`9ncBy+|}eng#4H^P=ppaV>dMiNC3JPdrFJm4if;iqw}cr1#~A&4=RN22-`{bzhUKnIj&p{+bS?FZ^m` zEBZ?FRaiU-ZKt)ld2RN4b7f0E3zey=Ws5H8YgD&abLBIYp@v5vt9=V8B-<2hf`ZOB z(8YT*>dE}w9kz0;RqPbEIq>Xd{i3x5V)s_jVVFTO!!(f%srY4s4|$wnnzTnDJfk)n$ftxHa{VQ@Ga^S%S}wq(4D5S$sW0eh(q+ z0iSs3A%vA&T*FXL;*_=!fV6(7!C>`q(*io=&pfV1GOYpj_2^}%D%kZC9TGzUWVciy zf$8qMpWC3GT60TPb}wM&)6sA4i~=c%h;I;+x6dF1t3u$l$)35*q)Wvt#u-Q)gd&@X zrof_=Moik0j+%waoy}#m|;ke&lY-=A93-gniYQ12h|o;wdG7lc>xx0l?4o!KU@y&b`N(on0y7h7UlyP zTyVk;`du}-QPX}{YY%imA?$Le%b~!%<$A6jUvEKRxgUYoRyrSjNpFBYsR1^<#|GdB zq_@Cu4x8AszmV;M8eq;4Z#Q(no z{C@kx(8QF50>D7cR?CLA%k3_Qy1@7y4%aXbuL>czp8Ei@nhE$bb!#(cCTf&_2uts~ ztL<2BRqRbcM~S(puNtP=*Al^LM5(Z7?E>+)^)3UWkEYK|%G>>?2kHJ$q%1Zh5n)5gn#p*((B!&jB&5IL5~I?(E37DX0N*&M^3Sg5%=jEt@;G**b8; z+f@Ty*#EI&c*AdD3{yT0J zg&b~xPa?=*UsQh3z5^fmbN||B+9RRfDNrYH_Au^Oz{S-(WkoJxuwLQ^3rPq&Q3LTa ziuvr$JvzRdZ&AwhPknZ^wTwcA#AuW*o|SZNKB|<>q^PW9V=Z%mrTLY73ITLQQP?|I zDObGg3s4%>$g-Qm{*}FOlstNFTS?u;lVngvPPGC?2woe0k1qK+Jm?tiTC+6=0_*J$ z$~4-zkyqU&()>VLcLMTRLUW1NA2%5!rHYan&3HZgqcq3{Gf&r^Gk#2wpsx=Z9LbLk z1O-^_moX1l364UWUV-Da0#m6x{oOvCB2iOj|D; zY^6`gIj!rB-4v7KkJ6Np{w%cmh0W`0JwFhrhTB&@{}tEfm76u@I=RGGZv8na zO7~oDiGihzw)g&HGXwS1PdjFlF|LRy#{wZ$60%mlC+DkWH>1u95Ei z;~)NQLfuxof<^hIcUv8}1`BwL^6G(-4?LRNa!EDX%SAJ2)LzsG!K@A?EQX zm})Lx_3;8#7xt{I{{dW5NhUETq2@FgZav~4O+V_0lIXOfe7w@DNJ3) zk^gX<|3-NKe%s?O=>LJ`|LLdqW*|zUbjr(c5}@%Papiw%T!y*;G5<`1{v#Fz(xO0s zOYqMam;g4+!I@nCo-FPiXY5R(gpWul97GBXY5dOo?e;JcNHid0Sn;SWgzxkF8={| z$>%sB7TY!GK}X>W{32^)*m7N9`>0gTo&y_5U~CI_l&t&qbk0qIta{(ziK>_e6@+4lr`Os45?zvogPkxkHjVv zn>>mw+DdeeCeq;?APmo_nl8Co6f1Tnmw_^uCt8GrPFtnh(`^;alUH-K4u@t{2s;9d z62!hf_s8USXFG;=BqmWM)9;unOJNRoT%Eg(Uz~Jbt#hywlPxBBRvLr^n!#d|U z2=xBc^JmUCy-H$-?tr<**KmW7q6^uDos%Q}im8^w4`GdY?(rok#4sF#{T5{XxG>u( zHI~#pDSS6(J)gUiNUGogi8^898&(>$Q&D($UD|E#aZw8K3ih; znDn-YXtkITPfrJAT{e15afpmx!`;x_=)p`{M(iWbemxv#IbeVM0hN@7uf?uw8Lnu9 zcb5)~wUF}G?F;Dl*G1x-Mqx&LZO77pPjt-|p%d$ut+iUBf$*);n;*8%i<&aEd=y)S z;J9vEq&z(SF6yVEP}q3(UFq||E}`yisIj&lO0?mv(5>)a7=LnwR;;I}#S{a6(|9Q{ zdakAPeFyb+NDmUL%GVJ;SB?sr`cdM%{9djDW}cWlpMKvPBii8c`*^@l zDsU;Ui%Sbzox6a>+*kk0OMTjKDeXniHU#p;7)nbF{@4PosNqut$HJdQdM}_{s#wbj zh<#$?7%g6Y-*g{faz?m0hef<|Wj()Y?h?d_mJ!@2<>qlbI{=_w>6un-|D% z5t{t`u3+Oq8v&;r%1&s->126K9*Se3)wPm!R50@+N|QdN;fqI_Z^(T_#}7DG>$F;-)Q;%=wKuNb%|62*P4H!x)T(Z0%6xZC5frY9k+r2xbb?-C8nDW*M(Y zeq{*Svi@W|rX(s2X`bYRVauB4)){$ZcC$Ap01~(6Rs8zbMtv`T&G3Ul-6GRW(uX~z z1R06N(@kWNc@dr&`=7;M{EXZS9wZyGPiC`K(^xq&G+%C2-(_OXPK|AdViD3}hF4Js zep_h^xoVlyKy67aezP1^Ag?%`l}ZVQs;X-jDDQHS*q>$aFQ8w5X$^|`>R-S2d<>bT zL?o0ix;3DtNT=S`Ml$Fj_z z_BF<<4US3-WRJsbiwJ5|oMp_ROCm=GqDTAK4n_uCoN`ENU8MSti{d)Ey>GdNv$%%J z<4_DdY(CvPtl}s~QV2E{hw@a9-D(w{Y9cs9l5Oah8_^C_QoZsf(`8tGMF60zxZ~~o6!LD^on#XL=rwZa{p2LymVty zWG3;xSTJLYf?@XfLIFZCE49OMqFCP4Rg#=;R}lj#)~**bosw4PNqHe;m#^!kr4II- zEU4S)%0S_i2w+Ttan}6)u`6v4UA_(j#04KPETC`6%NNv4QSsYwwgTzon~>rQD&t30 zofsvwyuYC*@9AEs@S!@SBCy8h*67-Utve3k&Yl#f3VlnDz+A>6mN}1a@3wdQ)YMN3 zr!40*)2^;Dze&DeD&ez#bKY%jiS*iC$y0rx&@kMmSLFT9QDRb2psOCLw7*cOi$=>j z1DDkJM*}e^cdr}Q6%A~lKHAAOCq;Y%Q03%$#eR|T`Rq+uo~>g&^~hC*?WQ34?%mXr zUGw)9r-r3N)Zp0c8uq7`CwUQOOY8hs-W&!Z;)HEprtFT{9gp9((T(RkKOr=P$VXQe z2f9Nlv2MaSo)HGhOS&S4!!fICw*jx-h+U>LU)68Aj*CXbB9neNzD)R%CF;acwdunTOY1h{-XWOhOZn``Qws8$+gaRe{;yaRfL_Ig4=aWAag@RfBsvM~9_ zyl(&WEgP?22}>GRVQE|R{c>Ikp~@3*yB*D|;xfyd7}s#jARPB%TJG@^_i9Mo4{ysl z=hTmOC$SHf(Pj#6f?m$j+BHEK{^2^-{h@*#CD9G20$H-3dGNPlKjFl6ZQNo{@RF!4 z4*6oQM3DmKS|$E=AYT9*R4+b&D;{YT^&j%{b-9~720f8Yu*r?Bo(NqwdLSw1c_KK~ z;zn>i>GTC_kMsmouW`qJdAq)f(OvSced8g&nx#mKz=T8I*Eg`Q+Yk1R8M`͑k9 z)4L9I*ZbCjAnzZ~q36?`PcnZhQ>8)JdvP+O^9-=BT+G?8CH?%NUC1}JoK9+veVi!3 zGrZ0#@I0SResHOESL{YC%B>Y_-nOm@sC1xe{!g#*|7cu-TwYtbEVy5~W`A#T{eA!W z3-AusKg%G0{b|4p1@K%tD*xTF{$D)q|0iGhe{ssNRr!A0f`b1n9D};I(lGrtM}{?aO>!bvzndr@Up1RVc&L0Hd3sj z!uEB%!RCq-sNEDC97h(MBz*oQC1Lz?L9DLM#cS@I4Fx^kzxYe8BGKN6tJ~-zHWvc)49Jm0oSA+8R?$)0u(@0>o z?*43m9-zZHoQ%Gb<;pwx!-AGLGMu1wd$^z7fP2I&I_K+oQB5sf!?#?qTogqlfE0}=s1Qs5X#qqDRlx|t1rqQgO#vm4 z5IS~BAP}l32^xgZkt&3y5(zy9kkC1ZKq_HMfcm{L?GJ9XG%+U4j=iDk-sZ@`2?`Mn)5 zCgKz|YOfyX-e?bg0FN4OE~bi&Q=y3yR@xra7^qo*jd$r zQeBCOTpwb8$c09$4?RGRR=phPX@^^<*6~P65~sf(+b=UU;`WW&!d9d;ZIqgJo%U;_ zZLGB^1Sq`ID8+=g?~&=4BhN}4AvL6x7UrmdGYTzXlP;IxQFij3oAYTznPKsg+1X#+ zqg15DjX4p>T<1{4pfvArx^A${p`x{($tg0h1(D;y-ls1QrY;k2maLM|!N+;~tFRq$ zrX_!E9M0C9xvE+OfdywBEa~D0Mbe8`!M!KcOFcP>>0YE#qPni zpc|kSf!7slJlh{?QrltCiVE2T@oEp!k=v&I@vSr5F;hlbD?#YC>agv5B8-+ z5!!>G;x__2yOJ5^J1*RUgkRfFHyzZj9$On{AigYBz!aB$xXtkpL1sy{j|J;M5{4Po zdx#2iQXfe_E*;(h`-o^=7cWhk>b)pfho-qyl5P24dTQ9-ok=8?N(pmWe0Wt~g# z(~84}Shn5iGtnY<0b<;YCCS$AWa0QLrR2$rV4Px?wd+9Etd-ZVrPMH&dS9i6G;NP! zeE(98+LA`(Wm}LaG`1>%3w}2j@3C)aiC$lF{L0&%0DyM=KA)GbMZIs27dkoHUPHI( zpSU-E7U54)eAHWgezPanY$4QOv~=aBRB4J_+k)EyZz(q`w(`7PZZMkcHCa_Mo1hTT z1yZ(B`I+tPr9BgwT^DeTE#Z3ENV8r_l?6xQRnD_)C)u$2tBd4B8 zZdOaw{-qeS#K|-33pvdE9py|4l)cIxEIh z7fueVs%Z&%iGz@^2jWb`rG^vC1`JBKVTY$UXy@t2;xbIkk<+{DF{nS{_&t+>8gcw5 zfTHWLdd&O(f%|$@5IM-+}qX) zYgX;EI@S~73_n*BuqdQ_|Chdrl;(ywj$*_z8@@J4V`6H2=D4 zC0avCZH--y4n8j_ana^i%VC*FI`)42Kbrk8?UzDU4q6g zcOerY;!>glj{OWEp)jbT?qEW{vL|>uGZS>Mm>^9^sYA#duYp*Dq89FjF%j!z?jh%n zg$#cFcy((jJ8lsr4}FGVMmojnZ^Vl8#+Eh3$Svf&m13ieW)*vOFgP)3KmF| zS0@ry^Bop+h+OK!nmX3u0*+|em~?A9)v?OX?)_HVK+a7b2IH#$2p|(c2{(%5XCT(E z!&ar47$hHxOX&Q>k>7r#OUa%5xw;E7F$;_%QIANL_0%)FvJB>^p>BTQ^&Si|cvKbA z_{6ocqaRo#^Lz!%@s^hpG|}{{hpt({3+r!(l7K~`cQ{t9 z4J?g74S)HgIpBg1?P)_NjGZ0-ZWzlJH~j`ao8UMH*+a$=oYSzR=BYNS&R1$sWgX#T z4|EXim1fKdle2^CqRn55RE5`oO@dwoiy;OQ66hb_mfAXPemFak1uayS z2eK6>TRjwruZqSnBsqzaMK*-~UJlu923tMHjIA(`uJ~YR;6%QibOF?`BHBJclIN6t z9_R?uff#uY48t_83xad1Zn@CM_-pxQGNEGo87dkzh=ER@mjZfqnp~!XY$dRi7aQ*` zXMZ^|1Xe>&x{qbF&|}!nYLpJdQH3AHzn-VMe?*zTFua!E?HP$j45jU42e!?RpwsVp z9uJ2ckZmoRnQNW!qzd?Men%q)2KLXEU(oXdHfV!KpOq~e$I>%8RrGXcf*lg#BdVKt zZy;i#_@>aRs9}g8W}*E;j?WgUtPmX~xU(WD%(v26T|LD0w`Cv6b2abtQo7jPOLDv@amFH$Y zkql8C-?d*)>}##h0>=E763}UBgkNg!WWxxnKKnYp)?--8wr_ghuv8_#Qr~38t=5)? zO+I@?cqE2uHQ?6*TjZ^915RRtW50q&1x*7=30K^INXg)W?gAm%p*siN_Ol+vuoKlN zmDB3HOH=kj!_;T#LHoFx4TmdCqe18Gzdt)S(4`f54w4c-XRdDYP9& zLTgkla$VVh~R%T-fS06$`>eg&7VDj>IJ@!9m6=ePP7egD7Lmooo)tEUz$3 z2+xsciOoS^bb*+TsQw%tnMQq}`l;n-98SsVRQ5I16Qkhrq2<05y)w*HxGK!Ui$@S&TY`9p6qRZn(b_a@~iC!T4(rli~DE9eX^C`do=4jf!? z84&^)V;FDPUd z_e>k6#)F^kae9O188spP7LYdSMeN2ZI_r)2+y%*JRW!oDR`HWl_G)`KEJ@qB$z z2}-?foF?Vu3`$pch5Tvopc73Y64jn5kVK@9H#%I3(6!dhn|LC_BbWxjz>8YbqpS}*iT}yN`i&ZD zWq%)k>#9{k5Pr(ZZ>y4W?}Tx2=AvlW>PaSW>;c$GL&e>}KXhOzOMbSEQ;KIioWIhD zFtq#J_C-WEPx=p-jBiR%=H{VKLJ*@$)0*>wt9v0uMtZ@+K2azo8090PTK|^=nZP$C zCNQRNOfmYH(nV6fQjgGy+Em_jdBPCeKYE9xEtiQ)`9>O;CtQ9srnB^mx>3(F$0-GW zj{b<4c+RS~1|95BzLzr_7=&~=H+L?m$KM0URiES4puZ75N$Ey`!|B3Lm47U!SXgpx ztL|uV*k&$HUreq}fH%D)Kmz73^#GHDfmSXz(h_rR659|I{S>E{1ilF|mHWF47g752 zm0@E8s&=qf$JHSR0(1zorr|vG1V`@+f}gvle8cls7!$=Qc=zPjq^4ceUTIcEwd?y; zKNt*9k%8vBd(?_c3&c-Kwc^{^se!A5-iJaLt0Hea_(cUvNCR4%Ak4FToR zT)y4jv8RDR@cnfbFRX6u6Uec#$l3!~WIRI=qaySZaPlwG1{Ou2gNva6P9$;H$HCm0 z=;cCE(o1exXw1&XaHb3qB{#b>EPs9g0VF>Hb%2$^Kau5@X#a{bx9+dh&|NAgR4YB} zeC_?Z;+daVe{&eeotrw>*!a3rv;btYSbC?ZmRr^`%4;|6`>;{nn5!-%=u_j$dHtyT zFjmdCW&Rb%rLhXgktWv~KiV&0HPbxaljd2`(Ru;ja0ac2h4e=3XL@6me$Ct^>p7csCd(R}_ zc!N+}6+@~!V4`V5WvJW5syppXra@>><}u?Mmw37JP|eec0-Hl)qNW*X+`9@G6!u|Z zv~aI4RhR#rQPUsDYU1~6m_5QSplg%Bgr0J0~+{_G|sgACNMAN+f8joKb|A4qdHyAM|wVJ5C z7LH^hs;pqdsF#72#!j;?>njLjC@pj)k3i4K4oW^?a}d;!ivl$;riM;RrwI$R%Y5-h zatM}<%5^pn&(6b>P2`Ada;|{xu@5>)+*IRu7_qlz^un=~=E5MZ6?hOk@@GS~h-U&h ztv0VXZ;eeG+s{GVvsS-VGCx-qIAe7GEeabBmsh0c6`Kk`4yc)-B|#EWmg+XzY|pNt zZbEnt0u2@jX<%Dg+EakFR@y2|D*w^CwM1C+XXxhHA@!ei2(ELJ_8)V1RZvP?qcyj# zFe_YfKRw!If278DJ{ibrlUX=1N+W-gPv+@-&h*Wl;wxXe@8ulI6-#=)PEK& z?Rg)6*`HKjiLnHZ`)J6MyG?9+FeEIANN^I+K;+?1LyW#rt?#4Ev3>N z8~vk$&M2@w_XA4bEXm>N<#V-6J2f{vX@l^pC1(f>#iWE1ynD-COAd@rKMO=}ILa2H z-q;HYaj;XtAg@O_l!-9d@(stnNd+NlwD%%g=gw_>#2?NaogNGo?v*8bbx>@kh}xV4F_ zs^R5jMyV@riM|*I#vH8QorK}MaYURg-?2w#_?_(0E5q zp{yv^gw4*KXirquu3A5PPDGIN{={s1A}&|V|M1fGNxeQ3ac(}O|Cn9s zWz+Mk$lewUXc`>!j4-7YNbdH;krSC!fvXjcPp|(vdsybnzjGG5=WoQ6EMvr{c4(_`i>K_{COhvD$uisQ0C4bI z4txl{?bAR03n^@2DIhYW{sUEZ0Syp=Eu!CeYKui}6QchO0P8p~r zKQzej1#f|#C)#Ci92^1^4i4TA4e9g&77_DH@sQvxxc@cla{=? zy5i(EE@__Pc-PQB+RmT0{TNZvGfKf4Q048L?58aJNw8R*7nZ@>lily}sUUY1KR)-)$Cx$A?N@ zCL-=$UoTtSUoRH>vc6A_SIg--oZh`|+&s=r6%>NucGi|>I(&V6{CYdHTfO*~*Z1yj zZ$rCx4o6bsx`w)ZkuHx0+b3%yBa6M84*pFZ?+yIEzFI2lT4@aTMppgv#v3lZ;`!e8 z&W?`uj&Vf)uBqG0j{cf<^H*3+@zrqD{zT~?eV&r({n*|uZ_J;$4szsS9k;i4$J@(W zTbpaUmo~Cdr-vs8T|`5(u!o0-*Skr5JzX@u=zJb-qdKd(h_Q zmS0|e%+Ps3mT%L-@YCySaaGUj>r>YFS-u9*?%tj$4t#~s>)GY`-rgQG2v*oyI?&pC z__`Yz8M!!9*Sm4s-`{_5aNw5o=l=TXY^Ye)MvgHT&`P@%8TH_3;LQ zNN9a~ziM=NO{8!hD`s=+4fEUcZoRy`>}kZ*FcbFRvb- z9`7&CR63K7uCKSZx36!m5C7}9xxRUNd^|cjIzB$WzTSU%{?8%i*)(xj{rd9qOqP;%w2bKaxyu_KJ!QRx79#yI5@%4FH+)a?h8j5*m~;fO|RkrHL-+u9})MH zk`bk{T>_DCK@(iK+#L$iF`gIoBH>7 z*_L})dRhW98mD{hTsQqPymIbEM?L3Rcad@2-=S{Y@AF%p*3Rm9W!1C`SqodAwq|Dg znP5CGe^unP99gm;@I=zMVs6LeHkW$-{AfS+@r0I0UQrskz9p=nv2<-9`82c}CQNwdSSj58C7$Je_C? z8tN~Pvkt^ZM$V8mUVr<5*YzOAly6**7H5fP$nvDOrm>4>gZiZ12C8hvXpB5*`8n>n zeN{!(M$dcQZfy7JNnF(S!lHkhXT2PrR_l~&%kSIUwO?=itV>lF+x6+9!cIddiCz&3 zKFuoi)Yku_vRxQzi(sO|Smn`qf&)8#qTu%>*T@4d2RZ$reDxeVXvTqgKdqjfZrZoq zb00*dzwDl`yH&!X1Nfj}6%8^D>F6*`JVoN=+`hF%Z)S?4g6AVC=;izO0KZ$??Wv-~ z)q~xO#OBi(h#m^iVl~U>mFMtT0D87jxU=xwuAi|Nu_2fVHv1+GFf{jC2ih$;rU&vd0+Y2mOw`YQ2T)#a++lK*kw9mL5Q3?nh>5`f!+*|O3;pkb)h_tZ6bMa2 zZlAoD-#gg3Jf5cVFg#kSh%ecF^Zsr0tLI%=!_^%x8EnjYSmV5}&epDMqZUWcx(@mp zHlg{sqdpVC@YA#IO}agXC!0gxL!_<&HUQc#sOGVksQFG^XBp0 zuAjlK_=)+m#U_T7Lu=GV!Irf&qSy#fB8uv87)VFQnW^!e8b7Be^00h83=gyfZC;pS zK~L=t)AyHLP6t_m4{=U-;)fe8!4#B@`B$z&zdag9qzdoN+}4 zLD47FHQIF~rC3Atgrsh-=SRvoAca5x5liQ57w*4xH=&n1a_=wMe6X*F798vWeP(l4 z1JDsSpX1P>A(SVE>oe2S!O|9N1^H+0S&2h#Gas?ijfbL&Y+ClG=N1l^S}BLHr+`Hi zX-IZTYH9?t1}(*7!qAqae6c_%xgg3V+`NT4mF{JA4y1 zKRXl5dX^2Koul|0>pq=;r_xYcf4nI3%2a;q+cU`3{L7pAQSqG?>@oQX!)U1v>kHFG zlid6{=Gi%`7t^KP;embovuo}3$xts6bXm}GJoRk%95avaEd5pB(J-9w8QCB_>1821 zKm4T=jJ3?S0Ao1d&|WH9$!>6XwaxP?+tLJ@479zz(9VPO#T`r^VhkLf1~dIit9=d* zB1;PEG(~P&c!8b*7m6*t>$5Xqq%ix@3}LSuRzH5PoAwbFfyc*Q7d*<>XTuSc#=oN( zxqDWG%Ru(a=@t3h8v^LBtqf2giq)lQ>&9KO@axlM`*U4u>+|Aj=Y%=r%6V%{@y}KJ z`gD3N1)#Jp)aiu*&yZf z@)}nEInv28`3??|wkr(kK9IarJSSB4!z^$ce#FOvm<=G(cE+D zjsA!b=7AuLgQ4R9%n4_Z-MeJS-aK_6z(E?Uzb-DR>kMzTU1pf6+jyKQ6IVXn1E_0^ z@gEo4g)$uM5@djG%G*2-M}6zAEh{S%TfbjhC1C&!BIUEQs@&R`X8)@5c3NGvh)z1G zg47`O3>ZxhWQKfh*Zg(eE2Cl8PBvlfBj;w9t~n(jYIP|Bm*(7$?mp-Fe^h))2;1*A z^mZR6zyr0pC0}S*39iho8J}JeR@$C6^cbH)MrSm%ej>?AuRkW2*&x1HKO@8hAnfXl z`q0O*$1g(DE-++iDgfO^){(fZFLV9X~*#3I0||Q`m&Nc z=h(I_^deJRIhu4COryxWP?#h?I;5)4V6}{|+|Jf-4G0>k=j*4z%`@P26wXEK9>M9g-75u#iTLkd?a zLj2L4T(xwMR2g~wuyd)%Oa?;=HbDfgm%f6zE~g0q(GGy!;UQXTPk5-TN%cqeCE?J% zjekG*6_xg}udn$_r2>$3_ubuqnSyR7C8Of#>?BZSsifgd7C2%}0}Y->`oA{&y#vK` z&(z`TDkuWNlC@=mJ&sCGu;pF~j5=Bd^Fr01Rl!ny;rxY(l5%!)?0q7KKe8lf-8yv_ zZY}><-zF!*R>IW@@{_hVGfThVHkO`HGyVFJXrb8s3>Q)7!ig3tmg~;`Lj4#`LpQ4n zC`Xa)Rder{xhoJV*w_#zCr5NbfvOpBQKW5Guz4ZO#QcgNWv#AHD!4>|MZ;V=qVdfz zpa1P2={*)3VwnPyy!{foD6ZQv)gPfD7}IgG!PLco(qtcyZkZ>XqoNeTF{8l{xXeCc zIEX}=e`e(#A2q>OpV{Zr&-5m4)_35ps1DuhKKPm633}IUrg=v4M~7Gs6TAzKjp`B0 zCzWOXHvYMPp~j+QVq!?|Vc`CV31M{#1YR z7W_GL?;@LJ0Ix|tDeh=AP=7MCb#cN&QWk?Tl?EbB>f@3EvcF-$#|^cJBv(=4mF~Dn z3|AZ;&Z;W2DS7wo27xktgjeib z_1lk=(=ogh#p*h&5Xw9f6WY5F5L;^3+2F({si) z$Bd^K-StZerAZ2!s`&)uKZ{t~fICgYEN`cp^0R_6Jdm*oHt@wvPJ2FIVm%}wA-O7t zpw`ZBem?;b3&g`0kjIq&X<)#lhCFw;`Xh`tSF=RclCF8kN;jx zNab6I{9^4*ODeaSZ#?v!++{j;hOvFK09AIFampP;<$_cOY0 zHa(%p?#0fqeMdX*>QCi6BXs)>gvA%S!9ZfRR8gW&PV0-hb_{XA%*b*38UDrn^|@J) zL}9G#Q5Gv)sVT1sNv-H6J+)cv@dD@!f%z_il@_nFh8Tm)jCelme?h~cu17%EMARG~^ zQ)c^=^mK)v6#Au{K%dO}Qa$`X8X4*D`mk=6@5TLYmiNe2|L(tu&sh>Ai~r)Oww+Ru zQav=7adh3v_7tAhekjt!X<|G)jpB=B!7VA=aiVF^DHv6Zem2_J^$RYme6oy1He@1S zWy2{D8$rL@Dahsg(DjAp6c7lY@>zIArv~XJ@ZT-&+VPTBL;k1v@nF;`Gx~IqijFVh zZP6KWmd3We9i4f;X-a3SQn=;LX0#{{j;Cpi!v+zmK$x_3Uq;enz5^h?SxSdG`LV2 zyd2p#;D7pnak6iHV4B#szBk}o-+$jQg{)6NamtAc{mlq|!ZaiJ(uxSO%KqO>wVK1{ zdxq`3-qSIP2mPH18h1_Zjt0{p17M`6I4{v%fzdx`|MvS!R8$3# z_vmE99XHbw6PQf&Znzl*$Cq$uhyJc*my^Irj5x$U5lnNB0s45L1``g^mV9=E8NnT^ z!Pb%uDN1wtG|a3(EO=;x+@1b-P#VLWyQ?*wNBw{RbwN*7nem-S8H`?QAe5l$JL327 zsg>^l%s2Y7a)^G~9=p%%QR`G9Da;)BfGi&E$h>iWa|mNbI-N}3E?qNO|3(MJje=Vo zzQYE`&Q>9v&qq^;Q z0?*BwK@bZZ+bPvt8KVKgAjjv5P1F07UQS_T#M zE>Cvo3=LnWwtk+Q%I`ais*3R6c&RFh>*d`Ij`zBM!^R4!_Bm)5JMbi6#h1!zu}kQL;AYtorn9~sNWh_XP481tHNi6$FN5DlxbZ^U>-C`L>KZQZ5R9vi`b+=tt^y; z4OY7uw)%^-%flp$+$Bk2+&A$r&2E-#%3@o@1~~%TW#Vo=87zONWSqKCxwomRu|Ihj z|LGqN>Ma65a`}5TMwD&*RwpABt7)Sf2Lzm}8DSRbIGK%E!x&BIhpE&)?Eb_8G2g;S~5yJ9CmV{plbPCaZ)b48eq2r$v>^2+pQ&D<3F*t)2blz!K2XN0ORQ&X! z;@62-`SaZ{66nZ!O};E|PK=|}vmz1b1*l@=!4yvRUY32ws2|d-hgV9ey3Z2M(d7b` zW7=RBA}i$=$IW;`4~1Dhv$`a%XX}BHW@J{D>me;J;8_USR@dRU1twq6^8yp|z|>;B zwE>Tt(D`3cLpw)M{;9T0y^uN8r-+f5D3fo+rA$Gl##z)pQ)+9kx z8Yj*QRqYJC34iPV{+&WQO;YVVGOM)X2*~h_RApw~9p({|`+HRUZ5$co?53n~YYWhH zMTI4{E&A1NEGQATD2#t3S(des#4a!5%adM>pL`!@@Z5q>P(JH86F7yM@#v59o&w0AB#aGwP91 zs>*V#iP%I1LW>+C%gf(0d{2U8Tqc}j)={Y=dw-MJxZC;bR#qC{kbqoc?u+Yzx&0Ic zH*aKliaEHS*!!LZtZsQ$Lf^1wg10P-q?o=5)0Oc3fY62WK)r-o%uDfYX$rn0CiZ>h z7C>lmV@TFWWpIk7zJi$)I!z7;18~(X=U@8bNwHAU`md6We=E3XvrEYr4xH@OU0S<25 zZzL(3!dSPL>TmJX;IZKBih!1cnU;Em=ZbW06F?yklr~u)hlbC9<$)L{_tES<4!F&Q z^be`nyI-=2im@ZkF6p2gtipp0PKW>sh?KP+jnk0h0E4uZP%crvzQ8#i$YSn8@k(x} zB+BIUn}iRX=9)?~KJJ)Hsk zH~b)xQ?QxuG;mrMa2{PEdwd9NTh#}wo@xWG7cp9-$Jay+`JttTXJ0X`FiyEVqfKgk z`TGR{^Rb0|Ez;*=_!fELiWY_29SP4)@_GzlcMGB%WQ_;w4qnkM)#IZgOmwt2xsj9rnG?`BRj zp=V%8lWb>U*!h^T`j8?@38H5%GOv!PpuKzklBWwuMdVm^$I8&R?Kt$>e;8}t3vuH)4!c<6209fA0@Y)zKE)N zP?MxXZsTkiPZM+Uaz%_)!(}hQf97r*-=8Psgib>-q2;4>@1eeuv5|%~pI=CX-#J`* z;aU>P6?S1m4|G~QzITo2Aq4b!%ErbGy{i zAZ-U#Yg|)+3O~PK-G1^E8@~<{waR{;5_{CkS$3CJYaNAquDxOs&9!wwkc@y6G#0tkhT!9_!5C-l49bZ5@B|X%ojK(a9nOB?dPj zmU<*n`FYoE6YTuha+~I{Z8-K~-t1kQ~KKm^anmjR0r%X9Ai5lzGXL}y9M^`1r`0$<-k3&f1pjNK8a-4kB zi2)ZXyk3uVGoy`{(+9Xi#dtHHC&`yVu{+yz0H0L}H&l>S7CK1uZfsdRmfG@d4cWq% z#bP6bI@uYZ^wg)gF~f>h{1TkoY(z|vt9}1TEBG@&Sx*^!EeKc+dVleLcz}{B5DoNp zTlzn%|BU!tNs_JQNp^Y!MR}5o-rW*Xu};s5kMBCEsv>7y%7}OJDKDmoT#1jr6h_?= zC@prP^D;>RA5F?oZt8O}iUy@~<$hgU-m8=mjVsXxEuIU%X@yJpCRj9pVg(-4C1#fA z)f07#ndYp`8YqCe?m{^{U?}b$3A_lpB@=+k<_Mg`F2!u387!acES_Mw9Dh=*wOanv zfwbcG4s=~GC{uH>2#lI%@U7^X()>Hz>*{&@snMF)UFL^mpXjknIH|Um(!)s3pOvb= zmtQsHpLwfo4;b6rG$$#3zo}8Sh=#UiT*a-Eh}u=vT`oMgRS-b^dL}V*v##`N)MfWo zV{GB)qtTv3WxV@tLlK9REo9>A5Q3L1=&e^LF1Ks-exQQ*Apc@L(}LLL_7IO z?2uK-5+Y`AJZ#W#0Lsr>v4sU;u7pc{=~xdo`Q&%IKF$>cNRg1os6j(smQot>^O&- zAe;X&6UYiQ;Z4x9P!Z?FWI!KIA(|9_6U8?1s=33TipWZAj)Ssq*UQpX1_}y#H~{S? zjxX#w|2Xvi05xJ@L=v&!7HR-K)^p3dT0tN}M8lla+i1-|YWw)~@k;JL%TkcqKHr^f z$WYbR82XzcJa3{D0Pl5Ho zTp0puW+sVGWN}+WiOth}%Bh*#qn2m&OdKg#Dvp^BM*uZe(IVf;EaSSLF#ebp7i#Ajfg)uDDq3?V`0k~tfrDl2 zH}|8>(8DmmY>B(+hs@XgHkzHmd z441C5i>p*ChXf*Z#b7oKHo(=W$r~KOEfUQk$|HJSG2#CcKeS-D9=!#y*||~NE$tHO z&M=jNNwo(pFXFypEkk==Gv!O z7Rvu17l5W&QhUWp<1|U)-t$=nySmqu(#BvrCvaexVkY*oToFL24gqiOyPFB;5P@H;e$GN`!KRI{%vN2&2ezREDP_AQVC+`6Qu}EbLZFLxKp-zM znwOHK#_bQjGQYHeKf)N2^do`xsYQgN+FmtZqv%XCnp1Ew#*fA5ftQXf@kgKHk)pA$ z=JaMpYk*ap){}7`tpkgL83y{S3Cx*NYAH1t27-^r9Jch^96tS9<>yN^Z*-e*G{0%h z1Y?EU4AKI8W`*)LbxQ@7pNn&}N~wy!Hz@#hq~e({tUrkoEY;fWHaD9SVwvUs4UR}b%)wyGRh{_@WLiL4O>1jT;(J0BI3dn3uUwHlbsHWQ zHt;3!?Zv5bRV9gqBFu1c7W2srqW~PPV)aD`^+BJYV9cAr_N8b#Om0(nFh;GmKvp*oFQ*#mlUmieuQ4oYtFzlBDjCwmdhQc-58^0EFhEf zg9+i0Po4m{Q4k>LgbW!I;jG{Tz#Wmnnj9Ntfv&nrI8OuswqBY7cTS>#;9o@QbWZjG zg*Bwa8FCyo{iooB`E<;WrxxplYC!XA8~Fg(*rz>X906z}-O#|7-g<8{jb(XlJdirM zs7qsK$`J-sAS}?N;=>JRkUaoDGzS!AvM+LjYXxT&$ziP+Tbzfs+~z#Dl#kM6m$jmT z4{g?>pKsLAAto0U~tj9Glf;mkn`Wu96}+Baxmb`cMzqL8Snx2}mYbbw=d z&X7~99?gU4=0ubQY4E##DYp_G!p^manJbd%DJAaIzKiNL4l15y+-<3d~OD*8~J0G@S0 zU@X3HbVshwshOWY0uW1~QNMmhy%U)I|M39+uf2l@Uclgp{^n)aT}-KhfXx_PqFm} zvi?@R$Cg=q=q5{mN#D7VJ>(Z58lZ$g5mR_q=kmwEi)4nIlH=W6qmKLm7w$H3~ZtRR7 zI4INH#LlJXnm9Gd>p!xdhW??q6Xl*ZdSfOBtKG{m6&fZ zy1`9p+bEI}Va@dkvII!pfbObDeTe~*-htFvg1p0|fXTPy6mP9?(&@cMM2VX=uLkGS zmF;smoep&b_Frs_gp&-t`Zd>HuS;{qZ0c873fWQV z5Mw2=rrGPAIC{GGfdfeM-PIA3F#=3p&3oL?v$+jDr{uXIpjxJS zgbt;#4~Mj^gf${Ybrv>FL+XtzBOfv)r_@k=U;;+YBe4shhSE$v6)!8_Usk;np(f;G zZdct~_#TlVt0h(9hU4#m1Euu+PSpPBQB6(a8te!a?Fi8C25PpLChtvFioXW0$#Kdb#%Hd5|(B=uXc4ndft}?{|v^Xdeq9q6PxSV zaLZ3LMcN3%eW!{jjNF!@_3O`&%Hu5e*T-LO)Bm(Vv+va@z)V@f%m4m^k^tnA82WFp zF08>8!bGAgV(k>JmuLC~aLkwxWRREA^HF-S1O~f`$VJ2KbrryE_vOA3J=*6S@_|{= zO0Zl24WH3r-)037<}{tLmn@}m1&xQiHDnlSR_OtSbMJE}u%TLB`{fENw47QX+#Y15 zI{6{78EYgSq~w(xU;xaB9rr{0s{`d9zz+*7+8B0pU!D7|j+-kXwuu?tpTar7cR?pZ z`}8;u9Kh;#greMa{Ks-f5@ESKTSpY2zO#e?`;y=`@>9lx4x|i7DPx6|nMPGO@Ia{| zG@Sk&eRB_tfdryf*gb+q`f$@$3~y~w6lfxrpXZ*6lIF7e*WsPeZSIem>Lzhqo(nzi zMf^SaJkgTV>Bb*B=kVHy!#02FvHv>AhQeS|GCu{ZvmH!LM6Tpd$=Qd{K}R2N7EuH$ zflWOzM@X<3wXod(TFrgaIF9 zW~uz5_t|@3`N#0u?^EtX#9BtfOA%6(r}rG#?<-A?tPd9S`+jNUj`5{*u`!yQIJS9&F1FEg zfRa?6g;ONss;Kgp*w673 z#hlOP^$H=|Tst$tQPMQmQz&nGmOC1%k58y#OtFMXT0*Jpu3FAywbh0_)Df`|iH}pC z=H^Gcr1PJIx)m?7qzuPP9qKDDh1ng|vYwOzH{4KQO&8v~4ssH)05m`sbt5PH_?F3g zC{6o78o*%%dDQU=UWq)E$?-k(H-$>=8O{*HaxK|uXzG$oJ0M5)KofX@nik#UN2D!+ zWa}HsUv?>jyuB0CdP12)hYLM{*;&?76xlikYhz*K4D($@EqWN*$SUx<+Id&#kK?Ql*SD3zDn%%2BU zA2LweP-fGv0iWMkbh1VCRV3qx7%y@bSK>S$v}3RB>@)V}Uf^vniYFOYQP9R0GhX1v zr%@EZeBSSk{_$GV%2wA9YEHMOSTPOsYTg~!muya(dKR&glzel}?7p%MC4u$lN!zO7 zXnbYr=3I9Gr3X(opHe-PPoj&0zy&lO9DOyN=FX!7x<+!wHHKJl=4uTHmi_jf6BAXr zTzSf1@Wa!N%zOlj{MO5Z0Q7~3EtQ2B(&kjhCgX9~L&z#>v-si|vs`wfxi7b24)5|% zTWvdz54^@E6MSH`n0I`+Lp)Kpr1McbF?q{|5Ulm2Fww9G)n&7_fbq`zVbf8u3Vr|R z&y?sSk?|B)Iy~(oN+Es0UeB5a z`%CagRY#4)&OMLjh{yAJ`*gT6y9$IK%!QnlDf`U}#uRxLpCU#ohGNiQ zye{V+^#4nweD08oW%S;7f3M~A2(j>%S#trww~KZ}au+X!Q4Jz}?FOhV%*mJg0600( z2a3!`QF&Py+=~yBrY7Fp8fD=o#x1tS72@eb{wmV|^zAOfPRt=$$6-uLqrXpr@VTb} z0y80oWsktL&-R4HbO6OSqZ$o7wX3AepPnL0vj>GJFh=i@8-{_ozKF;TgUxQkKSYr> z@UotC+dXI6VTlUw^m#`(a@RZf8mu(`5VAjP3fTZ8ryvQlE`}NhniTp--2k~|&fOLF z4bJB%bwKyO<@;9LUaJM&m40=JyviPr|C18gHim1mSM`F2PFDqPn3L|@JG`40i)POT zX1$uit9uBkoqx>{-4;oE3sgq1eq0_3Vj9_((2988^yO(5D2>){{e_A{;MB<4;V&k4 z^Xq2r*+j`r9n-279L<11E5ou_t9L<99be5?jGH3ZNkl$fnMzP>VO*odq&{?hrN$TN z<-kilz(DaYnsL37%)2-5s-ct)(5QSPke!094xE1{EKF zK3cIwgkBWwy=5TyM2LC`(7gM$MS+zmdGl^$=#T;DGbHVy5({xaQd*(&Bi^*!0QT6Q zW^|I@sJZ{xG`MF{(?~l%#s3Tt#C-aVTfrYO4yhfkj!8sT2vfPRUPDXpvUWH7Bs^fn z9bAN={X>=h5}e4vQi2Wx=KqlvP85M!)>rjOP>Yn%50!YZdTME$Ytp$cgh0Awiq4(h zi7*p=FWIBID0=QC>M*%+J|?Ta1-g2Et|syp%6#|xLQKFFi-Ung$gN7L_DrZJd(+cQ zMemof@@hFrUfw~vc@Ec)4T(vIeTc?AeB~`zGVopN``s-5>&v>gZ`5$PvB9;QFcV{Z z-K0nawTN7#PY=ICW1*H|)p`3Xd6s9A4+u*%66b~gZ@-7<3PWyBMY!5nOGEZo#bT0w z5VIeyQfS-}e%rVp$uW*k&^OdrYG7`cgpR0k6{Ul8K^aJN^#K9Y^Eb-}fPP-z{^=Wa zD-N-O$2GuenWEnH&5=#$rR&IOzzrX(9lMvD&SiGae9zs)<$cYV%! zTL*AK1})DuIq4R7x$5?iunJfS=BIZ*dDqfDqD;3nkjb#@fa;LLo6&R6q!Ohh7$jq( z8;DSx=r-2SGIeeJm)e+%jyXdd*b2GSdzj2Olc_nr?Y|IXO;^*eZ5f`zlK>csB%n(!p4vRZ~xhE;IiUJRYx;h!3De*-Aadf^vF{)tmPv>u3RN48Y_fD zmgXi-to_=X-3dLH)bL$+^J&SICU0 z?}!Q1_5MpIu@T%~R%U4bZ4=vZ19<$2yhhEumQIJMrk)hC^fw1`kr?V>VE^nn;W*e4 zF%y@gnk<=bcv^i{tDiLgI=1j&mT%r=twox%XBqYd?ONN9AFK>!HRCEZ`Qm z<$RgQnG-mzMQ-|9cCcdq#nD3CZuP{XRl7lmHK(ZH_kGAAb7UFqsCkU~QO?f1OSO?Q zP&y?AkAYmZs8Wj%1#n&D+M}#rK5Snko>7 z0DJuRb0o7oM{Cu>@vEGLFCEq%ZTI^!%P}mQ^_uV42KWx737-Mat3sn3T$2LOOp>ph zs!he8J`G`C$x1S*do>{~hvstizm*s<^c>NvwMs$UlH9(_fV{s0$_7ujkv0i33Nt)60rVcXxB;tD1oXkB^;nzB1L~vQ3XnIlS$aH?qf?}(t zo)=|e?J0LWyFVu81n4q&K#jT=kr>ZHFd1{3a~Op4nK5KCt8C zc_xOZNHFqGV}`htd#*#Ji9p}hSMDKt5v@tRM1qqZjeLnmR2f1pUuj~obmJ#xJUgWfJDb@ zzJz&)Dg)1sO@7E1UEh|9}4i;x?sd?rFm z&-frV&1ss_p_H;-t{Aw(OJFd$pie~rvv#}^rH$x~NfIt>Qcm}z#k4TwZ?Z5zFBvJT z*I;WDzJeirxst5E`suB@KmdCLVb5Z;4ijd_ET_Dc$N-uTqzjV>f|l;XnUF>aU?Fpe)>LkpBP)njTo0dh za_Z+1Xws{%xu8l;CZ1{!z)cxT46hMXe69%Hw$^Z3IfnUP#?Kg_$KRA3S&|Ff${MlU zQ=WOc%tCg{3@b(2ut`kBGvOhiukc3g2;B!BMT5CUJj>cT>F9rrwx!$2R=S^?hTcjo zoTi7KO1Z}`NJdH$&>HI!R}G_3s|t=ee^6JT>}I5AJg3$!nao#iaq?g;56L)C{F>*y zE_OTW4NGNPj>%Uo2pp)tHXG$#%F4!i!ili&5b zT A0RR91 literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/domain.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/domain.png new file mode 100644 index 0000000000000000000000000000000000000000..32369cbe9d99bcc7f7c08b21342d138193c40547 GIT binary patch literal 11881 zcmaL71yoy2_b!eE_fp(iq*#Fh!J#CD0>#~(0>RxWZpDihE5RL#Yl}mH0s#uerMPQw zl1tzB`|j`F^}p-CR@Us^UD*m1PNVsc}(IPzc`1Nvorvpg~YjP%zD4%KfQcqtU?AI<2j(t)il$^74*@#r~~5yD4+0O;5gHQMugM+;_2wI)V+ZpRdey=@lEYvbJli|lHR8w}cH+s{=4ntC!6=kyBoWe3%4zV=vm#{jIMl^zjGR0b7I+(U>!6ygW}j_yY35q0c$&j5Y>}yL zm0`90wAoMP>gTH7{^Nu5b0SVHsl<4^H3@K&yHI38BO>8=VTbxvSL`5n1vM&TB2$aplt@Ku6;nba&5n(%b5Y^QQ0nC2AMo4;czxkDy;%)r7dv>9V43xT&6j%l9*-Uz!Qez33kAB?bU zt4KYpG4+sug&#vC&X+)X7hKn#PfSXT5ZU;s2*5pNcZ905JYSeeNwfCN8#k0V8b05` zFQSZ8qD05e!|{2fvVbAg3LJt)yh$<#Z*n;?#D2UmQ~HbwC{)=OdeQfhNlB?^jm+Qq zvc05OvQIsdNGK;H(~vciR7r^ywEJVXS4mbmS2z%Hazh#^fus#6FWbE+(=n+lTHD1E5zOC&L?D;oUke!Q@ohwD zlV-V%)OH`R=TD00J~gGt*gOCl)+9k*i~uE-=f(vLA!}6U4k~7yXw(`r==7FtB2o(C z$c{DZBadpgt-`m00;rHkqQSkbFwtyhpVs&L_r+CG3er;fih4wm^7|16+hQSqT(5c) ziRiY@l11DiP{FK;-K0t!YEb};G4rl-F9 z76*LvuXHNC-L8^feze?vjTx=4Pb(p>-!yi0H*{NU{~LbOI!J{#a*gL!N@5W()vnFlh>Q#dbSz3N4CM`7OSi<#R=#!gil@_x(AA$2PB+v_ zT@0b}{&4RyrJhYlyRx|UtSZ(}zZ1pbTCBcyTpzkXX{2%_`OO>y>u}u-_HC}Z7n(Z< zL&!>+ju3STV};hZC5rq`5#n%BHp2-?!xqnfJ}9EvUd>C1yPN-RdVeF+&3zc=|Pb49?C&U)7Ybxom?I%j%GYI|1 zZmy)~o+&hfHZ+boE0cWv6d*ry00&=WS%ZbC4Z%>)svS-lUq<@9A#-{?%-<9M}M#9K$&*B+qD&6g1#|%OAS28 zWytK&^#VtpX~j*Hs3cf@TvB~1n86d-kM*aN!3XEOVvzTPF6BtvVup)v-?CX*x{Pvsw3v4h+*EJWGRwaGWf9RMctRF$!czp+m&AB< zEB4tXmyYq%uURWE8rt=^xAO~I>V6fs>TxviJ!LKUwH}fAdr30;(EIg5FpRRQ2E1@D z<+fOB;Sv}pMjmOMXb~9Ki|-eFFF<(CFwp5`TIg$=vsOVXKUaW6i(v}9Jj%R&Qqj?% zr?mD%lWEm2(yJCRFnNWr*|#WL>o>e(ihk;0<}gbwL9qWm`+ap9oIUxBhvN59_PddV$;5kI`Dkdh~J2Yl_Iek`0 zf$!!I9@b~f-PX~|5_v?PkbC&bp zE15jTh}*h3|G9gNj_(3lqbmWZz9yk(zgLWJZ_oM_(s_(Jyl?o(LoBW!f-`S^dTsHW%=2ILk6ucxB;tF5VL!1x`+I^!70S@dQ$&4M#XKU&O8NDr zmJi>#pgm5AIUl}HQEk}j`Y;@hN3rVsfU*%tL}l!`IUM|GH;ELLqiu=ThZ4@Am!d@f zt}z@8;p~h|rjw#rAh@u5VFncd8bVrvR@ew8)!37Yx;f@dwJgRHGeAshP&&w}Yw(BX z?CRgwLQ+(tQ~EHpGD_JdF8%spmON;2VZoTvi^*`b>NMlv4^GBM8D{pISoDANxab)VNYn_G&}jPKo^^V<{GZcn(Pi534~dsEu< zghAKs4qD4#7t;$x8-+eu{rSYT8}>1(P%qV&MSqddtQ~KNT&S6&=r%+r6riuFnkWKb zZq@Vm8tl0Ud{Faz!6+ef+5wk!meNy@dG%Jj9}x@Jsh;W+;DAw^EHZl5Z=3Hl&8Fh% znpioNaa%qZh>-jQR!ckW+{k;UgX|8NQ>d8`O27);p)c-{&{|IVZ0Nge-at#G&pU8o z8|_pQtu)UWMrIN)|1A3G!ouCWR^kTwFa{g6HR?j~a`W4^s0n*^to|2Cs$%UWs<;nE zSMoQ^R6s8!lR8A4b>n~zB`ppaALHBv@iV%ousw2CY59P(o6ekymNy42chB?(ut3}v zq*K<2c)cNmShcwy=3L+H?h63{R2~LjT`-Il+@<5@15A6U={GC}<4j%V%~V6kKSdQ( zO4FqibCy{C`LhymUYssqLmso4`7h^&^g5je} z-!<=VdI)WFm_MPur8FSX3@@_;P5(f?!c08P6*kQJja#;7z-6t@FIE`^)-%BrQEw9| zHZ=%~)<)x>1y}&u(d=Q@jI_gi-Yw)D!EGSLvcq~b`&Zate#7KG;vP^kvtC*EaF#L0 zWQU_IC+fIP&0I1jPdy-0xce)XzNb}b=PLeK&`;hYFWOanm@ z;t~@|o*&zCf8E#p!#WoSAKSDcEbgx5^{x2VB#Dn@vFlK9>@w93F*e~$Fe$cs{Oa%g zrg0wbS7y$ko=QZ8dP$u<3&R~e8E}W+^O`^8D%yl)&fCfc+XTt-wO%-4cTkEoH|mAH zxD^(IPPfY2QN;US@R+eM!fQMSAhEgFwKX?|Npal`P|FbuV5g2uDJaG`1Hsx~z*3Vk zLv8vwl}D{-n~k_SQiT z>}x%xBqP;6jRle#(-w!L917FK=*$E{73Bfd4K{WsXWv;MbCbgu8y||On}$F2V>xPE zSMo2;7uan3PvA7sD@6rJFkq>cQBFRE=~8e)F|g#BPrAx7iTPmH`RPwZU5wk@&G*K- z@Ntw0&p+V2sx`uGNdK6}uZ5;m%McZa51~EWBIJX49yr)7EHrt^E-ZhGZIFKE!1MHI zDaKOl@{PwrJe@89EBa6LApTOD-Vi~y0ra+pzK!|_l_XM9(uWKYy=>ZcZEdfcuKL-;&GforHVw@u?PlEKFtNY z?%>BqPQ0cD%GY=0OmI?Q&%N!Y1-kH|jK$N8;`Dhe=)U^KUxczkf@N&*hBoY)>$$+r z>FoP1a3Wah&L2jurtygm8>b;lg1x|;IM|cm**tFmR=S|fyucSKo}5B`;bz`3&x6@K zHPiz}(@SV*O*u!ilP6pL6>buUbg6&~67MgyDm$mc3pKa?iBm-~HE=5;y0b+HHmKKK zruvGe#Aft!hM1aFrW|C!NxB;?i_Xb;^;YG6l-b8RhzBC=3cI$I^C+}$aOBn3i#l!# zq6)QRlTvE3eYx=f?x4j1TIB|(5s#K|{XFUcH+Hx<+|nVc!MEksjFN_;(g6q^f# zV}1+%UHkIaqUrXj*o9E?+W2dqsDO^rq50i!`XUgL=nGT`H>a$s(^aEvd$;9%+yeQ` z`;K2B;SP*0p+1N~NeuSw7s}lw9H) z(VQvSQU1kB4)@a)L8L!c#*DxDUUDSY>m1GnE|9T&H70c()#EDwXmMgX zsG0;;;oAuh9oQh9Zq{UEWg!S?v2E5bl8N|{I71wAxtDik{@VKr*3Qd&+(~o(y2IR@ z@WaUw*0Ge{&u*zm!ta5^u2>e!$khk0l>`yW^P}$23_HM4oU(6 zQ2$N({8v8ad;S{!=6(JvAJadN29m!yp?~EEyv%LVqn?f0=3;n?mFJx*esNEV&>XK!A^(2Ixlk6T1 zVsK~pmhjb8w(3>Kxyka=x;AY6OXeKz=OzFyR^Ny*CPRf8MOM~axo+X%p|WR^GebkW z1S;4$K8aQFK+&66SKk6@XJ*)u66|vOKBk@kGB#GQcD-|PF!=mNF1$7dYDvgd=0^7- zBu$Hwetb#8^YGG?aGs_U*ImBG&DYYnLBm(MNaN-O3YXsvCy%D62xZQ4&?H*-M05Kf z1V)i}%=g8TW-4< zr3Xh?(IWnEhCYr|=t2k=a`3DV>-s<=SbGcjhM3Rf9U0gn&&}3$JfxUr;WxBZdd?6% zo!9gJ@EaC2QMNWT@4ZU*XR3B&N8)-*dj<6LCTPB3T1+<%;UJ+u2LF*Qpp5YZ;;|`# zmg!;r1o90xlTx_q4XfPId7>{Kvj6>o-1e@~v6#tYZJ&OQQsoX>CK|*|{Hh;wxf9Ls;Dhz) zl>n$mZl&d+mL7MNq=O@tGu_FceI;07myH+|C6_RxS!)9SpcO65K-J#7$*{RE2ei)w z+vu{vo40Ucw7Bc{XkbTY0Iu6E!Sn$7D+lWZJ)6Y&E%^JxPO6%%J!`&T1SIC>8EX@M%ih~VVRNRSL%Lmf!-?GT5QMZ zb(C2;Llo$LnyGEF>AIGcjPi_R*Kym*DJV);-g0O)KQ5HHu9~Y+^HmYfJdQpq8Zu*5ph?%eR+P6LhyuF)rie2 zm0`6I7@nQN9y57ZwrnLRse$();{|zI$YtO2M4uN><3{zxX_y{W5#9%q%yEP%dSO}_ z2)#en=R~KL5X6n&gg#FRn!*AG3;~CWBpKPN5M<2iP@p?y@XQp{CbR?>xR{^BK|T`` z;8b0HN8|C4!-XGNfmZZ!R-5dbMEzoj{l~Wl`%(1wLkw)yJf7ni+Na1!z@@ z!Al(+^5(VbT5T_eZRMq*Z~!E8wG7Q6R`eB`%=daqL)=t151Wxx!wi5-rLPO&!D-MQ zB)tA2%?O=f>t$WNx)2uZmqjh_Sr!{Kc%GI=6Gc6C@OGv*2x*JW zK)Zfceu`M=N8G{MR!c2v_M6T63;JKkMkKR6G`u^_I`XU@oS%)0A|s7>-7DOQAlC~N z5)t_Nl{36~3g+{5JZPhE`|KCt+DD|obM@DIX@*g@DIQr+r6y0|$)~@mfj8Dkq#2os zRhMRT9Ztu=mvZ5=4)){s6RbrBO(i1+Sp}($3x4Q8%coqS+GTo~TB0;kYcG$)VT}SZ zWDyl~^q${5?Yh-~04I`6-u-w`{kIqr*|0TFQ1U0uQFq+K`0r(<}e4Jrjfw(l3=XKI37^EZ)o14KlBP zpz3@Ykb?QT2n|1wLo?0=Pa3@wLiD@{=06jHlJ%FUf%UCX$0i38j*4&+NW$ygvz_Ec z4;zqynEv->kAf6ibMJ(4tHaR#@UMPi}G8(bQU-M&S#o9Qia~w?uKgHik z&IU=JRK$>RitC@NX;7D0nKCbyb`kgGN2(?0Y@auBOWp9$njj|Glcyf4ePeZyGb)NK>-q{~ z?H^R#BTaOC^;GiV!|uxV;gS_wPMd=kyyvonq#@`+J=Z+hX zFyQu13!?&;T>0TU7O2<8YW^ksJ+$CKlAeWCVQO?}2gfL1GwV&W;rqcukLj>xF;?`9 zrsQA)p8h|tZIxC+270zEoa$!FFb{Q)*1b^mPgkazQB@)XFreM7rHftHZ;oKCWQ#gR z2O1;7oK*ws!O~*YupZ@d9iqN^TLpJlm-VBeXz}=H`0p>7^u?S9}Ncm{#>!VL5o?HR@THjIM1XowK80~ zU)>BHuoe28vibhbK-KyAk^ha4c4Tw(#cRmfpfja|bFdID2Fg2PKn~a7rBlrL# zaMZD)a778Rm+aChf-Zy_0P7{OD|L=CH?MAarht?xrwHbe^7TIm=^#33W|KSM#*Jb~Y+5W>WJix`m zl09SGV+lp&(QdM$l6^!oj7X+!EG9ADea1l1*#gOFV1TrPmaiLH9H`#rs|OmX^|tJp z7_Z%XQM*&Q#|3zyQK!G$mc3dUZit!5B7vYkX?T8!FiN|8zC@tE^rMjo2QdE(#UTpm zFqBvwG9x_cb7&G!jxl=OQGXt00zuo{28~V_Zz0ZMJ3w|XwTN=>?Lh`eB8&h zX95l(1Q6AsN`xjx=8A$HL-{k<;7KiqNZg@Ls($0U#z)5foK$=Rb(ZfK!Z=Wn;9psz4O|Xgi z9uhI740a340I5yLkwIRW@4L6AgW3nd>vq8Q;^cX^~ctCcAs9%X7SlPLz$v`n2Dq0xhw9s&p;(3{m4)CC0k zurQfLs6TgIGRDH7*2wdYJswFd?Yo;0hj7e>Y+kz@)`RgLvy3{^{g2CuAR6(!;+Di|oL9}4cn$QTL8R~+x$M-CgZnr5xdKGH6 zvMK$0{|PB0hTKmWi`9mhxuQop+fPsUC`EDWt~>pjIny8uQy8z5(9YN2Zmyc}%7bC4NPlP(4>@)A%O3m0ALdt$s!@-igN)H2c} zB83UoMgrWGGS)3_d>E752urn`ewT%8$ z)+bb%C!-oc;#Qk|Gblaz@+95z?NYk7v5h2)ou$X#qbQeFFjSybeU&C-HiBXFx8Kg| zpBPFg61(O_d~zsA$8dU9IUMy9{L&~t;?(O+zoU^071XN;9$4AnW z%9W5O9kkC4OR1%Bo}qUi>{Jz`x+V&S7s~;pDjv@iB-P$Vh4O1 zw8oEQ=@5#6YF*W16!ap$2YfEY7}ha=3o|Rv^WTCY0bbqUkzGIoOE&=ltpO*VHdJpP zr-uh!rkicV3EuaiG;3rY71CP0uSQC@w6NdwlTtq)L#eJ8oa`FMLkd|Unm2MS4tfze zwy0)7Qj%AO3*lCg2EEjHWBuZ?g$q)v)~h=(6G9H8`KCxoh3l3cYg)i*YDAcmxLP}R zy6HUk9Y6E^qf2BLU@Xw196E|TD{Qv{L+tt4S(- z7)Z#PuR*cQ#LDjRlr4^a_D+Kx|0eDP^DVs13`J?aLqM3StFIcA@FAdLEqe&dgbxx; z*MTo$?Qg*lJhKE{n!Z-Vqc*ThOcRIhhSr)RSEsghW&l%|3^Nmk9*xevEbkR@1OR6qeVBqens=LsmjH2)#C;?V>DU$ zJ8ND4K(nDQ1Ac4u*lVBsRM35^NuOZ(Z##kcOr(cCL-EQ#8x(^Ofmt&Qo8R5(Ld9(JHpp1AM0T^pt9cjG`w7Z(GCWvalQIGo1Fs&O|WUZ9m9YnpHLkr^ILe zc;W@fWOA}3m~SYnoQ3e2 zY<$;DIh*7Rd$+D0-lj%Eo3Z$gTtTK#br&<9+v}IG&`8VO;!A;$0+v4WvW)js6olpE zF`=qkwcUT#jv%$Viz1NIRldA*1?$YFbQS&#>9Z5Adb^4_1!8gQ+bqRt=;wH@=;EfV zXF=q_@}I`v*!LKkyd~5(M{w87G)NdlMNWF=YWfA#;?WZXdZJZfFEa3Eg2t`0>IeWx&vUm3*E27qt9p5HN>6vJ`aQX{g3KThxcq&s1 z@yuIDQ`r{2<)C-SEbDN$0y{duS-feeYzXy(p8=d<{##@j<;~N#g^ZBm5Nq2Hj3SV- zQk-h1wM)~2GXII6Xj^gR%@~SwsAJa|8L!JwH7I7UV%YgzREZM_Z+B$^P3sLmZ)w5-Ec$}+7X~FRKME%R^w{U&6x|6%!-oVXfZ?t@}*z^_jLafBP7}F z;#!heQz9n~r`B<`ZL#}f+^mRAe(nOFsuu`e=Tepl!!h+9t6VOO51oOMp&)j3hsCLx z6j2G--lp0VU--j;=s7N*#+{%J%0UT-=$An{%AZsUvFBGt0^6NAg1+;-Mlr#_e&*Bg z1wi1-^&~(3iF_<^sy&!=8S^)pBs-WG>}H<3%5P(iA+6v=0;He4POXzuCYcJ^*stVR?9b047wT3#Jevhdhq8I44Wfkx_ zt5^1Q+PDqEtEvh$zp;D)Iw!pI)RwVUSU}o>L)(NDP`$8b6!gZwb4-)qRJ0VEmt$OK zE9tCqiW@@Ao@*A`bmp(R=u!WE{_^Z?tO66^ALom~r=rva)1xnuhrrV6vGFYSNM%kK z2X@1H&5Mln9u^9gF;P2?LcJ0?SePj6vo2!@riQA^Oa_+Jv3~CTQ&Q!p z&*M4jl`ZK;xgoF0773H(?L(qp-~B=FgALg#ZhD_xy&FA*%nTI>bRazgefXfLqu3fa zOu;i^culrAlSC~9g($i04?&b@hsLuZdul^eXB8&vvF$HggpQknQ&o%q7YP4`ZDfl#D(1f)hHA|>=tLN5{mNLN6rbO_RW2TAC?_fVvF z5Fzv;U20Bz-|x5gw@8r@b``ua5obe6i?RN(G<$0VsByz)qt9qyF2wkC2^zh)Zb_- zWMpJ$797N^|JmEyyC_sV-ziWr@qp%LheINJ`+7^(ucxP{&-;zn*49c&O0d-y29+b_ zzl(QvcE0u(V6oUaEY`q=7u_2w7959X>;UUM+uF+C*w_eUNj9dxwmj`Sor^h>Dc|{!xv^;#pKjisAk6W;+=Rg@}f~&}6J0+g0_h`u+R& z)K>1+)|M2s0#7u;!4_$OCmvoA9$k4=F)$q^X0`@aMdz88n{nY8mb`euu4on}Di*PV z#fsxuEQ|3?2fh%&!^1AAm-`Eke5b0mz;lX!GJ7*OS50j%AT&0+929M~)$4~HbtpB$ zvqZLm631$)E(H8~R#sM`#s@|4MBj39WNoh730a8;PF@d9mF5NXVzIqjTfzvDkUqFJ z9-dvD&1$|O9-ip+=$#m)7w)|)SEI6tA3HWTd-?E;3!4XG4DlQ+y=Q-|jD`rC3mM0h zKE`6VzZMj{a*T)Kl!S*H3te1XOz*^8TwGwcA$42p!HGG-!X~Sgcg^wGw%c!+ssFL^%JnbvzXfKz%vVvt7!lI=W23eYBJ#ws_XH_{?TsN zV;L#_-FTLYa@5iBu@0U-$JZ`l5j^z9>5m`7C#PovYey$*BbR*?c;Xg#B4T)g#@O>! z>~ZJx_U6>)FSd+X+{0n9)lqZUssxJuf=3&hTiCg%t%(eaYAkvKDUNHv&do)MW3dzG zJ0H0|Pn?`0vFj~u`?%Jz-7Y#T_T)#`HcVOn-p zc6!$L&2#R!^W=1V5jC{iMIZIEvUsrN`UX3>^YQxn`eXi4^v2kac$UeX=#{Nqlo1>D zqyl@^jAs~H+JL|w=FT1CWTxlkHCLCBlRsx?XG`CSolz%A z5aIbI`AJ$@?9FxGc7b)yoMe^k$q#Z^@0g*0p@yJoAKfZ79v+Xk%4=E8kFz_e_aTN_ zsq4w3Y{GGk)}FC9nZ7xGYDa$Dsfg)Yb9rPxqR8xs0FO(lXmW(_-Ype?f4$QQqSF8J z%lO4a4F6CG$&Q-qU=Hsvby(=_yZoFh8#}%WgM1A`L*hGIJLyaNZa4GJ`xtk_cOfOajTy@u%$iuvUON9>1q$`VT(i$+&!Nvu|@d25B z<`%!GyUSG;d8O|G&|QarN-$DCWn3C(`6`X7x2;lBNca6HAW_3cBheA_^B_!2hJCvFiJC3S zPPG24bK_vea_A{LXXI_*3pNCe0I)cu!jsWg4mrSr7ii+MiK; zH?I3wrFN2fU*tgfoT_4&qch4*-9ZKKPBtbakh147T7b){H${ky>~>d2Ow(IJhodU~ zXibI^NFSCmmZr>A!|<|}w8X>sp(=5jx`=C;3wwU+XjjY~K;}pAjX9lXx}@AFJlgxm z;29y9!iBLpp-`ZZ6k&l48Ked(2p|VKHGGsa2mqO2aQ{d4SY^4Qkb?T@4=Ui%hiOXR ztN(U2CIkuR2!Dc71MYLP)7w6#r%x5OXQm|#4PqT;w4QI!RwFB8Jv-(i1kw^DGw6Ve zH1QD@OY?^_uj`tRw)gSTcM)g|&u}U_;mswH;Jrtl4l1#o6Iet~(_nJ)IHbnGQ9uP`96Ww;j=EbwfOtRvcy{;JzeN!_0=u*H>Ve>A7O?akoMloV z1DGJhvJd_()LBtp--pkxlb28{yThfvo~Pr)pasn1QuoE4#Zzk_Z_aXyu~Q#Qm_&7-vbh)gW9gCl$~G6Yd7Txb*!N zLen<$Cf#x4*wG?gq%iiPOrv>wrsMh@*S`7BH_Ule_19We-W*Acex`%m##&&0k&t9& zussjB79U z;a$J}u2C8cXq%2IB-gl?k3jY@_cNxYBu!SU-X^wD0OR zTvzL(v#dQmtA~e;*(~c!dP2Vix?bM&xKTUXi1|yaEy5c)b>FV_XjZE4HQwoacONI; z5I{63vg`O{>-gGan9dp_GCQ;MJbA?1A7en_(peW-xgb8Zb=90yms^l2>p1@bG8YO+ zKMH~EThP`o@1;6B{&5%8jd&v-7 z=ep#W?>~heQX+Sz=%a2wWFF*l*r<(2cY*396u zY<|(GQSEB@v-JZZ0@PPa$ORQi+G7sViV@p;qCGu7;x|xr3V(+cdEx{zhv773tpvQL z?$$7p;vEEWH3ghfA-0vrA5KM6q8%GNhn6OoiH4T6Dk3cP8XJmtCl`E%>lYZ83N_MO zic{UBVYN!@i-UCAlS09DF5AH>&)*-05WBDB*ab_RhA!-i=R4C%S2wYl2YYygvk0tD zK;Qd*Hc6Hrtv}WJVlKi=Z&DabU>SuKh#|T|yklSX@RL6qU)?8G4| zim5m&@A5Ss+R#hhj6PDIpF%~1`Tkosse}NRhV#9s#b_3B{Q^oEIq#Eb*NL-u;;!Vj zkaE}4613>xlxtec)@0PP>hFgQ>n=O5Wre|^*BNr<$sw#{Tf!ky{(Y&s5Ar|f6h!~e zw0#krGVSIq+71VQRE%uO6^v56{aLZGHd{tliiU6Yf2Z#d^De<}HeR@_L3%7Gam#k( zUu&-Qh5duycBmn|iWb!hkKA~}UYeeF(rr6@8i%3K9jVo7;=57>`Wkm>W z=e((E<;Ryt%IQer6Y6R0b1$rXGcfl zlAXDGeczLZQpA-_hasv7xlEs%=*X{@QgxGF{nfs%EP$qhchaF=djBLaN^{`{w!4}N zzrNWxySy&-V*^}+VJ+#8^EGw5M%rzjMbNq57+_LT?Dq}@Iu0OOW}dY}G86IgDWvbr zF!&90Nn3eW5pedM&xJg-4Z%~vG|7;f=j~KU{Dud&JGnkXyT%^~TPm8Ud7Idm^*Ou< zGUy;9W2Hj1_h~U4gCM$Wh;=OuG85;3@FQ)o2z)+iL7luVkd9WB)AUPhu_SH}!bTzI z(H%`(L$?tRkR?0_GwZuxxmF7BEntBMSnh%5ORc-WyMCOKdRb4Ha4r8J&)<3;L`#_K zr~d+)|KQDk6@R-UpE`1P=LQyyF&CLw6+zq?E}m(oGQ1n*{;qfP#INO4dDruNT;y=thEr<;1P^hs?~EU#?uYE=Li zML@)s|LJfGh?4a0#5gP;V9|0HaYe@`R;oWVpvMoWX)}1=dw?`Jud8P%uIo9cq5V}#0wht1bR z`U6wO_PZnwR133PTO!|zmaLF*SUNVPFg)~gLfnL*?J$hK!?QFU4gO88hbcK{+%xUj zzr$?rnOF}MR!xnq<3foeCe@J4Ox4~d5lBxyabZ{&Gv z`C~v?CAizwblW&v`g92UJ=o&_qi#Ib6nSbzcri=z1({=h*e{@eJ(1zyGJc51@2&`R z_uajdA39`FaIsYFfizQ z73wTAFI5Z5W)_w9fm>#fKJO1p3RSj1&?QO z`_zw(8nMR4iwwvh_QN!Xr7+_EwONq)zfOYUKmKR~&;_IY8%e!4uMEgQ-s~7_D^KwK zwPBo<-o-hre2pPmu(>B~}S&xqJMoIA_4=nT@-KnQ0gR~u zZFC})28LA1{?7l8g3%SX&|T~$7O7z*_wdoEZrG%bfb9oUTIAy|;G1 ziXhTQ-SL)8l_?gKA8?7q`sn7S3pXUuy3iH92pTMvzZ-b;1IN>_tE)+;P{X zO-G=UbJG$gM0U2b0O~23a3p5y9X?_^lKfsOB{ez|BnRE#SIdF_&IDbAs^tHYWv(-Q zDE!;OaifS@oXVTC?s=hV4=l$$YVI*un-M+ZD|$5E=I&v+?f2dniMUBOq;sy!DdDWC zaME17@W8b0&^wz#>KtZ0%T3&`GXH>uoz6f20~uM=Q|l@)nPERKeYjEmp2o!3$}8r& zU*ujkaV&E&#iroUD!3sL@+k?st93>9;duV~T?F>KJLnC-k`Y|2sNLYS1)+>g5}@V; zaUZ&)j@NjI2N{PAef*G(*oc)#Vg%VTgTkJ!Mx9M%+5FV!ld|`3pIZB*QuOxR-Y%o@ z)p4~lIHdW(eq7!1^7!jJc@T)Tf+K;iP2QR0LfhN#ChD<1B>eNAau@yWUqjp>R`GKVDdHdLnt1J-)l9_9OrEk&9u4WkBAhdp zHx?M(Qy9~PD=AK1~f9Rp@^0>yyL!7xzJHrV=dp~GFVg; z1Jp|Ts5?=xT^6XV#dW0AZ5=8#Y6C0O2SzJ8^KXo81-?6dagCf2R4pjv!`TQRp_+#; zc=HLy_gl@xVi8AMNUGA@-1f1#^J#=AXlK56{&4!g*&OZw))T#hjnUP}6MD6z`-({- zaKR#w8e=j8yM%+=SvL{T(xK2{iPQ!Du4QRd@*5=(2D8>adlJaRU86m7%aM4X=;mu~ zsn)05RR+QJ(Zcp{1Re0?&U3I4X0ca@995r5szn8qK(S!8B0a14+rECmOx_WQPqz^X z?#dmU!Wl5iU{+73J$0HejFroeb=ZA1QBJ(8+4iUVIsainq)X(O#P*UD2EFMGN`>!^!qNU&f7(lgg*AhUk6qhsQ;Jx;SNG~=pR!yl&CS}w_owCuB1 zAi|!W1Su3d$gX!uL?o3@F9ILodT5DfI4j96jSy%?X`i>c%Cp7Y_$79IMLZeiegZsy z_F3aGI$9h1wuUU`eYc1>p^_fPgvpx^_T^aV1hr>o6C@?-%mqzJ0b`zy!Xtpi-Q0^? z+AD|^*f#9YpJ6Q+n}gGxqZ3cnOsT_pKnmEU<3(xu!C~DCEye8XQh~;zu_UP>toz}o zF&LWtgXvgDD{KH6*Aq|jjnjMGvbcGl($PVMgXUgrc_xab{0=Zpe~1gCBfZ+WSd#)T zF@eM3vz5A3Y4hO?6out5sCS_5V%2M0e7T73s4FBW*ZZ{w1)|P5Ary1SdPU-QWHG3>$X9wxCK%J>a>))9 ze3KZbJ^hQtCQU_14}?rF;+<&-ST^wa>iamX7#DS3b@2Qbl>dVlIEwXOI;*w(S0IjV z{Tq({2ipH>%HRma5c!|AA)w;dD>7ocDl<4(`S|I&-g__(?k{u5rDh57MaC=@Gj<2~9fCon&xb&nR z|CU_0c{Ec~@YCG)9Q+8m$Pw@7ZRFDq@7g3&?yM3CpdF=`?_+@Sh~G~l7OcdrcPz%x zh;LoZFkhLq&LQ1D1mHDd*H&N=V+sxP^ymJE1S->fT$&= zNd8&BCd+AHYQlI~qWN0vU85oiYxsy=5%&&7qj-}KWknI(;307}AH+;_qm_KtFSPl= zIzNWEolgvvg+W=S@lDR>jAh21$JC?}3|1h0%Wy9` z(pLBP#VNB@=cPJ5Bp3S$7?AxhNQiH&o-+J4LBUrWT6RGz?Fo2+gq9|_AvoLGkKT%1 zShG^O7hlBZbDBPRF-2ik^0Q$%@Umz7h1K_ z%{}*Mtq-h;_vG8CkNfuzc-{{&k;Xm(QthidSH^7YuHUaL)l+sK#r$5l19M?}V#u7j{t(ejj{oXM|u@NXUe7?-j`j;HNLQ;$W5 zCL07Qdb}lK+K7dgrexLGCI|fzsvR?|$>JpR<4FMc@qhqhs=nIZ;7L+=P zQq%BJ>(Y#oo!K2(g{?zEsX}a9^T>;Soux*QTKQi$(`S8}& zF3nu+edu*t>lWEi4V^8Z!GbTh36$~hAtblku<~H)D0D-OLFTaG$+eWFS z>;oMRcBft4R3(*#;Qik5-@?09!mNc=%d~^pAGp}oh37Sfsw+INp7wJ!B}wNseh{b< zlAC%pxcE|OZ}<@@&N*y&1rBwlBnscyokEBdq-w4xOwOy97Ed!h9b2v$u{YbGC1E#w zmdBqwNDy21C)ad_w^FuCDH{wI^45?HnRxhKXR-_KQLpfaQo*Uu-}wWNUN8_7Rp|fGR*WlI`HP3is+%v)cub4bl$M)nH<{OB9wS> z*yBbg{im(w`qb0+P{}w#7Fq{9$v^TvnoTeN249%C$m2mV==L*a2UCSPs&gXVzoq1x zmPN^EVMk9G8&A>3i`OUZBJbIHG_K9`B16+i!P>T!oiaOq|KxZ7@5$gq&!MsGk4Ixl zzWH)RfzQIBG6ZVe-p7geHnWGdl|do@cSylJHaYJ~_i*$&FfsU>iarIjd>l@S^xjGH zz0ZRqO`MQdn@LNT(}-Cjo}R9NPneI8I?1`H4ezf7B`14*@6oYnYN`=7!`)%V)9a+0 z8>wdB**!(3Y@*hK%?+x`9Z*qVv4y|etIHpAwnh60FTPJv-_37<$)3EPic z^?ff_2VyP68;Px2aYxU*Lc?7J5ue@5wi@%{C!NQINH=kzD+yxZx%XUFF< zQ&0SN8c(jO6(%}iKI|s1^4Z31j-NDq8*Ow!DeUfxbI+(c`tc#y5`<_`W|58qhxQ*} zGqFOTh+7JGeN%M9{w&qLr$AR3&(*ok(A(-rDPtKg4BAExM>5~Msg_EO(u zFMwT-$unb-2ChNU;JaubBEWlscdc1;Z^7)kB=`5Yu_MOTiU^=O0`#onTN5L(oTay7CtHqnPW2C^j<418!Tt4 z^cl7beLORL&?(#fxcfWU?T&oh6HFXgyvnk8D-pwa*#}Ku=xU}V%b#dq5>zc7$uBih z&5F8^`LdlAT7Lj<8PZmyd@a$$L6UFyN=cJic%fROf!uI+_EGeFrEk3$I!h|Qi_rJ* zf@ftzRoA9Ihrsg>)8(#9k$rebi$#Z_&&Krehh@WT2k*J9%VF2}Pf(r6j6RT^&Y-{n zYJR~XMQ;Y&uu}oQ8nI8;0?)oZGMn)|Uj()v^+$RizJ!^baW}0ENeo^cuJUY|N>IPl z^|Z+`9>YH@|HG9UaTKR?Zg4fzJ;vUGy*SG+RvT+-fD>sPDceWJD2s60E>d=U5eBQe zS5oTN@@QygDwW5N5$x?mtrt}T;_8asqE++XY?JcuPUg9$?ul6HQeO?HPn*P|fzW2=f_I8Sh%*<5i4R;gCOr72iRs@N!0b=VgI5X9s zwW`CQjD7szWG3gWQbTT%CyMns#an|Dc`{Ez;Jk);E!XF0S7z@!+iD~W-9||Y4AS)F z`KXfF)lquxcmeIQwhdlQ8beLY+4myeGUD>OU^{p-Ohro^su!_cvArTGN@zJV&9M5T zV-21!2{&y?ke)JrB`XL0_5^JsY%b{0moJKFX_j9&3lY;hwGq*>e}D)QXPAFqp&gD0 za-DzIKYy6UEm^Foc{3Ghv^W3lnQz`Ud}{Ni(OcssllSOPNO!xG5VefG;~Pa>Cc}|B z`YF1FC$GRz2vi-D%(Oiajz0n}f}84*fwt1(#2J>?&pTY$l)4}3&UhHr6$=SxgL(tq zkI^=#=ABjr&F?9ILNz(z^69a}76yRy1v7{0enQlrjcPLb`!)bZDTDX8L`KGE2R{;d z_0~(`^mF9m5z;9Jgl0|g{plSxFUPiqsYO8@3d1?swR4kwe`3}4-OvSUAw71(a{j4((PZfG zU!M0?InAP?$c|_r+7+^W{`C4w93hy@hI7!4z_8@SP3i%v5t83rXeMGVw|OS1KVX%3 zK7Y83=3O5-Op<8gHSp={s1^|F8>_yN+C5Y*TR6Ub=;`6lP?Va7eZv4wnBP}tcu|X{@q;ZmLfGRKaV<3N9?o z-XAYU8r=l`yS}j0unWf6_|%*1C)Md=|}&j5<+zM(QUQ5AFtl(D94kKJ(|W5X8&@T z|3!M{@gZb9e{%c-TTB2}!agzMuD=M?*{0FORCk|-5=Y1p0jc~~=OsA^C+|~_ux+j? z7w_NqG^*LpPuY=|SS^*%%C&uo+^Xl&lZ<@3IH}yAr1uAszJEqeT@v<4sMIv7GH!yP z{?S(I@DO)qe~h&fz0SItMbZ{QI%9cMI>*T>pREeD(V4UT|djH{}&^BSpp>Jz(^E&Ugl`kw2l zzru`ly5}`aqgKBe!z8FD5c2flxA#v2zuP>ie`85nel)3k1Q9|#-O6E*!+}@e$&;}+ z){FJiSst5l=3Gt0?cgMXNvqBXskGkF7Q#sxv7Oam>NZocZ@R00jLXiEUrnqt%G8Ya zq9?x`pZsiAY&HuF!v+q!7}?8MHUV2&nk}?%T|O&A(inY8(F}f0pg5ax1`CA>^t0-9XeaMIWcB*r*Nf#E;znAXzkZ zpSCribR?MG*}!df!yU(ubhq(W^qK`i>%V7@7&z>vijDEN z@J#}jcDIvhg79#%to({L1M6;gp}(39HUm-!=B7n|AdR`SbK5w6KiWq5^b>O-xjOrn zxg!*EeKIS7xqYcqo!9tUpV^U+#pd*wRb!@aZp+Nrz91XrQE~5LRy+ItxwZktmvK*$ zDFrH_=tFole-hJd*c)BZ-CN>W<;czI?aJ*akj?wou(2CzXGGgx-1N`4Ysb1uQ$8i! zp(mB1?TNygDuyHum|5DRT4h2%D@=09m=wIQJ_%NLWYV|irJ5Ya&pABxsOC&X>s!X3 z^I@*jnb$=cUy>bJwsOda2Yhrr+%O1cPHn8VL+ zKPvr_>pj8WAJ8-LhP8}tioSJ^8}3SH)wr#+_SE`a@|s7E%SxepPPOItqgP_@GavI* zwrTWdr%t!KL}#gD5q20s*;;`;M-()3U~^G69+Wuw#GE2u?Ic&y8FA8vy;AupIvW|U zU=MALYpcpsr7eF@ltM!U^u`bGi*sR1CaP;Y!SIOc)mN#oNY(Vq0*kM&)~imPNt<*3 zqTVI;IW=OAW?&!?)41y*V9EHW*q^^>@vY$`NIh^jol%z1(>Vb7}YszQ-0P^W;WzMy~KZ~|;ZX?{dI zvk~>*fR{pmyUFAK)FOjedXhSx$^uXv9`$A8#AOcjwfKOOUr#mgYyVMzLL{QeUl%oC zp%D))5Wr~bQn6_cNUoD1hkb6N005CDorSZ$NX#gXORF%$QIWH|F8SnJbx_>Jfnm9q z%0r%!&SrrIDR9oz!^2aRu207*{{Hr5CSmE-B5c{Y0yS|yHs8%|>c3^>1*O`tipWm( zJr&4CX>N8_(w2=&akxnOjVo`5vnlbt8*J4m`TZ$&qWe{+TmcNF2#kN0eF)3eb?^k@ zn?@k=Qb%u)?*SZda8>)K=D)113D0qI{&^&B$bZz^7$po0kzLX0e zP1Jm$_`rX)QTP7iC0U^#KX9C#L;54jU!3cnZ{6wo{RJY3&VG~ViGFUX%HB=fHkhc( z#rs8O$QH{+do|!PV2q0<)YvV#@`=j_xU1e_I*Z`)L^l~-&i@08w?q3Lx|(Wv+OTVv z^cp7E3HzB6N>szdTIMO5A}EV_Aid^%w(1EI&6KvY9H}r)w!!FkBPr`b*{GGRgdj}A z-kJpJt;{tVw|(0*)MzdDe~3VK1K+&3z9WF9%lh+&P?!dj$B$1VGCgX{Ej6L`j5_+5pTNx}jEP{A9wcdNdl8E^41?c_`er{|C ze|J*#kBM73Z05hw-Qen&Kg@(Pm#TP|JKzwrVC>_EHeJa!5N5;G;d~>qO2JGa;hCu! zq{&P+bXS|FCn34z2R*kIVLn(^SDbbN6A_-v36x`_k#*8?Cb+yagg&iv32M4$(l^ZQ zI6h=Y%I?Z#Tz==Ow%lRut7C~49W6R{(3#*LUh%vxx0A_zWghTdXMWv8*Rg&TE>J91 z_4V|-<{D)?c&6XhPYxR5(#St~Bn^GB?!FE#SUrl^E%U0L(puJ$mWh4LVqvsdtr)Us zA&#}0PJJ55WngaDZ|4_M`ka%!Dha?df|>ry{uf0#eKc_R3KP=|l7F#NCMr~e0<;u6FE#WP|8x?w7> zYcp_{8f*cU3JGe)hn|X_=Q82YGo&F_^68i7`!YZwluYP5 z{Pnn#pmy-ZUpbjO^*{ldj(&frmG>kCvZS^Ck*-SIIkAep8^~fhAG1<88no{zb z%IC|ZAha0#)lSc1j5;$av@^p~mc<@&nvd-jgCAWw-=B?s%%U)*@P%plMAaoKVjFkg z+#BQ-nIR4;p!(7T{_uWUd@WMzR=C99N&7xS4_+!OO6@nYt_PrwB?(8JQL9uXIzkS= z6vClZhE!ecB~pL`rj6{*kw@->;a)QBKUblUd*3GC*HUkn{pf{m`F< z=-;&ug+w42m^T%WZ&(U>lU!~FVdq1t*Z*^NvfAj9Czq{hZgRoYqHA9(V*2CAE+q;Q z;sfP=RPvmv-0(xCrjMx^vCD{)m{o+$FVl^?@}O4IZ5N_UZI<3(!(y52h;y^}SCn_r zA73iN%ye$uFk-DO#W3-yd=i~^U{GGAD9QqqKm#NP&8FNz zGYKj_Ml*pG9-y-D5F?LSSjQEXnpD`;q9Q6~?9gjpP;j|Y`2F=Re#a6DE58A5Gu%Jx z4;^`_%)j56G%|YMgaa5%eq8u)Af(yksmzv+wd>_+zjEQ8)7CU&^v8!L07|xuwDs=c z52*2(a1kqit&g0h3J;Q)^Pj&|RxKdG)V~V<%%-d)p4*SOCr?9OB{y?xNdlH7hf>XO z>M8Gi%;Js&h!d);IRgbi{K;uu8dBeXVutBU{P1Wg!Yq0+uI}9bqq!5Qyb;ES5H!0S zvw!Em{HkrX@gDC(f@0)DE)SB$O0pg%j!YiOjBUKq6gB!?SF-@okxf5!E-!u#*G^mG z2h7^Ug3r?QaXRbliZP3-1taMFSuRtj`?5#(N(kygLtpvLiCPLFC|?lvnfH{xQR~0U z(h6(uVQOqpa3Mli7KL?pn*_Oo`+(hB2##S zuaA&7Vh1rbhaWa34$k^^#wfx@HU`F&l2-br#)`)JMy|Gf#{4KKs3`I>N@8Vv2%5#^ zvF^Cx{=SWkjmyi+lamvz^?#FvUdzkNGZlm*4N;w=1x*rpK6CpVo?h=1`1<%H#Ko$ssUCE_yB+5 zZP5_B{BEDa!$TKm=ZAj?NeS__Wkgl{+mXGBxwDbSyM>jJB%P?Hi6KNqMa2O;(?FAM zVqyYuty@zZP^FKE*Z!21nfZ7QUM0ya3p@T;!mkKgGjVkZn? z$`1m4HXRH=z(NuAldkSg##ac$=-@!>&f{*!JKFZ>=}|evZku(51>*k3*idiju%_&E z)5h8|H_fwbF2yGl_IQnWhVrbvK`M|8Kr0ohqpelkG?Z3h@h3E-HAYtvO?jn(=;v48 z?u&m1mkUvOHDSS=fjcYkz02|8p??|QZf|cdk2Evl`D&`Gy0h_7s#+H3T2Ly2ZVskG zClg^%=1Y)e3|L(N2q@-lL@h5G&k2aI@4@HHJ;UNZw5A}6*a&mI5>owy;jffkU z<(+i(pOOC2Svfg54QGdn+Lo8M+f&_4#W})zdwWjyOgU98{na%ADE?7Vk%f>qC!0fv z;}XD|_k5y?p8zO5^73OtgO87o>+9=l>uYQ4>qAZCPxq&Xwd?C^!0GY9kwA#{x84nK+qjZLk_x0@U?a$54?H*Qib$0gl_V)Gl zl{xWVb_b1(jm^x=lyv4uQBhRjS3*%xY?>uSg_T_9_L~4Mnp25K$tQud-F~D~j>^(W zG?_g;Asxgiz3ezt0ek$eY;FEu`c*|&E)Mx@r=b1J)?>tF+(u_u%Oj$5e0t8Z ztg5nVdD&~GVMfP&YU4GUaK(6G-Xp$mdTfbzBINO0&If?$`|JPmi!0HQe*ymTn$sCB zkAFY_|CLS<4oUI%hW!g5=0X;D4l3ql2r-ZX=%FIZ55NO>{#WWht1qu<5+VpLQ)b}Z zdGWbFW4_2|z!UZu8UE_jx7$7!-YUQb)(96LMGffc*wx>^{fX*Jhzb1rc;44TaeXUn z9K7>yMz`^PUGgad1sFrJ>?x=2>vrVR(+0rQKmorNLac8*^hYTn2I5mhg` zc4G?giYR&6&5~LZew=i=+fdeA(CB_nJ=1bWsE)WT>Msg8B~+)84li~+o8m6wZpvxA zwK!c=c=WNK08uW2FNz5EEqz?QI`j+$%YAB=#!@7o?ZZ~={iObh zd3%UkGW27inJ`XO`jO!G1xU2YVRvAQ8^r?{cr5Y`{;kXIjZ#LhX z1~eo#oZRm9arcoJT$X)^E{l{YYrb$hovP7szgnDG_B@E>GGcD)PPS=I^w{HCu?q5y zqG^bt>3*bD_Xu5Ie-VjmA*_m+@NRZIYM4r1@;q>iLJY0fIGy_HNH<^Z?%5;~#dxIR zPihl=ZzeCb@AdWix(JDmpVYL?A|FGx%M#4*&==bIxj>Rm-N^9ZP+8N)z^g~aBByhd zVpjCe!-6;Ib?*i84Z7raqf-?3XE53MsPN+VKxG@LX4+|aFb(jK|F|zzvS4O=pkYe4 z@$q7&takTrUx)-~@y1qTe9M_e@(|alS*2;mQRlSAOfJBN^1|&?QTmLI=>leF$BN4r z%^UdIZy>H`&-mgsPHFC!(FJ{x&%le$%cWfO-Uix+tA)xFr|NGLOYX@Do*x|#1LqaP zi|cOfEtk}<+LD^~1mWj6xNaUPrSCCU;4T~Pd`r!UVY0q;KBeN(nwbaeo5n*wvZF;r zmnFr`eN&(P-$w4)V}Yc*?W@uc@Rj+N2WH7+=cuDdp)o2?;iGJqfGaotv^4yOFON%J zeCiH7j@)VGo!!nW)?Y?R4cDULC6*+cMF!a}a16T+l9%Tyk`31mu9jSr)$WIDmL)%Z z^GM;vAMrl9U3a&ln7!;xn&dlD#`f??Fi1+gSYDVKjFUL`%{Tc?J;i7_`6g!{e{j)v3N7# zb^DMi`qx-5=%tpt0*l>Pm2Y8rW~?9Nol)&>9Nho4fYDQ3eId}^r>SDm$FOr;qn#D@vCl+p)*m6X^5pN2H0+-Y47t6 z@!eh4N1Hm&T}{3X!lNK(h2Jupmc0mQUSU6;O7xN>NPF0gLAPo@hmsyk*gg~z-}1e< zEH+7x5jS|L*>UfHpGImTXm-Le+frCiUUMrohKnH>P@h|+e2|?T=5?Z@p<&6$c*a4o zPZL_;s9G{R-wzW$2~VJFIjp}dshKYKhtL#UpbA>AaTFoeTIrnSHEo)1 z3%v!a&29FmEqmv7WlMHR>Q6}l!Q(?_wn|&qwUE7|mfcpEX3dzD;&RUWF%^}`dR#%4 zYC2*e?b#Gm{9^lI|59 zCeL4`z<*_hJDXmgm~gfUr($jx>6OnvIdYRr$m9F6po7Tk*9}`TXnP@c>AFI-jeisK zU+dzl&+;KGtzykTITx{6FkiKL5S=H73y3WO1}vczUZgFb(T3iD%)XraOxxgk-2H3w zvB4chQHk%^NAw%I3*?W?G z=MW}eVC#Rw#^QRjhuZ0atBCyw(!RYE_gcFbH<@HgmDV%}McqdTTWs;${`*%0c`+8d zKXFgQc{~-a-EM8>zVJ23>dR<~{#r&JIqUqzP7l$AttI$?-9Jb{vjve_!3R{EF+Md z_r^Q~A}4e{=^TXbG|S5eggW(ABm1&mci@J2n`1T&g!c0mGbBbL+TR^Z1*N?%Wr$4p(1ZSE@}4uz$)L)6n#u z?fDEc8i!u5u~Jzjc#&=v_0As$)%TtP_G;dN81p#~%y_VcM-3FDO$s?%#x^Uw2!I_G zQ@wv)CP^Kb;(UCK#!N`YZ^$}iQ+bnZV0g^!CwjWU-LdZI@>5rn8+*Q;$NF zFiE}i0irHUov3gx|GF}WGl}7;OtEfP_vq-qQOXB7E*jk`8f6jnP!V;@K`fHK$yI0H zbg}HY!JvXMoWCDiZ+l*V0s?E%XN8hbY{s-94k1{hAyHCF|F zj68W>tZU%sQ4T``KG;;SyTF42uD9O96q#PlO)4cX1eMV{`DeaYO#+jV8>w%HtPH-h z-2L)vAV3%3OQ>X+_{O|4=^<)nrIJm<+1Y9PCCFlk&Ol?cj@1 z;=dIv}y$oW67s=QiItGQLVbvhhI z#SlCt*w`I`1&4(%4nPhHQF}nafwHsY2R==WHd>sKOlZowi#HBE%salu;h*u-U++<#a*8J&8xZZ z@M7~XdY{=B3vZ?Upjh$@Gx1J3DxZ?mwNdA*yf><77neaWkSlJO*KFwdwfTlLPv7p& zi97=$zUXX6S^Y8o$56c!Tmb*QAlh$oHs$Yo*~XGA04KM=4Q@07l7T*c{D=v1Sg2ja zM%eDJok!p<6x}~yoVuQeFVx33YkO`bH6c$yp|!`5B9K+X>c_NFPA$j%ga8OowV~JN zu`^7>W>UzLnacnRHM4BF8{!LZ%b@$sTgnjieVC1>mVgT)q~agJ$zyL%%^2y->7VtIgR%tX(gq9Jd0lh3*>xnp z(5JVg4`Zq-x;-+8wla=+$2a?Sz{@|FXPI^QG*>%u%JS8c%=G1+b;Dr<4(H5iw@{Yndu*_1TJsDRa>Z}c z!r98mG{Q*wx0x5F4X6=2ism&-*@0E_U!@#x@;-npg1fh+nR5bEv(RO?Y&iWiWDRY3 zLG0ZV7Ioe2X-*i-W=wCc-h%TjyV0Frf@@>P$H&LsQe8nW0i0kZX|08R+)bO3v9}Z% zb)}CB-#w?f;XHS{HunbrH}EJmg4dk!N=n*04exjI?+>8Pd4CHHjOqn>?2xsV-I+_qKg<*gyzWN9K|M8TMJLJ-XM5*} z^}*tTBzb%DbRGyi3MK%mOry`w%S|{tr^LKIKkXbFo6{H<^?_u+D^GHmAB3LtZk5gO z0ZHH9$5Q{UCFX%s64EaEw#1jVJOkbv4LtQzuQo;z@FhLOo;*J2(+77)}hMN5gZZ!;2wnv+l47k zO|vHx*+!V9KpZodbrPRuHZYjXtzq?L!+o5?)%g?IdmWkEAz5=N0SfKC|=j-8u5!$H60i zZRBa+bWhUAHDZ-@SLAcvh*JOqY}T=X^Q%TSa!k$GEsPAlRcRYstZa)aF9?A&_!g-D z#61>G1&TgY<<)8b6=a4fFoJ|0_9m)-b8kC_@*PNkoAQm_O7wW}Xp9hE!3e4r_GeRr-&3j<6U|Ex>f z1eQ&Av1I4i0$tJ)I?k4B9~+_XLzN+wD|J>2wi&rLnD4Q0eYtmuZIylDd8G~6TDBeb z^Z3}{2sr@wVAu4J4)pk{L|nH4CESjBWylwC=5879N;npc-b)lA0pX9! z>hJ7@SbH711w-r`Vdq~%i^Z{U=1ca|pYiS>O^yolE~{8}IW#FgGv$uB}a| ziY7p6mt`ZHo?ptZt8uS8keeH*Enu4`pXK4Z7=)}>ZC9cByTO`xR3Hz&N6up=CZoER zCXa*&`poHz6}Nq3%?j?-yZluA66wmrYO;k7ytlKNsr_SH{pNvUMcNJu^mL_$|2}RF z2a<4Pbg`2Leg0_v3kUd{MJy>aqlLV)382mgg)J!a>Klp=FgpyI6jjXzm9z+HeTYi9 zm??aNc}iE(a^*41Y7l+?!Kf9JN)OzBKj@Hx>Kd}?)ZC^k?k(sxtcR@FMHpJnTPI< zXr|xI{98sf@QN+z{7r1;L>%URb`}v z^D(9+YM;xw$?A%S!8{P~DSg2C#ZC=>jn!iK49C)jfygutn912u_Lby7PF#rwLa&BR z!{Q<9Hp1+mr}YC(QD?VV#rLM)z>Mo16X_<3M4HK7$-{#SfBx^LsTIR`r>RpVP}xgq zaN|g9D8wH8bK57p$P2AQq$3qWu)ID3w8;cTq3=ex+Go0jhRo{LT*2S4O(qc)3MPp7*(;lk0DGq;>7YaLs>Jt ze;+$_=A!Ogy)Akamgs83Y$VE#%HNcFq+`HLmp-igew`3e6)LNqrD`wI0u$V~^Pjz# zzUv~djSSKj&V*oeH9a z=^Ke2CCmf2hx`B}04~WRE84~r7yb+<=Q1z*`QIUcg3jj)adv9}Y!`)-M;k4no)4wd zy8D#>=Ia36CIzwvpWs?0e+JsB4iy zdv1m1P`xEbAuRfeeNhWoWikDuu*TLRY?99eSPtO=;#oy|d~aR(B-_Ebr#k*M&OV#F z|F56(v(y@#?{k9ymqHXq)h5V~mWQc=A1$|21r;p?ley&R3hYz z9&EhDbiJfGB4Tt?1*BCFaiuhMy}2z9vFgIrFT)_u4ssh-d}7am+O`!z5re5)4rgEM zzmM9r1{92e;tBK~emn=Z@ZH^Um=3?jJZ@Q@=!1Bd{oP5(LFljq(?lKL6|ZxcyqKlM zIOY=`r5bO|X8w=o1w(YoXOD<6&7SRF>=TzRS9tS7SWgiSiOLc+29`VGE!>P|#kE4g z6j;85kf?_)!y5?b?}ap&Gd?DT=ZBrR@=F9`mjqzdzk-q513O zdcW0j&C_>0u-4;!Gw^pTrN`Up-jttvj5R#E^KZs~MBG*QEzs24Y4!Rg?d@eK9$h7F zkN0K8-@l(v?3>e+jP(VhYYCjO8wlqgS;0cJsGx#}hG^7h%IAAed#>?(Mt9GOn+&a_a z9}4Ifz|7dN1E1s-X)8MP85jjA#>PJT^s;zOcg7F-7!;`5&&&%)=7yZ}3| z;eg% zOJu=d9^QcQ_TWQ(ai@N|=DY{z2PwgB5t{e!LV5(&8Zk}aq`<1~PsvSVlH+4~$@TU9 zUlru|ne8!csMYqu-7}X6)$c_);j7rOT}Q-OuypjVnCv^nD6{Ez%%HR438K(Q$=F^}{_3{R`21Yy zghCNP7?M=a6rC%$&GzhEEq#L8W4J3L4;8yV{UNuB9mHRFTG%Dgt0vdSVK2cEf*lE3 zLovasbsdKh0!ld}{pGDGxcu#qz8P@{cRsch1@B647n3}}J-n>4sGgkB^* zZVHct)jS--@Obe`Df)h)02aG@#-pxTt0wa z<~vO^9oqu-lXD^kC%j^zYr>zOT!~UKu6^e>@Z@*;+XDJ>VpjFvJhSO60YACMM7@sn z?wgK0bo`tu5CpiT$^v3zpp3xgN{}>cL}|DJa#Js2z4RwL3a7g-Ia$C!n5IvI090bOP(mPGLrqquSCJWWo%G}K z(uF=wQF8{*>;;gwK13lJ~ zYTAlo;IC(|EtX#0Bu-OCsg?Bo4giS21_LwYEsbvQB{G!_P*d?O9gOJtKcNwKagf^E z2La|Bj}MY&HwA|4saw0L+R?qAGYY+w)+98?=-BxqbRbAhKHMgrq|WHN<+Q5;Yoibw z`db{8SVtE%jQv*%luuAyza|{ZQ7$q+T-xJl%oUeX$v7zuG@3_GJ39gb!qv!`_#lOf?d( zHH&MO9D_vv=j~pe^eO~+Igt?2y7Ab_(l{21;75%UA!{CP9;n;bYKe22pQZRTeY zAN(6r4Dngp&-Bb0Q{)l(kAw^wcrTSz!$feB9UH8d_=-Zbo#0`y4W>a6Y9*>Rni+@j zzTQZI1mt!tlIseJV@hJ*r~ts{2h40g1y3jS|K>l#);gWM+_RHj`eY;PV8sR-m>khE*)p zie63+=ub{bFY8OJzg82<3#5-^G68@2ujqf*XHT&2$-BJ%|GgrEgGihI_f?t%SoUQ= zf{_Tg-v$U|#R1`LxxYh$K6?g~Mge+;{p1sSu1vqrnkEOvcW&U%EaWYlU&27Xx%+LW zxGm)_XFiLEOEXm8d5U-s>tX@*znl*7AIprn5TtI+WS5?>mswx4n9X>^w{qxTdK479Jc zK?ZLV?zqON1IYXIhfC_e>!Cge#i4@?is$8tdRI^zL^X&KrNOmB4T7G}y7T|(|Cj$9 zbgTAxa=#C{KYKddzgpLU?oQbx*%MgVQktHpP>K(pW$VOhEEOw?Y#u$)c+4rz#1?Db#B7zxA=bmr|OtoKjf% z!98nSWt=cmNg`u?zZjs!r{jXYEXJ7POHSpYx^Fkm+|X0Mi;w7LmKKGssJj9uwRt+$ zDzg2Vmfzg+zl8&C6{-W*jh71oz?mGXmy!m4Dq~6|6+ad)>&r%xmo{@OKN>rYVcv)X zi->uaxr&*}eHNNDejxYq0HN-2Y&C5;b=(_J$U$5`ezJjIV)@NlcBm&UOX~|gzxb`{ zuvimn3o-qy;3T&n0z5%LB}?nt%5tq_Rjg`sk_+mt>kEU5(|%BO z06qnmUY2+l(R>WZX}NjVjk%*aY1hpl;w^9;d*W1weOBk{!cn$ty1Byaw@VSXhrmr$ z^0hVLo$L%ghmBtxb2H@)!J*D~cm&Z$8G;4l0DvmFP);&cyDGmbT+b7~2zIbSFe=>_ z2)QL`3)$_@RJFLAg4&-n+YJ%h81~q?0xA@4XXJ?iQ_*L+HL~EYiYCQo*1b_v>2*<8 zZuXvC&v87;f~nYZe5n*Xxw>pA#~L%dWd$Y_R&NXbxRY-j*j9bMxKk1j zel}3XO48~=6|xGEpKo8jRMk~K)b*3O!T!7s1@LbD8VUsUmQj6nA1!XQd28O!PZf<${!JdQi^Nn1CHMH86ZtF)`e|s4!dPRidX0}PKstHC^ zv?XyImV(WT3L?|^_|`0vUw52LpPgAXeJ1KzTPJ1K6YjveD>P=Ah9*(%rV+V@%o)`* zGYo%y=Bp`oaACktOgcbu1t13Fm&KU+%(B>6Po)oxSl+p0YT{n3ql$?4X4kucEk%ECThwg`N;RV zE>v3-XUt;U{{1#RmFYLTe*De3Y%Ao{YlP5`tI_2L)vjkM@aqD*lFcv%xD3DmfnbUvopRSV=7;ua~J^tbj=Soe!Wn@$)h_vM~a`iYcS%q2@|@sd}2#5;tAfX#%rgNCQA0XB=MxC~4Ku z&?r0q-XO5>POL-Rbx5ia1slwiWDERFU{O4*skCN2SoUbGyg4m^(7$G^Q-fx>_kLHb?$uHM{U_^zc@d5n)l(?oE_2Ym zF1e@sdq#?644V3%?A;y1pY;EFc3Onl5BTpRiInw_)PZMna5BT~CK6k7iBFQ8vDkjKFf&^JKpoAt~JQHmUCvML$h6+=Dx>GR$ z#?Z48Kw=%xvv^VusayVsF&FgqWcbk@uWw1wp_HP%nMG|ZgOfKUZVWo;7}4azk@WtzeZv=mgJI9T`+W9MoN1l&APkD>KVf|M4j-eWHN6fvtOv5ceg21J;Qq9T7__ke z(tnA)CD|JX&4JOdG~|q56wsBxaInjJwAL~`v-Anq#CSTJxJ4pt*!%A@U`2aCio~Sp zH&&;!o96bqCL%!}y_`CTea(Bbl|N7kIA7`*_0_wija7RxXQ$#XHdzC)v}JFBXE|*@ zXBP|%=Qf%#;q>2#`{D}UH9|rI0pvF{CYr=}(+j3@ovulV%MmLTDH5m+#clHOy$KS6 z|Do1#&7F$CuHU~81@#P@IX9E}z-%{bq3FQfX8Svzr%GahopS<$@kO7qzcX1JayblK z*dmvCafCTjVcfSBi3YC0RuMTZMi zT|vrYh{4^RA77eXGb1^d5p|4{BTdwllVp4ArPo!Ei-KRH}Y?8*}dp{v6N|8n?=jnXx zR6op?@K|v0bFu}#6R+h7$6u}`y3}UQ?pZmB_DSI6gTd#490lcsV%2|oH-V~AK5Am0 zM}_q08YlD(DI?z%|AZS=_#TeytA=+53=t7;m)Su^0e6e&%N?1vXz6IftD_d@?lba(;=*ulXeK!%A&&%7^HVW5Y#Ppwe?kbs1ki=7^S zZ(D5){*5M9e;L0+94cl%Uxkae;-_6Ie)^Y*?`_FPP`0I{>am~uSGFT+1kP1MupE0d^%=B-O2Pz1Q zvuIxz`s}J6d_)EMw&=c9oE(gX)h^y}Gg_L)^mEexOnc@tsfyKd_QaYB8P0?yEb%Ad z=dS`+4#hvgm{<{4O1T1`nPC~8W|yh&oFPBgs2S~G!jL?sVuLKM$O1<$#+=mV%g@}+ z?5y^bQfgykm!HIB&1E~qwN7LBNAVyMs2J1=@eKlL*0P-(K4#P-=3xM&l>hR)h&hX4 zO>kZ`GuE53ySO8uH{CK$=B;js7h~L~%?W6RamGf0t`X%vkh3RX^?L=uplJxkFF>d? zzWxAg|nBEsiofNlE$)PEbwTLNwUMFD3Q^C?*)KZ#rpv=iqHO_ddx? z7X_c^kcO0DEqk$cEvczX-XI^nt)Q6;Wl`oG z`?iuH@4;~R{gD4>Iz6X?Wn9=x;yKLmeDUSiJ4`Q1pcx?dxsCqyo&YmkD0_>6TtxFX zSYJnWp^R-0mZC7cmorz&W#%_Y)U7bF^P4T$Nzm$C#30yMAks&u^FC)H9+l z9;m=0hN_jn$G^E2qd8d+C;)>wF%Dv^F*4 zKa!jRc^OtjV|04uVHs#2CGd?41xRpeV`+Bm&#y4}PauU7`NZfck|ov-aHTKj8u3%A#QQQng=ZH(i_vdcldTl0qi-+3Oyp12;?;^si4wujM9Lp~w zhW|oJo>&yHF1KeK;X0owJ`_Ed%%NeE4ip?gA8N)UvM@0g1fs{I0!LryQ*Vq2k?#6J z*~yubf8Z7T#9-mf9o@&Gc{=RtUxQ=(x7qS<+Qj1-W72-$<*0&LjqV;rImrumRiCg& zI~kNw{Rsph#i0M=@*hq?YC})z$p3lyAHC@RTj+o4_}@~|=swK$!n?&z@M5_vpbi

Xdx`_q;G5`Ro4%g_F{%=+3Kj`v=p5Tr&)(`Krp3qOa78wq2>hS*vEJ#+G zD2POhC?FPI5EZ$pPe=eRYiUJGD5x;+^-p+k*PYXUdKNn!T(4R_-=iz^CD3|0xBg3p zdia0wP1_Tg0+Bj61AW(~6RR`8{l;KzHeToRaeHXEj_U@hCizsJ&_Dj;c0v`1sGf!3lUObSNfJs5sn4}svR6m0{6cgwqw<0+Dsi)g>xQG11HYLcWvpZBXt?9In zh$8h35PXtz$AXNXN`+cgvMSh!bcsJB5{u^skuRQ7dAn0$1962wB0{3!5N2e5*?a8R zfER}vf8ameI2eJzD=XJ1J|b2HF#qj%$M_{hG-C=z%9ZxbTmN2ZR-K#uI8;{tFN>ju zto+?D;a~R4*cdoqS56{e2l6ad&82_*Nu`vlPtEg2=-9VGS3zSgeCh>%o^%s&PTu%K zJ9et18V~e+nZqp>e+erlC?&X=00P)Ch`7S2=D&fO+=dI@Ki_H6y4f}ydF#tBRUy!@ zF-sS0W49c4NA9@;ljw5`24LG{QIT#_KrxaDyv_Iv&Ojl1B+;gGi&9qk7U|QPJ+Kv~ z?>xI2dK;|)@^WNV4L_HWUr$bI$}2foLszu1;4W%5H>!enQD=fXk@9Sf*T=EAqp!jR zy0v2HY6gEn%B7MsNne@bds7wcWz%Rcu5&F4#=LwRZuqeuwj%XW=)7TwkxymX;zzN>76ozS;<^^0VNTe*Vx zc5hna?$WZ&>TIwtILTck4Tmb!;l0E)?1$7#;+9m={ty+43s7#ONNO8ad)#N_YF^Ke zc2w{UB>DiVrQ;M)a&R?V>%U839mj^^R(SP?{>H#<>0J!J+ZKb<>3ZypNl+BIpY}`W zy6uRCgb?w3Hv@MRbabO8EoT~J4Tu>6o9CFo^ocHpr+;cB7>dsFhS89FoLZs*J{snd zZKz<7MJ@k}v2qaB7U0ga@v|(jhW~E7V%Lnd{CYhORg+$()MM<1>5K!1l$zzG>-_1j zO)IUNRcuZ2p|$`6Y0<3GiVz%NW#~k-!z9_y%UAUMqKmN0cf1U(;=|AOSoSTtzUuqo zstr&OXdl9R$18AkC)+j>^@wDEaJG+cS;64WulgeA8K>f6s_#IXM`pDQoqW)*ZvpnD-56>KtPui74> z_zGP#R1V#uCOSfEQ=G5vn~l;Fh9X)Ya1MEK!RI`pnr5%)_PL)Crv^{%1S5G^o$)5G zGsTlC(fkfG-SEbJ~C8tqJm6NQn)}NsAI(iL3VT+n{QMpdc>JZ zhx)*}-@x}B2)>qEj08sH_XfOLqxq-Wv9xEuTuYdD)4uSJcxX(lcv^pDrc$@hl-Rf4BuXwB`KU>COP?t%=t6@hHQ7}8z9W=Syq2|KHYNd%!b{IszZs^ z7+}LBL-?9-JfmLCM`k5SDSOwwV(Ec)bZ5veuc;59gxQh&?|?F~q9rcLoa4xwar`U& zH*c!~wY644c@kbA2Q>~2ghirE{)Q|}{!3bVXoH`t3Hs*Rmz3drzUaJ4JyRG7UrFUh zW^ACV%@KE309abvSms>ncK_w9uXgC86c!qo=_~krkd5$bDE;TPXCj=G-48AmU;JEX zq8dKSnP&vGRY30sr3bnL(!ZqZfosLWJO6Rwhhl$NK^_gyK_&vV1-}$FR&T{dt;soh z#lkSP#7|>4`!9(?@N#pE4Mi4`4CV|tz{i4W)<=PXsxs}VPX`eGCnLiEg$?$iv9|^? z^~;kUB`ib7<1!0C!8Hjda~}BXL%&&VXIl7nMT%^MbL>YXnZ|@Cr1D}DE2lyEo6gJ( zt6v&x8uU^P7uIqDO&R#`O>>c~I!z}JKK z)ip}ti6rvpsEg`R(;~}s+~SbnfzgUtGwh^ZJQ4eZDd8k~BPE`*O=fy|QqDTkei^RF zGS1MgW_FR`k3(p{I60qBZ2^oUMEj*2S-4LNl0#QD)m-T&(gW`rO=cL*vKL8^$;l|6 z7-QlKIE+oWeq9IG8<7gpT(B4kaM*}>{uFx|6an3H7};y;9LF@pApeW0Y>>;r&^#_n zl&UT#QNLq%Iz|f&Eh$MeA87U-CZl^AvUP=YXkGsqFYcvTSR~9RB`*B0(?-KUN2k#c zRNv83iUpJ)WK4VlNUnPEw4W0Lz=Qm%t{Y4M0YpXoSv{4%LC5MeJ|1{-!|)gI$zs+~ zLF>h^a`QWwzLzD|Q%}x9A=EGaeAKOkv$b&jSBq;GdJ9KmL|s49tIF8OK6@HZL6`z^ z|A_qoOlbbtL<8P%KLe!``~i5c*vGPd2PZ5h{ntZ&gRBS)c2h&Y@1N4LdVTeuW~Wwv zm;?y!KPB~lnofExYtxl*{1y0Xxoqw!U*zWi)A-V0_&oDG4swXZ^;e_i@vqe!!ytdE zHh8qLeIX03eN3=7P-}M&Tf;0)MX^Z%GUBYiVG`hgs-5DkX45iNTDlzs_UOAZB%XJe za1xiQn2@Fpd!`tYpG5&?&rX=LI1e5IHJ~E?m;!^^+L8 zfC?5~8^gKC5x0@es@}6Uag$qqs4y2P$)e>{mE}LWt0TJTH@?ra_kQ;Ket*8d z-yFwUcgdJd?>oxRlD z?kfj#)uPbsaIu2A2zj~Dp;m{4#sYr$iWB7&PSnDnNwl%?fTF4?g;N+4&9#}Sk(3E> zSR8#wV^r}@=F`sN5Rb4hE+=)xm)>e$_DYhUSp@U)S!o(2Wl>oU(`O;gqV05u_lrWp zq_Rkrey<~g8tYBx^e5&MU(mkK1JTRMIjZx@#fY(!M8?4(dWRY&J|5gN#2*m??JP(c zRr7wX&E!h@I@)jZY`X@F3BMwlM;Jh~Q009V zjtXCKXPcHd8F;mbzXL8mp_gKsc9i0aS#kI0Xkj00qMrU@^6RurP+$nM&rxAAN?sTO z;vcB9l?H*0dc>T&cM$CLghDqMX6$>yDWr5k z8HDnWxGws&_`op&Naj&!DDHBP48Kx{($X_o$V|*7sUEHHl#^Vp)TL?f@->GKY(e5d zYgdi&3vPA>xue1BU)fa2oy}Sdy6uONby{?!l7q9~WuFAllk_(8vM?$YW{+h;2*HqP zDgPy;%y@4FIoZm&30f$^ni;mnlKy>sg42ZabDS#mNn5L zOM2MGSXYariMd{D?Kvv@3E=~#+$Mkmz(zKh*$Wz}%x5>LZA5({LCmky&7W82_v_KQ zX8{y-l^E3e4%D?acD=v=SgQsnO}Oli1o9r;Xh;C) z9H!|`?{75768;d0o?YDvFXBWFF?L&o#dkn>s{Br#^e%F=U{UNpVZ6+E4Xj@@KW4C+ zLwlBmT)SFvt}}v%@b7|=oLcL;CGz}k*6d^uEmGf(74co=n2>?dE&7kK!EvU%C<&$E zFSAfu7UXNZZccpDO$PDeQSJ#|!5qClOEa?$;W1d^nM^hVNXl3l18k|QK?#pSS=e!H zBcjx}>bZ@mW2#!PHX~wrwcc5iKunmrsm-Oxo}#{Y$vLmQTJ$~n$_&k(NHjCfRouH1 z44UjjzRL~FB{Sbp|B(XLE`uUk>FzRHsGQ-o1k}Jzd-__jbcOoi#_q`^@+LuUb9IRn z`nG8nWc$z&N2Sp|6BEWHLqP(?j*50gO0~)JenyTt>kl%&7({7+ zgQJF`;lEFND;l%Q!vbI5t1(T8E0qn8ZtR& zajCI+)oc7q727;qq4#ekQzg!S^`)n!`yYvkS;ivjqn!8)G)_(YJk4mi=QSsI2j@ex z1(o>NrgbMYa|sS3H@F!3x~!h+!%BX*VnD>M=1s%RiXWgS6%2*>dg`M?VjWC0CTS1Y z9D8!yV*tu%g z^qOu!{C#Mo?o4Givb8kpDWss`Ig~V*Uo^_UJ;1PG8;V5suNPqxy>x;Oq(PB0?*y;E zCY^I}GJ4`-d8)o*ZR4JO7Y1u#7KPx+0=WyU3V`=JI_6|0v#ZOY z?z2o|RP>pxWLB0Djj?Zp12CDnQld0!_zhH@#liIuXXlm@3}~3+kXzy^)ws#&c*B$; z$*(l6Uf=%W)TTuBv%Kf2ERX~F*Q9VkNQcB(5W~Op5gJC+4ODy#Pxd4k-in)X7wAw3 z-e19f9$@Ybt9AMA-76LbD);z~=FTCyhmMn3gZ}g`#KG>f)3!Kx%@D>pEKA}&z0e0C zics(4;C37@>|KuYaV0P9SmNMyrxv}iTWG&s#5~)zI!S;Qldowc&HDC6z<6B}vrJpe z;&DD6r3ekMzqAA_`f?20h5Hp(&tuBoz3kjE96m!v?T?IHw~>=s+u=eC&NeI#>rY(L z=?q9bHS-g1_a)36(4XK}X6%5>yj+Xnfz;(jG-t?GY3x15ii$Ug)@DujE)1|o@{=*T zVWjsatqrDoW(5!WtzyVYF17Nvgbcp)IzFbEeqs_DxPc2lt-Iki8OuEJt>;f78FFhz zWv$8=lgI2+7Yzcf_zv`E@Ey<2bvx$6%@01)RoY+JJhPV`p`PT_J|k{F7$v0u0{gf>u5uq2BPs#L!Rx7 z?s2{>eh$4)n;ia`@G$87(K~|r?Jx0DnY9#4G6XNBpg;KqKp&k5oqTEHR!wyMiK65+ zIfGZzNT4ljH8$3Db0}) zaC%W}CelF0M}6RfHC$h{70K zH(fyOAy~WacEf2bs;-qEEjPGcT+Ui70=2*|tmkL0c^z{4Tc@Nik`HO|EmLFn$78#Q zZhU**cs$6sE8`Fac&38z3>-xS4u9tZGkG4#)hgD)lWv%$A|I~~L35t{?Oy{8+X6&S2zvo@avKgAQxv7` zqxBdSMq^~bo+ZTcQHpI0`I5t9IiWO~@vlq$H0&#SHx&?c`m_fzYtrHc zM#c>SS{)cHVzH^4sRIR3YdxsA5LE2w(zCTOd%2mb@ZR2)7tLgFSxL9};m>_^TPw+s@I&*gV&RfC-1vW)#_S3W04&SY;UULJ7q}2jFrC`qcT4lNM=#3h_e*1P>yC_ zXP^4HdE)nxk4*5p!wY$LX%FHM*yvB}mk!}BIHVsG+g@!w#;Dgx8e15%4{gDIiL#WZ zL$_V_K#bU-Or!gc9CYtM%oMdUPzvU1!bX546Na**xBEe&t+NWwT}@ABy`H8+)cWMC z0$n>PlAjUE9uDG@TvhQm7I0-$k~Xh0IkbK#E;3-=TQsG|z97gOnE?+Oe{05U51GtQ zLyM&?^I+HZr>5@1UkG4^%j(kPc8=SB2?nM9nvHYNlIfS6#J9~-)M7e>XcPwiehW7W zQBWJ59{0y?IY|+Bs;_;Xiq^ZmnVv@w2SiZFS?nqoMvN1VcZLp7LXKh# zoD4S|p^`#t6B8eJ7*XZPuT2!n#(jQvWdPA?Kl-ef-H-l4}LAh-T&vdqqe1 z;QYK%lbrcVb<_tT8O5Iyriw~87)v^wV-Lcd_H`?H#Q{C9N{*$YDPBEYbBZ2e*A1? zzJomUHzRF?;i|u7R(- zCj+vTwj&NV!17+&kv%hB|0DXXN9h6p%r&6c)*pk4%wgi?9wqG7@OENC0ZKL zEWOrSeg;W;*NxTT5swA^Dfv>8u9H1U#r)1{Fmsx*Nk`Pv z)e%d9-ZZVcXl3fb5jfNKC?5 zPAVjz7TO9>7wh7-bpS-~%+rBBqirXJsk|HIgVLK*tE!$nJV8(pV~`y?r+q)vBmvfY zjW7D!k-f2B&?;2n?qgA#MP<&x2Nt+T^6@1r;}TPk#d9Tub7gSH>_d)W*UL~W1wOA_ zmv}UwV+Dfh)4CMM#yn`17Vf7s7r1M|lT{o{9Q5I5G!=m~1^lgRQgKu7!)~h`L6HRq z?JEpp-`mP1W}@ACJTA*dPJbnoz_G>e#QZ8>h0K_8WQZvI%tgXMWZvg84lBYGn1UY| zF5eBbWBF|M1?{MT!mJUsE_7?9u_sKubddP&xjevM z%HkGB06@V%@&8hB0GCXJV7J@n7|?+*81ui*?tmk4!GVUtx2XojZsWhyBZmvp-dDGZ z1i%A;fI`T_g{a~H$YXsNboa3Z%|q1Zp)@cC={G3?1e)%1zVtXcfWs}_AFzyg4X9B5 zcK|%SfVBS}0DTL_zXw3V*Z(Q}o$M(%sC9ooOo=6hx)+I z^37(QYAZg8E`+%|**17K4|q)N1`@31?jBl(o;Nmq+BNFx>H@WNNu5B(vkn^``xPIq zVFyJM5rDzOitpCu178{N=x`1{tz9nz{6n@=U2Pu#6+gfNfiNAKzRg^D=L@SpVeFd` zthc2r1vr7Mt;~I4FdkjbMHax!1F%ea3XfGSw24BY28gQm;Lgr}P-IgdnBZ(RXM$&= z{jCSv9q^Vn!jXEj$+kuYduYCro#}p!EQ}0L(>L@XaTj;PaS{!23ai3-^Hc=b=WJ9c7*{-q3p*x@LHyfAY z#FVg^o?iGFnoEB%rI*`{#bPO3Y(KGUMZ>Vi)*3K}-ZA^F$7zgQE!`ruNp|J{V!FHc zNvnt4SmL;(an{w_N)LY*+N&E_GToSV)mJy_i26oGp!se@->uQG^nKw3`W=+U5=x`llZm&A znC%&)>Lf}G5C{2jad<%HTi6r*I#ffk0~Q~h`t$P}H^4+geb zR~wVBp6e+q(s$>dws6MeuX0@I(#_NvOg&~9n`->jzUypZ-dlgNU|96ow#v0#4+Q2x zGG185jn+I`-)Dw?6TNyopOb&373*NtoT;c%-5@)SNU*6mi;T~mJ*+=1FSgC7k7?I( z1A`shjZZ1draG#>8B-Tlf*ImYit^lbn|WxG_ePs)_D(4=3ogDtHQmLkq#B8?e{B6E z|65#%p{SR_v(TAz@kz0!(20qII{*g#3R2_wQ#6z;ddclO%YhC}LLx6P#^DI>7Uhzs zA8qutb!jQilARw?e59W|9JCz)-zyYzpy9$Esg}{Nrhi?u=D)@G1QR+bfk@@?^_EP% z29?y3gR4#8Ghd}EoQC%vrdFl8p&vor0_~DgD|nza0W}O4`x=#jKUX-~6Hqly`=(uF ztjLU6Fy5CGpfYj5OQ$~;MVcGWJ7vAnMB8?!ORfYwA_`G8w0RC7@VReWc7CyasSQub zLjIh$Tpxgvl#JjVp}uv4S^G&8T5$~REH;?sY@`GxpirIMQrQ4jlp%9+8=#}`ohmFh z*X@7gSUOcp+%T0im^&^DK;qxK3?#VPJx2d@5*w_GCHp>@=c0S>deM7Lud zw|hR&imE#ehs}cA1^KI9gPEpVn!LFoE1eoA#YgVSml)e0ot|HLuHZCBd4~2oY|}uh z*5jM(e5YRYd>O{cP;geE$Y63PNDW-t;v%q(L^=+q3T`{5 z@q|9^cbgF>dX(Xb*UsT(_!@U9dF3ssC5D0TD`IT}E~4)^>u6|3pr=ZQ7X2;@Gr(mO|`qZOr0Zbc;3+o+$| zqEdZ9)(xA$URZISg91`xy@A73Y#LB!`k+3}%I|8MDbg{;z_-}wasOoFta@=DK3=14 zeKZxa^^LpMJMg1^fUu+{Q3xv2{H?3912;O)Od6UG%H=%(2C%hR)5>Z0Lk{1F+zZb= zz87GAe8^GG_NPa?>1-?^{GJW^h1wt}vo>HqZF<@z%Cp(}8b2|`x~1#dsz?g{01TE1 zP+m9keHvvtT=qwzqm@DV@8=I8!=FKBJ}Ds2SW;-wsQ-<5Ajr~D%U2=?V5yVnIZ;jF zDN06%LU$LNJqy29xAJ*cm+G2^z;@3|tzaP0O{~I%d;XS+4TC(oF_k1JjV{#psj0F$ z#*{dIWE6K_r4dw)dtvj}}UGp3EPpM*67bUM?r>zT!x z`?b5vY?dI3>W1Mz{FsmrgQYIs)U1C8X7cEO{#RX z?lIX@f3p9hQp-pb=$_lS0f-!O@Ouk7BCrXy?{dzC=aJ~bfnmEs9cxtvKm9;RCK>y| zM-!Y9bVxiCq@zGv1scT62MsbdUY1SR#G$;xY_eLZwcmEbhvuV4R+&+3R6j$!?wd`) zem2SBIlt}bOLejkrH!V)P~3dSJ?YwhVC`yJJwgTg#2sjfVe%_M28X#Wr(+1A(}?4+ zjg#EuOMs^&T#!N}vzeehFe#Gk1#4tk^>HnVP3Lo50@p<)E~IPG{4_%c8p(52t9NtJ zv*>K~7%~ZN1bJ>IPi*5nEYIv2{p1?`tr+W8!KodOdNGv);=aLTlh1I7uUDZQzx81+~WhRBIX?= z)~!`6jOR9x&0fWw-|e|i3gG1vKlC2y*ar~}mg>jDW9N1y-A_V)5m?_rSZScdXIUKbY*7|Iu)zzEVDI2`dt=YSTq+E-fOm%fOlqn~&r2bZuv37` zk)oi`8)gcg?IG6rL_{V&5NOoD&`!BlQI587!Ly@j3K>XZS**BX1r&A}y$uq}-b2!p zcc}wDDGYtL*Q*Wyv3xEl{0thQ4c+F37MYe?KD7S!DbVJ!+M=6G zv;RHR*m=)`jLM9%nRIcxgJn#g5Kj=Z4msCcziF|@Z-dL)N4Y!mcyXlAo>GP#ieYrJ z->z-efn^&!BRK((Fhyt1w$i>MezP|7Ub984{mw^?L%h~5yb;|%*7|1?(A2@*;((rY zqp8V8>5O88nSn7Yx4g5C+3aN1w9Gw)*wJ zx>1b)Qe`vufqf{>`FQxDob-LLHqW91F@WsQL!rtL9Y5de`01h3Y6k>Tuh!C1<_?Y( z7C;>UXj}g~x?T8w{yVyL`U0qg|B7z)qR;<|06M)}W?`7A55PG9-26}BKT#Fj-n*qM z`1b(($Sp_TzlHx#Gk==U^nK26kpigWX%RGl-x;&D3&-a06?{ne_cbn1jRsjypqJmV z<-SG;xY*5Tlb`=MU9ZDF@ZWHJ_2l`+lELylbzXQ1>1KGiZuR`;hZx%p!J?mBYWD*|uQGU4Cbr zIQ?xWJHC0jiPKz!>#yF2YyHL zd~_1kW9bwBTIG+b*44PZt#be3vz}gt`7Xa{Y^=dDw!m%`KU`P_8+y6VfAe#-H@t~L zKPN!qzPQjqgk{<4Q%RyWe~ReXCW=KC&P{%X!rqyCV|7Xl>iLInwyq^0kf5`%wrSNg zS+Tv%CP_K`98EAU4tA3h znapI6knAhvx+3;9^QnOHFVwY$XYjc_Swz&V-^3PSCIz%sVk(i+V%jKcm=t_2Vi|=n zTS71Doe43yxTGudd68_`|3dd6a(BB7@e6a)IA398bt;i+hNfzY5ZI#3(QY)+h{e76 zhG|5-{YFYWUj2D7+q_{z&jIFovF0bgN4Z#+tFiCZZE!e0FVEAXCA`dLfBuWVK!Vq`1n6MU%28AHlIw}piz7Aspn&&qI@*a&=x zLg*Db#6G3vE*H)cn|HcvnDx(vH}U&X{;>UZ1K-tAo6wjk(c{@wqh)mCYi`D9W-8pH zyE_yf`l&s>Kmie{IAp%jtr>S;1F-F(-c2CvDkKyJ)8+@L^a3(?fhOG_#sb^he@?r; z4=22zOa#@5td6o?=QK2yZMs~W61*-hFB>`wyvKqxv@6cu@8))t)A908$L z1b&L@@$X4(>T>yQpKT!KhA?ZP9HLy2`DE_iH!f*S5Nt@2zO=7Wv($$&&JkGh%AFLa$Z^b#b|EN`?qMq$Ad4id7xp*Uif^W2-M+d_T<=r#_nG3$#H}g9&;{OE= z`5P7a>-e8wmfL%O!z?W1Q2K9=IQB|!um+!#>J!;}+#)0h?`3RM%kV=0G-$!P(X`9f z#zxhAfC6g3rQd&?s?ocN5Z-Bow}xb(%c4Ix(H|?*TbSX0T>U{?fLnkt|9tTG)%X8v zb_2K&RzYFF$I`%S@G%%bO#z{e=@8%&g*}YP_(%ezM0MOIx0>0bhIe>^x(SkrcV8=`3A=T{lW@huDI5UNB!Ow zzDP^B&U<-vCNA75jHtNTe);lBpW>Wi$NVZq9+`F=ag!!|GedDTopuKhs=Nd1WD4L! zr??_=ld9pmFmF66Z9ZB*GQSFadBuAMu{SRK8=0dfZ@F%Zr1=5(vg*VFouY1>%? z?j~|8&E;uv4d2p^mA#IHQN!o!LDmLdaCJJ&3oF-vx6LQrUKje;FV>;Yy(UYqrsRL6 z9gD7*-vcr-Bg5;w)(Suwlu}&9#^IkaM4xouoOAyYMgLnW4w&_2Z_dr8w3j7eStf2_ z^VyX2&F`%n*Ug)A?b{-sAVE8&ro^+T+@cHYer%H!^Q)P_>*LW^?T28F7; zul#@L{W<3V&Ts4gUrq5>+yAo#259QIkZ3@2-L^M?pZ$$L{@vRD-8Z^!h8Ly_t4g4D zmjxtyVjo)L>Il?p_?+sLJAvI#jh&;G@he6j&?j%%N372H5(O&tPrxeh&)6}}uW%4o zSoM_!F$ebMgMmWg!ElZ6mCHN{s3wW_P32l1x0M+6Z=yf_?dMAabTeSx3G|b{4*%>f zf364&vZ6=Nh58%sK=L)R@*sawnn5wz=dcX`a|vfO=$E>hEaW}t4q)XP`Evh2y_&+s zpQW9%t?SqE=<1a6>B%L+j;ay(mF15{zI|7ZQ7$ohEnR_5N=15z$KJ3;eunO`e)B@b zCpwRZ>SL7RfQRBnzS^trfjnWb<*ilzvG0MNL#TY2mj=t|$RGTzoi8vTC!Jl$B&L4;qr!?CiU@&08$YS~F zAXt~jV>!N{%%@PyAWN#T&lFGfQcGwixZl-7|9V2|N03tCB?1lcix!I5bb@mSGxF)~ zVyMUZKa4$I-5ww>HSj$izn)Ff4FM@vR(6PCx+U>3NH!whZ`SQO%eIQexivB>e?Ur< zs367kXVi5U~LVAi5s-?KE{F|t^L!L!kz|9P@lo|&(6bbwN^NmQ< zTLlMy)XyAf|F)ZD^;#}*TVC{r`68pRDQi8s(plWZ<30?RI?Q3$u0 z)VVKxBJZHj3X3UkE5=;VQ!pHfd%PS8XN6-joOSKPTEr^dl1z;R{O%ife%fG~IOYm> z!;@c8y-B_c4m6?$zc~;7;&8A>UZLU8`?g5n44@RG`IyBU8iK$+NN<1RAUoM!7YRuGBC1%`jn#*CS zhZtsM&&&WSx`(x|DgvN|WZ|2dI3Fm*p}! zD2d&gTm zUs!`$#3tN`O=s?br@2@Vc26Lg9*;Aga6KDHCRpSM?dx4%L`!co8utN-ta$$nF+}~UsxeU>S`yz37d_j4*sC>DX^OEYQ zpmV_VqTraLU!?^fVW$FJ5$!3fz1|Ol$oNvh!hpA~U)4CkoX}dOR9&*-HSXTna`BZC z9VW_!8j`uhmPfwf(pz+I9U`MFl#)1`uT&~v0)w9f7%pSDC4B^6F1q~EvO&N7@~E<@ zL&?`TNzJ5zWLY)w02yc2dqOjA?gs5T*2M_L96eX)v%ve8P^Pc^5V`aO*B3OL%K0WQ zOv9pLs|~ZBy$RUty{0j96i>o}lc>LJ6=S{9_kl&f-}Zw^9rrma6}50twpxxhz?3&k z;~6;ntU9n3Yp@^-KCqrw_+uzNP8ngB_+_gcxVzrmjG&ud{!82bQk8lb&A##}s znz>U#Gj08+S8Zj#49);54t? zbN<{Embs%a?FI6!Fxc3JX)FVo^*6GzcTkg0x_<6TCtX2(@WKAI zDd$h42UL>!oh&4_^VId<2bLOBSJtT`RM$S4I+i+Va6(nm)$78rd4|m6i=|R&2`Zyi z3%9=D3C8J}B`w9(`>Z}cY1d(-Z>&?NK)LWhEbPR}W=~h!#!m@y`8-$@wS??1#>rw= zAp;W-G_dUi)3HOF-22O4m6dNhyLOekAA>_+SzD@9F*zST{kw^T^TnJzAN!vmh#8n)gTSE8s+g7YC}5bt+VTi=cdl4Fk*$!rz_%=LVA> zI|FRH#}iX+q)35DFrDie7+UYq0P6gxv~czL?Vp(*&^&7OzFN5wSG-+$8BCh3LQozr zXa!B^KK?bgkJq&{e+DJ~Yi0P))xrO~Qn;OzZ%yX^oSa28*6}Cb-vjyfxD2LQ52)~-4xEhL8jBgO+Cu8zo7Cv-0-9?^VLhn%V;QwTTjiY zmGDuoK2`j1>UqTu$sBA8*E*`2KvJ8t2q%9GwM@8~Lu~|5)>}!lpjKP-S?($7Gj_&T zQ!WoYhdMapQA9||@D0t&R0I^lEMyC-E?;~Nb^3l>?_81PE?V_qy&=guHHXqgR6DeJ zPVKb5=d31p)!m3%2>1AK|DMqHUaYNMZ3nu}D*u7-C%vWSIa#;dpKm)?Fh*hO3p^#_1`PYvtLp3EHU*Wv3CRC=FE{dTnX7qBJ0s|Fm2n-+9_ zb~IHTXZwx^N0)#6JnBYJDX43>m?irWA?4(+Ua8f5R%^_v$8ol0m2F)f%fYtfY%hx< z7E`$)zbi|q_w5mT79;Bf5Vv2P^}^0{raO}A1WjKMBKB%fr}`1IH=lM*Ka`KubG%H( z;eya3$aA-ioTK?iE-AaPZkB`Y%q83T*6<9($aehN0$hWs4%WpF_l$@x;wK)c$JFRz z-xzax!^VBrU2j~Tq!p>iAyzcW6R)W&AFX@+6!CZcD5=$nXOMLl+Cvcd^G(`dLIGNl z3kBJTn9xj+iaGVfcx|(u;-S+kWekXm%5!9^A^*TSr01~HpDh@&ROfbAnpN1%+;Q#^ zWM$RO%<-&M%@~m(|Mq6of~HQdtvZMpuCPsq_)$%Z2j2Q6{q{a&oUSnTF-8b~wRpxnq>i4y%q>kPpvRMYid(bgTO}Ka5S*#9l?+ zb1akMZH>M_RK$!{@ilk_$@MXO1Xml5FXaZ=Jat+TKnHiuiFrlK2HTkN9~hlfeE0V2 z6067%|EN$_`WY0>l__Q@7aUDUud_K*LP^u-``bo57nBl-2a|t$?UC1>qa`GS;_g`{Rr{jaP$qcDRX>PAKwRp`6naV1Z)XptK6W7~eA(4d zRttL6(l->)bC``~Ajyz+?6VzSjG)B2!@`o=g+<1LPli_~m5a!@XJ8Ed_N=f&%;}Dk z82kmh#B>lE>i64dG*qbn0ZWud`O}QPxfV-c) z(7Goy?u7zH0~8Bx#ia!TEn3{QI0;s)NO2F8;Ivo^!J)V|XmQ%$ZpE#* zaQ40+X1AvBx9*K*2 zPm$lB^}a7?AWHfWZC6`}w}podnw+((r46HsvxS|FmW_qAuY14EGc+_zfP;=cL|+{w zVdd(~Yw-sUuaC3ay)+uyGZ`N@3oAz(2&1Kqor8-M^FebvGoypG6!U9gb)dSNf{ney zi?<#&+HW;rCA1Wk|K8VqON!YZ0&$bz_qW0{Mrm z^}l45{;TXCaBz0J?^)5t!@sNQNdS519(o#?9%ftcjBahkg`vuB}TW zJHA6*TwH8zZT&0`MC{xZPu<DJkuO2F%$N^k3Ws79%Z%rFYA8UTD19*w}EX-Px{joX9XJEG$&R zRGY8*B_bpql+txOl6pCzR%&Q?cXx+EU4$o8qL7)p6;ew}OBX2AY;0d`=Tytg-mIYZ z&U{Z*?^ZLszIhTgeqg$Dd3XBzw5<$Y85_1SP>1aQu-pA1_+9Yrbj#fC!O`xIveHJQ zn66pj)ZfRanx8lJBXNU;Y!S8EMJDej_OIg`Hg5MvY?Oote$CIcmF~?nj>O-c9B*En z+|AZZUH3;8_AE6Up%xB))vcKBZ}c{K8}+ZAh!^MX?=9S&&R!y%R~i!TuJ*e=QgDd` zRD6)$s2V#tIK3N>9xfBx3Y395sTL<8`Z7Y#&(GI>6uo&C59kWMMxlxVYSVPNN}CtQ z$|+ATP|=^N%g1)-XWM%tFxtMnN1?6_i{>kyp(^@o;58kiZLXJXB{vtSxtsNsTm`Az z^7X?*O)pUW@ZRRHU#$bfDTwWW+(EAj{kseA{r&YW7u4GP>3(})YisMrk&{`U`qe|! z4eI7%yx{g?Ejx^MXJ~wu&{rBm8>+JaWczu0+XM6kPYtKZ0LYR&Nf6>-YBd zW(6LgF3k42ADy0_-s8Jch2jYs8jqHWqMVM;%x*Tmtd8f*VLCsdvOcasx3`?V(&Kez zG2C*Y4Q#$2_JaBQtPAprulSu?&8@zEpvmPhocS=$Y=0JhJ>wWyZgbrfj#pl7R=z*^ zn$riJupa(uOFc|_`1;v>Pg#v2DQS=VbJE2(gJd>uau=VCoX7|gm=Y%?&gry#y$vEu z&cw5jmxm>i09eED{=NEd^{5Ay$N0nniE~PzsT99F5_WHDs2RjGsB3lY<1p5M2?A^5 z?d_*8QOOZ1Kev^L`JwV2qQKzvg|8fX$FkF{_EPR1X~51XX-!Vwf-I@Abg@P**piT| z-}B>FzIFk2(bfmg0RF*X%Q%4pi;=d&Vwu)MCs>4e^~USLtea0KBJ~Nwh>^W2fK$Ag zUe;|*5ZUpr%gEB&x^th(W=Q>9KPGmC7r7ky|O?Q$6YQc-dONK>X z_f`s++8)b%001=&`8(sucAj#s7bW#$iUIr?P11y*b3@jSn_`K-qS=1Fo%^7AOw;;p zu)mbJ7SS&m)?X$`F9aYST73%Sw>sVh2L&+g@_!Kc$XsX`$8V@vC#z^~X{lv|kF*|< zAHy+%H9Y*7uRuqEbqOk&+{6uQKQiRmw4s+CZw(8bqQh2K|LAv6in<(dp1> z9(RFE>9rOfr1k9gBE#|!YLfW<1Udb#-2wbM<0=+vJ=G#&!uhK!#I4m>{#eFjlV@gy za5@@PenL^9o^XuquJ>z#vA$q+#ml&UQ)S*~t3|7Q?^hEpDZB{l*04PV=MGTz^)BbV z0#{hnE{fIewgQE$5fSXg##&F!dW79Km0atrHB8yS9;Gm#mDW2d^wSQLp_-BX{e>7d z8*Nf8ZLu~r!@ZpM?g_lVHL>?n$U>%_feUw=R~nI@_f(dDbWgC<<@jA@LHA=R z{@W`nGCLjZ7|G9{JG(M644sn3M-#Pt@wD}|z?ZJGhWM6GI2bFyF)&89oyFk(^3F@% zWsL`V-3ji+q0uv~ULD;T86{Hrr6t3T!LcO`q8$wg$Ps5K$T@KImo1Pj@8)%L3+elB z2t8egx))JpR_SH=oJD+7*%^o=%%<=wl#9MDygLM`n1x0Sor=L|giXTUJndYS_5VbX zZb@DC96atp(i}P1UuJbY`lBRcO25d0w5#oK()3waE0&GBE4Q3d*&KvZ*)|=fcj_^J6v8$68>2KXt%PLa;vF!dTc5I)K9l10k0GGh;}~Q?&$FV;Wp!KiGj487jVW0U-OEp_ zY=u^AklnA~W}6ZDM_%jsA8#Rvxw%D8Lr6Y&ubPMxduXI^YBhEcKjaF9iplGnoC;(> zhhrG>7|-G@ssp`f1_LN3WZ|oOb@OS-mZihFQm;Mtjdg9D0s{k6X$TaYoIY}@8)@qr z=-PfMY0~lFFZ1x;-JgG@ZBwGYQldDYEfZ9}?XPQNLkR&PW(M^2;S@P?j2{jC?wEgn z;NC3dO}8wyJi;o`Z+|MSnEH(53C~w8UeZ&Q)K8ds0@qlA>^#_2#IH#FzQb;|#XeV) zrJ_aq4=>vW*icqj{?yHb#e8zG;htT=PXP?9A)Oda8Q&!HN)TZ&dzVxb>ij&GRaGy% z4%Rzl{Hg@js?4DXRD(fG+i}??I8_F3!Cw>ZawN6;)u2!JSflDRJUG)zvmZity}h0C zrj-2EZ?>J9zIoXJ#rY{yQxU=+QXqh@k|<`mbMWSx2k%!3SMKvK@DzM{9MzTR4`6Rd zUQF|%rMD&e6;+re)Tj#!W2$CzBuk|U2Eic_|7LefV80&w3B!jq8{K-iDt0PM#%jWo z?7`D0LUYkknq3&e%=>NLKzo%izfohOUvir(A(Xs^Yb2|*P2a?XuvxHDia6@z=g-X% z%9r;x|izdV-(Yg^GWykX#@InLE3!tgHSQo({Yn z);kZyY8jS~wi!MPRg{5$k&Y?+*yP@G#&^Efm}B&|nqu~h;xdQ3+f2&0 z%BnSy=Tjoiwhtx~0RFw+%yi?nZFl-az^|GW>e@~j^<8Rjz54j-_&7~9dq>vj#WNE$ zs9CUWX6EuGy;Ivwx!p;<6w|dc_+)+KAP+5ClQF@$az&E+YQLF}Pa)#_P+B`h_f+4W zZ08jP*$5S4?fZu7(%8)qXlgJl;AGI%2OVH1FYfYj`|;HBYNo3`nVLRB<`McFA*Afn z@89RFIXsbguMSxXFN?56whSbmsxTipS-_0JDd{}xb`m<`qF~Ae=7yxAMg?=N*WP9O zw9=Z}Yh`6Gk|c_)v$f-zgEK-C#)Z7GK(xcH(B<>KaqgPEn3tHlIFrMbFE2 zzRB2#e}`u;_>NNuEf*af)QisO`OJ*{snUw!J1ts9?-j~U1HyhngHH48E=+xLIE==4 zBwmLzWCJY&Lfp;TAxB$7uqgE+BW#T#SXBuuzp@2Mf3pK&FP%kfB@>27W+*A~X zp!R4uJTB;E!XT6JOVLp?_&W0s+0X+!1NX(Yahb($-JPj#`-Q^e7f>Y4AB{%gK{_;0-B zFN1J_=oM#lVO1W_(3QQ)qc>ID$gDPQ*K43d43c32}MF8dTuTEKqO8_wb*(pRL$nzXTO%p>00@HL!@@uom7)z*#^p+iF_UFyNA&o7fo zN=wnnB{kw9!Vm?JPS8lIUQ4Z<`Dh(q^ISt`KK?4sNxShR#ZbL{G|r&|hnej!+i!># zar_NdJF}1CH6y@Bu|54kuo;YOVaR%#k!*B79`6VO}{LtR_sH zk!ZxRPW_Bn`(4Ixig=qiKvT;S03remhE^KIdi!Uj*i#l)q*G=H8W?qLXb&K&XaH|A zg_zlvxoCg#;Jc9-)9xD65~SRmi4h137NR>1pck%WbYQ_%+5>MhzG<#4KGOH)K3#mk zA!BsNk?T2+D_zEN-E~=E)9%7lhRC+h69{~D_*p$@-F0}zwKxHW2Tl*s$&7hj!#P0r z;0=deP3e*8ryq+1$X%lX|fT>8&G%d?KBp1mU<$bIaePeF# z&vcNVT%pDww@J^_?OU^!M|{{d?u2uiXgr||DnNWxGYIJ{Bz4XAzzNrp*7#2R_$L`4 zHaY!`t+DY1$yq+pZd9%y`$9iqA^f@6$uqCkkR36=vernB)DB;kgy&P6qP?t_9Iy-g zd15+7fll6->SrR^~vmRP#w zRQj$+G$g-rF9befz0mxQT~cBoW)O9QF_bhIH4Svo2|YD`{F{y>^HD?CZ0tiM&Q9Y+ zs-Di&EIIPwsD9`dH#)hmfVj~zjVeIZkTGc4^DBO>0W@jOt*_P|=fKXslAKuHT1QFJ z1gPmOox;%^CD-LIY5vLLAV8$J#6XbsHAp}UpPc1mF(EYBGb`DD2djMGS-9G7i65`# zklxsU&=s!KdVwcp1!z4SQL&3Tt~RigbCq>rTWiYTxc=zLE~cwpjzJ6BB-M=}32V`Z zXNC_XzKuEYSAq~e4dz9fwX*yoPeSeJ<2UJ8o|31=xOG_1Hwb|{2}qMW+&vdioqUGk z6dG6wOXjv|)uO4{!VVN3sXLEC@Xuc8J$>~fuv7l&(?s%!0ZKx1xx~U%qxhin`E^?( z8`(pUg*s?OFN=aG)SX?1_bO|XnZ9jjufe4g_+Py<&Jt>?s!h0^b zJZc{R(~Zz4znyr13(`ZL%y=a|!u31XC|f2Pj`rX}0yt;o6rPXD49VHLV&i*_J$R}F$N{xux0 zo<#$x*oHGr`kKn;d40G_)U$(l*qRY4C)FlF#plWL@Q`-ncdC6!Lt3n)Z8#eSbkNMpGXvGDl1kk$$~v&YV&V#J97tiK2P@Tka!1z?dCo-P3_hJ_Ns*;~_$> zsn2>~$DzGZuSKdKa`x805pvvI;=Zuofo&(~x5}L+xq49c9iR|HW6Zd29brajz7&Bj zJ6A0+RQ6d3EPz2zIb8ZKc~G{#T@^!UPa%KM#}lG-K@CT5QX(YQ2c>1pV3yb0Q<8F~ ztW|>Kq*<)uRu~VZ-ljNjW4?o~ai41Po<4WRvkqa~2~`{WF!j^Q8N1;r2V7=G|2_g2 zbqhzvnwD~^CrGPe`x(e_WGzS0YSiEYBnMFV`j6OUu5628B!VCQL}>132AU*QEO|hI z=TY)w&{XF5*cNDThH3h7X`zQB*!uUztKg{k2bD|Q++WAmC_`~{h&z9gAO(pY#HUx% zCV}e!+&)^$%bPf+c=1Ur`7BmlnCg+0Fasfc>JTZ*YI$Gq$%aBw#4ewFlqF>DtHnF( z1U#Qo`zk7GE_(40aQE6%`_t{Q(hJ4*iNq{jVwJ&x%zS3zkt_2^&8I&;C3=RbqlA}9 zz84tV->_mco44nCw3j}|45{yf;eNOBr~-(fg>`pav)v`chj$;{a?^|Y6jKewG$dHo zkCWE8m}u#*Ah$ZsURe+snT0of!zy-N;C=v_`eCz1Woj5#!yez2pXsJw<^c-(aM_A& zBLv&L8UL17{pxFS$6eH;u#Pe9530k+wHM~J#AGR&h{j95{NsU|=!pXG_wE2FOIw#e z+z;%COAKGkGU6zEBtfU8wyw=-mwK%9VsjL{PH13=tNBU@M20zqPVQAtB4+fkSYURR zH{^TDxd0&URxba-GJ{Z7gXjJZ>zLQI4=E#D%QH&1ZnTjH=KwCnDgit1uIGYAbd$t?|Q_sZg3r8d*rz% zp&XJg+$q^=a1^npoHXK0-~2x9#Jj~LV<5mW*Cb*+leO#jno-qarkW}ao*=myw)!gN zW>TFMF1}pBqXW3~2*L7sd~Us%g=IVf7*79ixEU0+gou0g7;t*KhrJ3-$$u75*S?xl zIJWxRJGIp8ea)$+f`ZSjX0wI>VB77I`p28Dpzs7w#1L9Ca)U$Aan5LgiO0W)1=bKq zZwjjF{W<9yy?4mDt4N?Jm%*qo zl9fEdPl|55upefde8 zJ~F!2yIa4>iuUsb&l`_jzeO_?!%1ZXJ(mwLIs8rviTl``A0<*Y_fT{nCz=0Cmc#XE zLo#6D1lV|Wd!DZxhcPt3XIGV)P)#{a9ji6dNJK#bdIceH?1D(D+NV1kU`*`ttNse2 zs33J1GyHvR>azAMQKDf+@nnt^-v1uoEVk+J=Vwhb|0CfRWjU80?kBA)HYNe*;n)`$Uo=kLBekc$5r zX51jKy;H&GAFw_!2@j!Gz}sjy=V@!}$Q*F?S@6u$L_f!d`ZO>CCdtchxRzBhehDp` zF(#_KFt6ak)Aw07dxgIh6a~1jTyN+U(Z}E+cU!g1!#_o5W#FYF2cW9`2G~@!TslQx z&*{wy=Lbt5Wh49jie=O_1+~^Nw?zeNl?sc8#=G?6bk$T3_9vi;wNDA4G7I^~J2H1ogvafN z{R|hiP}IcQ2UXkDl4Dt9S**#aHvuz+u zXb~&`?hL_xOl@pbIVShknP6(Fbh5{E+w{$pq{<`diylp)aQd}z`rP@TP+|ijhPheC z)e!6)jsDhXm6O4AvlZ9h+-`|+E(O%mhKaz-F*5OYl%jy4u&4+5D;)T9eF?0+I7Cje zKVINjjJu~h&}7H)sr%DvO)=_h2g1` zu0c|`EMY?PRF{|SR!Z;405X)&GdD~66}9+3bIvdlK-hh{`F|9DOG*C+StXNy?1oo| zR_toS&N^O*H*iv)+e2cNpsPU2Qea)&K!H^KWz?edU42o};;OU^03-9aG~P_?)|dp~ zrgu|#05$f83&7vA@-2!IoDHP0x}G!+Q}OFqBv^(0{mzWc~&iox38M8YiL(%Z_14}4a*BZPRPy5!)g^kMPcq( zicTRkh=Oyj+oX;RI~h+iBG)BJ*;rK;FuF`Q#Ro|n(=n@9)nB=R zI<_Ffv^4>^P_Nj2m6HMhHRu)D^N@PZtVpixqj~b#FqM=@%RS)OBVzGxI4`n5zp03a z8>q1g13`~Hq;Q}~>Mtu>gC?}kj#5gVPgwb{at{bee{#0b51P%qs8rZw-+i7+94HDT z<$VC;tOZMa-j8dQpo9XT<|Seu)kn)r!n+ zz!_KeWyIcV3AOv(07CV-xd35J|7<8Wy4-3WUcqtdSd*d$a}fmiN-;A)pW%^ruQ!xKa;nXz-f9h8DoosC z3gF2BdU_L>qEkx=9b`}^MLpY%#4}u7NDyy;NvS6QKj%IDf2 zfU(AJ4Lz^>X3ev3-r@+0^n;g+?u;R_QUG1p$Je#|r1TG=TJ2X~pL|)UsEvcgVwFA5 z^V$Q_5QBeFL?eXM#W^r^;Sy0i!D0IwQY}H=4?tvoLh8%;Gr*{rNFVs&zQu9M&4JQt zhB1HoFeMnDvB(`|K(*p@!asn zXP2~$5UOsx<+m#&p~W38{vacgGved=fiDX_l_JDDPCbzX8>&tUj|Lvmfp)WoC!#H? zdc*kn$GvhDshL`$=_r*U)S8161XSY6y1=p9;AxM?0B%M`&@*c20xIq}>?fjM(rFR`WRSkr>(b*qv=)fCle%XV&r zv$vig`se3FAH>bI1OT7DocGr~il1_+=vI0c*XRiAi&fi&wsN+v@d<`=K3RrPd(T+n zLj9EH%(d(j`k$x0T}Ne-1K3HS>;o>xCi-0k3RafaCA13iC%9NE<;a3_u&-3#771Vl zGsm=vv$bIwH>Rcrpxw0ja(lE&1vNf?w|^EEB?*##YCOx@R!HTA7|v+1G`)t(PsQq- zZuf7;CU_4G9iHGDukX}zQOCS~d47@!*L!(7alQAw@4epXo6`*Q&oGHgDSLV`@3@2B zYb4fzl=)Dr8Z71Ni1<9~{15FK44p6DmemMfjtCAvA+9GS-yu3Z?)VZMSBhEoC2m`I zVzYcW$Ir9Ea9%&R3iIo>vSYchFpC=>i{gC4&Fxkx5@hCSW!OVBrEa#~te_67l>v1u zcL8M92Uh_@9@VXTi)-Q7yJcIhtJDAW_`IX;8K|zYHucDwezdpz8 z*Af*l<5rDKc)t)t;+pogosl-NP)M0rV$OGWSPa(S_k~$|brXh$dd&c~sCwT-}i6>Qe?H(ns)@4prJYU`$AXU>`#RQFKO%m)D|I#m3e=J|XAFwEr zH>@~|=(7p8k~DsfHpKhB{M%~?HVVfidqzcTL*VoK=&Uq?aH}cIhw-;hZobgWJGQ71 zF-WMI3(Pst1=4!N12q-zw80;~aNlkPy%`oNr^TP4gSG^@c2-|fIqZcipoc2Qij3gT zG-9-)XUbGoQ0Yf~xJetzZ3f`pknadF@bg1_p9CF8)DJ!J;}$+}w*U1E!~Se4o-zqX z!C$sBGCLV8$!Uui7lMyc3@tWW?uK(X+(cfM>QQ&9TqZnf^WJt0sMD{xsIp{WplVDFxCJ+zBM38bU2Izf(8WunZ`i$(i#ldHPRC+JW90(QAodARv`x=74@;B{knd8Lki6vtu80J z=&OL$#XeE*RHTW>4o~J{2N?t9R7(nH-{IxnM1{Zlsg_tN+ek=`A~jfYwM?Jr=bFKr z0@jIHkqNE@=D5>zqLY`YHCK_4s#uAHImyT16zEm4T(*@k{pV#xrGMFo>t7S(yvsW>NYT)`rbWheQ{G20CsOrAEiEl0uDms$WDaE$iCur0_YGM4QBjgs&5IjlP4d-{W6) z)=lyc-Vq3~a$1=wM>{)VBFM&7n?cDweCQ?@>*Cg^kGmRjpW+rr zdi%N@##dStCn&<^h(IA+Y{^tWhyA|eRp7Mzi$9O2{KsD4ejD;Z(#T+CVe=we$LTV&}t!2wLDs{TIA{YDV^ab4hRGD$95bQJ7^GT0v4>! z*J%qbg-@^W$+-N|-Yk4zC{PVf+p%LbjqHyz0slm&>RQ|Ewf0wte*KL}W#IRlN8UdE z3JTw}@>uw*KQ3eDdQ`aaRVeUSChy}wAKR1Zv^9^PK6B;yQ1;yGDOXNbPt$(rq!9gK zUV7V0G+n180gOfL6f#nF${GMou=E;a1`qIUl33f{bM zs-#wxU?G4hZVoGWsja~_CYm^Ap$nAD6*f?V)nbCsVpC1znVT;VZHE%13VY&#us&WOFpmN{JV1t30llQvs_DeChfJ3sJ)(-7u&{T2 zJ~;D(S+cnVx4e-aom-#BX|P43zlTj!VPJu)!4u9fbEj&Ph@nRS0#+JwA++l_CHwZ*uA8e-%?!i#%l$`I0X2di;V6u-BU*>r`#qcSB~O ze%M@G!Q<&B!A29@b#L2w>NE{kTeq>JjFVXM_zMK-uNIycWb(_ zH2sK#i=NYUAKk3V5a+vqK^f6hPOyb~Ne5O)YNKf1R_zlw6W z_XiM}UJ?<>x=KVzt~=s2iXU#0Lh=;^hhzbh;>~-#o$(pH77=0fN?z+-RB0fZL4Kw6 zRjnyzNqVRH5k;6!-_YCao1AuXfz2~w4cHBLGMJse9|j-=SgZfam$?dq0hvI!GX9FT)LBRLH%5iu~W3{y$m%H~H_! z)BY9zwcen?$#L9=T?NAZe*G6$Z>*}avhB0v{7C@30!T6ONq=X_d+yrke!VBx-1oJ2 zzhZ+;;uJhOrwN2<&CWGFg=ymiAxjYbJD|D1CEF^J&D-sG6YGiuu=fPo4K3>_>*!rM zw|i_h=|b1+SwRK-Lenf(k9JHR7qj@pnt+=XwC@gLG^B49W9<=BPwwH4x72v>aLA-S z{6%`VAw;62+-M%|4=;QxWiK}Jy5ePbkkx&R3r$2=kPxt4gV<=^-j=h$e_FrLKyG_o zZr9|hOxitHf$syUe%Z;6Yu`0qw#N52bu*e#78}0+-CEG{^{XU988Z3 zt)7#n-5=GDgAJBU6CZ7x+77_NRwMN9y5TYo!5p;e%APpvq# ztdT~)Je`Pze$nN9EkG)|KIC-@k((^*289~U6NTK4pUwK{7AtZ{#Pk-OuLCVuxlI2) ziBEJQn9MsWVKr=RhNh@h*xboFhE5LuCLI=4Y(P$6QAScdV+rkU)Ha*h1`C470@xi- zxW;w1n&pKi(z`lKokrAh(KUKwHF~p!(=qStOnEI%K##nV6=*#2xVadHv+yF#RWP{{puEM6(MGxv)y+dms}N z$gnpo3s0Q>FS!5E^)HP7d${~9F#fy9f5g_m2hU%}(jSWctH}TP6K<57l_pU{52oCxp@ClLS1H1p)Zg@r^ox=zO&gQpE9uP!|GUFY#;m zqbF!!H`eSvwNQjTokeg1+D z+Uxs5{GzkhBwIrb8MfElHkCY4wF6LQ2R&QJz*-I<$5jsE2;r#dlMeIj4C9Ng9OVpi zCMCB&wk%d5eEAf%>wBTng|Is4TCsfaft{F-HW+_}xr))N3k%uVMMXf@nf81jq~ZRg zZ`XxVrZ75*gB&P#Yjo)CUpew$_l&=G`4I=`&Q%hsbf08JSf5Jn;gi!_j5F~6cYNPN z_^*R(ZQ)zknh5UyII27v0;59wdAmq#NJEjDqjl_PGKJ*6b^YTF92F%E#d3M`kpBnP C*&NFN literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/slides.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/slides.png new file mode 100644 index 0000000000000000000000000000000000000000..f8a174f87e6c0a9e1c5ea5576c383832fe55c34b GIT binary patch literal 14439 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�w+`;C-t2V+wLjuozzQbScbE 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 a&UlJDgDq?ogsE4S&QLQMM5*eN;Qs^t(J^cQ literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/trayicon.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/trayicon.png new file mode 100644 index 0000000000000000000000000000000000000000..f622557b31250060e681ddeaadb8e024dd82f07d GIT binary patch literal 19040 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 H7J>f-CiF|H literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroid.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroid.png new file mode 100644 index 0000000000000000000000000000000000000000..014a001bc818302a7834245f3cbf3e1adec25b62 GIT binary patch literal 18875 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 BMqK~^ literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroname.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zeroname.png new file mode 100644 index 0000000000000000000000000000000000000000..95cc8fadee709d76771e7b56066cb9d93304dbc4 GIT binary patch literal 36031 zcmZs?2UJr}+^!o$K~X@YN>z~Fq=a6S-a-kzE1l3GNCy>>4nnA*h7w3^0IKa`1ND0EZVh;AVggXZy7Ap&wuv`4 z^U%%>0KU_rhtg@7&?l;nq~&;gVL(!u-NQ z*XG7ww8qUv@7e9Gy@z+p_~zbHm#Cr@7(G{L_-rul77_GmqmAlv|4K&(+-z}sbABRP zGBtmF{443x)!}^K^6}~E*`pcu6^I(^^w|}O3+bW&w(ORJ~8X6vDr$)kLPL1WNamRl7JGaMpB=X~pnBvOO zhw`caI;&33w;Y`v78jS&gUJE9=*7boS{@Ss{}&H8$Ag0dWg<6pG)V&#_*IzdcLn?_ zAb4PK@Ma*c1FR`phs}ij!+x;GrIi-So12^CqoeEV>%+st>zkXSqodW;)tl>^v?-SyX%wbk(N4DYc12v zV9m2Cu_`(sDllLhIIt@rpnS#!0JPIR8n_|{08E_Kk3(86I13*E06-i-Hp~Ay0buR} zK4QmvHt{R?8xY{*r+gOE8fOFx;3v7JHYQlxw3a<7HJb(SMj9R7NH(ITNeal89wigE z`HamJhW+TLePjer2k2^Nxr5B@Nyf`_n(A0cur7cseF^HCzh z^%|!+n&t(>=)|5xD5I|QasONi&QHKE1X5u9I%8;r*neFyf|rhp%K4(fR>ZO1c^1Zp zy6xKBv%r15hk5k}x)Pp7C=jr$$YTDS%DMi$Vmw3iaCy@?rVpkO6Y#W52!N{%BEGSS z+*mcgh>PY8mnW>@bI8pY+-r$g6B?PUkkq>-)PEVFSUTq$Ku(#9BjVa32dHQhGy(gB};Aq8&#CZ;|W!g>8-6uR;! zIBWV~T1LGSr}w(*6$a|}wV*;^WD=#q?hzId#k>&rZoE;U z?yuPp`u1vFTDTle7PPxlm(w46ou84B?-3sz0ha>3A4%QZXmB5qvPuI`g+YAx>UW&mCnAb-O3XFx7QxKUU)&9fwv~B^!-*rktV}+8(no7yA5Cunz2mN z9p6lh-)=vrAM%7f z?Aj#!3D72e0MfWhsJ}AYS+rgL=sc|-c*HE4ZONHFov5u=;|HmI((nZXJt^K?eXI{0es|-{Hjf-Rl0{zutCSliB|9VUZ#>uWvCMoWLEQUGT?iltGd&}mtaPU`LU7qVq z|EXxGtXmK*xwxdRikrv@i#QwNqVMa2+{hJYboW{@UZv8R)}iR%lLBy6K~_lH=5bMN zs4MsZ2;`Tb<)=(`ICJ*&pO%%Hqo_BlKBHJH0%`d=3OL3CID z>b2(34qaBDLhYj#e!$O<`Xk8$5{GFmH0$qFYcwu@l9#RR-fV~4X8Np%0e-$&Zp9z) zPaQp4#?Lx0AT=k=2#9Q)W~6u08W@$`SDHet8apzN!nke1Z_sv2<2#oP8n^(w*DdE; z0>pu-80bps?lyhha*=WKMO9gVQ}1{+)n5kFAjuL+;+CG<$ECN_$=@`ZdtzG@y!=N7 z$fKvGYwR3VV@aqvWaJCi2=p-3s2jh5^p`-%vk5xPNXrMwLtQsc2JO|BnHwFRh8diq zMPHBJGNXJglK*nZaH4Owg7dKR#0XRpyOa|O->!%uSoW8KiKV`&O259*7q*x_UJ;{V zNV)a4EOLd)13tEP%G)g&p^zGfjFFoix56S21=7Ch0^Ov9oYVr#>OoE zY6*YP1*!Bk%tYQR2%O(v^lNpQBIx30eRT2K_7d;abHMAAGnv*&29sI^HDCti)q10w zi-eeqpH+|&d4|`)r|a;FoK0BPY!SARNd2-jns0sqEzs*thr1-5edmX}8Oa(^)~n}1 z`*V%nt}{lg5pV}f-J`c}#m(3Nc+a;V{7=D6=PQ0L&0V(wF4Q$+j4)v)`sU|9SoGwv zfkrSG#0PZ0$u+ZU*Bm()X5J0It>suePuqP?Tr58peCpV%^R`W6wIl)?pWxwUFeLZ? zbJEvVi@sXdjHUj8ksAn&cp!Uzi;xY;{`$;9SNNFjhYE`B_m*FdRRca)hh=JZW zYEf1uM6-Rr>$j_W7)`Ij#cr59E$D82f+H*pV{Uc!20Wrm{GXc@Md+S_ThPAwg4dE76G{QPstjDvEL^?YJ(Pse9H4Usf3cNnY7 zhaU&=VC~nj4L&_h*pN7%UP>@f)3?!pn=8OB*D`fm#5pI}eF%Ou@p#>SUGNLL=!Cf>+TiBA-iVFeRIb7>-qAJP9qYV(;^r#f=s58X!t;h>kxw1 zM^{Lssipl99-jS!3&s3~ZHO4HEEB^k)o7(OL0*1)DKQK*0>NTUr|c*8+$PF04u%LN zm{I2m<9IDN-Lf{`y=y8hcs}09;BbBZ8Sxda5JRgBDX&90{StP$r0|N?7urY*y4-!d zJp3ofnauRq3mDDbV$3PtL&+I2*_^_Zw0Q|3^x;ED?0_CQm=X5P#Z;e{kgUsqtPict zRZ@bMbT3$YRtN>g^{2%xj4aDAWNI^Kkk_$d=m66Bwz;qNW%X9OX3X2!HF1m~aOa*e z*-I7s`6vJQE4Rp6ULHdFdUZ8Vvjr}V%X^h#i>4C;SxJnoY`sOi&W1vu`2N{n*&W8 z@PR??RI()vVvRw!+!YQt$plF^Z)b$B#O28wZj#qNHQeA&*WJ{t^|bz*(6~v?XBn40 zj3)Nokt=NwS^<$ZZF`S^Oak#jf#q4HjL}q^MLX9^EE>BxET*W=AId)VB%^Q*8P~%L z-_cy#sEL+VP1x2&xqhff{j>)yo~+yC50ypjI6|#Q z?r$K>q_=fFBz+w5PSti6m{0d>^Wz$hIrH=B>2cg|9Va!7#GFv3pfMI&KIX6)sZ8r% zep=V!cH5d;#>Wt|7shWJYPd%NDr=Z^UTZ`x*%VeMPZnFFQJIwgMiX9}6Isfy2?ZL_ z)0ux3dt@T?scL;Oqt=Epb~U)>3ox^9amClU+3RH1nJP)KtNxquWs-<;bAxkc)9cz+ zCZkkh;3wzWmy#A>&-E%WXd9_O@CsqCKe2YO)T zk;B+$)W-Q(D#<_Ie@zpop}W6ZKGOM{O%Am>eU%=VG!ZT~T72Bk7ix(@&6{_8W0HRk z8Qq;i#^fPCo14(&Bj@mH_TySaUH<*D19tbb-9u+@B!7i_OR&^?kM8GVf+ckfQNn_` zg3&GqC`(?Ss*Z<_Hd9rDKOT)|vM@f4D^o_Ku>q^LYB^_hNNZ#T*_4{U^EM=({tAAh z#r;TS?RBi_{vfz(|F`T9RCo<}u7a5?{k%1VmbDjbzzT1R(b>N0_D_|}xyQq^u^>T9 zSGzh&Mo-b7a$QJ;SfO)!t_4$#euJ|HVLPo}JVzX@LNjEZrO|&y_9@?x)uFEU@GG{| ze-yOZ8V-l)X*ZaAcl=g8r#rB}&3m(d^6~@BV|geStmx9?LTb!8!}*PGc)n5{ScVqh zPJ(aTzU`FryD=mbz3Ifxk4bQ=9DAc&XzP;*(WDJN4799^dXpPk7+&#rLte1=-IhZF5tUHhjn&F_$AYcXrDR2?Jvoni)L1zhG* zA#e7W^vT*A;`FS<4<&Io^stkcvqA6B%4^w`b#vM`8brpB`nOlon|a)X&Z%uWBZMrn zBQcp0Vx4El2?${k5l6MASG?r3Vp|4^V27JpQ>mqEqraFug#Xmx4gA_$XY?w^$67 z5=Z5K%Q_|6b{84F@Zv3s*3)JiAWb)ag~=N>Qwk2w^lpG6{lA@rt4YMc9VysSv|ans zHN3meH71(&k=v_}9P9ZoR-}&zZ(=eXd7N4h;so)tF@ht6!i^x3iI+2_*P0%ORYXA3 z*<83vln>64M3({6%G0g*M}^(D9HoQg@(Q5-UR5-)I41A0bb|Jm*MTYYC>D-`>9hm+ zuvSZs0(fVUpmsN&r*3a`I1h_ZV&wO*96l{iD0RAG5L!R-rS=!NcdFWI80w)O1`5+x zXEb2$En3u~+G~znedHEKq-Bk2_vXWYVIH%iL!hGfHxUkY# zBt&o3`C}Kq+~Ep$5q&h0*ko68WF8SZ8A@;}GPYzH(PHau>C_|)i~Udu-B~#;Dh9JYXd52fs6CK>*DompZ?z`U?2Fn*02okX)l2nwRK*hd} z{+X^~kurnE&4StVuwamp+ZQ;7UmvwP`flc7KJwiGm}ocxRn-=ud%WQt#Ye3i7pwaR z7H{uL@-Wd|J?&R6(@D8tKhyHps4LR#cb%s4FO#Re`7k==FQZw5%JUlC6(}+HeP5iD zF18jMK+3&$Ekl9Dg0(?m z1#^-_hv$$2Qv8_qSZ-$#iIp|3RmN4{et{078!hT_jZ2k=*5*182=4>XlwC#0d*L*M z(Ajlynh@`G=&+b{iY`1o>7?|;-@QiSnX$W$$Cwsvv6u7$=dJtE; zcsnZgMGPLj(?*l0T zcx&D}i>t$(v}31%U?W#H5Z80V*GFvz)b_lZ?%#6Cuj92F4)Cu1CN)Pw<71_^1T0{& zQG_lc5=VWAP#0G{Xzd%DtpRffH~O;tPY%j_(X<7?1+|YjYJNuc?yS#*;8qASxT~v_smF)R!=+*83L(c<9cs*TD}#q74cPJU?H}DzHA7?QOiUzBE^S+G{REkCLyPTMp|O z=t8f#;>g|q`Oea-b^h^q7>ebfyElg{O@8X;+^4&DLAp*&D&h9fa{lFvO7U{ES&Z(` z{AcbAZv=o!2kOi&;y+K#hdCMoj!WEL0SD4dm~Krir_vrr12SyL zQ?Y2<{=25ksl_!~WVBtr^v6q;BI^N~$WlJa)Q}A898TYx@5j^PfS+@7nwN)^r6jT- z1}U#T;J{GOcvz7C>6FL9EO6lYKcNGrmPr)W7z#d4-{t@|z&qEWn*({fb}(#? zdh)jO*&#wpW}ABjV$7%WB|?*gqkb?#4S2nAI?!}ERc6=Cuy!lGhn8->oN5S~v);Yg z*FXB0iTxMD%r!2#_o=Awl^@Uf)Na;g6BkJHk#EFZ5i;_Wrf~?Q^zBXTz;)bNVy#~? z{Z&NP0czti?uEbmPP78QQZfYg}6<&Hx zcBcb$n(sD!SYT!*0RVh8bcpC6_W)S!{{I&C|Bu3tR{*zpi&ge(wMU8#EAFKHbd>!V z*9Ztp*e}#Ef(}W`cV>XAkDarW?~$Fa*tDSVsr#EyK@q^*f$zFqeQ<8yo$BAxQ7I-F zF?x6YqQ4yzoQ^H(r}c`RZ!&EN)(5!$TrJi_qvvp!lmX9UeR`xL+j&j1%f&`weErir|~w}T0J#y ztNSY}hCLgceXEVtO|g%9c~KRjfs|qOC@P6|)*IBP% z%w=s;MMcxQl_U-MlK)yI2N`?B>px!{81UAYA6r&fE>1>iR+A97q~tjl9u)A=TWjQH zQ^mEVu@n|y0PUaP@dGfZHJ0m-!WEqmRNZr50dZ;*GP&V@$!qt%ug719tI5hM%-zQ}Lr&d7kinEr9Kru2CR*2HHS-0ce%^Ik z`G(Cr8c@U%PKLTuGi$VXF;Yih77NT_MU008QB-=qnmhkoA!ti?q_wV}rl+X0f z&{Rl~{iNiX?=E0IX0%8@D;<{d_w8xqvn;cwe_1JKM|4-pqi+XDvy7&%1j~XTp6|D| z<=JNpoSS@)heUJK(Qmm-C0V&nvv=@lHm?4}u`b?5OhVn&P9Y2GZut0uUg`e6$66OD8zLOiP3)haLBxEa>iUrQe7T^- z66-H7HU&r9%N_K*f;B;kl=7(cm|q3EBK2$Q;uMk{0la_IpM65@%e+yS3}0u&Kpit? zzy&pHzCCT4+Kol)>^me2`{|>KyL;Nn^CZ{`dvV1>j4(e6If30^I>w&zB4q`T+)H9T zif)p{oVR~B{|W_KzR^#yOXmf5=A7}ja$Gk5XRcw$Zr9>l>$MUZ} z!sdCS#lG!PV+229pMQZ#Asl(=(iOf5 zH_G-0X#30hmK5!W3de$O0LX?d5E~#w7Baa}A`IBHSY!=EG-gSRL1-N)^^{84;JxS@ zY&{EE=zGORU-5kU5OxU3Z?!H}rT`?Xg1{;##)a%=qhx$OKdG{(-E>k|xk6-%EK%$B zx@b|0gO5?|TQK~q@D1nJ=y3INxWsG4)YTZ6hnjMCH?GIoRMDCT(M*!Q9LN~!vA#)v zvL+;LQ)oX4WpKZnqBTd_>%9`-W@t{I`*%Yo6ke?-`6oy}fB7SQdXx_~iHO!nJHy_0 z=iyhgi)HVHL;x?GF<*8E?;KqK0E3C-gx37?roEdx+z`m2Rp{eC4%l)gJ~~g1)qB0p z#s##e!tEUOYaZVfp9W`f?ilyO0qhsB_%~4ko`ypH?QDj?1p$CHNqvYJX}=&~E~0Qf ze|-}wi5ctVMbD|>0!qKYtLX<>6Q{+R)QP3;VMp?U9H@)vY{?w#gDTy4e>avHAZP)P z*~v{4>@@R&2P0U&%;#WNL!iF~0PG`JCQXoLeGb1;@c<@|fQFBdmUpS7FjltV`Hk&){+kkZVj_Vi_D@%AW`QWdgY#M=>B#0A4NJmz4i4NK;z_)MP!_KvFO_j7I6dB*h52j$-&6b2Uf} z*=>q9q-WH)T^FhOsGzZe+-EYwn83_x;_B${Sr>Z6N2ll(F;@?a1*Qt4l36AD?7#-Sn>GU5WFN->1#m z#-t<`mr!R`f-42=m;31lJm$n}W&z zBW_#CsQ-q*@APltyDfEJNF94z-KG~A-q$82XLn)fdAYawK$IrT2an^lh0ml2McL=r zv$1}>U2D2GP6VtPl>uEBB4@s;X~Oc69~GsFjb4!PvnMCxE#X(2#j}ncee`At05gS< zQM;h*LrOJPoYA4wwH}*~^1|Q>h9SJYXni#MHxT0EELeN3u^3sc4*_Qg8-XCts~RER z>LYOqF;F9IIq4h!uVHSr`bAF*6VvjSYq@a0NNP)p>joSOSr1;@PY`Goj@l|{6iYR` zRg|nu$7`ALS{7iI+xn)v3Azp;Ms7hRY(*vc*PPS$C8B+4CYl)a(=B%cR7v?8Z_C+b z>FF{S=I*D#f9;S$?Q;10Bn>@wfA5@#t$5|Zon5LUk7|2)F?lEHzPGeQX!~~_vsAtUNGqlB zs61kqc>TTR&@sV{){J4R-gsDY1mi!64K?cuw*E&p9}m|b*`q~}ScR()=hFN=cfGy$ca=N7Y#)20naKQw2HpZ6oC(~B8!*->{? z=^~xWhJ>g_cPN=Db28X1HJh1!c>Ox+zW43@?NvdUL-(f}ebDj9+_cM1os!QdE@<|G z^)9I0`vLmr#dXP`wGSc%f2@ep;*)NFiL0mMSq^Nv@Dy{^e+X@{2tZZ~z31R9`V$lx z)AW+v&-{J<__8gqgjf9UyxUt<$^xX+7q#EOAy%s&VXEN6kU+M0gsteo2>iJ1v7ri& zTkl(<#H9g9>^DN1lBqvHt!%k52ssIvKEL4?QS{1>OMxyVv`v{| z-{l;Yx9nmI8I7d-1xt$`{)L&yS6t`mzD#OqTkNgR)s!IjdnD{oObEf}jEdnY2&bN$ zPp)Gj642iv1G+kn_3$b+jd=kHvrZMbi@N_Ft`_=~Tp2FX)65AxJ+aB8AmSirEjzf; zE@t6jhU4o^^mqVKVL0|t6w8rC(Y3Sz#sCf0vdAE}T7hv%Hl)`nQQ zU#;s@j4dT~z8EM>P7XA#V`C&#e{lS@xe#?(*v+cHZz=5MLge$+QSF-b4YY^6Uxr)I zdw-3s%u3nS2W8WsW8w6BT;gsu+~YbG2F@y4$zkbR(YsA>ktil0N-}bhw4hs357PWf zdz6zDJfp^!-TO1KK2m4oL`-sCPdwIA$lL3SB>&^~q1Z%kezFCMIwlgrIGY4`o*Y{} z-**%$@xGkPUZZ1qj3ObScDt<;F!DE&h3T5iGbH8&9MlRS@XAMaE2LuQ=e^AuXbB6! zE|h{_ky$~4^h0t{`=B@XSGdUMg$rX-&J9@L!J@c;po7_kM9>KCXZC4uj-`(8-_vXvuxb~W zFg1Yd(zPw4>X(QEKX9OBOQ1A!LTI_uygDv;UT1GI zr}rjVCPFT^(#+&QWTt_hU4hEoO8cvxQ6Y$(+GVADdFj)2>Q}gu3V&y6O(q^x6u(A9Hs ziRJga(YzH!Uk9+=C1f3h%x5WCkk1i(JXv zh76BYgGP~8a`~-Y6C-n)q!_5Ya{199dXwES4#MvNIIe*nRJka zZrsK;Di}UiV^~*VflnpHDgnV{iTK<=c~e9Mrd^riebvv0X>IKyv1JYWuh>h)HV88E zSz=<-VfYli9|li^fX9b5{=B+DI`%9+T1U|j*5-n>{$EgpAtgV0UibEolM3YmyC~o7 z8QdayR_9@Z!(lj|L>aq)42aQu>ZqrZSyfcOqvD==BXb|)J-W;{nq?=gBU$bp+68b- zg6c6RZXQz8(7hFm5X@((f1DUlV=i4Zjx>Q!kLSHuqS}IpRja$8MvT|!ZeC+Bl4gD^ zlPQG#ZV{=CJFfkBHAUSiggmx^l&E4M^Gn|3gGb?I7GH`oDq5W&77bc?NI|(ODF<~$ z;lQ%)>1oG3PQC?h0`;&0-=6@z5!Fp_;LjlNRlXMfv%TXPsY2zz(3sD8GLxQFVY`E( zm{-lR1vLrbp6N*jNiX9;GRk>ui{fPcyMq&>uU2j_aEMB6cuT@~<(mo&+1$j6-yqFT z-E8FgRb)f1PtQ-)&6!VFI>(0i+nZ+^Cj>wcZQ|a&JATIpDzi_x+_8lT%AWJ?3Jhm@ zrRxdMDQ!o#6dRdSLf{6cG2jtZPv+P=G3HEjWDFg8uG-9ve>7+HA1#E#S#I9k5Sssg z2xGwrl*?C!Eg}^1YY7JnFIa9FTZfT(zO46of(^2dTHwe{1O;wWKJ&vnNyHqKYd#%< zLkD<)wR}cM?&?AVG?ac(GkvF_EXaT+&Dt8V6`ew%23}!f^xalRSHRB~F>qHT4ggC8 z0LYyJ@qbQml|hpVC8R;xLdzs~h`|f_XI4-%t)eEK-C%aNg>@f+TyIs3T2r2V@IU1r zl$~;@&g=7F`3B2Ex@GgpSS-S#&J`O0;6*7uG*OJ&8WVeh8UZm5%C4R)3ZjTj`!r(b?FoJtZMu#D+07x@v3YfVE_he-JAB$)kA1Y-Eu> zh^|fOLNG3I__)s}kh_br!6ZL<+`;HfDR)LF5zavaKU}-_V_Z!%kgG=ci^UGo$k4;s zY|99S4gVK~Y97j4yiJlnuG^sUvwp~@v zr0ZJ>e4I>w&o{<42<{|bBHLWXm~Ld~)*i<{Qp~KX-%N;(_O+YP(K0z zF_33SyqG~VLZFk|IS8oR;;2u`jXpXnuU+|BdA!(ASY0wU)Zwt!uIuk?3$5#$E>xy# zYXoUm^=x(6&?%HCz))48nM-4(0Rh3%63eVfCDYBppWgS@SDtQvZrLfFo>M{DL-+VN zKT^xhA`UkYhr`6!<@ui3dd4%vvy1yHu5FJbOJs9XZ@2<}4ak#aN{ z*sd`jNnS6NN~;)cKc^|D@j`Y~u!qCnP_L={(sw=+OY)Z&*UX;NLOyv(GT<88T z62*ylwUWfsqUGB7a)CN)LL?k6vG@eo*RcGM`w3SZNti)`@2#uhVdKE4dm^*=6{?1o zmxt01k(RgIW$0AUYt0n!4+0VjR<~Sh@0tHM6X&=&hFE8^oQplwibRbzeNE znZc%8QGpH}ZUd|OZi}{M<$cO3wQjpIs4rKRkizwyPP!lj6Xl1msw%g@RtM zxQ2TWgG1AWm18)nzR?f~`Zv`KKytja4xVkC9`$QO7!U97`q_bU>8IEk$#j2iY{;rS zkF9(Q?9e%lMhIJ~e1-P?9v8^a{ob9#%*snHU+Gilt31IK;qf_@F2C|ek>IpOugR|{ ziAGg&jY71h;lF49E-m_s^@YAG?1+q!JOqY}*lO3E=Z8q5*d?rQ@5zD^&&98#2TI4? z{~@t3n9?n2dfYu96PUG_cB)Wvr1@9i6J@G>1A6>w5)z zn+V>%kyWhl=4*_VprL92zk_^}B?!EbX$>paO2}=a&&O~QYg&fz7?=>cbZhHkt~;PW=pQuh?Lb0*-ZlK)2+^3_|X zNMjT6JTR9i)q$g1Fs*nrY9!u{$`;ivQV)>Vcx3uO;K!&{rE%3;T3ybdvD&VPvq-cq zz9TJekut3xjKQov#RSIL+4dHOSMVcYCfoPOex7uq#mDuP#G6xfpe}_nb0vD%nZ7Gd z#-F3XN%y7x^AqrAuza*&Z5pNTk@91E+tFfRT|VD$fsN(-Sv{TzpZfutq^GV#qB^XU z962G3CqGcic=B~0fDhOLv!5k;MU-+}N=m*SnfnUYA8sO&IO`;#g3w_o)5b zG!<$0#al_sV1rxm&*bb81v|o>FeFyD%`Xi8hXr4x0s2b2@`dh`%D!AugoaZVCJ)=e z@8}Z!ifPl6tkAeZF>jx&@w?{lER+qRB+gFOnPUl?IiY#6*ga0ujQdP7sdMVGBykV| zKP!r`Tn5g4E4Fs65ClsdZ-ny`M+k%&XNc#ZyjzSOD5yq~RW-`RmP%K3R1#q1WaT!o$+C_SZ zZoyQ2?8(ybAGlTcL!fBoqR8jR`Y_RKhi?!A#PD2s+2rt?Nn_`7pN?LJ&&=CWM8sxfTSBqcoYAN5tyQ+FF3_ppCA=7~voJ?j?0v+(djBD*M7 zEjTi2=k|{d4FALy@`>bz=yC}sYwdK`8jkasiO~5zm4we5n~<*X%+!RYHuE3mDCHub zxEx}ir#sI>EQo?9y}ny2>rkf)FEQ_NP!;$WYFL z*2|u}tYw+_&&=#QTGOAsxb>6`^)dw^xvRkE+eAe|e@F95oYK&s^Kg~m*ouNy1X2}& ze0zOtM!d?c&kxnhh-_ex0(W+_GD9foVg z6-y4a?BsR6lWwvgoHDqCCU7c+hnhx?r(}y6EE=Kkr*Aa4%=K^17iy0l=1Wk5 zbK*+|d_Hp3-(VJ_!* z9k1PmVyroNJ&i9mu?AluDi%VJ$V|yaF7r(?tE1w)ohmb-UH>;t-AAm>;<@zO zm(S%z?f(T8)FD&^ZhBZ;PG>v*|Dg%qd!H@%uG#e^JkiRaI-M5&Igxw+0}`j7rHXLv zLq5H~K6=n-06{C)B{;1QF64x{b$KD)I+G&6omaIdf1?3U3LC1s4jt+x8T8O|HPaS@W(V8Sex3N_S3!}XlKVJ z*sBcRrDm3=;TJ@OgFwAD&u^{k?q++u=qZRMrF%4knwIu2&{bkJ@_~{5EP~WLXi^iC z2w(DAV^iX&G}VthBg&8kEr>&XRZ|VR>>ur$mO@akzzO@tuKzJdJCFs-9OZPM5Je(adry zt^6PlB*q04vIo9K`Yjf41J-tNra20`Eq=$_dP-tGFf>aNy=g()PZoOYz8J@{z++&v zGha5M_s%iKS_G8=@j2=mKHiLXoKS-^eS{AE&mlqCFSM_x++~mk(zTI`0p47p9v$An zPa#t4F6$1~?V`JLPtG)9qCW4yk5}%Ze|gYYLa*{7tHqs7u!9FBz57Yq8(nQi0N^O| zu|75&Z~S^k5$0N05~@FIXu^6GWp_5Yh?cgg>(!6?IZM(Sjd4=f5TZLbgF0Z2m(gP3 z%zm2Zf9#EC0zVa*4QlQxK!iDhv$Oe!ViU4rndFr6E`2(=$+jEx< z=p^|OYpTCc$AiL*pf_m`xViE7j?DmX8Vl{As%aO?I1J4*j{#w6ICOW%JEXymm-_&! z6i9iXN{o{C`-QbkmZx_X3{MNZm|<>N?d&mW&E=i*g9n`hf2&-1tYI@J2q;`fcb05g zMo*r-0P1Um3C8O4c2{C_^7IK6S?`J@v;E%`!UA+^8SPvQ-Vuiucs4akW5_&OC=p2K zp1YrrVTs3C>j98Z56H~j@;7^P!69t-`gne{{s9AVviqAFr_B}9V3#+-VVM8ijaT{i zZGO;Z<>u;hjmiq!KA&8=Dw&dp+!&zY?E2)dtitdS$bSZCk!=Z)GRRs&e!V(PdJ>4L zD1)M8j<9XS-P+X5=!Z|Jxx?|fPb4`HC{4kb+c^6{=b;>`*-%f>2M=n#yHkQs5vD@F`1%)b>!2KSJqVvt13`VM3&Fk8eJLKCcl9MiB zNfmOxW+eap8y7xn(+-SB^aWVrRJAYfX293J|Ed_bjR?>Wp&wGm#Wdfeic&Fq05!YjTW6A6B`)H$hf)#tjVV?}b48@>xb?&`d>Vzmdqg zOV+E`stGXQd1X5P`>?!32dh~xPWuw49x!CCRaKscp$z>NWlv8G0lPfknTaz6PF;>E zNQ%5AO&pkfwNUj_g~O-b(Hi;J6Z`@BG)pjCuTENfCjz1z{~kO%u=eMyd?jvh3O2D4 zxqX?-^bB8KIB{YD)7^&VStSTbjZfOO8uy{_It)CE(HYt9J9)q8mh=+EK4*`aL=N-O z@s0(|o~|JR0wdc0GdoO@Gz*2ja>EGL(=|~czAD_6&~S|4THtbdZl%$77ci3@Yw0XHnu(T<+_fnwRf?^d-lz6+A(k0x}S z1MT0tV6fnZhjp^>u(GOtPoUH*V_LUol70J+WS0_D)7VQiufRoy5S6B&&nJh8;!Z$K z4WbH5qh8=CztNJZ&`SxBvoU)v@_U0BSuY~L5|Nk@heI*J8oE_5ikT!8#@Qv>6_I)( zX103c2s!w(=f!2{sIT4O%ah1-I=iu9^M5>#&!@@|G>_sB;-< zvhG0vu+q2L+dOKs-;?$2-1wq8@m&t|FKL8~>gvo15`G(%@Vn=#uta`W{rm2v3l>>0 z?TNPkJU}@wxJ$&W|2S+&5$dblIow%Hmat zM8`t;?f{ZStCex`qxya1N-NE3_9=u~DppR7@Xjewy{5IVOO$q)vK0N3n<9Kz>8gqP zZohn8U;r}VDCj2UHKhiEG^n=p*QQ7yIi+N&>DeMGYzW=IisVRlDcy`-B}HQ4XY0de zDw^oRALhcmM{6*OcqrP?!Clqzn=PhSwWY*_EDo>Wvv1pjLS?IDPgRgSV`W7S3w_0q z%5c1bZ~UjRjB>duD&3y945=*sdDrd!Elqek-8v~Hj6!7f--Z!|;X}KG_RGD-qckKvT#KKEOaN-HDpfXfVjmb z7G%qX8#CuMrdqs7{>15-yhSiAIdW_od`d8#0PL`#=++@^*<}$Co~x`~V;HUHzGIXU zsT_7{#y+a?voCTh%kX8V|4@ZSf;X*rQA@UsY~RqhkFgxptt5?=eRG>I<{#lJB|*Im zoR9@wtNU>tD~Y1Zv|QmJz2DlpFGCd=pTsX##7sEAAxt?e?$pt%IT*PfYW4TyA{D%= zg4ZG|A7d0_{R{NmBtLCEqMwmfC&gDcl>-@h_rz1O8W7|VIGinZPz@%Y0>@v${~yZU zGp?znYadooQ52A_AfSLjx|D!`fKsJ|76Q^0K_N8hT~wqu=@5DgNodkLqSBF?gx;k0 z-s`*LIp;3V|9L*V-}Wz=%$~hx&6>H^b*+_-O+)P1n-6bMie^*k$PPeLP>bvl_i@>3 z5Tb;3v_^z#z>CcgGi4b0I!u28r3=O)ZwQl*k>kPKAq!O@yD0Dm0 zu&`=2#nr5{X4jso>*U=$Q=uqc$OSt#9DSM~PpZa5Ey~2>bdJ24gWz0GS})wGJlPh; z!?oizs?K|X@c-lI9u+E=E&c{EX`6Ua(XPDr?~{h6Xv9f~elq3b?U|D4ZWCNp2n1G!jjy>!9>}w6YzgnTj-|Ph|dZmiv<3uJ`ynjz)Uec=CBseS)eo z5OZDI4#Cg0TO^Z#En?)R8>2fSiG_DJKh-}`vQHEyFe}9;(K3)HZujEp9JYX(3t+=M zgh4Fgag#*9sN1~>$*k!$tAhY7Ryhr~9!)5YMobxECHfbM^7+m|HG^8@6ehEvM;AVI z&!#PZJ|{4vm=Htw8p#!FQ*|Ne=O`ubq%g@L|M_Qfu=6%hH%8?vnuolyAgdS zHL-zKzc98pIokv`@qRy%T$47NXnG6&fVe7VG86fQLR)m5xbZPpGaYQ^ z!Y|8iQ-+f7qN@B+1B?KWaR%Qh`9Aw=on`ulfRSkFYf<6WZl`&xcZrBW8)`HMsYZS` z0^1upVQKFo0_b;877Y!HAI+%0+`VsG3W*^SZyE5gc&rBCD^www5rC44 zAhSiGMTn{i`pJ7;xKeA}N0%=IiIp!xzT!3@xcfJp`JNvRFtfl-7@Ww-$FqvVvW4O!IU5)9h%HB_>moSCCv22!SVaE6XhilDN!ZW&qH-X0^-X#x#P z>(?xfjBh$Jw=&VeY@-qOL2^#74_`Xj41AeB?&xfC7fsePoJg7%p+n_6SmBeMlO7bV zehAgnlGeh-w(#}4zRrZlO}PE=aH=Mns5;#n@m}yeZP|bC@Gjx1BQ}?*z8dd1Aa7_p zbbq24+OO_En3wW7hX=pgQ%qXiqH}6;-Jiy@twMtK zssLkw;WiTZ-C9yS5a4BFl~tz#_INAp2Y?gX+}Pud|5bNomEhy|OpXr!`t~2$)j}u! z`u6F^A+sYSC52M&tzEA{J81KEo-GJ;_R25I>yojT9$ zGke(bJ12&eI!Ua-yYKLfd?IXrc#cFV9uvw!RAE$=J?;G6SR7}nef>xoLd9;>>8;@_ z<`PW(X#qxaBilstz>999ojv_dMhh|XOUuvM{?eg_zVhT0?U4f$(_#vrt8RqMQS z)SJ62DJ1g+^vPGZgC`%prOL%@b?J4=(?UDjK!YM%P?rm4Bw#IYW}dw4(GlnC-JiOD7t`hMwQJ*S6A|$0x}miUfb|`?P)ww>dMi)F`Ib9fCS7~Q(f4z_<%if zK!`-`SLRzt;ay`+Ihf3|cCKvdkC$ES!`VGTcI-Z9h&88?Rih?iDHYpOeltf(@LGt9RE)n<%njE5La!4IwG%KUEo>VS zN@R}ma&gry19K3I$3B6h7oC<8O)K1NagjC;TPbUF_2pesh_hHsP=5#-%V*ASK48Ms zqw@L3&8U80h0QM43Z6*iXqfh$J@IaOF9UgH`=)Qp_#HL`Wnuk8%ep=JXQ;`V@bFQu zjU$Enn__>6b`0K(nCPdlSysWfs;|Wh!;EJnLHp+9wRwMYIscDP3xF#+hqa*cD>r;u zE?3-?;@ocf(EbOzJZbuVYu8mLHss3-eYWrb1E|~|C6}D<9|UvF8{uG4L^u9Ia8LR{ z6$zl@5=r|<#}$LVjWI30R#SO9AwpPSi3UE^F1T6+()hyQ+WtJyDODqiWOJybOq9i7 z%kD*FX{5en_%5sD9(nTA2j94MFhc(>{d$C&N?*H*3`emMg+tY{T)fa>fLaI%k%{tt z$d3k!UfvwUnQL9DiDyo;Kj#9@v1l7{^?P&& z&Omf4V(b@BO@*idgXNpJs^@R=gj~%cMv(xdv6ds*M6Z;0434~mr5DFhMsvcmzK_-R zWUA>s7tfuOZ{rDlmZHJOcUnF${-PvZOWhXWDC|EQ>Oyj62P2wT#A4@|*h35T)xy~AtX@%~p#*+nN15W55qpRYznC)y zSbPzdTW{u~+fI`UD(oSEZi*C%Gu47qQ^~ZfMamnZ6k)n;Lv5JfEHdnf=f_-;MCM?V z7$*-wUll=sf$2jp4vG!ny?s?5wyb<_=VM_n(0q<*VF(J)f)28lJiUARB9L9?zD1oAUUV*`8`OZ&y^w z;N5Nu3k3c7ZWgGRSpo`IqGER}sskRum5QmS3gBHV-nl>8kA1Lr(QqfN#;;*1eGsQ(ehDwWL> z7j#D@U%(-;G$I9dZWLhFRAVMB7JT>>WInYts<-rcE!u}s0h0vBn731sFyzAK93n+_C|-|CA>Wb7)@x*ior{9PojwnO-x8In+b!tBUatH_150F}HJsl6s%6vnIjf`cc&oOnzuTxF`{FpQw)9>-V_J`o^X8cP zJ1_bk@)ory`NWMTnQ>p+ejrWKYU-)mMK`Cvbr*O@K*sgGP>SQtl~Truw~6)~OQfzb z2rGd2i9c>^W&)8nHel>+3Ya|24mtc0m7xY^e=#_?3NA;k#u(2Q8nJ9pmu(bLDX+n%}{E&*=NcSfaT!^+eIq9;Cb|8?h$_%mCki1U8g_5<}R}+J2|&DS!ZeP z;*Yt4oN;51XZoaR>(njZ2i~S3B>|2=qGDX^j98}*u`?NH+T{ZEN2)cb548aNHm6iV zlVG5$(3{JwmJAkX(f@zmMvK`Qc|F8T`gA4<|$Va^>t`sqR7SaG? zeCHlmgXl&qNj3+#*ATT*L${&J=v;H;o-WSOIZ@OY5$}&^cmM-r^Te`YVAryFgfN|c zToq?f{?KG|Er5dVb*M)bITkK#=itTk|4%KM!rR$mui7M9E%CQLBe+KA%;yk`0Jv9w zQkYGM_}EzI)%CTN){8pE@fF6*FSe7@kr$CjYpk-ten^3s^Rn1!a;`pPc1qlqeP;e7 zI<((q;gUj-=rIei^IXLnqLbZg29se*Nk~rD)KFhn} zWA4jhWBY&fYUBU|5rcPB9T;&o?1TbREui?8&&)q?i9l`OJ`0lmn+*9kEAkjV{606d z1$Z*T&;sW_Chp9|5mN%0F#858fAU?7PA~8ga!E)qZ3h&W2zX8hj;I7*Bm#ahinb8? zLmEM`&ddZbB@Twj(*H>zakn@UGbAsQIHMHp0bRab+6cKiXS^L{?^anz!kE=%1rhZ)b`2}OGix(Q>5Cj+o zjC=9Hnc>DJxeTF&den*JdXd;}$7KBlNas96VHY{xdFNDa<>U|KNa6|t0AK<8tz0tMaNdT!ITmunSKtj#|86%+~+xc43 zYIrw90Z{t=xbY-(L#GsFSEV{qC4=<+}}k=s7xgr1uL? z6Gng4%s(&96Q$Vodbr+(?)@w!ftnKoy}$n_+cFrT_d*HVq_%F;^x+TBN9nz?IQY?} zk$kJ(N9X|7Jdd4Y18IkGWGTFE_C!7^+7di#Y>@E{RGV;hVHpc~)i-x};d_9neQ*ww zQszjQzj@PGe_dY4@+;(qc4we`_D+({Wu~d*D@^p?xg-VW(f*CR@@!=3Ki=0;t3!BzQ%I4fz>1&zx2cPW<^NAp;oxj`?bB`^5x#UK#sbRM$iT&93oTGmw#!4Pn0@?E@D* zY^t0Gf3zLF&#W$S*Ko{Q3-S2DDuY9-bhd@(@iN1W7=+R~twz+FejxSCQ{&2GJX;2v zyRca!R^)8L_7_@+c%TH>0oj{VM| ztJdLap#-coupy9GHr-82DCRlDmWYr{r9Eg);_yw?Va;gx8Tw~eHLPzLo6>w~PseMBS)b=3y`Xjyybd)L|XeFs({y81_bTO3mi^V5^ znI{>$I2IP~aUE=E4Hw`;N_er3J=y(o|3*5~2#we)v=Rl6oI$$Bl02C19)B}UHN{kM z>TSOE4hJPjAhh`%&XJn$GS2bhM7r{wa3GeU6UBc;@$)0KM7nJ=`ZmM>n;)F|mRz@G zq(;om4;gdd&|6X2lBu9+RD%pLDL7D9H2{%@ym6G#{AVup|E<0}#jpq`AIN_^YRY2NMBU##sWBZI=TgD1`q+ z!LAdM42giOy!W>@rypWB>0p1>e#?RN2ujS*A837A2(m10C|ay$ay%t0>Zj-A3rmzt z6hu`T%R65VGC6_$f#8icvw<{>&HN`{7|!YYfQ^Na;~2P--7`%-O#-NgQ*dkw4iC)! zsFhtcqvD0$J+-yFPf!GKfgwqitG7v4K863&at>_WOb`{oM)%@>^ziQ_Km2XAB78fq`i2v2c|G2?_>y`=k z{;xhzgrMAieez!wdHWnyhPUW|8L3J!X1DTZ(`K#3|$H~|Lvsfy*F}_Zu0HG)ZN~dMx9rePe`ch?qfqeqZ z=CKx3gm365x}#d8yS0eO2+}WFodvHR&3T{Zposr$fR($s!28OSN+A{GC5bUYw+*Px zKLl5tP-4)x`GLSB*bo8_y46VYL_xIabvjU60O++^6FYOJi9P@I8HgbQpDam3mIaTM zA>JM&z_(ZH5S(#Oa+i~VFg@yb4*hv=0jMwtS zA6ZG|!!>+6scY>PvrMLq^z?=CUoZ0%rd6*j>P?FUpSlO{R=#f2Ecj-D868JSnOvZa zZ$7@xQ_~H%e>te>c1sux(S@ow^=`I!M$J)=@G*vf_tfUOac{Id5qozZZ{-!~mD>c{ zd2U@eR9Q+#qP082lrp+BQ~+MaT{_>DI;HuoYp^Fia%;Cq+b%pM(#)FPX(^ahH4rmk zCXp+=M|apCuxlb)tNd&GK11s|*>dO`k6t0Cgl8$9x|mND<|QJXhw{IFrtrjak4#p? z*fB-)ejN<`I$q0fwA+eNU5*NM`K5IjM56%qulVZx(vxgMmqK4GoEW|oj6m{e*^Won zJ_PfmBr0=#5@(#%gyTExvoz|Kb5i<~;TR#a`y>iG;U5$vNIN$=D$L)#B^@x^MKR&D zA}nz)V)12&IYh?@?d>{NeV)zJL4dHfS9>R2h&Nr6diBx$Mor^=fBL(YGRG%K1Sf9s zMySZ~$IM70G{;JRF70D-ws>}9PUU5^vzn9BQa+SLH(dvhxM)_srG?XHEk~@ZQ$itg zDU@*53G-^cjwd|LZ8>xC`UfHJnGWTP7|RcNLnHxlV+O-3%4t}5K@jHAUTb0YW>Abu zfTy?y7~t&2Ep^qgzNo;Yo;{`Xetv6o{=jWGCl|@Mj(L4_hcGoWF*wiG8hKHVUsF^~pzlXiRUiIn>cy2}0A9QGEaB!J}%@RSQcup{zSaZIQkh6L%L6 zWmVMRC(fD7^|WbdKI{H_2_5dt606(%n8*SJBP5`WgcYV$cwJ}IZz(-3PMzT{{X|=1 z#-diIGmtoU+{A&luMG4Q?izgxqdn~p$OnzoG+KS_V0Do#{Ia_GgKs#r9ILszYjTLp z2oUYynNU4JIB&}T-isUcES%Wm4Y8ArCA=|Tz1~9i5DbchFLl1bO6NLB@mSSRr&1{krjjqFj32Y=nlb3*0_2^%G6g(oZox$g6POAhrk7 z0cG+7{YV-v1@(Y5$?QXDfj$_P`!mBOYuMDL{>cW`y<=HET5Vp=E5kpRL1tRW=>zLLrB=j{JJy*|K>!d#-+>IUY|dgd5o_1A>S+Sem7BkiJjaw_+GUNjHQs|Gu2Cb6Q;F`xQ0L~2UvHJK5 zm&=ri!5*dJ#H)Vh=D6~(R^bAR!7ViD$cSgTn`P?IR6KS0?1Nuv4ek|)#oHcL^oP~3 zWis2L<-LVnZI`eW=a_z1pS>4+K6wk0L!pQTFZ|0{ShI6F66a|q*BeCrZL~-0Wtmu| zwk4Z1&$226=hbYXD%e-d2{vK0O$Iyg)NwU^?7fIs@9J-UUPm9Zg906?t9N$mnul@( z$ySy~tKGIqVq30cRjub5o8)rz?_S)Com4@vt?Kg;0DWqf3P*@GUZ~h?&e8VQp;eYbfbPN%iwwrEs%4oLE}J$&#s0-_j?({#<#OH+^WJn2EuZIWK(B zHblu?ld9=`vx5J~-hE9TvIhDucv*MJJ#@vl>aOubRv*L*+t5L{Qd^MCSDJ^YsH5Z= z9hM1RMY;Za_P#cC#G_je0^eumeU)>c>XZJ(T8yK{UmJ<}gwm1FhUMfl4ogWv9h!!& z-Bgym?Iz3()`jdg9tQAA;vI*X`WaH+MEnS>_2hx8^QozTVG22n`Dee&>eRQcggP;P z8@ZUwE><#lI&-mXA6sse<-F8m;1UpZ?Mr0)ysN$XkJ9Ts$Nsn-#%$)8yDBljYT{ z@__f5kB?pbrS>Rv;Y-C7MMk?XU_&A$hCf3#{eT*5Zh7x7gLm~HT_v=3WY%h9dzKv; zR~4j!)Twqe$^-Jsb(5-LKbtUtQ>$j%r-1U{^Z=&{U1cm42jhjbc>>b6AA*x(Un?kt zs)Bv#O?3L|5P23v8NCU5bQHg9M*~WOPH`jM4l}wUR~zI{XqNNsUcrNcFeWIAl>9f- zS#tFnKQ#F4f3XJTgA`azYM1zPi*;UYo224rJ|T|sK;hG@!Wovss)a3wO_N1W^wbtL zAwasw6PlUEy0e9|XX~EgbXlN$6LdjEt;fWe1d8L4)%5dYodk*UkC_y8+$y)n8Ni(# z;6h_<@ou@#2n^%8jN70pI54&ul_d^d49ndXy^;A1X)UXa*8qJ@cK0u1QA=2Qmd|PV z*H{HgLX>0I%9smJOS8mq(O)Q*Ln%)s1Knhc@H3CgfSoWNHkA8r1iy1$;v$)Do#pn! z`M2$tFA{aagBah{V7HK{Y^V`zo5?;3#pv+V2k8&h_y|Otz%hgnb70(=~ z&CIyni(nnlhiSqj4(n`B$Bjje4QEHAyy5L#*R-+s;KOAIgj)9=Jm?UIE49i+s7UKO zc0u|r4VZ_#)T0!gg1c(aHqYQClG`%vc%1N+Y(19hFwXbaz{wjZ}0YkB-gS)Z4E{23^o}34~STi&-C80 z+g7JBc&*J*wHwv6F3jL7hCSlW3yr*$F0+^DaE!%)T*21fV1HTJ!Q)q(4j8+x919aZMF+b~=K60mbStyu*oyfe-O)2ICby_!m@gu}X2r3eUH- z2kUOAOa%QH(f-k``2i1rxO&|vFe#-uA6sDzA(!|VHdHN=Vb?Xin4F#I-&H&=dw9WT zWr-|#7<-S@={eJ_WToxEOWz*RJn}^j*y#6jjiqBJW{@8JK-dcmy*|d4)M6?;7s8(YBe9`<>r4q#1MEp71E@+@M47-K` zt$P_|%B&xaC>1T13g~-R_TD}fVt}}{ys^2GD#KHSN?(jkYDQXLnFk-@sJ}*ram0l- zA{#s;rLpWFVP}DHRX51dd4y#s5u+pg^4$;{{EWm?0(UCwR@qUDEQgbbEq!-`h-2Cu zYSpp#-}=zi^{UmDollmR<|JPJT}R=Wn~uD{Z!b}F1MF5j-KdJ%cRVx9Mf7{c`Hz$o zL#mTpKAmm(jW5`k2<0m*0omzfSA3(t&TKKI|Nt^kOXeK7!#`KoP(7aY2KI zM&u#>qW%R7x?KtKw%IAEee-^TuJ>~8yWwXN$n7`%s}d<1 zOdOQCt0k3m-O+1D40cL2_dTDAI-XB@)RmRfM_)z@$M2YIUI%H5SaDTk+l`w|n zVXNqZ$lTiHWSJ>$n^0NP-Ve-;dlRD0Kba4RwV5_@+rCk*yWr#@Yfp6ay>D4QwaTJ+ zDwlCFN?xztU9jp*NqP37f}w`mB<(wb`S9Y|u%>3OE*2FxGJ0JFT*tbs9Va=8DD_>e z#i{HViZEk&@VDT=^LwTom+TaOb$Pu$`R0R=&1HcP`yxhvfTzww4#?nJu_JAw=W$}B z`U;*(I-X`9*Q_fKxkIZTyGMxw#iNXnCaSFlq%p5c^36P?r|b0;=#m@bTW;7)PR71d z%4_^3KUNHNXkmXt>{IQK@AhKcT_cd@{J`yL9pGCIwflA$ujHaNl)8*Lo;$T(0im z2?x6iBbZS$rX$0<%3CbT%D|_%ebz@X_w2j5;e4;YN|C+ln|IzeV)v24F98Py%Aubb zyV6lbpXB8>$x&s|0_=#LyS-YFA7zPBjS^8zDxK1sMtK^uTWxt~w+(aKFqlhzn|OXNekc^82Y$5-Zu*1vXqBQB`D6gag+4bT!XbVEDy-N|`ezov3$;Z{<$x$B?Az!y&RhAE=p{2U^0}x@g2wn+I zC<0)Z1M1p?6;Fo8rMT>jOR5cNP^CwzYiAOi^B|GO!n z1=0rwolU;0KzaepSc>>@WEbl*w)XC!RJ#VzQwVVZa%#=_Huz#12+ORBHaXZ+Wwg@mkO>^D?6nov!=Ez;|fz%${PXS16Aao|S5y-i>g9=K@n;lv>$@%d- zUjsWa8qno6-f9^%Zg9^Hn3TG?#ky)4;=iW~n96rE|1oj@F`xf`ryk7!hFL=G!iX>I z#3DGOa_^D?)ycrKkLmw17AGyJlVwQe#S0Qhq_iJkI`;^6()i-vW;SjL<|iY&Adv$C zVJy44s=?YRN0vOgs(NM?Ie2F{r(oY@pvxB!Y2~eOL#kKMf+T9MO8a5~jjpWZPtK+oBFgoovI8&NF$o}MQ%S%rog*h@ht){AK z)d1vTGGqj-9myI^8V1}S%7+PzRt74=`8X`Zqb_|w!~>~Cf0iEME#bg6;OLJkb1>!o z*r-_8^Bj2nD~_VMHlNCtw;p|rh(+Xun?S)lFR&={bnJrZjw1owz zV=-mZrt!sJLrSI^Vq9`TV_y?5Jp$g#HB_6H4BELqO&rz6bz9;7Vr9ZoDSmwo?2Ed|^@1NrIND-w&` z>Id9KG<+&vUv%-W)SN8y9>4|gTJ6%pvte*e-C52`B{8mwoPr=SY-Bm@?Pk-5kA@<`Sfw&~Lo&YRhn2NL{{HNI?qWh|Mi zmDU0vb*ZDxd4ib@l7%$XmaAu^W8ds7 zrBMwY9Z2y=|LuEQ=r+{~jVKGCsK@vxGDA(rg-GoZgvuS7flEh+SCNRI7sG2p{aSeZ z&31R`6y2(o6jGJYwkcx$vg$;)o}G=$o63h-J9C7)1sA&x4BWaf{t(*S#pxoYV za18b?3t(Xma7-iz>0iDa$@|>eaP~G}ohdakB41t^Ndm@IhYIxHxRi!8VzlI}@Va#! zaOeX_P$K3&Ahg{FY@G!T79$b3hNcXfKiwJbHms`qW>)6P~r+*{4km5@4f(m{LUKDzh3#2CpAsp?0GK|8$p&XwECXOJW9&L!N!KqMMgEdZW9v&FHOWhERgd8DsZvx zKlasUT7ak9ZjET8f5`4KqTYuLQPQy-o#@VnvR1#A+Eeko6ZOQOS{?g70)y{Z)X|9g zmJZMEKxwh#t!NkhVMV4O!LlX&Ov4V9Hb=BQPn2Vvh4ieScFxq580*=3iF;>u6Jvf# zO&A?PG1d-YMSTpqi-(5|MsM*7kDE#UZ=6h}Hr*$2gkn*D$Skbh%v9i7|_GtN0>iee(YWRFC^hpJyI`$)}k1|EH zoWXtRYuhY8Z*CUU8s(NHK|xKbA|jTB$WH~u8926rw@|p;iIS|qFqc{H5JD?ik_H?o zm9QRag!2Owyvf$_>d3F~D!72*<4h1%7poEF>ZVXC1h+p*HTjMqbDGJ4pXFWAbtZ*dP?_HQ)R+Wz6md2aG@OdOt~Am_La)#*>%EZDZWYAZl-Ldn`uZQXjJL*^khWR zn!Z^YvS5uIBrfS7_*G^eWuY7vok*69^BWAyq-3S(YwS)|#+N@Xy zZqxO_F&^TMNU3u8Ax`VyrISF;aojE=UaJ?I-DE>*8n1N?*tKzN{=Tb-rJ2EmtZfrs z9W}A1PF!nYYA$O%ZD(HsB$DpiWP)IrlllkDTLO=qjKh~gz`1QD;_ya&TNt-?gc|If z@E|Wda>`OOD#W&txv2j*^h$Df&x!8p&LVC`dsG%;k20#ijA^^R(KvVM8?e!qx>!+M z49Hb=%<3ajoNuafpMANZWkBlfZR^+S!gSSzq_8z2bse8pxKlxo#lYBrncJaU|BJ^1{ zZxXLIT^be|c-)WxW0+`?5=KPCVRpigX!jmMP+s(w^j-3qy^R5|YKr9JCpJy>brgoRR)(IGq2q={ zCU1*->uI>0yjYJ8iuDA<7OrOqs{-%^=cxX3a!(;HzlW}6I(xA@Z*V#sT4Z8gEA=*f zU%%)O>im98k10>*XCOa2oJ1SCxB^nR3+xq%2+bmBESR55CgTnlvblm!vGd6aL&Q0y zx5<`^v@#DI&LZrRLPXdtAdr}M{D6AOFZmO`bX=&P`X<504=aFU&dgNEL?PZOmMBH% zh5D|2eR;_5rYmDUiN@v=>96w$dr~Tbx9$6C)BWX9(%lR^8*$UX%%e)}C;;`yH-)3G z{hS02Y361=nZT3ag5mUhk@nYtiLoJLq=Esc3=5P5{ujvl6d#{_osUeEkEfI)h_V!s zQz&_~^KRO?o3UqOYJJ-$Y2X9GC=uaTBKW(WVm^EK5=>5mlMX04!43{Kvok;FMYYp1 zS4!s6FC1}%AxP9RdaE=n50xCxqH7TC+qwxLGvjX=D|GGWcGzOgDTruir7nanRdztq zw(8u)(oSxiws!7B-&O`v2~@Bec1LWLr}$E}I`1H&EHLL5v~|&|40lpu6ZDm@&vOmZ z!a41Yh~VyCaCb-jE+u}xe7L5ZhTpdXZA0V{#u-N~N~J;SD42;<9unMg)1=~4g@u8q zP#Y(97Ks~U%fKHK60MnE`l6EvZ3Jgf-UOvm)y~2%acLX-D=fcAW}PtA!-FAE z%meNtt*LNabL7{oUpof$H)}jx7uDjL;PPgr4!?&`Nk-d!2l55Gn`XZYbYn&fZZuf! zkLl`gtgGRWzcOMrCW{Xi)30@YK9fGQ)pEKG7_K7@hfBx8?K6=>g1dbs5K&UKok-9e z9j0644an$jcwBKsj08QL{;X;4YtlUf`@1iTJ79*FKfVZsVwzBj<}#OsVg^G3I)BKO zklv@c;|XIqHOWzv)Utdp#OZEfKOSn3d?IJ0_O~9Qm5(VZYliJJH&Rjj+xH ziBiX`>wJs|nB|N(-1nw+*)!OaRtsQeFBb7`6&1HpOYM`AyK3gm`#Bcyj<3LDk=o`k z?8c6{?CuN>&$DBK6B->&4{kMoz>id@ls5z?*k$%*Zf|OXuUmgMOD&Mv^WSe7vmRu& zS$e$ge1KR8ZX-)xqX?q?Ejh+eO5#!wuv-mi4aIri=P`K*NWq;Anp6ec-760|a`-f; zfH;jhrdf%sG-l-#9cea9-%@eE-IGUMj2xt|>;jHk2X- z6U}KZk3sOBdE+}c>kfp*AL5H~74|mH>NeBO9#iXTYwvfPhT`5Z#B6};96HuXB7B>P zmot3L^{c)ZRr~1kT`)shR+RV&w96HCNfV?V+0E)b=oc|9PtSFto#pe@%=~+`%tOqvKOaSp*0XFE?1>DLReK=`h8Wzh0d^>T1gYeSxtg4|qf+F` z?(ClTgwl{@(%1*YxDpr^OS^AhQcursmvVDdb!EHWcYd6CdgUr^hZdvgm^&A~j;{M< z4D7%E5kbPq$Z7mC=not+Z#WrjAi4kDOl$nAUrE!dXv!$y6(0pDhh-50Bu2SGH zjE%21MmzA6&ZbNl_6EYdSnYN2l}B6Q$FuG;KMO}8ZKE8U9qRR!66cXoOh62uT5d=e z@{C4WMFzTPI<@%a*Hv=uDBd8=z?*X`o0bI#$-~0{0hNO>Iwmkpe&M!{NkqG^v)sz4 zAMXQWlW3^-gMc7tSCjR@?oJ46jfc0v^R~XL=uO*{umBON+?3cN%T0LJ!*Rn2<=H2I zyO$^u6mcv~!QCeLRb$QN*Epl(WJB`{B zTm)F5bKxC}t{TvsF0D=|X=r)~;s=X1z2tFU^-k18xHmF*P#4pXJgR-L*+R#ZJYz+S za}0nZq|Tn@O`y<}ia0aSbYn2IT?8oG_gtmF34^PC7KA;O3%cS|+_^+jbO@cxX{Z$$XcQ#7L=4 z+lw^>^l?enn^g-i+E3}lTYFW1o2vC6GBl$!dv_=|eBs|4*o6>)Rt zG?yjm{me*T>X|)GMk&e~T6()U3ktm-K`bz6Hr+6hhg8f8&CZv|LV!W(LX$+uYacxc8$%+DE2o1SFUxi+jVgsd74r#7P4)Mg-zV0^3Q70p|i zC!DhUbWwMRouTqQE5AL5$M_CtOkm;F*m*5@f$>EgO};dhqw|hf4xOJ5oc{-R(X>nSqFGF2|^gt}N?%o&E9Z;g#iO z8PB9dV@S5b@%`}MD~GP&DdmG8i36c7G&yQ<1JCB6;IJB5T=R5JvoKk-mYux}!x6nN zVY3~he%hXRBWdn`2K_!Z41hJ_@Es;Boa1_~nL-wypx^1oI6A_^nooM8W zQbdeVBSv5+4eAH9PRz-;$`wX17|(Nkmg;p(>(rNaUIYW|&hza=fv7ep>!`WR8|A|~ z3mi3+XD14EeF~{Tcv4_`|5P!G7l2(D{sqJl|DH5Ztz7kv;zB^`a;1pl|w}D}|qfInPI^B82wd z9IU9101*2Xg~17S_P4^hv-H|do#<`=r0BQw`;CqO&xP58YP5A^(1ZHu@ZD7thGNc+ zDqYdd!4ydjhW^!)$@pzUAPyx%Z)u+*!jb7KZ%w@z{Con)S?`Lz_4=l$#6Do3F&oTg zP8VSBWv@IR0GNVTUWW`1e6&^&@WX8y3EkNtWRP0pk?e6FjV|p|IIGZU3Mb30cJHXr zy?m7?H6`h9frNfIts$qgX6gCd+Mx5qy4LRH)kgpAL~`FFS(%*jw(OM}mdl#Hw`|ak zJI%sL*WH0~=mOb!w?$4CreE;er0A*cJ_e$@uWpZq-q(yc^Fv57?Mu28-vD1<+a;}n zi`~)C2;z`p`IO^*he7iA`21vHpSk_sQi`U$`AKwfni70eHE*F#bblq9p||yp^_1E} zZ-?()-73Gx=3<+KKg-YK1@_n4`x2PFg{sH)@jD^8pdzKAOns#g(K1M0HtH7Sfu@$G z)wrJq^r80;SqShyo$~(7r@7G+GKbgq5ALY}$d(w~mL^AQ=z!Z<{@%qAYy?KnG&cDm z-X}deWjB03Go_}TMa*)#r8}h!H@E`%eOAddTE#I{61dXI{Q2fj@=~W#Vcz7in-K50 z9rEM@dFO>WktWG=6KLRc|75;4SU2KXZ)!=>Fev7oR@X`L0t1Dm)sUaA<#WZ zg7?%^&YvSYZ|CLiVAP>T@Aw_+$YGRhKRYGsdoUUwV7#=KPF}cwYE#>rUQ=0oB)XOYU2`}kK4sY|}ExX#sNgraryZ@yI|X1c&3E2*TcHQA%1=!K-<0+CfOEMI|0`algKI|Lf+RUP&4% z!?soCdV@%Dfrx;luP1O!y8!otD#@`k=41I-*c}?tR;T;=(Ri107B*9O;^2>{-*OZP zp8Xd2{8;PwATE33xG|-qso9J#4(6U;&z$O0uR8#ngfV2Vl2a-YNQW0(z)?rgEo_aV z8Syi*%o^p_LV+-O^;&BP=c$B8ABR+N?R}46d59p$T(4i3*dDso{QiZ6h8&GUJ9$`O zvSxBY&p~H|HWG&$jVu#X`bNf- zfwBm=og*CEXEt$Xo+3&@7`qTgpnJNX&h6mKZva#kZpR&G3cCuoz5?)?>R2G2bYRD& z3RIEpnAA*$d$QA>a>Et#k9`O&V zb7Z-gYwNGtOOY&U4Rl;;U?@a3WIT-d`2Q`cyNl1yccpHq^D3PyAK-|x|+zXr$5@2weXS9dcnY82?z+dt`+m9Dhep5@}Y-Ky_TyPi=44j}xzVls7dVE5d-FQ26Z zCwF8Y*}pov^rGYH>C68`c~86gVM<@|mGh|&6$EQTzwDT5TN?W3gC~o0ytpv+a@NkGpc5{8R39sga%Y-mUYt=EUwJjc zbG7G*tX#mZ=1*@AzUSpqZbPIS@ck7bOkE^m)nfHRmHEucjE}OpWYRJqf z`roeneYNDxh1&F+m%O}uH@!}~9t9jMEdQO-p65{ZaMsl+L9C0;EK0S!_au)WXkxYL zR9AKFmB+RjSB1n#u9`6O*Xyu5QY%gxY584IS$=b-*vuu?MIl!YKX?=?SaZ_xtIsmI zHOssXmT=^@9R!V^foGwCBUy;y6(BQEq;-)7FoAYHSfs&foB7?~ic6pf*xw5lX_N)| zJ$dWrTMbcCTfb_lMwfA}>+CMD7WJ-05i4g|zn%u>xpyrJQQMoy=Nbr__!DvUtZYA~ z*#(^Rt6HSdRV+Urtf;+f(Uh|{Oh9UcZvuB)AST?wLu|rXObzBn1gLM^@ zTs;CD$h&d`F^YGO0eF|9`G01H1?@l1u5X$3@6Y1bvi+Z*;r2`n tFC^=}KCl0Ad*6Omh8LFqq8k_))U@Sx``qc70=()FxK!ECWt~$(69773LO1{b literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-mark.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-mark.png new file mode 100644 index 0000000000000000000000000000000000000000..c8042ed5cae23c3032ab8e26fe70f444d6d12c1a GIT binary patch literal 44862 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%0Dhl82kZ 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 SSg>aM4OwX=se+g9z5fSYc-Q{` literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-upvote.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk-upvote.png new file mode 100644 index 0000000000000000000000000000000000000000..b0a7d248b5c7d6f7155b696455aaba9abf214cf5 GIT binary patch literal 41092 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 P3V1=(e!pL)Y7_EbY4HrL literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/img/zerotalk.png new file mode 100644 index 0000000000000000000000000000000000000000..3e2cb5c674b94d45f42c8f9ece5b354166c9a1cc GIT binary patch literal 26606 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 K<>K29g8vK7>Ix44 literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/optional.txt b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/optional.txt new file mode 100644 index 00000000..3462721f --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/optional.txt @@ -0,0 +1 @@ +hello! \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/content.json new file mode 100644 index 00000000..814afdbf --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/content.json @@ -0,0 +1,14 @@ +{ + "address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT", + "files": { + "data.json": { + "sha512": "369d4e780cc80504285f13774ca327fe725eed2d813aad229e62356b07365906", + "size": 505 + } + }, + "inner_path": "data/test_include/content.json", + "modified": 1470340816.513, + "signs": { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "GxF2ZD0DaMx+CuxafnnRx+IkWTrXubcmTHaJIPyemFpzCvbSo6DyjstN8T3qngFhYIZI/MkcG4ogStG0PLv6p3w=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/data.json new file mode 100644 index 00000000..add2a24b --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/test_include/data.json @@ -0,0 +1,37 @@ +{ + "next_topic_id": 1, + "topics": [], + "next_message_id": 5, + "comments": { + "1@2": [ + { + "comment_id": 1, + "body": "New user test!", + "added": 1423442049 + }, + { + "comment_id": 2, + "body": "test 321", + "added": 1423531445 + }, + { + "comment_id": 3, + "body": "0.2.4 test.", + "added": 1424133003 + } + ] + }, + "topic_votes": { + "1@2": 1, + "1@6": 1, + "1@69": 1, + "607@69": 1 + }, + "comment_votes": { + "35@2": 1, + "7@64": 1, + "8@64": 1, + "50@2": 1, + "13@77": 1 + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json new file mode 100644 index 00000000..bb24e26b --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json @@ -0,0 +1,15 @@ +{ + "cert_auth_type": "web", + "cert_sign": "G4YB7y749GI6mJboyI7cNNfyMwOS0rcVXLmgq8qmCC4TCaRqup3TGWm8hzeru7+B5iXhq19Ruz286bNVKgNbnwU=", + "cert_user_id": "newzeroid@zeroid.bit", + "files": { + "data.json": { + "sha512": "2378ef20379f1db0c3e2a803bfbfda2b68515968b7e311ccc604406168969d34", + "size": 161 + } + }, + "modified": 1432554679.913, + "signs": { + "1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q": "GzX/Ht6ms1dOnqB3kVENvDnxpH+mqA0Zlg3hWy0iwgxpyxWcA4zgmwxcEH41BN9RrvCaxgSd2m1SG1/8qbQPzDY=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json new file mode 100644 index 00000000..52acca16 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json @@ -0,0 +1,12 @@ +{ + "next_comment_id": 2, + "comment": [ + { + "comment_id": 1, + "body": "Test me!", + "post_id": 40, + "date_added": 1432554679 + } + ], + "comment_vote": {} +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json new file mode 100644 index 00000000..67aaf584 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json @@ -0,0 +1,24 @@ +{ + "address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT", + "cert_auth_type": "web", + "cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=", + "cert_user_id": "toruser@zeroid.bit", + "files": { + "data.json": { + "sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45", + "size": 168 + } + }, + "files_optional": { + "peanut-butter-jelly-time.gif": { + "sha512": "a238fd27bda2a06f07f9f246954b34dcf82e6472aebdecc2c5dc1f01a50721ef", + "size": 1606 + } + }, + "inner_path": "data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json", + "modified": 1470340817.676, + "optional": ".*\\.(jpg|png|gif)", + "signs": { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G6UOG3ne1hVe3mDGXHnWX8A1vKzH0XHD6LGMsshvNFVXGn003IFNLUL9dlb3XXJf3tyJGZncvGobzNpwBib08QY=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json new file mode 100644 index 00000000..1a7e9ee0 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json @@ -0,0 +1,12 @@ +{ + "next_comment_id": 2, + "comment": [ + { + "comment_id": 1, + "body": "hello from Tor!", + "post_id": 38, + "date_added": 1432491109 + } + ], + "comment_vote": {} +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/peanut-butter-jelly-time.gif new file mode 100644 index 0000000000000000000000000000000000000000..54c69d1c8f509f0df86c2a1b387e7104bc040844 GIT binary patch literal 1606 zcmZvbc~H`67{`Bwh~g2Jt_qXlU}ogS55#i~#9Q-7T}?AJ70t6e50XeV^y!>Fr_f5NiTpfOi1! z^;-d70bpqfkVpVL75KkQzH0cphXhl|f$pG{4P@6=*W{CmIvjuj7T;cc8wVgQwDHw1 zHVfW8llJSkrMRf~1&`toD&cfDQeU~wlC{M$C2CD6>~GoQ-+==vSaENEQ#VU+(VHy^ z@yI13@i$RvQcThHjkL1au!jZ_YZX-AzY=sgv*c`ewJA6HNC4g26Xu-D<76TjH0Eg* zm!5Cu;(&$b{Q%|J2dPS-Qe?An1G-sm*hy~e>@tvOU36my*kVctI7RT#iL73n5~02m zciT3%0$KCnnJgZmV&ED#AWM4Kml~%~0<#ORw291o>3z$1KzG+nL?zVi4$VxiBjG+~ zIZlJ^!D*vQm82#TxD=IZd zL7^~clrynLB&O`GA^Y&9wQe-IeSM(Jq>&`;M6|lm!OPhp9)c3#m_neK$nMh&*V&O= zu|=LZGw-csQuUJl_m>J>jFEy&wyC9xx&s;42Gj=^_pd54{{cw7v1)MsbYRd&l4IFQ z9Qgc%f042c0h|AfhL*k=&D3S`*>zqTLW7qBW(`jaRVd@7O#P3W2`L~v8BwTe!{#_R zncJ495+DgeleC&2IVII$LaBAFsG_M^zNcPN*V@&MJ=_b%%i5hY+s|l>j={>x#>OYE za!-$)%SjrH@C!da;N}sTvvS90?w4WMj$sDBuR(;fwWg^3s`tF;p1Y>8p&PvyKDd)JY142EFyG6+F%2c9g0|$2Hm@MC4}4^42ll@<8NXs4BjQ))R@D&M1++ zoJCD!wo=<%rDAYUd)P0J-=NRU=X+I;Uz2|#x!^Q_VF!xs^!AGrim~)dGm|F zHXfa%N#3Y^z-c#ik{w!dIm_$m;T~26nmYDr^RG-()YL)DVpF!7J61A(;4YGmHHN-; zq4YI^PkF>%!rV)($O*^5kSdDzlBiRSZ*~{a7+GKnfkjiz2lcF-sQiQ0wpCzF2A1za z$PizsJtNhIG&kDGH9LI+b%qMSYVnBRkGRz%2EA)=Y~@v*F)dJAu;Br*J5s%qVwuM z8r*t%CNF=cVr9*J>=3cVdi9lxj5!$9NZ!z(XI$7FLh3*%%GkEYgjd%=S^<&+16?dm z@VEu1O05c*Uii{9Cjo(ks)f)<0;{7nmGTyuxG}PmM0csKgZ20K4h<7WN6~$_9$kH^ V`Bai&kQ*v^2ASNs*rpCR{RfJmfm#3n literal 0 HcmV?d00001 diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json new file mode 100644 index 00000000..7436b6da --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json @@ -0,0 +1,17 @@ +{ + "address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT", + "cert_auth_type": "web", + "cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=", + "cert_user_id": "toruser@zeroid.bit", + "files": { + "data.json": { + "sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45", + "size": 168 + } + }, + "inner_path": "data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", + "modified": 1470340818.389, + "signs": { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G6oCzql6KWKAq2aSmZ1pm4SqvwL3e3LRdWxsvILrDc6VWpGZmVgbNn5qW18bA7fewhtA/oKc5+yYjGlTLLOWrB4=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/data.json new file mode 100644 index 00000000..1a7e9ee0 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/data.json @@ -0,0 +1,12 @@ +{ + "next_comment_id": 2, + "comment": [ + { + "comment_id": 1, + "body": "hello from Tor!", + "post_id": 38, + "date_added": 1432491109 + } + ], + "comment_vote": {} +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/content.json new file mode 100644 index 00000000..8c71b84a --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/data/users/content.json @@ -0,0 +1,30 @@ +{ + "address": "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT", + "files": {}, + "ignore": ".*", + "inner_path": "data/users/content.json", + "modified": 1470340815.228, + "signs": { + "1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT": "G25hsrlyTOy8PHKuovKDRC7puoBj/OLIZ3U4OJ01izkhE1BBQ+TOgxX96+HXoZGme2/P4IdEnYjc1rqIZ6O+nFk=" + }, + "user_contents": { + "cert_signers": { + "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ] + }, + "permission_rules": { + ".*": { + "files_allowed": "data.json", + "files_allowed_optional": ".*\\.(png|jpg|gif)", + "max_size": 10000, + "max_size_optional": 10000000, + "signers": [ "14wgQ4VDDZNoRMFF4yCDuTrBSHmYhL3bet" ] + }, + "bitid/.*@zeroid.bit": { "max_size": 40000 }, + "bitmsg/.*@zeroid.bit": { "max_size": 15000 } + }, + "permissions": { + "bad@zeroid.bit": false, + "nofish@zeroid.bit": { "max_size": 100000 } + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/dbschema.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/dbschema.json new file mode 100644 index 00000000..3d1cdd7a --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/dbschema.json @@ -0,0 +1,54 @@ +{ + "db_name": "ZeroBlog", + "db_file": "data/zeroblog.db", + "version": 2, + "maps": { + "users/.+/data.json": { + "to_table": [ + "comment", + {"node": "comment_vote", "table": "comment_vote", "key_col": "comment_uri", "val_col": "vote"} + ] + }, + "users/.+/content.json": { + "to_keyvalue": [ "cert_user_id" ] + }, + "data.json": { + "to_table": [ "post" ], + "to_keyvalue": [ "title", "description", "links", "next_post_id", "demo", "modified" ] + } + + }, + "tables": { + "comment": { + "cols": [ + ["comment_id", "INTEGER"], + ["post_id", "INTEGER"], + ["body", "TEXT"], + ["date_added", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX comment_key ON comment(json_id, comment_id)", "CREATE INDEX comment_post_id ON comment(post_id)"], + "schema_changed": 1426195823 + }, + "comment_vote": { + "cols": [ + ["comment_uri", "TEXT"], + ["vote", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE INDEX comment_vote_comment_uri ON comment_vote(comment_uri)", "CREATE INDEX comment_vote_json_id ON comment_vote(json_id)"], + "schema_changed": 1426195822 + }, + "post": { + "cols": [ + ["post_id", "INTEGER"], + ["title", "TEXT"], + ["body", "TEXT"], + ["date_published", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX post_uri ON post(json_id, post_id)", "CREATE INDEX post_id ON post(post_id)"], + "schema_changed": 1426195823 + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/img/loading.gif b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/img/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..27d0aa8108b0800f9cddcf613f787347d9981e05 GIT binary patch literal 723 zcmZ?wbhEHb6ky0iXa9k4z>53@HBR_Hzvhc6JPKHPSO+W(0~W{*!Vp zN=+!e)X>LZSp~!n_rkGVK%h z9k_L9<(o^(d!N7A`+9eTzQ!EZMr*-N2_|eB&45;SC+a-zP~lXP;z?eTv`FKm^!Y8l zuZ^S*OlLmOv^VZNyYQx zE1Q1d^QD!~t!MErXFkzlm$bqCmuUZ)iN%&IQkAQ(b??%e8>EQMBqK<8T-y}!%q4L0 z4v$MoL7}cEx5PfOihDclHe=f1_`ny+jJ+qGonTF#=e6?cS1GK1Glv+XQW)E^VpGzx z%$u!=(=#3~+Lk*jmQUf$-=^(}f)AMWru(Y&&oE(%*JUs>JH24vgCGuUPSS^%^#tgi z6`S6zDw0tR+QR$5bp7w`G6mDQzjYm%RoE)?D^8cegv~i}{SvGJM6wyypd + + + + ZeroBlog Demo + + + + + + + + + + +

+ + + + +
+ Content changed Sign & Publish new content +
+ + + + +
+
+

+

+
+ +
+ + + + +
+ + + +
+ Add new post + + +
+

Title

+
+ 21 hours ago · 2 min read + ·
3 comments
+
+
Body
+ Read more +
+ + +
+ + + +
+

Title

+
21 hours ago · 2 min read
+
+ +

0 Comments:

+ +
+
+ Please sign in + ━ + new comment +
+
+
Sign in as...
+ + Submit comment +
+
+
+
+
+
+
+ + +
+ +
+
+ user_name + + ━ + 1 day ago +
Reply
+
+
Body
+
+ +
+
+ + + + +
+ + + +
+ + + + + + diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/js/all.js b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/js/all.js new file mode 100644 index 00000000..99eb0c2e --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT-original/js/all.js @@ -0,0 +1,1892 @@ + + +/* ---- data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8/js/lib/00-jquery.min.js ---- */ + + +/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) +},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("