summaryrefslogtreecommitdiff
path: root/searx
diff options
context:
space:
mode:
authorJohannes 'josch' Schauer <josch@debian.org>2021-01-19 12:54:47 +0100
committerJohannes 'josch' Schauer <josch@debian.org>2021-01-19 12:54:47 +0100
commit7a1db4de351875bebb4a8e7ffbe6710ad5b518c5 (patch)
tree41fc39a14842780c6ea061b29a00888e8071ffa8 /searx
parent075e7e02683d9db1b303de8e8c17ff7da4c62510 (diff)
New upstream version 0.18.0+dfsg1
Diffstat (limited to 'searx')
-rw-r--r--searx/__init__.py52
-rw-r--r--searx/answerers/__init__.py8
-rw-r--r--searx/answerers/random/answerer.py32
-rw-r--r--searx/answerers/statistics/answerer.py15
-rw-r--r--searx/autocomplete.py34
-rw-r--r--searx/brand.py6
-rw-r--r--searx/data/__init__.py29
-rw-r--r--searx/data/ahmia_blacklist.txt16177
-rw-r--r--searx/data/engines_languages.json2848
-rw-r--r--searx/data/external_urls.json156
-rw-r--r--searx/data/wikidata_units.json1006
-rw-r--r--searx/engines/1337x.py18
-rw-r--r--searx/engines/__init__.py88
-rw-r--r--searx/engines/acgsou.py37
-rw-r--r--searx/engines/ahmia.py82
-rw-r--r--searx/engines/apkmirror.py12
-rw-r--r--searx/engines/archlinux.py10
-rw-r--r--searx/engines/arxiv.py27
-rwxr-xr-xsearx/engines/base.py9
-rw-r--r--searx/engines/bing.py10
-rw-r--r--searx/engines/bing_images.py21
-rw-r--r--searx/engines/bing_news.py19
-rw-r--r--searx/engines/bing_videos.py5
-rw-r--r--searx/engines/btdigg.py6
-rw-r--r--searx/engines/command.py183
-rw-r--r--searx/engines/currency_convert.py39
-rw-r--r--searx/engines/dailymotion.py2
-rw-r--r--searx/engines/deezer.py4
-rw-r--r--searx/engines/deviantart.py85
-rw-r--r--searx/engines/dictzone.py9
-rw-r--r--searx/engines/digbt.py8
-rw-r--r--searx/engines/digg.py73
-rw-r--r--searx/engines/doku.py5
-rw-r--r--searx/engines/duckduckgo.py52
-rw-r--r--searx/engines/duckduckgo_definitions.py234
-rw-r--r--searx/engines/duckduckgo_images.py17
-rw-r--r--searx/engines/duden.py47
-rw-r--r--searx/engines/ebay.py68
-rw-r--r--searx/engines/elasticsearch.py140
-rw-r--r--searx/engines/etools.py5
-rw-r--r--searx/engines/fdroid.py4
-rw-r--r--searx/engines/filecrop.py88
-rw-r--r--searx/engines/flickr.py2
-rw-r--r--searx/engines/flickr_noapi.py10
-rw-r--r--searx/engines/framalibre.py9
-rw-r--r--searx/engines/frinkiac.py2
-rw-r--r--searx/engines/genius.py15
-rw-r--r--searx/engines/gentoo.py6
-rw-r--r--searx/engines/gigablast.py2
-rw-r--r--searx/engines/github.py2
-rw-r--r--searx/engines/google.py68
-rw-r--r--searx/engines/google_images.py43
-rw-r--r--searx/engines/google_news.py4
-rw-r--r--searx/engines/google_videos.py13
-rw-r--r--searx/engines/ina.py9
-rw-r--r--searx/engines/invidious.py11
-rw-r--r--searx/engines/json_engine.py9
-rw-r--r--searx/engines/kickass.py5
-rw-r--r--searx/engines/mediawiki.py4
-rw-r--r--searx/engines/microsoft_academic.py3
-rw-r--r--searx/engines/mixcloud.py2
-rw-r--r--searx/engines/not_evil.py64
-rw-r--r--searx/engines/nyaa.py5
-rw-r--r--searx/engines/opensemantic.py42
-rw-r--r--searx/engines/openstreetmap.py8
-rw-r--r--searx/engines/peertube.py94
-rw-r--r--searx/engines/photon.py4
-rw-r--r--searx/engines/piratebay.py126
-rw-r--r--searx/engines/pubmed.py4
-rw-r--r--searx/engines/qwant.py42
-rw-r--r--searx/engines/recoll.py104
-rw-r--r--searx/engines/reddit.py2
-rw-r--r--searx/engines/scanr_structures.py2
-rw-r--r--searx/engines/searchcode_code.py2
-rw-r--r--searx/engines/searchcode_doc.py49
-rw-r--r--searx/engines/searx_engine.py4
-rw-r--r--searx/engines/seedpeer.py78
-rw-r--r--searx/engines/sepiasearch.py97
-rw-r--r--searx/engines/soundcloud.py10
-rw-r--r--searx/engines/spotify.py8
-rw-r--r--searx/engines/stackoverflow.py9
-rw-r--r--searx/engines/startpage.py75
-rw-r--r--searx/engines/tokyotoshokan.py5
-rw-r--r--searx/engines/torrentz.py15
-rw-r--r--searx/engines/translated.py13
-rw-r--r--searx/engines/twitter.py87
-rw-r--r--searx/engines/unsplash.py2
-rw-r--r--searx/engines/vimeo.py2
-rw-r--r--searx/engines/wikidata.py1090
-rw-r--r--searx/engines/wikipedia.py90
-rw-r--r--searx/engines/wolframalpha_api.py20
-rw-r--r--searx/engines/wolframalpha_noapi.py2
-rw-r--r--searx/engines/www1x.py26
-rw-r--r--searx/engines/xpath.py118
-rw-r--r--searx/engines/yacy.py12
-rw-r--r--searx/engines/yahoo.py5
-rw-r--r--searx/engines/yahoo_news.py12
-rw-r--r--searx/engines/yandex.py7
-rw-r--r--searx/engines/yggtorrent.py123
-rw-r--r--searx/engines/youtube_api.py6
-rw-r--r--searx/engines/youtube_noapi.py6
-rw-r--r--searx/exceptions.py72
-rw-r--r--searx/external_bang.py14
-rw-r--r--searx/external_urls.py77
-rw-r--r--searx/languages.py144
-rw-r--r--searx/metrology/__init__.py0
-rw-r--r--searx/metrology/error_recorder.py147
-rw-r--r--searx/plugins/__init__.py117
-rw-r--r--searx/plugins/ahmia_filter.py33
-rw-r--r--searx/plugins/hash_plugin.py54
-rw-r--r--searx/plugins/https_rewrite.py5
-rw-r--r--searx/plugins/oa_doi_rewrite.py2
-rw-r--r--searx/plugins/open_results_on_new_tab.py25
-rw-r--r--searx/plugins/self_info.py6
-rw-r--r--searx/plugins/tracker_url_remover.py2
-rw-r--r--searx/poolrequests.py76
-rw-r--r--searx/preferences.py92
-rw-r--r--searx/query.py122
-rw-r--r--searx/raise_for_httperror.py66
-rw-r--r--searx/results.py111
-rw-r--r--searx/search.py584
-rw-r--r--searx/settings.yml275
-rw-r--r--searx/settings_loader.py132
-rw-r--r--searx/settings_robot.yml9
-rw-r--r--searx/static/plugins/external_plugins/.gitignore3
-rw-r--r--searx/static/plugins/js/infinite_scroll.js2
-rw-r--r--searx/static/plugins/js/open_results_on_new_tab.js3
-rw-r--r--searx/static/themes/oscar/gruntfile.js1
-rw-r--r--searx/static/themes/oscar/js/searx.js18
-rw-r--r--searx/static/themes/oscar/js/searx.min.js.map1
-rw-r--r--searx/static/themes/oscar/js/searx_src/element_modifiers.js7
-rw-r--r--searx/static/themes/oscar/js/searx_src/infobox.js11
-rw-r--r--searx/static/themes/oscar/less/logicodev/infobox.less50
-rw-r--r--searx/static/themes/oscar/less/logicodev/results.less19
-rw-r--r--searx/static/themes/oscar/less/logicodev/search.less6
-rw-r--r--searx/static/themes/oscar/less/pointhi/infobox.less51
-rw-r--r--searx/static/themes/oscar/less/pointhi/search.less10
-rw-r--r--searx/static/themes/simple/js/searx_src/searx_search.js4
-rw-r--r--searx/templates/__common__/about.html23
-rw-r--r--searx/templates/__common__/opensearch.xml10
-rw-r--r--searx/templates/__common__/opensearch_response_rss.xml4
-rw-r--r--searx/templates/courgette/404.html2
-rw-r--r--searx/templates/courgette/base.html2
-rw-r--r--searx/templates/courgette/github_ribbon.html2
-rw-r--r--searx/templates/courgette/preferences.html16
-rw-r--r--searx/templates/courgette/results.html12
-rw-r--r--searx/templates/courgette/search.html4
-rw-r--r--searx/templates/legacy/404.html2
-rw-r--r--searx/templates/legacy/base.html4
-rw-r--r--searx/templates/legacy/github_ribbon.html2
-rw-r--r--searx/templates/legacy/infobox.html2
-rw-r--r--searx/templates/legacy/preferences.html16
-rw-r--r--searx/templates/legacy/result_templates/default.html7
-rw-r--r--searx/templates/legacy/results.html12
-rw-r--r--searx/templates/legacy/search.html2
-rw-r--r--searx/templates/oscar/404.html2
-rw-r--r--searx/templates/oscar/base.html2
-rw-r--r--searx/templates/oscar/infobox.html24
-rw-r--r--searx/templates/oscar/languages.html3
-rw-r--r--searx/templates/oscar/macros.html46
-rw-r--r--searx/templates/oscar/preferences.html59
-rw-r--r--searx/templates/oscar/result_templates/files.html55
-rw-r--r--searx/templates/oscar/result_templates/key-value.html2
-rw-r--r--searx/templates/oscar/result_templates/products.html22
-rw-r--r--searx/templates/oscar/results.html42
-rw-r--r--searx/templates/oscar/search.html4
-rw-r--r--searx/templates/oscar/search_full.html2
-rw-r--r--searx/templates/oscar/time-range.html3
-rw-r--r--searx/templates/pix-art/preferences.html8
-rw-r--r--searx/templates/pix-art/search.html2
-rw-r--r--searx/templates/simple/404.html2
-rw-r--r--searx/templates/simple/base.html6
-rw-r--r--searx/templates/simple/infobox.html3
-rw-r--r--searx/templates/simple/macros.html4
-rw-r--r--searx/templates/simple/preferences.html24
-rw-r--r--searx/templates/simple/results.html14
-rw-r--r--searx/templates/simple/search.html2
-rw-r--r--searx/testing.py4
-rw-r--r--searx/url_utils.py30
-rw-r--r--searx/utils.py568
-rw-r--r--searx/version.py2
-rw-r--r--searx/webadapter.py255
-rwxr-xr-xsearx/webapp.py300
-rw-r--r--searx/webutils.py145
184 files changed, 24897 insertions, 3670 deletions
diff --git a/searx/__init__.py b/searx/__init__.py
index 2f3ebfc..9bbc7c8 100644
--- a/searx/__init__.py
+++ b/searx/__init__.py
@@ -15,52 +15,25 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2013- by Adam Tauber, <asciimoo@gmail.com>
'''
-import certifi
import logging
+import searx.settings_loader
from os import environ
from os.path import realpath, dirname, join, abspath, isfile
-from io import open
-from ssl import OPENSSL_VERSION_INFO, OPENSSL_VERSION
-try:
- from yaml import safe_load
-except:
- from sys import exit, stderr
- stderr.write('[E] install pyyaml\n')
- exit(2)
+
searx_dir = abspath(dirname(__file__))
engine_dir = dirname(realpath(__file__))
+static_path = abspath(join(dirname(__file__), 'static'))
+settings, settings_load_message = searx.settings_loader.load_settings()
-
-def check_settings_yml(file_name):
- if isfile(file_name):
- return file_name
- else:
- return None
-
-
-# find location of settings.yml
-if 'SEARX_SETTINGS_PATH' in environ:
- # if possible set path to settings using the
- # enviroment variable SEARX_SETTINGS_PATH
- settings_path = check_settings_yml(environ['SEARX_SETTINGS_PATH'])
-else:
- # if not, get it from searx code base or last solution from /etc/searx
- settings_path = check_settings_yml(join(searx_dir, 'settings.yml')) or check_settings_yml('/etc/searx/settings.yml')
-
-if not settings_path:
- raise Exception('settings.yml not found')
-
-# load settings
-with open(settings_path, 'r', encoding='utf-8') as settings_yaml:
- settings = safe_load(settings_yaml)
+if settings['ui']['static_path']:
+ static_path = settings['ui']['static_path']
'''
enable debug if
the environnement variable SEARX_DEBUG is 1 or true
(whatever the value in settings.yml)
or general.debug=True in settings.yml
-
disable debug if
the environnement variable SEARX_DEBUG is 0 or false
(whatever the value in settings.yml)
@@ -80,17 +53,14 @@ else:
logging.basicConfig(level=logging.WARNING)
logger = logging.getLogger('searx')
-logger.debug('read configuration from %s', settings_path)
-# Workaround for openssl versions <1.0.2
-# https://github.com/certifi/python-certifi/issues/26
-if OPENSSL_VERSION_INFO[0:3] < (1, 0, 2):
- if hasattr(certifi, 'old_where'):
- environ['REQUESTS_CA_BUNDLE'] = certifi.old_where()
- logger.warning('You are using an old openssl version({0}), please upgrade above 1.0.2!'.format(OPENSSL_VERSION))
-
+logger.info(settings_load_message)
logger.info('Initialisation done')
if 'SEARX_SECRET' in environ:
settings['server']['secret_key'] = environ['SEARX_SECRET']
if 'SEARX_BIND_ADDRESS' in environ:
settings['server']['bind_address'] = environ['SEARX_BIND_ADDRESS']
+
+if not searx_debug and settings['server']['secret_key'] == 'ultrasecretkey':
+ logger.error('server.secret_key is not changed. Please use something else instead of ultrasecretkey.')
+ exit(1)
diff --git a/searx/answerers/__init__.py b/searx/answerers/__init__.py
index 444316f..97e7e58 100644
--- a/searx/answerers/__init__.py
+++ b/searx/answerers/__init__.py
@@ -1,12 +1,8 @@
from os import listdir
from os.path import realpath, dirname, join, isdir
-from sys import version_info
from searx.utils import load_module
from collections import defaultdict
-if version_info[0] == 3:
- unicode = str
-
answerers_dir = dirname(realpath(__file__))
@@ -36,10 +32,10 @@ def ask(query):
results = []
query_parts = list(filter(None, query.query.split()))
- if query_parts[0].decode('utf-8') not in answerers_by_keywords:
+ if query_parts[0] not in answerers_by_keywords:
return results
- for answerer in answerers_by_keywords[query_parts[0].decode('utf-8')]:
+ for answerer in answerers_by_keywords[query_parts[0]]:
result = answerer(query)
if result:
results.append(result)
diff --git a/searx/answerers/random/answerer.py b/searx/answerers/random/answerer.py
index 2dfb088..d5223e5 100644
--- a/searx/answerers/random/answerer.py
+++ b/searx/answerers/random/answerer.py
@@ -1,7 +1,6 @@
import hashlib
import random
import string
-import sys
import uuid
from flask_babel import gettext
@@ -10,12 +9,7 @@ from flask_babel import gettext
keywords = ('random',)
random_int_max = 2**31
-
-if sys.version_info[0] == 2:
- random_string_letters = string.lowercase + string.digits + string.uppercase
-else:
- unicode = str
- random_string_letters = string.ascii_lowercase + string.digits + string.ascii_uppercase
+random_string_letters = string.ascii_lowercase + string.digits + string.ascii_uppercase
def random_characters():
@@ -24,32 +18,32 @@ def random_characters():
def random_string():
- return u''.join(random_characters())
+ return ''.join(random_characters())
def random_float():
- return unicode(random.random())
+ return str(random.random())
def random_int():
- return unicode(random.randint(-random_int_max, random_int_max))
+ return str(random.randint(-random_int_max, random_int_max))
def random_sha256():
m = hashlib.sha256()
- m.update(b''.join(random_characters()))
- return unicode(m.hexdigest())
+ m.update(''.join(random_characters()).encode())
+ return str(m.hexdigest())
def random_uuid():
- return unicode(uuid.uuid4())
+ return str(uuid.uuid4())
-random_types = {b'string': random_string,
- b'int': random_int,
- b'float': random_float,
- b'sha256': random_sha256,
- b'uuid': random_uuid}
+random_types = {'string': random_string,
+ 'int': random_int,
+ 'float': random_float,
+ 'sha256': random_sha256,
+ 'uuid': random_uuid}
# required answerer function
@@ -70,4 +64,4 @@ def answer(query):
def self_info():
return {'name': gettext('Random value generator'),
'description': gettext('Generate different random values'),
- 'examples': [u'random {}'.format(x.decode('utf-8')) for x in random_types]}
+ 'examples': ['random {}'.format(x) for x in random_types]}
diff --git a/searx/answerers/statistics/answerer.py b/searx/answerers/statistics/answerer.py
index 73dd25c..abd4be7 100644
--- a/searx/answerers/statistics/answerer.py
+++ b/searx/answerers/statistics/answerer.py
@@ -1,11 +1,8 @@
-from sys import version_info
from functools import reduce
from operator import mul
from flask_babel import gettext
-if version_info[0] == 3:
- unicode = str
keywords = ('min',
'max',
@@ -30,21 +27,21 @@ def answer(query):
func = parts[0]
answer = None
- if func == b'min':
+ if func == 'min':
answer = min(args)
- elif func == b'max':
+ elif func == 'max':
answer = max(args)
- elif func == b'avg':
+ elif func == 'avg':
answer = sum(args) / len(args)
- elif func == b'sum':
+ elif func == 'sum':
answer = sum(args)
- elif func == b'prod':
+ elif func == 'prod':
answer = reduce(mul, args, 1)
if answer is None:
return []
- return [{'answer': unicode(answer)}]
+ return [{'answer': str(answer)}]
# required answerer function
diff --git a/searx/autocomplete.py b/searx/autocomplete.py
index 00a9f95..fbe634a 100644
--- a/searx/autocomplete.py
+++ b/searx/autocomplete.py
@@ -16,19 +16,16 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
'''
-import sys
from lxml import etree
from json import loads
+from urllib.parse import urlencode
+
from searx import settings
from searx.languages import language_codes
from searx.engines import (
categories, engines, engine_shortcuts
)
from searx.poolrequests import get as http_get
-from searx.url_utils import urlencode
-
-if sys.version_info[0] == 3:
- unicode = str
def get(*args, **kwargs):
@@ -41,22 +38,22 @@ def get(*args, **kwargs):
def searx_bang(full_query):
'''check if the searchQuery contain a bang, and create fitting autocompleter results'''
# check if there is a query which can be parsed
- if len(full_query.getSearchQuery()) == 0:
+ if len(full_query.getQuery()) == 0:
return []
results = []
# check if current query stats with !bang
- first_char = full_query.getSearchQuery()[0]
+ first_char = full_query.getQuery()[0]
if first_char == '!' or first_char == '?':
- if len(full_query.getSearchQuery()) == 1:
+ if len(full_query.getQuery()) == 1:
# show some example queries
# TODO, check if engine is not avaliable
results.append(first_char + "images")
results.append(first_char + "wikipedia")
results.append(first_char + "osm")
else:
- engine_query = full_query.getSearchQuery()[1:]
+ engine_query = full_query.getQuery()[1:]
# check if query starts with categorie name
for categorie in categories:
@@ -75,32 +72,32 @@ def searx_bang(full_query):
# check if current query stats with :bang
elif first_char == ':':
- if len(full_query.getSearchQuery()) == 1:
+ if len(full_query.getQuery()) == 1:
# show some example queries
results.append(":en")
results.append(":en_us")
results.append(":english")
results.append(":united_kingdom")
else:
- engine_query = full_query.getSearchQuery()[1:]
+ engine_query = full_query.getQuery()[1:]
for lc in language_codes:
- lang_id, lang_name, country, english_name = map(unicode.lower, lc)
+ lang_id, lang_name, country, english_name = map(str.lower, lc)
# check if query starts with language-id
if lang_id.startswith(engine_query):
if len(engine_query) <= 2:
- results.append(u':{lang_id}'.format(lang_id=lang_id.split('-')[0]))
+ results.append(':{lang_id}'.format(lang_id=lang_id.split('-')[0]))
else:
- results.append(u':{lang_id}'.format(lang_id=lang_id))
+ results.append(':{lang_id}'.format(lang_id=lang_id))
# check if query starts with language name
if lang_name.startswith(engine_query) or english_name.startswith(engine_query):
- results.append(u':{lang_name}'.format(lang_name=lang_name))
+ results.append(':{lang_name}'.format(lang_name=lang_name))
# check if query starts with country
if country.startswith(engine_query.replace('_', ' ')):
- results.append(u':{country}'.format(country=country.replace(' ', '_')))
+ results.append(':{country}'.format(country=country.replace(' ', '_')))
# remove duplicates
result_set = set(results)
@@ -116,7 +113,7 @@ def searx_bang(full_query):
def dbpedia(query, lang):
# dbpedia autocompleter, no HTTPS
- autocomplete_url = 'http://lookup.dbpedia.org/api/search.asmx/KeywordSearch?'
+ autocomplete_url = 'https://lookup.dbpedia.org/api/search.asmx/KeywordSearch?'
response = get(autocomplete_url + urlencode(dict(QueryString=query)))
@@ -124,8 +121,7 @@ def dbpedia(query, lang):
if response.ok:
dom = etree.fromstring(response.content)
- results = dom.xpath('//a:Result/a:Label//text()',
- namespaces={'a': 'http://lookup.dbpedia.org/'})
+ results = dom.xpath('//Result/Label//text()')
return results
diff --git a/searx/brand.py b/searx/brand.py
index 91d2ab3..d71c57d 100644
--- a/searx/brand.py
+++ b/searx/brand.py
@@ -1,6 +1,6 @@
-GIT_URL = 'https://github.com/asciimoo/searx'
+GIT_URL = 'https://github.com/searx/searx'
GIT_BRANCH = 'master'
-ISSUE_URL = 'https://github.com/asciimoo/searx/issues'
+ISSUE_URL = 'https://github.com/searx/searx/issues'
SEARX_URL = 'https://searx.me'
-DOCS_URL = 'https://asciimoo.github.io/searx'
+DOCS_URL = 'https://searx.github.io/searx'
PUBLIC_INSTANCES = 'https://searx.space'
diff --git a/searx/data/__init__.py b/searx/data/__init__.py
new file mode 100644
index 0000000..55a254b
--- /dev/null
+++ b/searx/data/__init__.py
@@ -0,0 +1,29 @@
+import json
+from pathlib import Path
+
+
+__init__ = ['ENGINES_LANGUGAGES', 'CURRENCIES', 'USER_AGENTS', 'EXTERNAL_URLS', 'WIKIDATA_UNITS',
+ 'bangs_loader', 'ahmia_blacklist_loader']
+data_dir = Path(__file__).parent
+
+
+def load(filename):
+ # add str(...) for Python 3.5
+ with open(str(data_dir / filename), encoding='utf-8') as fd:
+ return json.load(fd)
+
+
+def bangs_loader():
+ return load('bangs.json')
+
+
+def ahmia_blacklist_loader():
+ with open(str(data_dir / 'ahmia_blacklist.txt'), encoding='utf-8') as fd:
+ return fd.read().split()
+
+
+ENGINES_LANGUAGES = load('engines_languages.json')
+CURRENCIES = load('currencies.json')
+USER_AGENTS = load('useragents.json')
+EXTERNAL_URLS = load('external_urls.json')
+WIKIDATA_UNITS = load('wikidata_units.json')
diff --git a/searx/data/ahmia_blacklist.txt b/searx/data/ahmia_blacklist.txt
new file mode 100644
index 0000000..a5c0e82
--- /dev/null
+++ b/searx/data/ahmia_blacklist.txt
@@ -0,0 +1,16177 @@
+0008f4726e2b9231c09355c0a176cd94
+0010e177f6fcaf499b1fd518046bde0a
+00140a082312f66c426de5ab0c2c6f1c
+001489ecdac8b8535f34bb65a678003d
+001a850b58240b760ed5c11821e64c7b
+001ae86997f8b3e517a46101df2ac85c
+002ab3c58ec26372ca8a16fa04097fad
+002ca30d3c48fbabec4748d1ad8af561
+002f82d895d220051c5c490f07bd2f06
+0032223cd6dad0feb29a6b93756702e8
+0034e8102d0d6b44a12c44940e79e134
+00367fbc39135a28347dd17f25095cc4
+00373196a4e80c24a520f08ed7232e30
+00377cce47784d49d250ec1527dd4c6a
+00392e810e7825e5a7e4635795626015
+003b7721ad5fd66dcb70ca66a554abe4
+003ed39119889b93fae7751c2ceb7756
+00433ed7d7fb1e659de569635558a96c
+004545573381002c98edbea07ecce710
+0048dcde7e2afd2cecaf7ef7180780e0
+005058cec8d6ffd3bad1c749a25589bd
+00538809ed5fd00a7d145dc536e105f1
+0053df1dd38b0a7e373723ad6c7307b8
+005aa0ccff6de439ab4e4e628b0552af
+005b7acb3c2804853e576aa65663bdce
+006764d9f710c03932876234851ffc7c
+006ed781ea4e05accc7727a58316a67a
+0071f5068289a6770bc9003c9fbfd393
+0073818c20b2c7709056e3196ade537b
+007a73add89e3bf5f8ca180184604ebb
+007b7aaa348d99204dd924ab0aac069c
+007be7c1c38f6f29f77b65ade2b01853
+007c3df36f8cb0a35ad4fba7c28128e9
+008749e26c3566eb70bf1d0f256e3746
+008b0025d3f03ace831c0967fa4a0ecd
+00918e625657958bbd5fd08d9a931c93
+00928ba6bd24dfd87e12a830900a6d89
+00929b53c605e9e50cc818f382be038f
+00998ecf41af4b2a4fd0af9b905ed429
+00a3b612a567540163894169b78b9c92
+00a7f2d21c6cba3ae02422401d49e317
+00a8568b63b7ea784fade52085ae5655
+00a89d2291d1a3a1fd160391ad9f1139
+00ab0106dbd7b42b47f63255b76a434f
+00ac1a128b2451206b2a7c6366352c8a
+00ac3bce80bdc994f303941bc803cbb8
+00b14adf176addf980b83eb857673d2b
+00b3176aa3ac9172b3d113d8090a1b96
+00b7238d24ffb710abf3f4d212b02a9f
+00b72c5fe0695156463eeef0b4dd08fc
+00be79509dd4be21c2cfb20e2e54c0e4
+00c25827b5c5bb282ada3a46a9dfed37
+00c5e3a334cae51709c9b98dc24274a9
+00c97286685afa91fdcc05d08d8f4d31
+00d297325d32283a85a11d966e70efa5
+00d9c83b0193b470637606b8815d95a0
+00db9d9ff9641feacad14176b6586954
+00e4fc981bdf5b7f387212199de7a93a
+00ea4e2e7fd07475f866efde3cf29de5
+00eb1e933df9aadc281fddd853cb9f32
+00ee964a85a4c681ccab861fc6ee46d7
+00f25e838a6fb5bac49fbdb3ded92b6b
+00f3dd2bb0b34bd96b426884ec5dccad
+00f729b27968913438fbf67691ebef6b
+0103f981ed3351e36a12d29d631224f8
+010669db7b90458bbeb4e3de4c758f78
+01067d8a4b16ec2466200c3e41961c1d
+010890ddb4c62da8dfc174e418437722
+010ea7123ee29776e390dba449cf9c5c
+0111f597eb58bcf715807b568b2a1d86
+0116d303c7f51659900e56455e80ddd9
+01177c79cc4dae823970094c4822b6fb
+011b5d530cece0a3fed2f1bee9a12256
+011b68d0c9ab00ec43883d0dfe754975
+0121791d3a0ab2b6f9adc85a7c3320ba
+0124cf594fd210d06a81cdc31ed01e20
+012a10e3befc963ddc87c63ae2911878
+012b36bdf7cd2f6c7cb60b0b3210f10c
+012ef974f5b4f307d168e00ada58cf96
+01323cea7c44f7d4587d83d7e9fe232c
+0134e00e8fc6faa9f87978e1a370f4c2
+013ac9677cc3e343a9cd7586fa4d6d7b
+013f07dd014e877dbdfc4942501bfa64
+0140a817d177b78dd06c98b8fe0e370a
+01440f491db052b0b7918508ed138362
+014460c8ab46c9bfbf64c740f5fe9768
+0146656b5d8c4dc633d1759356bca217
+0147327639f2821d0b306aea87c2724c
+0148b20eafc7a4822fee536c4532ba3c
+014be60ea314977759a3a853595f06c5
+014f5d09fca09a8e6345e1b34935b0f1
+0152f35578dde3a1458508c41983c049
+01580f129485a12c915ca506c3deacbf
+015c1a46929d6ac6262acb4adddb7ed8
+015e18e7f2207ff2c57a0328ef004880
+016791d8701640b7e50386542bd163d3
+016c737fe17e910ced778c22b5af045a
+016e99308792440162960f48ceb67b30
+0179b2d47ad553c109a77735fd9e54b5
+01814982bd45481f313f7cf0d8c3c11a
+018189b5fa04493aca3247bfc3968d48
+01855839a423395a888e944413028d60
+01867f9ffa48aa3e2fa7c8946b490a54
+0187eb3cf5945eb53c507b5b96b4cda9
+018a97ef1b4b8750a08606b7582409a6
+018ecf2b8adb2004617eb9198283d809
+01972455883dfb10b1a86a4007b9fe94
+0197260635dfec18d1ca367413fc20ff
+0197fd936ab57b542a4bffceaeb2d6f0
+019800ad8b7a58ef8343a510d9d54981
+019ae64ed14fde2e9c6fe55e801357e0
+019f1e59e2117a07a5fce9f4fe7a7f58
+01a3fea2e45541449e96bbc4471751ab
+01a57bfca99842bd8dc6d00ff6faa6cf
+01a5ab9e2080b00ccae00dbd13191428
+01a7074d0c29e85f1529d72a092813ed
+01a83de81a34db23d8e1d0cdedb226d7
+01b37288412b4e4ebfc90351ee373887
+01bc3e531b68b8062dfb0cd50dc15e73
+01bfce0b47cda6c4a61241a611273b43
+01c083cbd068d0ff1bcc2a958f315e04
+01cc4e13d5ee5c25fdb3397ee2adfdd6
+01cc73f7be6c6a09f1405f21f737a364
+01ce4cd52aee7cbb98badf2758767ef5
+01d2bebc3d521bd49cec1dcf1807b861
+01d7a435a48346581dd44056dbc4a25a
+01de33bd940fd991fd55563d692a74a9
+01f190140af9becde6cf1dd01fcd459a
+01f35948fc5b1c422459113ce786ac79
+01f82627d008e50411e8f8d37f6a4bb3
+01f8f2e292f9b9f609f3c673cfcf57e7
+01fa008eedea8531f2751786ba49bc82
+01fde11f5c7e9b1a3b1287bfbf4ddcaf
+01fe114f85a3cc6d5e288f694b937fc2
+01fe443b6981e7c3c0076c25332ac9ad
+02003740b7bdbafad9d20cfb8b2b6068
+02052e3fb4aa7d9f93e31c0202f2bd7e
+0207c80eb3b4ebfdf06d619add983134
+020a26bd2e07e1340068bd2bff420d3b
+020b298a8af3f8e80374d2b4731f2db7
+020baf4cd4ebb620c88ba26a47e5758d
+020d29b1642d553e9c64d00c0266f47d
+0213d8700ae82035cd1525a57c3432ae
+0216b34293cbcc4eb3345075ed2b4ace
+0216d286551434f146b10a800cdf5e32
+021fb404d2afa572658675418dc47ed8
+021ff20738a9f49a07cc856ddeb345b8
+02201937de04b0f44384fe7a8729a097
+0221620b6f7a6c8f2b8c22654f1ffe00
+02274c10044d60a4660b04aee89d38d5
+022d50338ff9502a3dfe34c4928b0762
+02338f61dcfc26b78eab670857683d91
+024001dd4847513158cb5d67c4705f9d
+02400fd7eb58ed95cebf6b8ab9175ef6
+024092c599ecb95abc003f43b66d6364
+02437a3d51e6c1b33bb2e3fe8be5e472
+0245236428a5f036063fa6e2aa1564ef
+0248b116ecd91230882a25a65f7faeef
+024b09b9bcdad171018d70220d049c4b
+024d79f57506a4994bd3cde30b2a998b
+0254b35a80052f596d30ab7178812f11
+02596da0d2e5bd18f5ebb3515a6ceb5f
+02626cc7d639b8dc20f48f3b33eafc7d
+026610e8aa4fc1d2ff0b85d1fc79352e
+026de3a3fa1dd7181d4a29b97e72951b
+026e82fb0d650f67f0f4d42da0a9b3bb
+0270944e29ee36dde8b6b3c398666265
+0270be0aef7214c7fdd44aa854ee0989
+02738c2e465f764b8e75ee36af205dd6
+02773e6376cf04b3bd5bc557edb207cb
+027d2c8a0f15afab38f185a661a12f63
+027eecc41e1513c7575cf9219ac0c6a7
+0282005216f5690127570b6e0385d2d4
+0285a8152235d46839b4a0c08d58ddc5
+02869dc869b7982e80932addef97a26b
+028b4bade611761182500c53fe013c67
+0295fe6011a3b7ac80cc51f05554bc21
+029c585134b256ada1805781fa7465e3
+029ca164b97ce75db17ebd4386cb5db9
+029d5c9f1228d06216d16298d78ba2a0
+02a4ca50cfdefb81ace51b2ad30260f2
+02aeef5bfd58cd9fbaf9097e9e8f3bb0
+02af4dfb97c81949a862b03d8d2149ab
+02afb5d8f2c11ff7aa3de2dcaf583e5d
+02b19e3221162da19b50051d02c5248d
+02baa92abe8ef70246ac2527f606f432
+02bc6589cc54fc58e0fbc9e7890b101d
+02c1a70284bce340a698b49ef2263933
+02c22724fdeb1b77c9d83d171517aa80
+02cc2dc5875b7e4e3bb3dbfe1f1a8bf8
+02cff67f28c0f923d7fab7ed20e38335
+02d464bfce934d7a4f23959210003aa4
+02d65237c6b53642be70ae35f4eac928
+02d97ffbb6c69e4c5cec27c1e88c36fb
+02d9e81803b1f68819b7748968bbec3b
+02dd748d15607f2cf394a197db7c7bf9
+02fd522aa48e7dcf9e4e2e4bae71722b
+02fea5bcf3a85e295cc07c0408b95783
+0302b771ec58fdbd233e755c4cfe8192
+0308813ea03b46ea48b2187dfed16267
+030ad459eeef5d137028921bf7bbd6a4
+03144298c092883fc02701c6cc9fa9ed
+0324bc6c45bc6ff68c114f4120ca2169
+03257a5e60aeafd8c7f1966d68e871cc
+0329e624df2ccdd66803e4b5c65a7b8d
+032db122dc5dbc4cffbd0e3b627130b8
+03335b010c7d458cc1008c4649162849
+033ab26e48d62c0251b1df6c407bf8c1
+033e1cf13d22f08baf70113e58087714
+033e72b4f869a11df6c077f921de9396
+03434cd052821f38f0484ce86bc46ba3
+0343ccf85d3ab5d5d5be9589ca7628dd
+0347a3b56554a8b8b0c0ebc1ad46bfb4
+03483bb949079341515ca85794a96c29
+0348b7fda21987cc79fcfe51d6265dfd
+034c2f1f7b2cf830a3477b30b44590f6
+034dc7d908e4d6582b50698e87a259b8
+034f7318933d53dde4870df4fd2b12c3
+03535813c7d9215a1e2cbdddb84f044a
+03542701b5fcdee9e7397fb9ccb84a5c
+03584f44c383541682bf18f1515ba348
+035a2b6c907eefb47fd3517b3482938f
+035e7485b58fd1a001ba9d8cda365a6d
+03639f51d8804bd28b9e8ece1d33e0a4
+036c808021b0379f47406d112719ec8e
+036d1e83796b3e1d632ef251e03197b3
+03752147841942c24935dcadfee218dd
+037f34b93a0d81bdef370fd37441d8ec
+037f9d59c641e87901b0f7a7c78ac293
+0387f0b61d7ee8b06ce1e813ee5f5b0c
+038817c32d55abfd4a6ce35d9259ecbd
+0388920c2ddf0d31a417418f7df2c03b
+03896d7272c21e66203fa7a53143d8d5
+0391efae80f8bd00fca9a6006a32752e
+039df073fe5630a13e3e47caa45362a6
+03a1b57ccedac923faed4913416aaf1f
+03a57237b8847605a332d502610513c3
+03a6ce5a60cdd6a6878433604bd991d1
+03ab57e67b5f1d145e1e2f93ccbd9cce
+03b37e35f3f818e4e7f5b08b3ea1ad76
+03b4737fc62c890b4f6e220b72ad8004
+03b482f6d191a55f3456f8e90a777431
+03bc20b2b401d4def45a310edbc747a4
+03bc87ad3ae40cb88ffdc2ff5adc3635
+03be7b1606d04df6d4e7faf5ad109016
+03c48f6b9404ba17da9e48cc8a7a3f4d
+03c77bcf378f59624520c87183e950b7
+03ca271a52b63a7888227cd11cf2f7e2
+03cfcfd4126cd702cfed51bf541bec41
+03d193490d7a271d97730280dd9d2abf
+03d1a0c15481b13250bfe51b9de1807f
+03ec33ed97a4b5af1b6147fe966771c9
+03edf07e831e59422f6d33cf7c0df622
+03ffd1dfb83547396200e3f325f40904
+0400c08ee9a0b422b72fad8e0bba3015
+040c8e1e8fe3614ccfd121cce82a4ee6
+040e38baab0dc1ce2136f709119f67cf
+040f3af5be9a1e069a32cac204b0aa55
+040fda88fd07087d9935f4921a443a93
+04100a501a59f302dec6860a2601421e
+04110020a853e508f8fd4726cf46ff48
+041cfc66a6ebd50a143773ad38a6d180
+041d0bdd135ef4287e8198ae4a8a5cb4
+041e45c7c93c0c051c46dcb4e792ee8d
+041ff214a5779ace005c6a929deacc37
+04277eacdda67d927146e32bf7334bf9
+0428da0dbaf654291f3bb753a145a199
+042f8bfd44379a99f6ee109bc3ea3298
+043061594cbc9a4ebcaedd79575b47b2
+04392289403b44b5f15a1d4f37113baf
+043d3eee7d90f8efffa564f423ee4b8b
+043e4f61fb03b8355dd5515dd5acae62
+043fdbc4e305130c6c060cc93bd746dc
+044341ac655e93291393d626d57d90d2
+0444523ef1998b3ae0a3ea5d61ba1f8d
+04460fad5a0807ff7c4404240eb17f4d
+0446dc34fbc9f798158407db20ee43c6
+0456b3e9dbedda1513e4254cbf9732a3
+04590b9a9bb24aba744397c5ed9e3cf1
+0467d22a8a078447fef6ca92b3696040
+046ea1bc9b9697c1b74d5b407a68f911
+04718655e06dc9f3b44e05a26d3e02d6
+047657fad1a0e1ecde91aa8dc903ddec
+0477a428cf5591d0fcee466f56e84ff7
+047b34e5a9c8aa0b9b158eb69151e3c3
+047efcfc8548d2f93ba0d0f86cf2490e
+048655817dfd90ec0c83bbd9503eeedd
+048940101fbcb90f903cadc03790518e
+048f2f9712cf9b671becb1aa3fead3a1
+04901c1b8ee03233f1504890a33a1e61
+0491c53f1c57de44616d6c5380c39b3f
+04933d16ff025b0fd5f236156cf0f1fd
+049be8cda07b90c4516286375a57aaab
+049f0f07992ec5e755855fb1e0562bf2
+04a155448fcab81d12e842fd2243fed7
+04a627438a4333145b3c17185f601244
+04a8c4a47cd42c27d03327a71656a56f
+04a9e724322752867c6fa81394f7cdab
+04acb9a09ad3dac9c3066100e38851cb
+04accf86ad1c7e85aaae70f11db1b492
+04adf6a990aea9bfa6c07d7c1601c3d5
+04b0511f96dcc3d763bbfb6964319cb6
+04b29e460c3838fa2234681600e0aef8
+04b67be655edcd4ab46f1f0cd001a04d
+04b6fea9b19f438922ab3cf358ba5b64
+04b893f9f75d53598213c5bf15dbd688
+04b9dd20b4a5d9673d1cce9488a82a65
+04bb52555f0b61172dfa652f3dbff0cb
+04c018f727c08111a155c842c6e689e5
+04c144edc8aefe30041c65cce13afa40
+04c3b6cc04321791d93fc33a2dd4e99a
+04c82086d33f38b06240e247285052cf
+04cdfbc6d2f6de1c08cfe30e4bc2d32f
+04d0ff2f92ccca0403337db573f17408
+04d3e6bbd0ba917977caa1df23427760
+04d579338f042a5c6035cb044046e514
+04d8159d73072b0cc91ddeee8e29b0f1
+04e231a78948bc752ea8cd53cc09766a
+04e679fd9dde3fbbc5bd0913228088fb
+04e8e9c9feca5fa86ed60dd2953efe75
+04ea261384887ef6e8f5602a9a24a024
+04eb8f5cf86a40e68317b5751c0480f3
+04f2c6f496de3110fa2021598dc7dce2
+04f3a71a99a1db79c0f90caa67ff2f83
+04f4357e7ca3413b627b1d1e5e9fac97
+04f5fec56796218b247a2ae982bd5a49
+04f6501bf06dce3c6794364647246b4c
+0503eb131e712a38b5ea49a834002d8d
+0509271c25c2ccc40a47d139f485e442
+050d55200a22cd6ab9e1cf2a29577451
+0519739b082a5ce83e8d8f8f5483df8f
+051a0a23918f86b44126a412094b2174
+051ea70f37c7c634b8360a3a65e97702
+05232121fadc31451ef7e7195fc9dd6c
+052a95fe99fb2f97809d96016a99fe52
+0539e166b066e708d94e02d4094598cc
+0540ecac6fe8a4fac8dd71a7338a159c
+0540f8e1b015d066a807ea28e54460fe
+0544aa3f14ea2e08b6a0564d7255f543
+0545cde86e1960b0d65e5524dfdb77a5
+0548a9443138d2ac97eab4026721cb38
+0549d54b2e7c305fa6b7cb5e1eead3b3
+05600a454c17ac66045de113dbcaaa0b
+05608b4aa4af64fccff5c391070b7a95
+0564aa25224fcde6f7ce48804b026826
+056bdfd7b59da8d1e7298d5a2d7e49e1
+0574ddd3cc1094c06b9fcf696e7ab10d
+0579b7267e32af48471cb65fa55efc20
+0587ee74310b646b011c25ffbb2fe913
+058ab46a35a1978c967df2a7071c452d
+058e3c07cffd4d782bbc343821c97dee
+058fb39d7471427200bcdf9315604dc5
+05922ddc93eddd17d6073fb8b3fd4657
+0592c7f13feb763cce719659bf6a8660
+0592e14d97aca207440298396d591c8a
+0593253d57ba0d34242209a157b4ed96
+05964f31946a5df2287e21b1c340025b
+059dc8f5fc944dd8817c7248bc348804
+05a218b4ae7618224e393ed460e2bd38
+05a65d00a8c57a4650b8f3955a817400
+05b43ded340b78e681499dac34454a20
+05b4bb66c1be417cdb1839be725c155a
+05be06d93692bc3b82873530eaf38d5e
+05bf5f1e721b6f9c39ab1e260e246df3
+05c30f415bb3d75776ad9c0294f0dc20
+05ccc18c527fc7af31c2edf24494c491
+05d92e0762a5d11e946efbda219a65d6
+05d9bf848c4f25c2615037cd5650537a
+05e0fc7a820fd7b491a33f89be770202
+05e1f2e770bb212b053224eb8be0fd67
+05e4687d127af6ecd1579b124bac4a37
+05e65f8d6e1cbdd4adde86f33f2e23a6
+05e8b64a7ff78eea9c2ea1d4dd054c44
+05f10c99070cb8775b18c6357b5d2a31
+05f138de7edd1bb6ef3989f7e7ab35b8
+05f672dfd0b0ca09cddd507321a63b80
+05f6e96c3e1388a453a2c9df8c52ca05
+05f718d1056fbfac17fa9420fc2fe15d
+0605d2da74d44dc6288ee8db8d836801
+06068fca0cb5a0e0cc218ee8b95c74fc
+06116c06efeae75ff867a0d313a7b832
+06137cdaaaafdbbaf6950fc896bb3cd7
+06208cd60ecf6f556f9247ed515ccd63
+062391f4f45dd37708dbc6060f9b4c5c
+062bf40fdb52c2b94b8b77e38c982064
+062c72ec1afbcb3b10564a758bc96d9f
+062fb2dfe27618d5fd8510ee00ab12fd
+063e97813dcd1f9a258ca4a9a9a2b9db
+06467ad3b06a7e8d4445937f3ad92d52
+0647e59ea78c2082ecbffea826581ff6
+064b4623340ab59429f3a208ab5793d5
+06511790169b5d8d0ba16c402cd9820b
+066695c6b8d7fadb15cbb1b9a345a677
+0666da3578df09a9bf0f680bc43fc780
+066bb32fc53b81636c16f0efe3ed4b7f
+067415e1d91068c399b17667d7f28fc5
+06770110943ada17e9143baa7e43133c
+067919bcc9409139ffc6bd407ba77e1f
+067e8b2c9451070109a6dd46fb55ee66
+068544d4b84f96163f6961d04285b1fd
+06868ec175f1a7f63bcbcd75cd52021e
+068dfeca71ed47d4783d078911f6f68e
+069094b274dd168e46b1c57e5be5ae69
+06909a9f73551ad54892bdd812866d46
+0691ed2d375ca749d22854b49a430782
+0696b5a307cf7c4dc30e059428c36e42
+0697e6acfa92c23ae507a26082d89ae1
+0698417a52978698b08c6228d4640f86
+06a796a09ca594b32b2e5f945bd259a8
+06a9957912e28cd5f08aeaf492ed3bfb
+06af48fa2d0baec9d268aba5911ec82f
+06b6248da8e3f7555697af8d573d73d6
+06b8477effc8005b84c1a24c4e2d2793
+06bc8d51ced82454e662d3d96ead59e1
+06bcd7a02c11fa069278c65c4d4f0727
+06c721e0c2a92f26619b300cea253920
+06cc76c699fd14bce9b8df18b08f5372
+06ce313c3b8b81038263de735b21ace4
+06ce812c979494a286b41babfab1563b
+06d2b655473bc0faf36360f4e8d129cc
+06d52208bdc568504e84008bd25606a4
+06d8fc5b98128beccb77ff50b91af202
+06d9d53e2cd4b9364360bdebf199a729
+06db2d33258eaf878215280e5805c0c2
+06dd5bb14962b16f55f7da69b72328a3
+06e225aebf17a2d1bcf399015678b2b3
+06e33afe6cdc5dfae60416c18262c8e7
+06e5d47522b3e3be03b69bea930043c1
+06e66f87421788567bd8e1778248729a
+06e884bd9247f7e82763f87d48cd7f1a
+06ea755431b6ac1b86ead981b157be6e
+06ed97c9afc6d00b1cad3cc8a707adc8
+06f14011d2e2c8e114447c06eaa58fbe
+06f56b7bae870aaea0ea1ab49cbe207c
+06f58000dc7acf5b03c7cf37626d2bb2
+0700210a31892b7d21c91808cc143cd8
+0701befc6f0a0210ff3ef161338c66c9
+0703b25d809e575b27f0324764799ceb
+0706ffd0494fcb7794f5e864e02fcf9a
+0707454c84e71cba27196ffebe49e019
+070acbda93c9ed024c94ebe7a7bcfdfb
+0717450f6dfffda33819185809708ccf
+07181afb625b07b655612dc97259c0e8
+071e441f2b19555fa57e4071b82ad0fb
+0725dab2dc6f5e71aae63e069e0cf0d6
+072ac3fa0b1bc2ac4dbd6617f26a2bf4
+072d539e33e2c215409ea1429f6271ba
+072df47b55b4b55e36581df68c85c7db
+072e1c774685118318e7bff18f0cb5ac
+0732e3572fb688d035d2eaa0a5c70ebb
+0739d96da7101e4beda064ac896e0d8d
+0739fa4c66341622bedeb92e37a1ef4c
+073e40a1f561dcc708ad0ed2ae6a5ee1
+0740b04cf0ed9d00cad574222d1f8f41
+074241af8a0490f43832a1c66112ed3f
+07424d3e5933262a691315419a28462e
+07434e220d0f1cdac5984b53eec3cf6e
+0745508ee3ef74318c229f93020992bd
+074914f1b33b6411404bf9ef9d6e3fd3
+074bbd5f050c4362eff2803c7755e3dc
+074d258ca6750e452e242fd525300c42
+07539928a2fdf1fdbfc77d4e2d832944
+075e876da2d6a5ab6f99f4279a0e3bfd
+075fa01a439798e8fdd575b3521c1565
+07669c5a075494cc9f8467037ab4c5ee
+0768777d1aea8ae7f8b58f99a634206c
+076a87895cffbd1926f463837de01942
+076a9fe26f75500add3a997a11a9fbda
+076aee2945c566dd0d1f9e6fb5ee4385
+076be6ca26665ff52a83186c19da4945
+076fc0d4b2d93ea5b8f49d5a4347bc5b
+077191f6bccc6e004f852c8b30a630e2
+0774ff2f696d3d3807ee8c4c5dc7a18b
+077dfdaa83d31b5964765d734d163e80
+0782016d0c643ead91f958261606479b
+078913c35cb77670b1505b6f0cefc504
+0789379206806e82d02562957f21812c
+078d86c7f587f450a77815b3c4438f4a
+079209ac4790abebde3f8c83da2e84cb
+079277eb78da04ac53561d9c1f27cb0a
+0792d25a8c9dfa2e98f82c88eba21d05
+07938905a8c4929bdd02d6388dcffbac
+0796292449b67030d59903bc4927921f
+079d7d250c9ce7541b7f991fca73a130
+07a3087ba3b43cbbe6513b50aab72253
+07a32080ced64fabc51cac78763f8a97
+07aa9387af3cf3c7f0040ff44dd9bf13
+07ab1525ba7acb140a0a148521bd96e2
+07ab344174250779fc068289c982d346
+07ad7d64b4a58ade444d5bf536293110
+07af1b7f9523698984f14d5529127862
+07b5417584913ffa1d34b70785dcaae2
+07bb0741f3a34b7f13dd7b37f84c8e6b
+07bb47fe5b36bd2794d4c7b472d69f61
+07bc2aa0578dc9d26dfda23840daee05
+07bc61eef7d11906209d411612bbcfec
+07d865388aa721874d2e59155d67da9d
+07da155f5b679c64db6b08b0b88770d3
+07db784b509078fb0b00c5080afd2b95
+07e629fc2615045100772d76afd37f46
+07f2969d8e633eaba7953faf8584f7fc
+07fcf1348e9e83ffbd2cba4d6f90bda1
+07fddff595828007bf34233a92ac13b7
+07ff70a690e4bc62bcec745187a32d4a
+0800128d8a224b87ab2c356f8b178473
+0801199a333b7c2fb4250cf907d94388
+08029e1a629c040a9357ed1d1f4b44cb
+08035fb2855cc2d97e25422508edf989
+0806ca6d476fd125103bf9acf94e93ff
+081106d528ddbda7a3640f1eeb6f0e31
+0815c9b87e2333772c123636737455c0
+081750113426a0eb8ceead9cf1df33fa
+0818bbae37e01c5a5430b5e0ba32a864
+081a74595f90ee12c9885f8022919351
+081ef7c9f54a5bfafa31647d98bb84ce
+081ff06cef942d61e7fe271b99ac8a18
+082562d517e166ff4f23b7a3cad7ea24
+082a3dd92be3fc581a6b5d7edb4db308
+08311ac4669d9dab261af739153d8dbc
+0832426dbc556aa505f8fcd452b111ee
+0832dd7b163a804bbb400f531398f2c4
+0839f525be96d19646ddc6ee31bf879a
+083ce25d6a509f9f462442806278177d
+08437ae79ce1ddd3685e01d2bc17cfa8
+08468e827f44bc49741ae3672e7e4d62
+084e3bb4c493bfa5eee2968c00bbaa48
+0856eb1b42005f9aaa8d9ed02a4b56f5
+08581977f69f411700dff19c9f5694b2
+085aec5ec69d1e257de4e4e6ae1d5479
+085ecd2037d9637e90fed043f98b0a77
+0863c18ede44f82650056833b79ac8ba
+086765ebf69c91c379f4c90aa3de176b
+086c23f66e6a00ac43387eac58297d8e
+0870a2c7afbedc6deacc18e0f082756c
+0884a0f375d15fa52b1cff208fe3891a
+0886aa63e1f392af5e37d6e58374d847
+088a8c3eba0e1db3a7d9534fbaf2e7c1
+088b2c8de9a9302891abaaf8af28043d
+088b9f58361b045193ed8e3a8acb7f5b
+088bf444eebe451e524e0fb196a8c464
+088fe186746b8e1e11f847998ff169e0
+08912e8d365146f6c6ca19a89de89389
+089ab7fc9a1518bcd064f5676398d808
+089ddb0c4e8ddf3307ebf8382ff6427e
+089e4b855c0206e25448d12135dff5a3
+08a04beb76a35c0b002a783a8377aafd
+08a0ec8386d809d6e6223a9cde792167
+08a1c98822c0fce33a468c8e6244e72b
+08ae06ac2584b4ec28c7ee99185b6d59
+08b4c315947d17490354a74bbc41e904
+08bc72ff8e9f3476c6f18c73efed3b3d
+08c15b037637db9a12d6ed64546f6bcf
+08ca1183b0544f178fcd40eb902cba2d
+08d0ca5f0a5f64f0edf2dd5904f4dd51
+08d180589c3bdd44c027c6e157a59008
+08d2a34b9ea1d0ad7118f47c64af3e8d
+08d7ff0b7beb367a004c425a81d18f9c
+08dcf4b82fc648f3fa691246435542e6
+08e3a8a969fbb8d82aded8aaf62bef75
+08f20abac62e82f22ed5c2a09035f316
+08f89912c40bd7901c5063d7c6853383
+08fd02e3dd10863359dcc361a3c711fe
+08fe4c8d3ae05cffcb731e29ff1c6e1c
+0904f2e8a8a469a5c38d690fc1e03de9
+0908b495d39975bf684dadd276e6482d
+090b022871ef8b904ec75dc9b111c381
+09113509e91b7191716c6ab3438149b2
+0919c5fe197e6298745719e148eadf09
+091c400b924b641962aa59b6b609452b
+09227c6d01fb39bb4390e379f600d16a
+092ecf19eb8dfdf89fa61c38af501dd1
+0930438aa7674780b62dcf099e0d5e33
+093c464b2993a4d26fb7c63832ba8c2f
+093cd513443d447a8d7fe533f93cd27c
+09414753a458b4f3bdd0300ce713a24a
+0941e1658fff83e62dbf090bcc1ceedb
+09441092353cea254fdc0700735dd97f
+094ab9a2f50eb82ebf0ec88cf39abe36
+0950989cd5ea851e5149f1e6f14ccba0
+0951dde966c7ea3cafef6c2b0de77dad
+0951de59ae4133af0e2bc20e38c32d99
+095aa78342b166beaaa70fef97fb9607
+095cdf3a6cc64141bdb8379318ecf620
+0962ad3aff935223aa4c75b61fa792b0
+0963d0f60ef92704971353bf70080151
+096741dbabb7d8a36dd76e83774139e7
+096d384ca4aa91838196c54da291bdb1
+096f364d89a2330e434246252f8f775d
+0971cf04d4d8cac734a59bfe4e8d975e
+0975443b3eed87e4ee8f0409f5f3df3f
+097b47950d953d08d75b4ff7587a661f
+0988d9a2a055e330355df038e5898d5a
+098d8db5a8664154940a3b748fd1adcd
+098fc7270dc6e7c07d9dcbbaf33d0b8e
+098fddf9f57bd2bab5370f6365a24aa7
+09900de1a1267991ab9a72333e87904a
+0991d5dc055f327ddd8ec2a3a1ab6c6a
+09942e65bdb4bfdc2ccecb2e1f9c04b8
+099fa8f893d58361766e427d02e058d1
+09a2de78a057b11d3e826dc9530bd25d
+09a6114739e3c116a1efdd235ec5cb67
+09a9c9e3ab00b7ba8a99a6c2ac3d9713
+09aa0d674db01e6853d2dc00146fde82
+09abc2ab7df0a42cac48e33a348c46b0
+09ad5062470c699577c936fdad6c9716
+09adcae379c1949405f89677553cb546
+09afea82a038e42edd663d77f40c99c0
+09b616f4c4ebe56e3ad19d99061aca8f
+09b79aaf00b690556cd774b9ff4e3362
+09b80d7108a15ac8b6021a5cc4a75f15
+09bb833d28e2093890eeec2a919b13f6
+09bbb2af26d1705af39eab119b338582
+09bc6e9b4bb8b14f81a30ebff96cd618
+09c5ea56e887a4bff31889a7ea18b60b
+09c7bf695173a0bc079046ea5c77dac2
+09c7dce017c60fe0b840d3681f24e26b
+09c8f372965087322fea42c4df91f8d4
+09c933ca1e8e94afecfe48f54514486e
+09ca7b82432e6748849a1f4573c6db38
+09cbdf32e63e1d0d26007ac37d7fdcb8
+09d087393bd0649e21eb045e3b2beb55
+09ddeaa0bc16d528bc8b44a41a20277a
+09e07f311951d1dd404107081d02380d
+09e13507ebdec887ca9a84a4e144a7c8
+09e1df4b67a36423a3d2d435fecf0ac2
+09eb2931b9573e7b1ea2303a5d09a0f2
+09f3702e9f4954c15477efb6d27cd457
+09ffface5278341d4aaf2b2bf80cd33f
+0a02dcca2cc6783b6bc0c5d7bf317fa5
+0a0497c6a3fd4aa18c58c1c7753bdc93
+0a0547c5804955993753bdd7480627e1
+0a06bf1d3b5c84a3e63a443746d16394
+0a06ffa089e56f463e564b90df709090
+0a0be5b85e0e3c91a0981e613bb20e4f
+0a0ef04a14bf38524b36624d2a3c1337
+0a1232acde436a52dcb2e645df45f920
+0a19917a52402917cabecada7cae83f7
+0a19a549a9e0f206e467bd738228ff9e
+0a1cf347976b37c7169f2caf49202b96
+0a1d7c682eccbf088c8953d77c1ba199
+0a24b9acace735db35badb7c363c8b67
+0a25bcd7ec874651b629df44483a2965
+0a26fb59db44a817c7d6a1d7666db219
+0a334adcb90d3377a3f59798e2ce1f51
+0a34802fe17fb87f7d91f647fb62c6b0
+0a36133325855783ea8eaef4bc259d51
+0a3719b282c7299777c1697302484d0b
+0a3e893236fd57a394ec71d418984170
+0a4199d7b5694f36dea4aad2c3f47fed
+0a469bbe55b8801b6580eb3a5a40c38f
+0a4f57cbc4df95e6e0ff8fa56b6aa6e4
+0a50eddf543178726358c07c2b034ea2
+0a543c193e708d8148a622f0ca6d0058
+0a58bb4e9c869625a53abdb9b4655b17
+0a63eefae5ffa7553cc17610083162d0
+0a65932359c3aa6bf1ac193f4fad8b71
+0a67459edeba9638ad5a2da13d6da6de
+0a6d53c04d62d42570f460a6f6283240
+0a6e27a691780835cabb089311ec0f25
+0a6e95df7cca7001aea1c40dc9e3832e
+0a730b09454fe391cf373ef34002b74f
+0a7806c555a70976ce5d4ac68a5d18ce
+0a7aad76799ab6a3563c59f7e341cc70
+0a7bed806fa74c05cd03adddb8b46def
+0a7de060adf4be59403efa8a2c2b5fc9
+0a8131ceceb4e34ed068c8889b9eca5e
+0a869a5ee6bba473166cc015f487d5eb
+0a86d7cee84b1c74c6836b5435d4d184
+0a8c3a73bf669ab7a319c2935de39c0a
+0a8d4a78c16206937dc1543764e663a3
+0a8f9e9a42d50771a6d02f262326e58c
+0a909df0710cd2847032808e1960538f
+0a947b496bc5667ea1f679291c17937c
+0a95e3417712d42b2e4a916129587e46
+0aa125fb2d7720d719f866b1502e8ea7
+0aa220c8834b48055307ebeabb4f4fae
+0aa5e4fe100119d91d15d9bbf7243d10
+0aa73c719eb1967f2a6b7e8c4bab15ff
+0aa866a384250d8ec81af9a7fd788efb
+0ab3804308d9ac41c611c41dc1769c24
+0ab6beedfa035ceccaa9eff727bc5a8b
+0ab92b332b23b5519260039eb100cb0d
+0abc7f847192dc406e6b076d3ebe1fe9
+0ac0cc9a1c7f03da19929f3d86273d4f
+0ac508b362663c641fce9105107ddb81
+0ac7bfb6d3d3c11cd667655aa5bdcf19
+0ac8020d4b6feafadc1d05ac1c230b18
+0ad0287c8e78d10c4e3f3d2c2f7a03a8
+0ad0d8bd137e833c1aca656de8aa11e7
+0ad43a62e74c0c4f51f025a9c01a1c02
+0ae0ea5d0fe28a33b1b2a04cef3ae6c0
+0ae1cb1b249bc92710d870116588ce9f
+0ae26b6e2f3bd3d82739d822fe8d5ed0
+0aeb066404549a91de6e9b03f0b56edf
+0aed7decb3a85be9349009fe1855fa16
+0afc5b415809876089482692afeaea94
+0b0346ce8972761ab8d70c33dd2b99d8
+0b042781aedebfac15ab459bec9791e5
+0b06ba1bb85730a590b5d6b81806e217
+0b06d324bd2613bd2faf250848b9b205
+0b0db59aa7441843447435ab7710238e
+0b13309d3efb217b346b80a693c02946
+0b16afa2bcc7c9ba016095d71ff7d698
+0b172c57e20b0496574a05ae715ea138
+0b19018fc9bad3f67544cdfaacf2e162
+0b198f4715f0fe3d0e26341927a74421
+0b19d18d3e51274e4f6463912ddabef7
+0b19f29a72bc09882e52f665a7a5f24c
+0b21c031c7505e2e5564cf415700360d
+0b24de38c8ddc8a94901840571bb9225
+0b2ab129e154df85e1ef572ae6972d62
+0b2be164b8795610b012c3a62f98a5ec
+0b30a59f92f36ee78f652bf9e2731d41
+0b324eb6e182de50033d60d51cfa99aa
+0b35a79443c5d6aff0d1149a865be5a1
+0b376011b24f94bb9704b7413dfc842e
+0b40028a51fba9b3f3669b36c3895e64
+0b442aa6dbe3299a2c315721d23b4fc2
+0b4b8c4b7f3a7b9e204e6524ee043063
+0b506f8508bfdcd2a94a1cdbb6a86abf
+0b51036353765cb7d620fe9535f3f84f
+0b52d83733c975490471610d585ff239
+0b53bc66e3016620ee4b3af927d44637
+0b55ffedb2eb824fbadb9b7d73cd9373
+0b5e429c0d43cd1a824ac74e275293f4
+0b628f79584671a1468b731263bc5758
+0b63f89e16443a3329299e697962f23f
+0b653d7255312b2cc1e64adb356b41ef
+0b666eb89c21ac69b2d933a54946b23e
+0b667328f139701101f7fd459736f7af
+0b6840b8e665eb17b26dd47c568419b8
+0b6a031c6d05387696ead854371d25e2
+0b730b5dd3bbb77202229704ca98452c
+0b75062d1fbb782cf6f4abccb85a64b6
+0b75b8ac78fc955346844ffa451d95f9
+0b7737e09d3adc5b000b5dde43da7841
+0b7e6bc018ac51a920e5a905e87ad3c4
+0b811565f042a8dd6ef0943d344a7cb6
+0b82dabd3df8171ab7b29463f7a10f62
+0b96552eefaab9e31da4d067458bed57
+0b96a5290a55d9e13a0902304aa3830a
+0b9c7884d88e3fde417c4f7a218ee9e2
+0b9f02ae3a2d7ad12f0b267d0ac5cf48
+0b9f02b807998ff4d0fb2cd71b2c2f92
+0ba1d968975ad74c1eebdfd1fa137d2a
+0ba739acd34d11a5d543c2f512257466
+0ba918b2e4ae5a50f6fe54bb6909683c
+0ba9d1affb34139d41a4cb170728d0d9
+0bad721d9972d7d9b00d2f3571df8965
+0bb0c3d9639c83f817c9ed17200040d2
+0bb37a7f32bcefa49c6209b6cfd0937b
+0bce5c42a39d2e960e7f9d262db42ef8
+0bcf20f6233c20e877e71e5d3b1519d4
+0bd081f954e2002edc25caa206ab72f1
+0bd3a43392b90f7d41f091db3e5484c8
+0bda4266222fff5a2b85904a3c947383
+0bdb6b35d0471146383b699f630326dd
+0bdcc29ee516de7aa307bd7dc75f442a
+0bddff61793eeefd08ce666ef9de6152
+0be3b5402135bb0691a051b61964c667
+0be5947c00058cccd78a86f12882fb32
+0be790f0456b41840d04d17c31908b1b
+0be9758097779cd514cbd4def5ab0986
+0becc9780c18190a4ef4de97524d06d5
+0bfa51a39c0f135d4a3e1c7e3c5fc06d
+0bfc33bd0f8a28812fdefa831228cad4
+0c060c98eeafec2386d9bed805a72f2f
+0c07661043022cc8d8cb4936f6ed58b3
+0c08bc325565ddeae398c5bbe237b163
+0c0be3b19f5ebcc311bc9b06c9609285
+0c0cb0acdef4a63e6b88abfb204b58d5
+0c0dc06b800bb971ae87210568aaf4c0
+0c0e282cb411cfe115ab5535378a0e1a
+0c1066d0a1c1918b62ae4d2657c6298e
+0c10b316ba7bf29316e47b169b9ccb14
+0c11b6392e4fb9c2984facdfec2b327a
+0c14ab1ded7689f88e2618218a33c10e
+0c164219da269fbcd54c6bd2067ab7a6
+0c1859192d3f9cf0a23f385666e15183
+0c188e683bc169cb6a23c09194405929
+0c1b3e35cd0c62d01deec40cdf8d308a
+0c1f8c87e46e101dddda9c0b972555dc
+0c2544f754e6d37207ddf7eff16464c6
+0c2e75fc8d15ba9861666c197fd9ff8c
+0c365d4ae6d17190335a52bab9aa091f
+0c4b63b996cfcf760ef96df6e94e828e
+0c5375203369e0bf639809f0d0e82817
+0c569cb69826b55e5db8707fb1cce4c2
+0c5af4988f4651aad0c12e7efa40ac41
+0c60d10383e626af487ee609e80a2384
+0c631a68d067f434646f1b8a3270e43e
+0c64875e5d45226e1a592aa2bafce152
+0c6505c9bd49a2879eee1a73334e2b46
+0c6ba9b3c049d8a8dc24bb310f3971cf
+0c6d0fcac209882711a1b08d798e341b
+0c712101f41262675b63c893a288399c
+0c754bf9872b7a0b5f87b7818cbe456a
+0c809e865a6f66ef2725aa5602e2b4dc
+0c8879c58380563f25c02cef57a41e24
+0c8ba5a43423184143cd2264a3dc2280
+0c92475e9795e94979c936db5cb0c183
+0c96a0c1440c18d0a5f07d5268b4b672
+0c99f194044366e5000933867250f5cd
+0c9bade4536fb12087e92055a7d75ed4
+0c9ccf82c0acd274ee74052d5d96b56f
+0ca08ebf1d050a505145df8c36931ddd
+0ca2a5e5e81d0c0b6509fec16badb8a7
+0ca44e0b32275fb360efb954bd0e29c4
+0ca582d5e5c0f650aaba4661589cb17d
+0ca8e3f13411dce0d88d27a3bed5ed13
+0ca9f52d39136f30dd15291e090cf06f
+0caff2425e3e7703c8a2514ff6ce7b84
+0cb2b1eaf15603d5586313de8a2fc57e
+0cb311aa28ba7a088d026043f8d1d763
+0cb54c766ce827132320fdfed1eca362
+0cbe264402f9c82eb5b61241c5e2fe6b
+0cc05000008985599340cc87f5d1b5bb
+0cc41001512935aec942d1766348446f
+0cc78daeac83e97e557d2015f8b3b97c
+0cc87829681460790e2c90d8c2582bba
+0ccabb436f87e1cca31553dde65c12e9
+0ccc0625f04f77b5ba39c441ba039f17
+0ccd993eaea261ba56301aaffc4a81c1
+0cd103dcbb2a3774d4918b48e06b916b
+0cda81de698cb75bc2337e2229f7c5ec
+0cdd90bba7b5422ecfb59eae0f1fdeb2
+0ce0750d3d153b57be78ab9dce57c043
+0ce0818ba457a181b56bd1fde803b029
+0ce2e16ba90bfe64dd12c4a4b726dda0
+0ce365c24e6587f7cd3ea0ae0875e570
+0ce544a6dee68c7442fa536a1704f069
+0ce7193da57ed84ed405eb4a5bd031cb
+0cef86f948db0353c36e42dfafcfcd87
+0cf13c813c2a5cdcbf744e7d4fa293d0
+0d026654316328c989c5703b96268bbb
+0d043c7b19b46f6d8c16177562f2216d
+0d089889c7894526987d8c624961a29f
+0d0c0c6f6fa9476b898af05a698ca285
+0d0c27351b2c8da3fe3a85f05c18c623
+0d21ca02239ce0119f1cf3f937ef38c8
+0d2938459f80e9535d1a2ce9770d4515
+0d31748dd012bfd45f543f6e25a7dbe7
+0d325484f4c13489acae6d3b7d762c61
+0d37767ce986889d6641fa06293854c2
+0d380e7e0790f512a4066014af8ac82c
+0d433178b005d63f5c8a182f559661b7
+0d4537ce9283f497303efda887933126
+0d462f5ca83059c8c0fbfbde4e4c341d
+0d491382c717746600d77c5988241b3b
+0d4b6eb2e4e960e96458ea0a9a9d89c7
+0d4e4da299f63a42b1b2ea5c633a5494
+0d57285519452c46dbd447e9b98addc4
+0d5ea69ea289e169da701ba5039b7e05
+0d6194dda4c13bdd2af3f8af6874a65a
+0d634f81f9b3d21b619ac7ac44a77a16
+0d637b2e645e630cf9ec356abc012e40
+0d6483789ea65ab7fa8aa689f2905443
+0d655778ca6b82231cee6e7aadc962d9
+0d68d3281f711450e3a93e6464534356
+0d6c8cb94799222cad0b3294c60d6282
+0d6ce06655da03213089e1f0e8790fe4
+0d7139e85d5aedc57a3c066d406934be
+0d727d070aa9966ac7bcb7a45e6b9a48
+0d760e38c1ea31f81ac929939a62c054
+0d77a2d0a4756ea008720f5cb697b836
+0d7b234a93a9bc1cadf118e3bc0eb3b9
+0d7b950cc82f90aacf9e3a01b5ff54d3
+0d7f70f4bfae8ae1f2d74a4b21fd2af7
+0d80f597a9bce794c3c322de3ee090a0
+0d8f59b30c9d507dbf2a87229e790a7a
+0d948cdead4ceeb51f08e4fde057d60e
+0d9616162f3447bc2772e9bef721a84d
+0d9bfc675171b7512f60e2180ac27900
+0d9cc323adcd7912d1b232cee172f5a3
+0d9d153a19ae89a62edf4a7676d999f1
+0da1144d92633c1a03b8f2f9f5626d19
+0da69c29a7a4e3ac1d04495b5a6de834
+0da88b948d8e1deb0be142a2d2766f8f
+0dadaecd66fcf5c3825ff4b1fa47c65d
+0dae9e80c1851f7f0506d2c5a8ed73e7
+0db5d869063fed7a970f7e72d02873d6
+0db950f044696feb380809529fe4609b
+0dc0549924709113303d05250bc53ca7
+0dcdafab2352b39ab88ffd8128a3134b
+0dd094dd9a37d13ea5c3485989c39e36
+0dd1a13a96ac99da74135c30ba94086d
+0dd27af4feea046484d7edc6d654790e
+0dd58e24193d8ea33e68146eb23acbcd
+0ddc50e50b86a06dc5b20e639b49412e
+0de353641b08516df8b601b2828fa4f7
+0de7484b954b75f1a045165d0c29f66f
+0de7ba720cfe4b39d3b439445a2c9df4
+0de7e98b0d1ba576650c1b1f47758f8e
+0df014529780a8e3ef65cdb4e0be8286
+0df5ebb3ba07dab03b08664ddd03b305
+0df84fac86e058bb2ae958028be35618
+0df97919d01bd980c358e7a3c571e3ad
+0dff6538e8458ae1afa246f972cfe65f
+0e02f4271f5c0789577710ff017be6c7
+0e125d9ba1e7135a226e523bad5ed59e
+0e156170caaa5b098a2fa664c23e61a8
+0e1770494214b19d9c7e3de2c05fef5b
+0e1c308f09373cf7d83e70c7b8f5d81b
+0e1e40a16950ebc250d5cf24b1b16a52
+0e210164523eb617bce3a5bd93b567ed
+0e28e85962a24d8dcdf8a49767f15235
+0e2b009a910411939857c50fd7149be5
+0e2da7eaa888fca0ce22f118de6628ac
+0e31ad11b4f016108bb4b4031dc5fa67
+0e34f3254da8588061021d3fb133717b
+0e46bb9f1ad35e36b1b7837bf1783d95
+0e4d72d9df1f05bd3c16c6d97f033886
+0e4fc91984e6c2312a7aa403399d53f2
+0e547ea85d52997e7e093166fd688e31
+0e57175070bf78cc0c1e0e5d909acc05
+0e5724341a22d1d39f15ad427431993a
+0e58ec4ec9eb8286b53b44319c3a9442
+0e5941408cbe6ad145187923a89285f9
+0e5b5dfab8df9a5ff3882b2af697026e
+0e5d6e2bde4aec6a6e4cfbea09c1099b
+0e5f13fe179bf0e09b8f341e5f48c0be
+0e5f24872ccf98b41cf41fda358a3e1e
+0e669729c272cf6d00351861b5b6ea37
+0e736a09e9986ffc6e70b1a1751b4b44
+0e78348146c815da304ba1ac4cea89e6
+0e797f413e0a82f0e140121afb1a5b59
+0e827827cfc9e9e638317fe7b5aaaba8
+0e8683e7bc393f6a1a867ce21cc85546
+0e86e26592010a4963c3bd4ce7b5765b
+0e88dc134e12605c30ec51d5960fc1c0
+0e8b8a661598539a506764f0437cba94
+0e8d8f63596cd608c32da08feb8a56b8
+0e8df75411ba4637b64252f450526870
+0e8e8bf30e198984cfe11b0626d730f8
+0e8f36a9ef75bbcf52ec481c7197aaff
+0e8fb81dda7816cd550757ac6030791a
+0e90bf9465ce433e985b730bec9c97b5
+0e9676bf477a871e2526b9a3f99aee67
+0e9f2d3bef56a7e97652f38f88590434
+0ea55695fbbb4646087f89d21db8cb2c
+0ea8a38a926d56ab3aa669a5298bda4b
+0eb24e59eb5b9a513739f363d6b315e4
+0eb6a5f3b9529ca81c9dcca81c5cec66
+0ec48493b211080c8c8bcb4f3d381cd3
+0eccf0f3d0c1d6a3c6154cfbca3f0245
+0ece627667ab62b0bd3a8d345f488a16
+0ed19f0cf12ed6346512331c057666cd
+0ed5edac05f7cf40fc7ebb71d8238eb9
+0ed84c68e73e52ed46d4a9b4628d3b54
+0edbbee4e101c0244f0244c235f8cb42
+0ee71c4f9c342865813426d1d2c00b8a
+0eeb3af04852f25165d5a66303e611e1
+0eef3663b2177162ef2a24da7a0b781c
+0ef32cdcc2a9bb9cfb1c8f645f3e6abd
+0efa937a3c26711df681d70addc6c10f
+0efe9f0c4b5326699e1ba0eeafd82a2b
+0effe69bdc61c3352c76643f4a2e6be9
+0f07edbc8001026d4418485cf7d30e0c
+0f084321f75e82a07bf2fdcc639bec02
+0f0a1925d6ddc2a70ad46b8468c3a141
+0f0b063bf82e1356e5d05cc9b4214b26
+0f0c80cdb642a17a3c252d08c4f79785
+0f0eda8fbb72a5e561633cb7e6946475
+0f13bd262e7e30828766d7b35fa17f1a
+0f17a4d379d0581352759f09e7d34e1e
+0f1bc9b3c7c58b52553eb8955d2a0f44
+0f1dddcae4a97d15da0a02eef4b6e8fe
+0f233507357d545890de3692eb102165
+0f26277935ad7cc3d6042d98ef0eb44a
+0f2edefb17adddf309028c9de43fd8f8
+0f2f1246781ca625a3bf7b9dda7d1d26
+0f2fcc14d0ad6124fd975f62326334af
+0f3067572f21f76a043e7b42e290c4ea
+0f3102326411a0ae1b29b6b344dc0d7a
+0f361974ab831b65df64cae2ce3f821f
+0f3801db65893fe3fc6097f378c5bdba
+0f39f0155f32c6b709c183e8e1819b12
+0f3c314ef0c2e3b40eb4ea32948534ca
+0f3dd4b2b97236e9b44e6c029796d7ab
+0f3ffab0266a3737656da83aa96cb7a8
+0f41742d11a9f0aa8bac715e305bdbd5
+0f450c11d33a1e550e16513639a2655a
+0f46ef50485715aa306f0192e6de7702
+0f480eda91f4f6e357e3f6d15148c913
+0f4aef21c3dacd6cfd76135c481b695f
+0f4b688ab5cdc2a3d05ba9d3b6a8ff38
+0f51cda6bb5fa57d1fc8819f71cd917e
+0f56846ad3af9de20e09f7974aaba7e8
+0f5c0d76db59cf0a4cf9a9993035adfa
+0f5cc9b0af3bcf3ab24ddf2ddbcf7848
+0f694ea96523802d3aecacbbf900d482
+0f6d0acd80a1aea135f052454c3a2568
+0f7248e691f8401eec164e36f50f5837
+0f7290ab380f0913c1888b2501444ce2
+0f78e33fd3a5ec0961e241f99b251ade
+0f7ccc8ec1b11ef3d1f3530688a42fe7
+0f7ffe43653f89fd68a9ec7de71e4eb3
+0f8337488ae733dffdb793ddbe938b29
+0f843476ea15266b09a0238bc68b9049
+0f880699c627024a53c3a2d56c75103e
+0f88c6a569ca9b2fcd374a30949dbe42
+0f88d8dd26bfb06566d620d948801726
+0f99db2b7a5695cda1cdf86583a8b01f
+0fa1b7090bfd992ec9140b152851e7d5
+0fa268c92338b27b7da0b9a85d775061
+0faada83c84d2e19ac8e4743a4dfebfa
+0faccfc399bb3a63b9c1ebbf942e54f4
+0fbe06ddb8e3416aac63fa8b4fcda858
+0fc2ce4e86a1c636980f874fecc00938
+0fca7d178cfbd75a1936c47b83bc30b9
+0fcc66697dfe2e8050b0a934c1141092
+0fcc8069c0e8d9cc8f3a45cd3cc1c226
+0fcd88b93a783e8da024984898719d38
+0fcda1b2506043a5d951dacd64b9f45d
+0fcdb49e090d9ff8830cc6fae07010e1
+0fcfce2f4323f70877fb289c263226e3
+0fd42ea0b57287a4c6901c0a30a67646
+0fd78679937e17bc38fd166795ba483e
+0fda526bee0d1ad217d53fba68a0adc0
+0fda627d40584896a1199a1d9b110947
+0fe0a44d748de5df478988510b512aa6
+0fe25de3422190b0f760c439c0e052b4
+0fe3df008a2982e716b9403bd6487256
+0fe4483817a6fd1ff7c48ff689c93882
+0fec9e6570ac779d7c8b8d0e0122d271
+0fed82f6f74bdf8384493db0c7671156
+0ff02af53f8f13b2a60e68b08d82f554
+0ff2c9c047011f191d5804f686331310
+0ff7b3c1a3e9dbac555f5d0699527a11
+0ffb26d29a23cb71cf0ed64cb53698d4
+0ffbed1cdda7c40e39acf2fa5fc68c3b
+1001305fc0cabacaa99cab32ecbb57c4
+10078dbc57f60d59072eb36fd420ced0
+100906e33016af6ce1c670b0166c0353
+1009a7cd5e03024ad2921603d3233f86
+100a826c6ffc8644d03f279b1cda3bf6
+100be512e608ebb8a96861d003fd12d9
+100ca3579fe90422d14ba15f108d1a60
+1016cd94bde0643533c4013e7e2a675d
+101714eac8a241ce06e02521f3609580
+10181ecef7a5a35fa47e42433e79a5ac
+101c04899b115b8ab2742705288288f1
+10205324a44f7919152890ec351ebe93
+10212d06b7c2c6011624bfbf68098ebc
+102e843e300a601258c16dde33e88fee
+1032aba198dd5b86fc6aeb6a0c943fbb
+1033daa4dc4cb82fe24f6157165a0525
+10399a21ad01bcb6df26c4108839990f
+103ea9048c56a5d0bf54965f6f29e20d
+10429c6e838a19729542fa22f5ce3625
+1057295610e5cbc904074183aa168d09
+105f49e991ce8ae8f2e8b8a6079c687b
+10608cec96c6e2ff666223e7498ba740
+1068143256e7fcdc7ce24bc5e3ba92b4
+106b378fff1a4a9514e1e47be5d03eca
+106fc3ead7856d5d8fd45942f342c7e4
+107bb7cb2c8d5e497366de3bab2b277c
+107e824cdb7aecca3334aa8d0f37be3b
+1083ae8361c36e482ac2972e91e94295
+108469397de416e5dd83d39c4b23b5dc
+1088550a31645ca76b6fc00e4a3db18a
+10894d6b0acf1426a6d0254037399f33
+108a6006f113f0ea3147ef5a51c77030
+1092448650d608ff173afc701d482c31
+1092b158485fca75f40b4f6a14142c1c
+10949f67e8182f1130812489f0f9d678
+10953298b4c50836fc6044d036c1bfa1
+1096f4480b05634699c1b8ead3505bb6
+10a93be5e8225b84a67a0f92f5c6fb6f
+10accfd982d8eadca835ecd8dd8ecbe9
+10ad35dd7e53d6dc0fbf6ca867bfde0f
+10ba518561fa25ba99023681bf6853e6
+10bad937f7c4a608823fb4b02763c647
+10d00e9e72874137d4c678d4bfe0eb1f
+10d66bd9d0105d529d725b52147f19db
+10dfbdc086682198b244a8830412eaff
+10e5aecaa113e019450876b6aa37ba56
+10e6541e72f84aaa3458e5b1f4c15814
+10f1a36f1301e293a64f59fb7755be82
+10f36ed1c0859b2172511517313dec94
+10f94cd5c8a9f942173b3e8091ef0410
+10fc5488af8bfbd440f04af11f1bccca
+10fd1043393f347d937844e4f7e0b296
+11056a7a40fea6844e4551b87c8dd989
+11057a4ab71cd7caaed54383f9866e06
+1109a6e6b79d2a6d40f926a29ec0bc48
+110d551b984759326f46e6effd06fd35
+110d6867f3f9e443b2bc391836196266
+1113691aaf2b966f77c7ee81abc01818
+111bcb1f9843aa7b90051c9cc418b12d
+111e73222aa3d699b05716c3d5d3e591
+111f1aa2235cdac22b83fef964a82a3d
+1121ba5d884fdfb8d2b49f06ee9faac6
+1124043baa1c4cef2046522753c0bf6c
+1124c4345681d53b3cc51bd9dea25a48
+112f6104588d393db0ba5b1446de8960
+112f95975f05e195ee79a29b3244ce95
+11379eb9b2d4be9f88bbb4ad9ba66843
+11383a4f6b07012c43d81df60fe31cff
+113f0d67f8f8eb8e803c4a1784698af5
+113f8166fe3cbaa763583daa349e10fc
+114395d2576aa3cd1714e3ea168a27bb
+1143cc566294ae910d1c4c9e7e7fc5c6
+1145886091b199a2837bbb67cb3c9225
+11517d554441e7e5281e55602406bcdd
+1153bb7bfbfe5cd592a712d020f90902
+11559a4e1f0b4a40665091ec7070e660
+11597e8094494755622df12cc9215f9d
+115bcd62a8f5c554a8e9dea9c6164b86
+115d3bcbab3ad1c10b4e0695b85d3ba7
+116277ae4017505ba017ee9e38a48e83
+1166571df4bf038219962b0af06873c3
+1173d9b3539090aa76ea43763c3a54f8
+1174760872ee045ec13570ff261f5d41
+1177ee8d3cf58151f26855decb87448a
+117c7121c9d179c81727835daf0469da
+11825f0c778767c4edac04da84a55045
+1183d806b73ab05d71bf0f1e36d61b57
+119617e80751cd2917a931e71ad96421
+1197b413c0a5ca464f5a8f31018d2d41
+1197e4d7a711f01e55df77dba9c36099
+11999aa9de849e73f59f90190551a5f4
+119b7ce99c777bcb8ef630ab41ae5453
+119f0ec6cc41973dce1ff9e793d2cc84
+11a2eead415f1d5fc48f324a07c03d3b
+11a528946249869507cfcc3f5db67b14
+11a962c4b608358ef1d4eb837eb80b34
+11acffd459726f72aa9c061af7adcd85
+11b17a6adaabc1df315c3bf0a4e7be40
+11b1fa687db65526bfbd1648bd36abe1
+11b4f0e06ad027fe519be0a66e8e2f1c
+11b76eae548ed79cede3592c6bd50c30
+11bdd976861834ac9025e5f7681bff6e
+11be0d0ce8a1ca91041f8a7ff991022f
+11bfaa40f390a20c5b1d0b2a08a95726
+11c258da2996684bb06c6d79877a8550
+11c479ecb5642ac01ce3eef75916adf7
+11c489bc06dffc7e526233c0f7b5e867
+11c6e64505d16d8f28703c049b2dd923
+11c72cc08f344d75d7a8cb3893e92dfb
+11cf970fd27bdf42cfe379fe06bd55d6
+11d2012c1028a12246946893cf808587
+11d3ad285bdaac42e33a01fe0b0d0366
+11d47070343043e1abf20a8fa2c73b30
+11d7ab551796a9923c2fae5199584b9e
+11db6ae6137ed18f695cd6a9a333b2b3
+11deac2627b0bf1e7c81c4f026464dea
+11df5de877a48379b0f11611dc571e42
+11e6297925095f809e1019e649c73a43
+11f41d781c031cfa9d8728f1b93e037e
+11f7bcb4f885dbee02e53d17924de9dd
+11f80bb140dbf38b6dcf63574aa0eda6
+12026eb357b3e300dfb6482abe259021
+120432a3bc6603feeec5d0d3b704f26e
+1208d34d9e9995e83ca1ff6650e81a1e
+120bdb07b34c6597742c090cabe63d8f
+120f301d851fb26862a35cf3f8576e31
+1213c1e4e9df3ee5d13ca7eeac7eb5fe
+1219b28926238df6e1ba11abdfc4a52e
+121f4d8eed1994dd2cfcaa1511a064ae
+1230c3eb87eebcf7151d5b700467db1f
+12396158edd29d2337bea0392c44c3b5
+123a21f254a8908de84adf24705dbe50
+123f6d7cc10ff9816c998eae660f01dc
+1247402305775be71cd7e2fba51eb65b
+1247dcbf6a4b474dd2399f1a179c9309
+1249d735aa53c98af0cb629e993ff8c2
+124ba142f0d94f8281e865a09e35582b
+1250af952e10eb41d0b464f259358b40
+125f9ee0547f854764f2351664b07638
+1262d6717e4c56e13687258435e591e2
+126345495dbb65717225289702942812
+1265814c354605c17a7d514a8b969d4e
+12670c8d7b1608f535779a0410b6f135
+12670d69c78ff47edebd42edbfd7eb76
+126cb41e3cae5b0bb0b149459ecb54aa
+126edc72591b20cec30af20ff365f7e2
+127474dca128768f867589b714cf387c
+127707e65caa351159a4e22cea3726fd
+1279da5bc23bb63e4b4206f64279df75
+1280def9bbd502c005892b80c09536ea
+1281f131fb36462564d49b92e36ed593
+12871c2ddb304f196a2127b67d6dbf37
+12912bf30c7ed273f553ff3b01495b57
+1297c88edd5a7496e750ea1db855e519
+129864aa15d10feebb69a4aa4ef9d917
+12a31409ef8760344fb16798551a8610
+12a77b697957ea2c133a31ce19dcb63b
+12ba035390e11882b70764044a2da62d
+12bbf898ca9d0bee089408bee5540d34
+12be5eb2b9a5fe40f928501662dc1334
+12c7c32e72a46fbf7af11c352afeb230
+12cfda304e51c98e4b312a05d558556d
+12d377322985e4eb110064dff4c7bd56
+12dde9d976637b4c76c95d27d375bd79
+12e01fee72de518f1c153709035f276d
+12e14838734a6138fad1f1b41dedc7ac
+12e2a374c368ce27e9dc81995f02d511
+12e380ca9cd6f88dbb9d0bfc32ae2dad
+12e488090acff250a05d7bee2608f781
+12e96adfb0bed9724eadd952048cbf2d
+12ef1bed8e44d1383884cebc5f7a31f6
+12f3033d00cad371551a0bffd9bf7c8d
+12f65b36c0b646124a6d85e1ae94ad46
+12f8f084b3be4ef72978c51d4efecbb1
+130001313ced605c946ae0e14a33e3fa
+1305036bb5070cdb2bddc34c16891dbb
+130bdabb875443ffe9aaeb37db150313
+1314e38a699a0efd3c7fef462d5a16b6
+131658a51a64170089ea8abc020d5358
+1317a6e3f2942772cc82f9cfc9ba7432
+131881688c24aeb84662f1bf4ffa6f34
+13201c16878e3ef9a97eea2e859e05f1
+1322c8e97f4a68d957c3513d5d57769e
+132368fd5de0bdfa83950b5726018c98
+132582e45cf266570aacf9311900a13c
+132b943c9af8b67d80d251cc6934fc83
+13302ab045e1caead15bf7b07ad74c89
+1333b1aca22be3e0c03a6d25326a69c4
+1338cdbfca3fc8b7a30b66e855d4179e
+133cbfd181f450dadaca2b31666bf58d
+13403f4b12366b0d5b74a2b046dc279f
+13440b79a087752161169627168b0cfd
+134f971d504b1fd1cdca10c1f2f8423a
+134fe57cb2cbb5bc7b2c0221847ef8e6
+13502156c7da5961ce94e194f90f8fa8
+1350a1e32c9a3e0474991e3a24cc3ce1
+135573b557221ecdf1a9d893ff4ad83a
+135ae5d4d6b3b2a34f86478862a6878b
+135c92ae0a7933eb24f685d4f4ffe6d2
+136416f89dc644c844558dda59162007
+13671d538df10681fb4a6bd3f196fa3a
+1368b418d08d979fd0ad4bf82ffbe2ff
+137012cb7eb02a4000b8e74d9da1b599
+13725042c309c9d7a8a9bf138399d66e
+13750782190adf5bd887f2b0262d9295
+137a3ecf7c08944dc0aefed82ae5a2ad
+13833267b90d16a7b73cfb69a6f9e25f
+138672e70d760fe9a01d8606cbc461cf
+1389ac1cc5537693689c1168d771b917
+138a802f4751610beea1d0b3229e5588
+138b803ce1ebe0d658924024369d65de
+1399c930687a8335b2885f0f558a9719
+139b8eeb57d114d4354c4355b4915479
+13a371e69f5ad1444e21cd2257fc9f01
+13a433e30b7937656541fc4b6d20a3a9
+13a990f13447b552a57e86d5a7ab9a65
+13abb1447a9a517d1559aa6ef7c1bef9
+13abc932d1a744f71038d45ddc88673d
+13afd099a43e91dbb8d6c1c2da5391fb
+13b530aa7222ed177cf134b5f7d4d8fd
+13b835f43e880515fe4d00d82ec4d879
+13b906fc74c9b65e1ddc92dc8cd4745b
+13c308a0c10631a72dea575208930781
+13ca63f638ffbeda82970d4c2895fc70
+13cc674232435e22462275038cd55362
+13cc6e999717e8c0e5fc8def220bec54
+13d26abbcd4c895bf2f7b4a2e4be4389
+13d4fce1a5538165405a72c80fffcdac
+13d89593a361ecbb484b2b8ad2cf9912
+13da703cc8cb20c6b9da59d6cf775e6e
+13dd6a5e2ed55080b70caeb0b5c8b88d
+13e344650d5cfb4ab99448a215427e95
+13e966d32d34630fd997294846626345
+13f26e38b8d28e7208294ddb0b76eb1c
+13f5921de3c9709de899f2b7226094fd
+13f8cd49949d92f1ec5a857b8bd87e3c
+13fad78df24e2a5709adde62e403e01d
+140265066c1cb7a2408b0251c1292ef3
+140369d27e96feff02891f6abe9522ee
+1404c41dec97d4128d0f07dd6770f022
+140bc726205d1e2d395d522999c13951
+14109687a006f0ebaf143d451d5cfd91
+1411017bd6e69eba5f4b44c7d705a1ef
+1412a50b30c93d7d4a9bb01d2fb4d4ad
+1413a48c20e9973d75ed28e20d4f5d01
+14190622eb28c4e0481ebb8b4ab3750a
+1419c14bd28bdc9066150811791db025
+141f9d78c9003576ccf090c3ff761a22
+1425fb223c5ada047bdd7a17e8ebafbc
+1426511b083e72177477f0fd6fcfb99c
+143592cb82c7e8aa8a485bb9e45daf8b
+143677189012c4a983edda0b56fc773f
+1437a13ec545e8f89d803a7e05fd4b28
+1437d7f6d43002bf9a563e48a2b028ec
+143adf4bc02ddb5b2b61b7d9d2564479
+143c8b50a7fba0927f72a0e4986b6dc7
+14421442d970bc8e8358bb20b614017d
+14434a8fe8ddf027fd30c468178e3a50
+1443c4ce7292bba9367d19de4fdd929d
+14467ba6dfd0953ea3ec446774115177
+144697347d9759fbc7acd9b19f3d6543
+144c9d148333bfa751279d3834828496
+144cca949a0e0b1e58877a53cdf8ac1f
+144f9eca5598e6393999d827ba074ec1
+1455a351ba9405fe99814a0bc38358b2
+145c2c96cb11b838fedbb7dc66d0dcbd
+146b45212f4aff1755933ff730812f90
+147c9d7a91b0258a01258488e1862d33
+147f437dded2dbc2dc458cfa5e17b21c
+147ffe6a6749cfb559edbb17a4c2ffae
+14826e1b8488906c054548b5f180eefd
+1482ff8a742104dca59b7e3109e47c27
+14838e15c6709927853da3d178bf59e4
+1489a125597040774edf209a82405a75
+148fe26dda41d088a90fe27d1c98cdf3
+1490ef903406dd9701d9b6a5d8024158
+1492053a57056db6f8f9a6ad25db7b05
+1498ca4f00d462c7808747b3e78b5208
+14a64cb438e64f7d03d384a70d398e38
+14a80a0eb327049a5a7036d28e8ac553
+14a87dfe76db97843adbdb0aec7486ab
+14a8c9fa5d1ffaaeb32201982081854c
+14a8ead15bf9cd19b208caf56e858b09
+14adbce250383c02af7340566843439e
+14affbf151c62afc246af74cc0f8375d
+14b16159dc1a6701488da930a30051cb
+14b44fca2a57d193d21315d39f537970
+14b53e202d452936540e488280aa4b2c
+14b8ef1285611e75ac0595dafd927c29
+14baced4c2cc51a5ab4012e4df3814fa
+14cb0a2c18b7606ca37e323f95744eb4
+14da0bcc720e18333647503872a68a5c
+14f8b6ba8f5e01b7e86114cd1e7b3cee
+1507644a1f768138471019a124d38819
+15087594c3b0e52c8d54f5304cc7ec3f
+150daba20b4b365421fd13b12a8134f3
+15132a39a8497af69f16d8b33ca6bd68
+151810620f57e96fd73b48c529a3b6b1
+1519b36be935a03c82aeedac12ec598f
+152628fdf0aa47b40f16441cf5ffd716
+15295701bf03c51d4326d38d0c0fcce6
+152bbbd64bd4767054ef4837f0aaaaaf
+1531809569a06e06bbcea67a491e936a
+153185b470ccf434780f90d6dfd60811
+15339e4028ac0d116c2c29af8987717c
+15362c8acc6bb1aa0b043f3b97846458
+1537e4ad6d713f2d9d8ab58a2d5f47f3
+153b025233b2aec538f53c49c92f1e5e
+153cff860211b3e48c595fc1ef3cf78d
+154128bb87684bb1af24a5779a8780ca
+1541b37529db87ae97ae35d6f3230d51
+1547ee6924920ae7dc03573d95c84a63
+154aa7b39beca044db4643d55913f1d3
+154b7fd72c9968ecf854351bb2b72326
+154d1e2de882f1fdbb1973ed48cf29ca
+1550f4f78825b8bdb13e995cb993f069
+155665b312213cfb4cdc1809690c8ae3
+155b055dc44952f5502674905dadb8ab
+1560b3940ccff4d7ae0559e22e8d2200
+156370c58c2d8bce4f3f9046001f3442
+156457e770c85542cdaefd61733999ca
+156da521cc8d497709dc332a3bce058e
+15721bb8e99ad3c6b4dc096681c69cb2
+1572b34c6d902fdf50aceeb444c104ed
+15771e5d104294424d7def0206c4a076
+1578e3aa63787355b804278210f88ce7
+1579daed36e2674c89f8ff0ec5785b4c
+157e1a5e77058749a0bdbddb7e3e30ce
+157f7dee58295642e4bac3f91784d41b
+1586ef2d9ce8a60c1239e8267dd4792a
+15888fbf65a9f1b116ffe2ad88951a2c
+158aeb242136ece5e0870b45c49c7510
+1596cf0f7c7db667cd240e03f3a4263b
+159845465bac31f8269433b900cf944f
+159f45a5bc0d401d55c7b00977edf1f9
+15a665434ced6dc3e0e741f3a4bcb2ce
+15a8d74ce500df5615740d2a3e6365cc
+15c18eb03fc9a648fd9762dffba372e5
+15c45c01e0ec5542fec5091a531e4fd1
+15c9a3737668b270fe74dfca822d10f4
+15ce2158c0dbe7ba8dec3f51c535d4a0
+15d3cdf1c738824eb056d817ee43b5da
+15d438fa351dd07309b8e8a6a9efcbd3
+15dbfa4f4df1685218d9f58cde2db2f8
+15eb32ab38693571438d0b3388e8c0af
+15eb731fedc0462c6ef3d705099afd2f
+15f3ff26f9bc8e910959adf9c06741c9
+15fd6bdfb9abe078ef1838fef53c8056
+15ffb2ab3af03e027dcb98f42e93471a
+1604abd91db4e383bd2a5b0ce3ca55d4
+160654e90aafd0bf77f4acaa849bb6b5
+160d78801519d9055bb6f67b83b95697
+160efdc4011e235b7240fe4a7405a9b0
+160f3ac60f6671a4d1a44b5e811228b5
+16173f15f06e07ca3756aa418215004b
+161b8ba4b43c23af6a4c616dc441806e
+161d036be3d34feedf8e421dbb55fc50
+161da74169b57166a7201a491e341de4
+1626d84a2e833f3ce89078219a8350b6
+162799e90a77c34fd6035b182acf44f8
+162a68c9f0855386655ee02c58eb3638
+162e333bf9bc0a7be18fa3a1bdae4a79
+162efaedfbeb5eed177beeee401b0f96
+16346e70163a293a2ab03f4f9a6981fd
+16350304ee08ff39ce93eeddf78481ef
+1638dcad3d17e8e5fd39fd7f14a8c2ce
+163c5e48acc01167233fdc11e88f24fd
+163d5b27932a3a71e85d1d5fb5b4cc96
+163e04705261b4e147b5b75214a2ab47
+164401c43ca6f0e04f4b5d6b75675bd3
+164b90dc96bfa01e3e62c05ecc957896
+164d19eef54fc4ebe43c13dcef481eb9
+1650c4fd9b6a5ac59b2b08305c0bc477
+1651b1946d8f70df1b33856f17e566ed
+1657595806a3080e6610ec81a4e26aa0
+165a10b0e9e7c0383e6a92b9b4ca83dc
+166b9fb4135668f87b88e7a628d72afd
+166e80813d5bae80cda52eaab899d93c
+1674da3770255f4f9747b190c4231703
+167b0ba18e9e4b6315b61a45a90aaa40
+167dd8f520e50227992177ce73d0ccd3
+1680cc81cd05398808f935d4fa92a769
+168405070e66394fabf683df83b5142d
+1686b7f11623e34c0b3c329d21dde6cf
+168854535092a71089bf6e6b756aef80
+168b87963c4cfea3366ccf2f1c29d916
+168bc2d8b296b2a0e68d3b0249b59b3f
+168de987686731aa5e286c195773d997
+16926ae2808b7641d15bea6dcbe4e511
+1694e0dce621f88a1015428d4b2c149d
+169828a16daf9588e2a2cc1e53952acd
+16a21566b7500403cba299c5bc1777a0
+16a257cae989eb5ca11b381bb3457bad
+16a34258f35b011549abedd88783794c
+16a9e250bd21588716e040b2bea9a0b8
+16ad0bbee41a266472301e9c24a159ca
+16b411b6ac66e08fab2e802133ae5b62
+16ba117d6e0ca109e47994522eb3d950
+16ba73e2438afaa1126c4674722adf6e
+16bc3ad7a3a9907a224d155b8c974035
+16bc877874ed8caf02f7dd406692bc46
+16bd1986e5d3be72916faaf1af577934
+16c51e5074d2fe489be90920ee8fefb0
+16c655d1470b1cc0b6f36cfae3a60776
+16cec97fb27cd6b86c3bd0edbf0aaecf
+16cf18cfc4100368395763141c332493
+16d098f6cadd7771099e5da5eaf623a8
+16d18b7d97d0e20f865cd29094a2fabd
+16d2847e2d7389b4ec52cd05e8accc7d
+16de208fd4017270da4d8bfac06d4ec9
+16e49c6dc0d4f40bd462ca8d1f9b3e00
+16ec3bc5bb030defdc3cfe85fbb1277d
+16f1dda6837fc0057318d2a171a6da56
+16fdb8e82fa2777b4fcd52ad037fd17e
+16ff468abc517442af901de06a035a7f
+1703d79fcf1e16958d69f92b4e9e0fa1
+170f631d7c7e611889d38fa6ce44e3ab
+17131a6929fe2541760f5f5e7d69e876
+1719dbde647e658d4f7ea3b2f35fa41d
+171a0814698c7e8fa2d890544143ff27
+1720713886ff4ba7fa04c1a97def968a
+1725650f77a713f860766ba22c15d916
+17287e67922d9f23a657d6834e3ec420
+172b0a0c079cde02cbbe16651fd57ff8
+172c46fe07d782e2ca49f5bd398b8174
+172e88e363438471be93b2bf996272c6
+172ee161b2d2fdd2f8a55ad960e573d7
+17332fb7b388d3ea1ca0fb8d3e00610c
+173969db55601854c9a01d48087c8dd4
+1742156f90b313f703947f1564b4b200
+17421db1da34bb7af83d712c1cce34c5
+1742f826ae6ae0350548e84a8fa9ce91
+175b421ff245894f2ff54cacd138d706
+17615f40afd0291bd471fd7f066519fb
+1762f6dfb5a659145c65238406d5cdbc
+17707376046a2b17f66b30f571e76fd8
+177c24702979be311fd74c1e2b373c18
+177f24f33529cca0708befea74693dc9
+17803f1148ea883641b9c4e96f4cfcae
+178076f0cd2668c1a19e460fd1bb2453
+1786e1e5dcd5a8c5685b0525d93e19fd
+1787ee1fb4afd597dcfcce3d549bde31
+17887d28284474c6224e6b07ad2a3bcc
+178aaa66599d744f416099a5dff36bb8
+178c4a76eb34640b1cc53c9d3eb5fc44
+178e28e5d80ade2ffc49afd48c4600f4
+178f238fdcb8eab7ac8a3badd7f81962
+1792ae1c220d60771b29e47391eac1aa
+1793acfca93b8f383cdb788168e9fa3e
+179576f743f3cb628a0cdf3444d73815
+1795bbdd1aad8d8ed5d1f5b19a828f01
+1795eaa4c817baee58ea099bc752c371
+179e091ca936927772463eb22bc8df8b
+17a63ce5addd37f85c9a40dc4ccdfabf
+17a8d978474fda69b1e4ea99029cefbc
+17ac9c171d92848138b92eab39721394
+17ae1457d0a54bd1ebd74b786bd74581
+17b01e3f8e23a7e3814152489a87c3cc
+17b6aab771131cb7e07164b5453e83cd
+17b85ede3124dccea9fa36e476d18c07
+17c6541f029115cde6c5fc13bc1f9946
+17c7f71d4a7980177e7ff1b13ec4fc1d
+17c874dba69f0a67aa1bf9aee7538d5f
+17cc714e7b341f196acccbd37b7176a2
+17d67aa0b9bfeef7c85526eace1ceda9
+17d8dd81c78076a1cfa6d7cd7a90dba3
+17dc4d80abaab61218522d947a22ccc3
+17dda51aa78a5f03328561b716dda609
+17e0b6fb412720ddcbef59af5cfd58b7
+17e3fa62d575d242452c5063a38662fd
+17ec633977e91f0e96fdc713a499ceb6
+17ef3da9a794fb25f059e8fcaf895790
+17efdb11ab0d4dd6886d660fd9c37d43
+1803288c0ca7c15c046cf6e4dfd34ef1
+1804af9ef5724726509c35733afe00f2
+1805599f3644e85eb61f5088cb5bde64
+1805dbeb723c2e4ba646ab7c51827b86
+180da230860d49513f134adb28fa88de
+180dbc03b80475589ac6581181e082bd
+180dcfda05a3982f933d7094e5726e6f
+180df21db7881c77d01e6a8c10ccfef3
+18106a7102d0891150702c7dff9c5431
+18156fdc4bee4c39bd4b9897a8c52be7
+181a1d279bd5b6a967f855c1c23b1aac
+181d72902b0583970801f58c0b48ef0a
+1823896127491d5329dc5cba7f7748cd
+1825ab263f59879af4166e9c9438b9d3
+182c1a1ee7d51988209fd100ea4e6c31
+18312801be5f072f1229abec0aa6c3f7
+183a8ddf77b7c51719ea237c917f34cd
+183af19306f11248d5611c4502819c5f
+183b584c4366fbae04e264227db8d57e
+184166c21cd997a8bac69a9b787a833c
+184bfdd3aa4119a2016693d6e2049827
+18536a5ce7522bbed131daf75e16896f
+18570799043de652241ea35ea2b9576a
+185ebc9f05dc1e452349634ce67bbf0a
+185f96bc26dd88494593800856f946fe
+186092b63126e09ba178fa04cb9adfb5
+1861aacab14559d0918ca809e2dfe677
+186a58dd6a30a634edef45c791598f57
+186d0979c5213ebe9d19fcf539959db9
+1877417a3f887d1df90854c7d81a8100
+187a15a1e1786e07b1923354eb0ba960
+18816d625e5ca8913ec24bcb2928f983
+188c59a02e4e8ca7408594fecccfd10d
+1890ca9024ecf1e921e6fc37a41ea2f2
+1896c58883bea94fd477654286c1150c
+1897586300d7aa4fb06850e982e96bce
+189834b3a461cf73c36c88da18cb4225
+189db1a5dd298d7f865e3560a279e151
+18a3815ff20567c0aad6b4c73aefb7ce
+18ab15a9d35ae0dce67d2acc90ce298f
+18afd2cc721bbe772c84b2650cbf9400
+18b03fd564fcbc5e1daeb30864d170ca
+18c01979395fd21aaa1afd30b1fecaf6
+18c0cc78c51c63b2c74241c584d19aad
+18c5413cb8158c421e6029c0f7f79111
+18c5b1418410fa1211704271fc70ee71
+18c5c1ad2cb0ec25154852f0868b4ed8
+18c63ad2c9700cd068c2417e80ad9cb0
+18cb8cbd24b6f13cdc235b29aad97921
+18ce1eb58f8c3c8c1082f8bbb5a27f87
+18ce329c0f3438528ba85c785a7fa98f
+18cfffc3bbcfe78c41409460ea16bc2d
+18da3dcfaa7db1074a36859346069f2b
+18da4e60f5b621a721c9f90247911342
+18db9cfcbef320b40e6fb89a9b034bbb
+18ddde4568c661bb38f04715f9016221
+18e2a0cf77667d81beb0b1e002f36255
+18e6e01ab534218902d91940ed943cae
+18e9f101289de43de9068bc89e758686
+18ecdedf836c0d37f33c169915c1384f
+18f35f49a2bba9c775c3f002ca5668e3
+1900a8f9d7434cb34a09ac3d66147bd9
+19017e667bddf9d2f2091dc0afd29d90
+1902b2464d9b891d6768073f9d9d834a
+190360c42290149ba02180faf16a375f
+190438e79f64c4dd643d48dc0400225c
+19089039f06140c106b099e80294f132
+1909815e1536eb7407d31dd252ba2d21
+1912d9392f3bbe63a771a8f4c31c6896
+191876a58129c9483e17519d19c3d758
+191c21d50fb34bccea75a9f5e0085e2e
+1926a6fcc250e6f7d4b22109424537b9
+192911af7fb2957c61f45d94b3d7b053
+192c99e05318b118af317d6d1253aeef
+192ccd2bf255fdbc832fc964ca0c396e
+192d4fe87bbbf20ae0b4e5639ef67e7c
+192ed1822c339b11e09a6a36e4dc45bf
+1934663bcf5c19c18cc1bf04a10ce240
+193dc416c4e5b5fa6a8116ed7c86f681
+194272625a93c44d07899561222e41ad
+194bb396b76510eda54dd12c853802a2
+194cf236c5fa6c6d71346ba98ef2b797
+194e41e4f4f4d64e8a8719c636a0a20e
+1955b59f64ffa9c32ff702a8638fc0a2
+1959c245eff356824f2fbbc5623ffb54
+195a4130b747ef50ee69052e6e134adb
+195cc6401325aeb3998b559f2a0220bd
+195e7ab75343cd74f189756242033fea
+1962f538c584b381d5066ed669e6b832
+196e078018412bed69b9233ca6cb0db0
+1974494ba4e1c76ca572743a61c84a82
+19772a3101a1a5bd19d0d1ae4856cedc
+197a593a9744727341ad4ef449ff03ed
+19845cab3fc6f8f2d7db6cbc7c443de9
+1988e0aae55d4ca1f51706149fd0fc9c
+19902069923ef3e93b5ad54535ecbef4
+1991872163abe6df9500e18c2d5bff2e
+1991f9431fa7498b37d2d1539794ce63
+1998846cc14a849f802ec3183093ca76
+19997b58a81b807e054e0fb466ced908
+199d36a4a8764626d01eda0ac9bacf6b
+19a0c21daa8f2a26a2cd3bd3e1bc2b84
+19a377539be0e8b60fb5791be5985121
+19a5790851ffad796cbdb8199fc519f6
+19acc4e18058f122ec9b7633986a0237
+19aec2fb6e254373f08d4025e61fa328
+19ba5bc118a0293ec3b3293c7c5b1614
+19bb48ead70293f636e3cbc733cfff36
+19bb7c8748b4c21e13d5c6c7e98ba2e3
+19c1207538456454633c4c909befe3c8
+19ca46dde9ba5371d98c5548f88905b8
+19caf2332c229daf71260d7c41696cc7
+19d9ba29ab67d5bae320ba050a79f91c
+19ddd135ba48848513e1d18f0f61bd4c
+19de5e4a710ce7a2c9bd23068f1e214e
+19e2bebe5e05d67c34fab2f752f94229
+19ec68da2e744f0b17628f3e45b1a436
+19f3c7f25f0f36f54b7cd2868cd420e1
+19f6102477fc6004da7865dea8234a79
+19fac42a1160ca4875a65834aa011a73
+19fcb848f7f3d01f823e6411f3a1c4c8
+19fd7efaf11e8703b6cf436d7b250469
+19fe8db85e32328c58cedb30c07cc9ee
+1a01c67ab5e1e6c9dffb85ea2cde993f
+1a0254aeea56ef866d3b93eac02c3360
+1a044a9f10165a4ab603e6d37475f736
+1a0c0c367e4460c92fe1313c535d3f2e
+1a0f75092f4a1abd59067bc2cfc38156
+1a13d05607dbe47a0b743c69cca03c70
+1a169f0a2150f5ab8bfc02a2d9acca46
+1a1778c0f5e59262825fb3617a93a674
+1a187efc5cfabfe0c6c4adc0a4b2f847
+1a1bea0bfb0ebd7205e4c9fbb2cd0890
+1a1ea60abca15d6cf161416bf7f96156
+1a297f2fa67c45d4401545471e094993
+1a2cf37cabb44379dccb3f84a4adf420
+1a385044b5ba443dbb80659102fa6311
+1a3a93dd9edf2f6c365951c76c8e4145
+1a40756fdc2db70639cb022804924ee9
+1a47ab0ac3256b384127af5d0908c34c
+1a4e2113fd1a1c6271e0f55a9ec5c8f0
+1a5e134b2176584cc633ca7e3aa30d71
+1a5ea3c9b56368e5b22906569e050b1f
+1a5f3f298cc32b343b38d73ae9a4b4f8
+1a65cd1ae88eca0a13924dbd2f0f0292
+1a6c04adba6f524daae4b8137b178dbd
+1a6fa34ae2caa439db47aa2d5b90425f
+1a71e80eca75511850d7e2c592c0548f
+1a76cb0c61522ab412f073428ca9a8f4
+1a7adf7afabcb46eb94fa53b7d27210c
+1a7ce9a33f1bac4ffc564cd8fe8242a0
+1a7fb060f907fbef4f7b533d51be0528
+1a8356399356c12f4acf334fab63940a
+1a94a0cf974e2df1aedd6ccfcdff9449
+1a95429edefbf7281402a0ada795746e
+1a97c27b02647ded320e7940fcda44b7
+1a9d47f566abce3aa4f413357d7f8709
+1a9de67ae1b021261a4a38e230a80a41
+1aa033a9cd258b166ff38abbf3ae54dc
+1aa84a5f4432a1661a5b473f5526fc83
+1ab069898a2937047d73490f99df05bf
+1ab59403628e422131eefc856b022e55
+1ab639dca03c7c4c87c8e10c9af59ed9
+1ac3e703d0718eb0650da68f80d3de6b
+1ac71ef9aaab8df4cc3c9d7af0955c28
+1ac7d388c0360162b37d0b3459912ddd
+1ac7eb9d3b6f6f00f14afb83636c1dc5
+1ac92eec816e47d71593cada5d499b88
+1ac9452cd4a9c7f861edf63c7862f416
+1acaf1b0a5ab2ead73f1763e822834cc
+1accf87c2605c915579c98ff7042dc11
+1acfa360f69e7a8647100b77ae5deeec
+1ad2bfc1873dbd2e1f08cf392f70aea4
+1ad342b64aed9975aacf1d049868a363
+1ad48594361aa150481b5d05d9a64ffb
+1ad7b78fe59a95e7c37f10783ba9cf91
+1adfda5ca096dbad40fa9bdd70b78d57
+1ae074fff7107c76a6a6da7a4b5f28db
+1ae22dfddff25f404fa51bd876e69c4d
+1ae4fd14d6c7783fd3399a8eb96b4a5b
+1ae91064c5c9feb1c60959215f718fe5
+1aec334259366b484628612bec1e561d
+1aece368e684a29f960be6eed0d12498
+1af0026e7782fe287ff1ff952727e62f
+1af0992adf8f1afa92ec197da728c404
+1af1a7d4a8f4a38eb911054da9f7a5c4
+1af2e9e9b32d871f56cf5600896a51d3
+1b0fd04acde07874ef708acef5dab48e
+1b13936f76437dc9dcc0f4aa0b635ef9
+1b14ebdd1b605232207e6823907f07ad
+1b1841b7ad588ce3a0db13591dd8257a
+1b1dfa23dcbe3fd21ee09755e311f933
+1b1f2d53912a7e1d8bfeaad27cd3c846
+1b204bf3f15338447ee4bd6bbafcf6a9
+1b235d919cfccf21f02fc9700260edd2
+1b283340ae51e0355717ab0ba757cc05
+1b28b0d954d32b0368c7e237dc5bca81
+1b2c987f2d479c1ed2a6c8127bc31fe5
+1b30d86924d267c98490944d853efabd
+1b3136218d9e2149c98fa525a15cf905
+1b33793abca22da965835fc6dd1d5c26
+1b34b47a399c0d6d5a8ee25c81ce0e1a
+1b385097ba5788f9e8c4587aebac41b2
+1b3cacdc72cfb7d138775b4a4570ed75
+1b3ef39821ecaf051e342dd03c912cb1
+1b46b439e42b350335494156001622ab
+1b4fd7148d75a31bb0339f44059a49e7
+1b4fe7e47b5f57818a5419d747c56f74
+1b52fd835ec549fd28e8eb5564e77b5d
+1b55ad0f9f08f47c88d9f6f2746f7207
+1b5b63cb2c425cce9138d297e7abf547
+1b5feceb0c23b752c1b95af98babbc51
+1b6039811d8fa688205942c74d462c4c
+1b690ffe6531701026ea9fa9f4b37ec1
+1b6b4bf1173c88f2239d492f9488fa86
+1b7416bb290b9c0b79032616ecc1ea67
+1b853c23773ac4561e18abed9237ccef
+1b88b41602236b6f974e1eba0e81f0c6
+1b8c70346132d9192f2f0481c6b4072d
+1b8ef3c117caa2db9c9db567bf0ead10
+1b919afeb0c276d77929d6fc786b3b1e
+1b9688a9eca2f3ee4f93dc62de5e1421
+1b96f7357b58e1f56a8f73cd96732b0f
+1ba0587a640df64c7b7d6dba6570dd35
+1ba1c66a3f531ef8c3662ebe84e38ce2
+1ba94b5ba0cec79f0d1be9e5fa57b94e
+1baae12a117a5dfedf40990d32d6d63f
+1bae7027eef30291a99486be148999e1
+1baf3d722a6c7bae89dc451862e60095
+1bb3747f571b3a1333838f9a2346c054
+1bb806d3c499ef2acfb75029e3d3cd84
+1bbfa2e118096dc92cf2fd5c50d385f6
+1bc152b63df7db6220f4555d5e3c51c1
+1bc2de3e1c5db99546ad364247915581
+1bc53eebe47666218db66a17876a60d9
+1bc6d9134ece43b0c97116a1a55b6456
+1bc72125feb6c441a6d395623cf56288
+1bcb4c5ee51202b5bd6bc7ebb9a337a9
+1bd31e13319b3f381fab316f1af82fe6
+1bd95d8d69a9100b567070e64cc5e8f2
+1bda7881dac87f39cb37fea119cf1cef
+1bdbc6d43098f58b03a075eca06acd6d
+1bde2a672af7cb1f63f0db89d5c489d9
+1be224ce01786481b8e0ebe3a4d946ff
+1be3f8fa534948e1ebab7960bf17ec15
+1be86e9f3f5a4c2709395cb0ee9cce4b
+1befdcd830978db67982ca8e72ce5569
+1bf4db8b3b586f04b54ad6275f2385ff
+1bf725e66e16541ae0554c00748e267f
+1bfa1f3f2740f7aa14ef878683b241ad
+1bfde0f2f2f4beca74c92a5f383fa987
+1bff523507a91da1f736ecd1375ace47
+1c056ddecf128240376d17e61d9e07be
+1c05a35ce5fce0c8f6ae76b2aaffd571
+1c0d127999b8d722c509d67a7d8033dd
+1c1684bb2f563e35ffc0956c38fae5db
+1c1f87b36710b936f8e35a627add2970
+1c232736d64f5ddc442ba1a034817884
+1c2362cf32af486ae9319fe3e48ffffe
+1c2875e9e1c0b1d544fc4453c6cfb688
+1c2da2ade9dd899e1903dc5bf30df5e0
+1c3352ac3bbcc3e8cf07c9324e5b849f
+1c37c2212d44fd6079810f5fa50b4903
+1c37f30fe26f64c56241bb1143c4923c
+1c398b221f95964e38853677b94f9632
+1c3eddf025bfbc5ce3bdb37cc9df247f
+1c497d8285caf445c52794b6398aaf6d
+1c516d0ff1dbf512a0768dc247abd6f4
+1c5269fc85197c035bd801a606bf9055
+1c551b3670c8e72e28751a67de1bcd13
+1c5594d6c9db3432bde9efd85dbdfa80
+1c5729c939d2063b05d9a72a1b27e201
+1c5ef6ccd1e1a2d6f7350436bb0e1245
+1c5fac493f96a637d4b0c9feeefea6e8
+1c618506efa9e8ea391aa26875367df8
+1c6413b734ac7d14cb2addbe77feb632
+1c65b34377434277e505efd75fa75969
+1c6ba63c761a7a045526bb475bae8589
+1c70b2f4a393f5e86041637b0c31ec6d
+1c710c2c983dd83979f4f3deef18ca46
+1c715da6de84525422b3096c170dee26
+1c7b97ad8c276ae98389ed284358d062
+1c7cbd22af7ced0364329e9cb5cba809
+1c886f2bf65aaf547a6ffbdef9aec99f
+1c8cf4d4d88d53bf15e99a9da76a57fb
+1c8d25785d3007f90b358915aa4d1385
+1c8fbbe22c8752befeceb140a81103cb
+1c9105247c94d44c450a587ae06e6b37
+1c919e5a1e92b3c1d60a9642893e197a
+1c922914fa6cecdef19b9b9edd99fa4f
+1c95433068f16677ee11bb629d6a9a99
+1c960239783e4d3b64fec91d68d0badd
+1c9ac3437e7663be7ed6b43dd01f9495
+1c9b7bd554497d2676178fae8055506f
+1c9d33faf8d714dc4b28269f8adade1b
+1ca40d41f385d8fbdf0733523d5fb34e
+1ca9c427590bb10dc904f4ed435446d1
+1cb01450c502d3616e28381eaeadd802
+1cb1eb1827f5ed15651da7ee49d0a43f
+1cb249dc7d64a73ec89028c8cc87dfc5
+1cb2605f2eaa29fe585e301148c8f3cf
+1cbb3cfd12e92a59a97302365a9e61c6
+1cbd10d74af38249f3de290787a89c4e
+1cc2b8da4df808ed5959ba717b8a92ff
+1cc61a9cbdad1b3c29c8d3d08913e47b
+1cc82340d9f296b33e8d367de663ab7d
+1cca1fd853689c7826d13076e11e4431
+1ccb62c495f377772133c0c9674141f4
+1ccd3174253b38c5151a5fc14a2976b0
+1ccf15ee04a2091ea33c2b0c74b75f85
+1cd49b31b147cc07ad8f64d1e3a3d270
+1cda86ceae26b5507188994d94519cc6
+1cdc8aa61c730aec3cf03955ca00bc9f
+1cde52aed850784ffbdd1f8bdd74d6bd
+1ce0495e034c795ce76a0fbe2fd236e0
+1ce9471ffd1d5ca0d64e2ace51bb898b
+1cf3a97b0cefd7cc2126e7f58d3c1f70
+1cf633948316db9c050900edbb44ea97
+1d03362dee7f9c248d13a60c238d9be2
+1d093a549c4cffa9b472eb63fcf54acd
+1d113f1a32f4313fff0f6aac13c4575e
+1d15dc7f35d3e44a01685a123be846ee
+1d1c564c7540e0e9ba5eee1b487a28c4
+1d1e5b5369c5734f2ffd7f971b4812fe
+1d230f76154536dd1f68ab2f9d94553a
+1d251fd31f0ced1e680e97084329d84d
+1d25762d461e3432f5f5e781615aab16
+1d28843db641dd89ca75b98d70b75c7a
+1d2b64367fc03f3647c7aba242e5a4da
+1d2b6b00d8438aecf98c0a12838cd04a
+1d2c7d438cc938ca3d6c9ab3db455869
+1d2e923d5aec3f551f1af6687d91bd06
+1d2f1fa013cffa1c95f4617f01ce96a6
+1d3390f3dd4d30eaf8b1795b40db4b89
+1d3b6e555acf6adfe9cb5c7390df5926
+1d3e18d89b0e3617b20e0060c7a1fa0d
+1d3ee6aaeb36b1b6973bb6d074d3209e
+1d41a6eb4f9e4783b2d13cf2d6da6950
+1d42e861a607f14727b5af1aeeea9b71
+1d49727300e7f19e60121378a351a87a
+1d4b649158da2ee150cd332bc2f2ae6c
+1d4f5084c9eceb6a63a6a74a3f7f8b42
+1d54f169f4edcfa01f4ee7f7b1287a89
+1d5a6f8c98e54b657cc89c2c344bb03d
+1d5da16226e76fcefe39b336834f0628
+1d6424e25837d4afb6cbe38b0e7be785
+1d64433723d1be38c672659fb40d7eca
+1d67faf81e82e8b73ff431536e43a761
+1d6b0fc08c47553a03d0c7e78faef0cf
+1d6db69c4426fccde44471cf5dd99953
+1d7184ab8fa4a330f79a0f254010d49f
+1d75c3e5c64d36238067934a6b5bd8be
+1d8e8854d2e87238703ce83f6f7f605e
+1d92a0dec1df93b48ddf595638bfd586
+1d93724eb1e515074b1651114d9245d8
+1d9724b750b0fa2c2a34f6786f07b639
+1d980f1cbfc30b9eea016167dced928e
+1d998d315d622aeaf10e54d3585fd681
+1d9c43b62fd15c4f4b0430498564f8d0
+1d9f1afbe0793fdf9dfb526c4675ba1f
+1da0ff3e8fbee38693012dd6c906e947
+1da3d71c665b0aadacf8dadae4d4b0dc
+1dadc146b6bc628c1d66c7071e2ec5ac
+1dae85d53e737bd8a34a948f265aedce
+1db342d235729696dcafd2eba41db532
+1db604f0b901a211af979cf531431c84
+1db912bc2322243cbef3eeabd1f854d8
+1dc99153261feaf63cbf5dc9f782ce86
+1dd24ba91686e38ebaf24820e2cc732e
+1dd70d8cf4f829bf9eab4b941b03917d
+1dd724add6282109fe6c7650595a7a73
+1ddb0ff48979909c18123eeee432ae59
+1de18c012861b7bcf4334866cf41fbf0
+1de33607694a3b9be33343ff34f6b291
+1de362cd4f99288848567602d594cf8f
+1de7e5d935426fe821f311d88e8e0058
+1def12276fe95a74b8345b116a3e71b2
+1defc991dfd4c163e8add52ed6eb2367
+1df269120c7a5cd845673260c80e2ab8
+1df7211a6486e05f99d5a7e2142fa3ab
+1df7c7ff22544e1dac957ce8779753f8
+1e0297bee028ac32910301155e420786
+1e093a09a24e806386acfcfac608f429
+1e0a5a5dbb2041e52ea407ba4f533dc7
+1e0f80e16ae145434f8c411a8e2025f4
+1e10e07eac2601652f77c516469045f1
+1e1328cc61b477c6c7c0ad130f1c561e
+1e13889a631af76f8770b148f3266c1a
+1e14bb61524e306e8e4d95ac6f804141
+1e217870c90d609341159a213004b0e7
+1e21d46852ff85c1c99badbf74e937a1
+1e28476e99f08ffaea9957a6e81a40a7
+1e2a5dd5dd581d7f697d049aa6cfffe4
+1e2d473d061b25cbacadc8e81b2a737d
+1e2debbf7325a740ffc65ec5b98058a9
+1e3742b2b5b20008e07594c897b991b0
+1e3f07e2a69769822afd77b8515f13d3
+1e3f9f5412761923a856b28ed16bc5e3
+1e41a9c821208f4af7a957e3812ad77e
+1e43313fa63d297fd45f96477a83354f
+1e47574802305db99ae224a79458d9e9
+1e4ac082845408c34dcfda95d2c3853a
+1e4c3b9aed6f93702643a6fd87cd2867
+1e4d7ab62a626d55209af7ada24749e6
+1e51638207155f1b9574f6b635b5a5cf
+1e553bb9b50526a9c59f30dae9eae9e7
+1e5a03571a2f8f8788096f06f5c3f683
+1e64c4d325bad7977fc39ea0d37e3c73
+1e6d9ca2170432cb1be1ae70c656440d
+1e6eaaa5ff3c86fe6af62693a6d68fe8
+1e6ebe60d467d8d7334a5cfbd9d88c40
+1e7114a14275a88ec288dae33b2a7f8b
+1e7974041443baf74d83e32c3d60321e
+1e7b229623af66dab3543e37427ff9c3
+1e8551fb74cc4bf894b97069ce846660
+1e877ee8ee6c5b8de5aad7e7cd53669e
+1e8a719dde67b68bdd2e68cc285b862f
+1e9ad85ff554cc626e469f94efd8c0db
+1ea168ce8ed19889dfb190487cd9a2b6
+1ea16a31e720d66a4409f4d7f8343655
+1ea4c69fe4572133e7e1e438d8a29c56
+1ea682506f577e3b1c0dcd67243b13f1
+1ea731e70b02b7f5c3ac9bf856c6b2dc
+1ea8bd89f2c3bf3c77f4f264f5059f12
+1eb2160221cd2c9bb9785f8f0820b5b6
+1eb5735e68b5a5d0be1876a336904235
+1eb7af774d4ce0724c4c52433b02f358
+1eb801b4833ca880ffd79949a4ac4551
+1ec2cc2dbc77269e3ce151c3517f8a43
+1ec642f8fbb3456c881930c8275bffc7
+1ecd01f763f5b00d23308d24369896ed
+1ecf976041ca155272ab6ae013dfc8ea
+1ed7d04497aa7dee308afad340cd490e
+1ed8225193b382030853e6e9c376cdfb
+1ed8817d5a9c63e14e3b6205a0cc8bbe
+1edc8beb63090ac1b4e22ed775019438
+1ee226479d8e600cd32246f8ef35b53b
+1ee3404f0f9d964a1a30303b1577a0cc
+1ee50286387f81a0edb45a071809b6d2
+1eefa30a405be0d9a62d0dad0ef5723b
+1ef1a84f486dd0825bb3daf6cdfbc28e
+1ef23cd90c7c02d7fca0a65572cd52ee
+1ef6198f69484acec70746c6fe730c2c
+1eff1a13b0b03b30a7193bad98ec22a7
+1f03f58d9c5fb2b2bd8aa7967687df26
+1f0cd802a6a3eebc4441d53aff8b794c
+1f0d66b723edc83d56ebf38444c7c8e6
+1f1100bf4e86aa6af9dca73aaa190813
+1f160194fab2a1c32d025cdd751fea50
+1f190c7faf3962f1f33f6cea47f6ad0c
+1f19ccec4f55a3ca8ce06b2faf7fd68e
+1f1d15890a5645b58dd16c7a60bdb1e8
+1f25672951d3b2383024840476676a09
+1f2b24f2abc92d254ba82069ad8166f5
+1f2b87fc650ff9f6c8498231e59c34a7
+1f2bf3145738bb3ce94d61911148101c
+1f34b0e8947185a35569e678a7059b3f
+1f3a2b11291a4c47678b4b59ad951c29
+1f3c7724d1e6a1206e8f4842d260a9a9
+1f3f99b3ff42831d0c28361e6a93d74a
+1f40bc7eeb38233be81f9ac2245ebaa5
+1f43a543b36eea7593ab5949c94e6b85
+1f4607ecfa8af6e93f86a2619ba0836f
+1f4dea72fddf6c9b2b54129ae4abc37a
+1f4f8a4343328d083f652e1da31790f3
+1f500adfd6fefb72863290ac89b76492
+1f51e18cd6402138cc6482f53a4e09ff
+1f53cd4a9882d09d7166287fcef76a60
+1f5a6ba0281ebc175462f82f7c873364
+1f5cebbcb3842e618f74c5170a002e06
+1f5f8a866bf173f8fd0f8da0dfc8aa0c
+1f61cf632a076ecf0d9dff5fb8b86434
+1f627025040b65fc663602cd2164ea24
+1f637206c6e9fa14759fd616458db31f
+1f63b3d3a035fce7dcd90d800a589b33
+1f653e87ef27690ee6860680bfffe413
+1f65bb2eb5e57613e896db20992ef190
+1f6e99b3e05a25685eb3c782252b4166
+1f70917b1306deb9799284727f17ec02
+1f87a2b3107ab515439bee42f107ba84
+1f8cf64d9e7bf652ca0385b2783ebd2a
+1f95f0035781c0a8238260c1f2cbf19a
+1f9787a30dfbff8dd79243076ce83920
+1f9a3554b9fb62157c3b777cd71588df
+1fa1a959ed32118bb46b295cfb9bb90f
+1fa239fa417be0afa0743b70f3c9432f
+1fa353b33d1295bf35ce85d3b4f3b7b1
+1fa4bc65b1a3ab94db7dc47509bfef0a
+1fa4d9e192fbb1f457731596d69aa1d4
+1fafecbe6340890b1441b90ce823246d
+1fb551ab1ccea36eab643176b69ea606
+1fb7238403e1fe0ef5799ec4a3a70c6d
+1fba69c6f45869d5d4a51a95ac9e4ac1
+1fbe3bd6ebe509280e8038319de6e2e8
+1fbea2b833320d83c6dcb3846a4cbfe2
+1fc4fb26f96dcee4c6ef5e2217bc8b0e
+1fc56d40897af19058724fbc04b6a1b4
+1fc636ccbf7a8371cd2951150b8942b8
+1fc888f07db1f2dec62d51a6d2f8d59e
+1fc99ffaadd93941fdfbbff16145ec39
+1fc9dd836297f81c95b956305fc13799
+1fcf9f7ebc0bc0081d54875439dfdec9
+1fd0dc463a6a66ee1061b0cc71300175
+1fd7bb7305292bfb8353984ab8d3878c
+1fe21ccd74e6a0438954d315c3361987
+1fe24480b788af42cb93dd86cd31718d
+1fe25d4cf3901de469c6f131cb96b53a
+1fe65f4d6573e6c88114fc41b2b25568
+1fea5eeedd5f3b330dfe8e6b323bf42b
+1fee62b9a5de5b338546bba878a11de4
+1ff183725fbd56e3e3415a790b6626b2
+1ff694e808e1086f0750f54e91f1a89a
+1ffbc23bdde457759a482961ffc5bf13
+1ffcba1bf87a28d40f48efebfd54c7df
+1ffe2349801d5ed45c7d0f8125271b19
+20006027dc6c8e874a6e3fce657d33b4
+2000af510b463c1b8d01f2f57af431b0
+2000cac5beeb011000593f38d5a58d84
+2001a35d123e58891736e86a483c35b2
+20119de668caf13b4e0c1abb9a434c63
+2013ffc0383bbb71c3caff9975934979
+2014d22b3bbf71676a58ce850a47ba5a
+20189ee29f02bf6b281771df2109d07c
+201a8a1c94752c7b8b2f9330ccfa4e86
+201e8ce91cadac3cfc11c556770cc992
+20287b9ae50d85e4289f91edcdc70c7a
+202a8b4b8c12a4922c4fde3fdb71adef
+202ae6f0e145e8a9323db327579477ba
+202b99966e26b61d4c68f222af0435a5
+202bf0791ecbd1f881cea7afa2398fb1
+202bfef6e601913de679a21048a6de91
+202c14124dcee02f37f7b91e095c7c30
+2034b9fce7627cfea69eb1f3fa163295
+2038239340f5e02b7979e318a88f0427
+20392ef9b7ac54af49f27b23b44da158
+204640a0cbd1456de2b632d1a89c1e12
+204cf58d7534d47b943bac5420707e89
+20524d35be88c5f4ac49ad675f9a62ed
+20677be66874e0c1f63257fafe99d66b
+206aa967e88dd8371103ee7aceaf1f7b
+207945ca6be6e1250831830c63b4dcb3
+207b50f4d1a482000024099ffe686e46
+207dcf29afec40dd80fba9e5aeead9c4
+2087861fdbc74a62ccde714ef4b46e4f
+208834852f0ce19041587a3c76dfcb0a
+208dad50e08591c182bf4449ad24469a
+2091975f600da36cd57572961dfdba15
+20929e5ba39b5addbd75f860117c08ca
+2093238a89860a433f2af0ac0825430f
+209664647ce54c6792d499f591fe3458
+2098a79019f7a7d232169f542c66f212
+209f00a4ef5ef0b9b643e38ca95cc8c7
+20a0bc583849c3637ec32fdace214ccb
+20a2159e2ca038a849c724c24f82fe86
+20a2303a3828632199cc218a7fd6e7a5
+20b11650ba84f35c485b95289a513eb6
+20b1ca27e7fcce228155e2568b1e68df
+20b5d00d0250e34c3b92273ebe8d9eb1
+20bcb5fc662f506641d99d185110c334
+20bf562f3ef2efb63d53e524993499ad
+20c27ade1612e6044b4152a14711a5b5
+20c3c7b77fb89ca2fdade9d3b91256b3
+20c8d783df09b7732205eca0ab61a290
+20c8ec4638186311588ac1a2b6d936a9
+20ca76a6cbfc04553902d48cf19e7ce2
+20cbfe99d235ed8aaa3aa5d5b6653a1c
+20daaacf2a1570fdb14553a1e7869d4f
+20e68e032260118f213f74a0c0abbe70
+20e8bfd020534a60e9a7b8a62798bf11
+20ee76ee11fbb081da4dd41f16b7a294
+20f044289d25841df804ffae7ec190ea
+20f1c10ecca57ec94722f185fa45f27b
+20f6071143b69164a6b12677afae0e0d
+20fc88dee0139afdabf910be234cd9b3
+20fd5e32bc2c8022d34200ba63f0a12e
+2108e841862596ed50f7b6e2233fd318
+210b2b57300d6e8e729c06bb469cb6d5
+210df0a0d87bb812040d2f61a6035863
+21114a4f5159b4b1fd5731eaca04aadd
+2114e088488812306d0bc211bc050300
+211506fbdf67f649425bfa0569a8431f
+211b9e4f47535e543814e2e5eba60553
+2120271f0a6f66fb686ce9c35e1dbd10
+2125d4b48f02a9984d36b6ab17e2fae9
+21287a3dda3971fad56f4cb8ac3ab843
+212955c95f5366584176ff1320998748
+212f68898a926e495429ae787c5453c8
+2134e86794d48e03fb7d65da6722a03d
+2139c380d775578fb2315f9248e5416a
+214375e016d7bf4109b0889950457434
+214a9f7a71e5deb2b0610861a0d0a24e
+214dee30e7f6cc4b78a40dc82759686d
+215378aedc529e3c4af22303e4820821
+215623634aa18fbe210143d40f46d7e5
+216581cea881b54ca9411cfa37eac543
+21678afa4d522c95b2272df06daf7af8
+216b96058100dd6eabdb01c3b125cd2a
+216e509baa68b228b4c1a08f59aa6b37
+217ada5f778f2bbf79f5c435c6e64336
+217cdd275435adfa7d5a311e8d2b9c93
+217dd0132d1fc622f462ca2476ae4f8e
+217e40cd1cc773cd75c09645c0c56556
+21888c33351e700c47971aee32f6fd0d
+2189d511732a866643a2d6ebabc1d5bc
+218c98bac9546cafc3b835359051540a
+218d6494fa219fdd72b4d562bce2e29c
+219124cf8022941d7ee78f8c22d0aa69
+21958742cd2eb467cf2f8147119426cf
+2198438db54488af0f8d56480d11859e
+219b8277e8edbf8760bdb395323cc23d
+21a122d35e941d21e3f157a90f19a648
+21a49dbd01826abf1c14a25c2d452922
+21aaa995601b5430fff898241729a97b
+21ac935c1e90efe82e29d4713f4258db
+21b2f3c098346c497e57f631b3e2a107
+21b4c2fe3abda803ba7e938e3251542f
+21b6e2cf428705d1f2a7c45a97eb59fd
+21b8691eec484a1001ef6c6b7c45babc
+21b9175529047f2b6fafef46ec00dc88
+21bc8dc0685268e1124924d95e5466fa
+21bd604ceebe9a5410a25d4e37d93c23
+21c085993782c27f9ca675209e409391
+21d0653e8bd58449fa888ba0d2d98cbb
+21e6f9149b06ee1b5185156380169109
+21e80a2fdaa30a135fcb92806d6e1c04
+21ee76d14ffe533f6d094aeacec69a76
+21eec9a7ef37089db1475dbc7b22c34c
+21f2fb1f4a7c3b61e6dc8a8263d8bb1b
+21f985d0dbf405faa5ab43c4e4f318d6
+21fa0eddfd39e36c9ce64c9ff3505709
+21fdab3ad11e3a57f5ac0bc55bcafb6c
+21fe3567e12b0f4bb422ee217dcc6f1a
+21fe408e243c4d89357e7273123eeb60
+21fe68b0bdf74908309d3048a86a2b4e
+22052ff6682868fb0fba1b97e05588e8
+220e79b001eced4cf4de996641b9ed98
+2211287b67cfa7868c55fc07903a21f1
+2214e0beafd685ffd286f79685f0f94c
+22154821c566fe562648395306d622b2
+221643eca3ff5d873b67196a13d91b9b
+2217f79a2dac0708b4cbeea21ee81d1d
+2219cdce6baade40e8ee43123a6131ae
+221c1fecbbc6b8dfa49ec586de2fdf39
+221d8ca56ac8e54f9d75c87fde6deb8e
+222056fd4dec1f4b22d757b3834d9668
+2225198a13b239fbb012bd89da7cc400
+222e9a7fb5071f2ad6cfc7c76de459e5
+222f8b97cf325940c705412675a9a8f5
+223f0e442f50a4d7204b13199549159b
+2240e134d4d0c1eb22155bbf8c57b923
+224d340f88f64bc782dc6195dd81470d
+224ef4476dab2bf8c623c76734fd5e11
+22512044abb7f990d1db39f654c17468
+22550557f6d912a1dc24b76171a3c77a
+2263504422424e691b628f5858bc3b2b
+2268e395bef9d1170245f4f33a026e24
+2269332a1325b2938133feb36ea57eae
+226ffe618db53256a7b8c0fc34f8a05c
+22740457727943a12c7ef53001ae6da4
+2274c6a0d62095ceb2414c27122652f5
+2278e1a9419084995dae3ac27977433d
+227b02ff44e8098029d0994a2f043d92
+227f818ca054d208b9d70807c65f015f
+2288df92a27c1c51ee4efd3e940b79c0
+228a41bfeb27a9f6304e57a09f436771
+228c2bfd7e7a84ad85759059c13af446
+2290d64f65bdc47a0f617acc3aa33ade
+229158404252922cbbfddf3abd60cc9b
+2291f5e5d05d6e0ff78bde9981917918
+2296da092377ef367555af29d1622121
+229b265edc8358a792c842edcaef61f3
+229f4a25da60dece022517ea70a8373a
+229f546ccec9c50ceee168388023d923
+22aaac41e92058d14897d664036a3d50
+22b33495e4a6ebfc1d8fee0736fcb59d
+22b3ee236c7e1cfdbb3af79c79164e98
+22b4f78210d4b2e9991745e484d903b9
+22b796888ca66a235782c3e50ef3f2ea
+22baa8398201f13e019f1853ed79844a
+22bec97dc2c9a956320fe329d029ed2c
+22c849455dc39bf6fedfb81e6b487033
+22d018577687fc844448a5e9f65dbb88
+22e3cefc994d6054b9f102876a5a0453
+22e76b335f3039b491adb374962eabb1
+22e9b04e730e5fc914e0958f3552687f
+22ec716f28470f8952922cef79e4a609
+22fe5a4eda2412c42751cd5f8dc80957
+230096bd2ba463869ef3e6e15b5d693f
+2307ad67acf54c1110d41b4a309dc3a5
+2309ecf0c318c55ef73e7346f042f442
+230aca79247840cf72b70d92f82f2ad2
+230d98dd558ba1f2a193801b17a9129b
+231046f3b83fcb83a6439c9be18a349a
+231277ff5bdab895bf0934dadf1030f2
+231d06c898b565e6d8854c8c9fe8027b
+231ff12c2b315cb59a0fc90f4e346bf5
+2321913d6b504211533cc99dae150ba5
+2324de7ece513677ef8769e422df313e
+2325cc2f6550bf5ac897d079c9dfb3ac
+232bc0fa11b44c18555a0fb9757eb50e
+232c67121a2b1c7044e331209b39ca7c
+232e27a74986d1a245bf908419607ee8
+2330a838ad55f65de8ba7f2b7bc6489e
+2332042a51ba1caa1313b3a914d36c5d
+2332122208b7f8566813837e09e4bc28
+2336eabe3868a237398eb22c546640b8
+233719391657d784007800775b692ea1
+233b86753b509906f1bc9b1faaff00f0
+2340c7ae12c6d23f5e84f65870b966f5
+2340d34efca2d569665032ee663cb7a7
+2341bc76717c9ce1ffb9dba9e446cfdb
+2344b1599a04b45d20b8600b1b5305a3
+234773cf5087d444ad1b09fec68345ce
+2348c9e38775cdd42dcf51b8d7fec516
+234b9143642dfd7df3bb5e72e474cf3e
+234e09fffd188d48f9a013e0a6303946
+234eb78491c23bdc64bb3133a7a243aa
+234f08969319176deefde79b2d7960b9
+2356d6c05dcdce0c76039d2bdc7024d3
+2356e0d0ac855d1365b8f7fe175412dd
+235765941c8999bebbad7b7f78dfb283
+235871d4919be9469e57a48271e4bda5
+2359fda8884a019cfb68e5289f091b56
+235e0f64ea33828dfec1990c97f79036
+23705cb8c890dd647f958df0076064b8
+2372c8fe17572313daacd18947ec4892
+23769e3bb710fe8c9e16b22701238b7c
+237ada752ff3f04bb5874a60e1b4d5e0
+237d93f523e67aa31a494fade3f728ef
+237ed7529cb7692d070bcf6fcc2e4aa8
+237f93eb24ecc133ad949b1981519952
+23849de25e9c080f4b7e047faf7540ac
+238da06e9e1879f89c1b06f8c61c52e2
+23919b4a7638dce6537df1f214b4bc00
+23962194679fd78d420f13955756b863
+239af04a3def39f2f9c1e790beb728af
+23a33686b8f36307233be5fcdddbf169
+23a9870df3c7f5b0ba64da7803c61cd8
+23b05da5869200bfe16e0dbfc1e8dc52
+23b29c1d5a283c225310a366ba6edcfe
+23c247ef7a64371abc0d4a810ef9ee62
+23d1f4fe676a67b0e184d7653ba2dcc2
+23d78de66a3c576fe6f00e93c0505e5e
+23d861429a02b66ca2c59c97a47af9d1
+23e60ddc3be83b07fcdf6ee97a10549d
+23e739991c702cdd38c3146b6c4bd47a
+23e7a20d056f792c3749721cfd551bc0
+23e94cecd2cff4e82bfb36831bcdee08
+23ea42669ba1e40e96285b41c33f53be
+23eb4bf051d35d3bd5c94feb0af40512
+23eea01a8c1e678069947c8acd8cf2c1
+23ef80dcac18eceaaa64e2c937af82f2
+23fd8b158ad0ab97a69d72a2a544a227
+23ffd9a6683edd6e2c34153878587811
+2400080184703f7a90f30cd0cf0ad4c6
+24018266bfbf05093d9b6c99f6205a14
+2403e6252c232ff10e6bb07f367c7137
+24064dfa420cf1b66ded2334456743fc
+240a3df83d58bdd0f09eec7152d023dd
+240a7cfc0de4bee6b78b2164ecc8d876
+240c7e24c2c855a32952c18b1b086f7d
+24132957781be21ff42129bd749f9fa4
+2413d77dabb12ba80341258c067881ae
+241499d31420c56d57a643ee290a1841
+24167fe798a2b4d48ee104a255858703
+2417638409591fe1407ea5933bd955e8
+2417b3032f8eb8bd92eda138b124cb1b
+2422e50110c67f3d05c8f4420439f99d
+24282147d4b97323dc28458e18df2d59
+2433fb0553e870759061fb786bf2a539
+2436c5893c9a61fa5cdf345e13683f79
+243b55026041008fc711d7a85d682005
+2442c062162fe5e2d179bcaae129a027
+2446bddad80663a13682dff5051a758e
+2447965b2f1a5cb02df387c1fcae8d58
+24481c8d08314c7eb7613c12d84181fe
+24499e15186e6cbbcc79384d50048b0e
+244babfbce81aebf2dad6785ea443bdf
+244c6be6f3b24282f91b004a94601e7b
+244d7920546453eb317d06954ee03524
+2450696dfb28ead7c76bb60a3857807f
+2450cb19e43294851f93d2a404a6d55d
+245237f5d3144d4f7ec1bf1c170680c2
+245bdc8f03002ce59dd6a6dd9718bda1
+24634b6e8a6daf7ce4a9f04991c0adfa
+2464d6f38b5513fe587f99873eae6454
+2466d807b163b60d902e58ba45ded1d1
+246bd6d1e23a7ebd2a9dafc3585b2d04
+24752f39435cd3bc4ca81ca6f880a5a8
+24769b7789cfeb91cbd62fbf75be18a8
+2479c5ac4eaf9e0394b284392287d5b0
+247e9a62a1740a9a9a679a1bc4d56c6b
+24833dde6c3b9ae7ba4025599f14925d
+2485174cc1ba3bd948209bb72d340d22
+24876ce2ce6610ed139060433e0de03a
+248a75f425c62d826a8118a459cbc72d
+248dc1e5046236c4c4a6ef6cba0db19d
+249611542af9cc822f4123467e75aa92
+2497c18164dfc8e66277d94d16480a68
+24a1d1ebdf4b8c321b8aab77a503d4e5
+24a623ce9b635314bcd2d07b0a9ac65f
+24a9417837ddfc191f1f38ac1a7865ef
+24ac2a2a4e76423706e71f7b2acf2274
+24ad66e7db37fa5bc0ef3ff7b526848e
+24ae0e243269dcab8a2609eb5513630a
+24b3b8f755c3e5232ec86db982b84e99
+24b7a6e30dcfbf4f590ef27c47f09c15
+24bd5c494d80749c8ad839e9a815fa38
+24bd893098dab55bcbe8f818119b794e
+24bf10bfe00046e04db4f0f85df9e0db
+24c6c55ae6fec8295195e7b4ad4d09fe
+24c8b10945df5e8feca5adfab9854913
+24cd8e084c1e718c158ccaffbfa5d42a
+24ce3a4a3f695b096ae9c6d443737b7f
+24da3462eb9a3d96630ee47e81501783
+24dc58bcca3ab882cdc7507d9a32fe5e
+24dcfc8579edbfad2769bca53cbb09b7
+24dd09b7fad3d6fda2a9d959ff7694ab
+24dd9fff52647a767660da78a9357f84
+24de69b459a9188ecb2ea3b0259385c0
+24e24f8bf4ae7546f5769bd5d77e00a0
+24e2719b7df9f01451bd08a2a6a40405
+24e9d4d99623e716d737018c8c7c4a67
+24ea033cbee64fa0957d73ea7b41ff36
+24eab75a3c370da7da792b351e18961a
+24ee4add0962e3022d8148b7a2c80a92
+24f07b7f8d40ed98e9951610651a6751
+24f0922f413eefabd68dd4fcdb3d80f9
+24f106498a98fbeb132c45f99b40a48d
+24f20bcd80164b0f648406deceb700aa
+24f35bd3c67b5b2db6236d4bb2721439
+24f916e65f03be6d23d9e0a78bc657aa
+25032fefc3ce694c6af6dfe1bc08186b
+250381c5933b06f042297845efc0dbd2
+2508dddbcb5c8e0572ab44b990ada201
+25122c0c6444bc6a06a9e49a7a2a912d
+251a873981de9f79bcd13151ca26a454
+251fefa2995787fb8258e70a8c42c025
+2530507e587cea9af52bb1556ee72e3e
+253a1d66ad90844143dd5e0fb9c26bce
+253a525a91ccf1585d4e5c63e7e74a7a
+2541f4c4c3f94cf767832ffb81a68227
+254558e7172b54103ba7762edced490f
+254f9f1fe3cae4afd92ee7d3a14620df
+255255ad411a3f0f4317902829096d39
+255552617fea2189b9d8cf554931a35a
+255557afb1c78300fd59c743a70e00f8
+25555ed899b93275d70bbeedba521c17
+25582af4677d15cd4d2f5d8585d784f4
+255b7415738d9f0f6da59174155b567b
+255b8e7c14594478abb20423689cfe23
+25607e362f476000d31d85a1d16b80d7
+25628789f0d42c31b2c73d4b8b9e0e8e
+256491631e5ccbbafb0af67bde86ac6e
+256a69c9aaa7f4a5ddc0450edd41cd2b
+257404ca1346cea3e9cb0c4654ade32e
+2576d0a2e4dd55bac8475af9c25df988
+257c3007e4e5c788b508319e7858e4d2
+258639812f8cd09ced7091c296c949e3
+258811ab96b6278eee0a44c8cb65ce94
+2588b7a4d701fb3e009b8c525d2039c0
+258d492746f7f699b7fcfc98443dc36f
+258dcfde5fcb7e0384bf20a472e08f49
+258fda8b168674f29a48111f746cc9e4
+2598f8824fb7b655fb2f393f4967bbf5
+259dbfe47d47a232865dc2c5dae3f1b8
+25a44ec98436a44b19a0476124ad8977
+25aaaff5641ecdd6c34771bcc4b06a7f
+25ad65e1cde09c9d9e4d2375a0f1b6cb
+25bb264e9cc643ba6c5438d448a15605
+25c5b5c7a19a6b654d5fbee1c951efba
+25c8ab525979112e3adfe727bf7c28b1
+25ca459ca305e48ce063ff543a3b6752
+25cba26095cd6d80c3b31c0dd497f7d8
+25d31c2fd58946a759ffa3240f9f006d
+25d40b80e855c7f3cf05fdad772535de
+25d5ca0e3202c2203b3369121c92280d
+25da801e322704450461c999bdcd707a
+25db28637a0da4d2d6c178e32554d1ba
+25dc69cde0007f08217879d0e92c3c3d
+25dd342a7a947460daf1524f68b53442
+25ddba81ccf287c6fa1ba586575afb8a
+25e67d139b32bf5e219cddc63d25401b
+25e7b390f241de5ae2b2a80caab4966e
+25e8e8a5a06ac2fa4a2ed2baa73f69fc
+25f052d952f70c50e2de114f93095e99
+25f193fafc725dc4eddf2e48b7836e61
+2615f035989060746adde494dea956b2
+26169ffba3b71a4c39caee0e4eeb84b4
+262b14ae12214bc4ff5f7794c1a806c6
+262b6a5b98680b2f1fcdf47e184e5b53
+262cae3fd2845956882a0d815d73bd70
+262dd50d0752f1232e50dfca6da0a949
+26303a2fa9e2eb1edada178e1393ba65
+26306dcbcd70900872e49284df850636
+2631175a7b045a37f47968c1468a11e1
+263163056b30d3bdd958bdc486521d6a
+263220f7267a6273d33ae77ef65ee82c
+264001400ec2643cd03cbf138444da04
+264e08626ad8accebe4af504ce469a74
+2651453c24b42b645de817a05f48824c
+2655f16ce76a6870a47a7b8bc77e8fb3
+2657bbedb4082a9fd3ffad475e1ae7c7
+2659431f9edcc9eef4e91f87e050b382
+265ee3126e7ed3ad7416d8fae7b09a12
+2661811c5fc3d0f84a2d2335e90f4be5
+2663d9be4f2a14c32c32710c0e4143ec
+2665bfef3edab07e30904e6525afd278
+26691294c9672056234895cb29fb7b88
+26692bea5ade0d84570e1838ae993dfa
+2675ae9470fe7cbe2aba675a6fcac86f
+26764e6b14ec4787fcffb43b4bbd9b5a
+2679b0c03597ac280fcc788161166d9e
+2681147467b16a0f9a3bbf7bd614f7f5
+2682dda97ab9399532881925b2767230
+2682f0738a2a391b09646d9b6408dffa
+26877848be535edfe4e57fad2ccaf961
+268c0b8c9d87d718e91065a69f8b4911
+268c3eeec2d6f8ac045ec48fb7ea3b7b
+268d1339477f2b4de6d8728438a6487c
+268fce392976505b67f65cb72ae77cac
+2694b272e257dd253866791ea5b2ba1b
+26a271fd0150db3cce8113f160a8eba0
+26a8b09b10f0ac1f150e11ac8bcbe808
+26b13c68405152386fa925fdfe90b179
+26b35d5f6f934ab81d87cd3173bf1499
+26b44d8be07fecd13165efca1b8c8ec5
+26bea74092fb0200907d81436ddddf4e
+26bfc6416e8596bdf502056cfe842c2f
+26c2a3bae5f215140bdfbb0d7d94377a
+26d12b44fd97f44cf597116729b18ae8
+26d3cc420e3c294f2182dd3061722fb3
+26d55ef9a2eb42ae9da7cdf7a2008db1
+26dc6c0ab36f8ee64b1f4b2adccbd1d9
+26dd7dc1fe14cfc29ea1b29534206690
+26e1649cc1c607166b1f96812dabf7d2
+26e2f3b3894c24d7355843de06f3e741
+26e33b964900f3450585de422539ae70
+26e3c08095f9cc6f8d46d55ccdf3cd8d
+26e7c888ed87a301ae545b722f47617b
+26e98276419ba68c74f1a36ae7b45553
+26ee5963aa9a1cf857bc54c14643805e
+26f82bb1c9a0b6d88c30f7d8bf746900
+2705744d12738fe0aebe9895a6c3379f
+2706b7693d728e893cd742e6c5455eec
+2706d9bbd6832367cf3e5834093ae917
+270b257dd4ca3e62b0309b3a6a43212d
+2712657c73761f47bbf8f02a18a43b38
+2715b7ca7352ce1b3af0b0a5b72d0de1
+271b81ddd186be40072cd540fc14d9bd
+271f7da74838dfac3ad02d3d862691b7
+2720acd23bb67537dde491280ccfdd8d
+27246f9451475e08fb66c42d26a03dc8
+2727f1ca3a617794aae4a969d4605357
+27283b3d3b57b0c16af83c4a357e3e9e
+2729d1655e8d028fcfe83cffdc98849b
+272a8051d8c069abf1d8e7b5b73cb593
+272bf9fb980fb3046328e70b51f8fe69
+273b2a858151b4a9c238ab092e2562ac
+273bc07a65dcd3a2d0576670513371e6
+27411bb34d1c7c0a84f14954340fae54
+2746f2e565e5de8f06272a4b8194a818
+274d7ec4d7a320bc3ab7ff1882bec2a7
+274ff2f8363b7d695aa0cc4be4d2c56a
+2750a70f7b54f95670f1335a6db4a9b7
+275aaff213496338e9dd19e538308a04
+275bac599e3cf6d6307d794b5659c381
+275bf842a584120132495a0f490f45ad
+275d129c58644722c031e3bdfe4a2ad5
+275ea105519ebf9247e93d42b54a5ddc
+2771d3b1bc3f32604fcd4c2f803f9e6e
+277d73120ced94b4ced1ce5699976656
+277eb4751473c94e3bcb313a9c607322
+278391d2b52ca4d4372b3f5cfc559c78
+27892033e4b8b4cfd3b1f4d2ec4fb948
+2790c3bbb5d4a35df9557fa1c31f204c
+2791a12e6cccc055f22fe825c31edcdc
+279bd598b22d7529e08b305c482cc043
+279dbba3f48c40bfa58d356c3c89aea7
+27a18f94b88f1f9e8f3d9744a2038fae
+27a1ea7d978dd7735c6c89cdfc0ccee4
+27a3106157bb138184d42926d4a349b5
+27a5b97a28fb09fad98ad0a6539379e6
+27a8101a9d61b1e9de28ff11a8c65cbc
+27ac0e4198f057030e712ec12a8ea9f2
+27ac12db5919636bf3154f9ae7300ecc
+27be87281c0cbe573cb50d8dd2e06392
+27bf9314949f532a8a185ad1804131fd
+27c3cdeced267df8f71071a884ef86fc
+27c57c453d88cf3e9b82e9078e2f9227
+27c624352b65780d0825016292d2ea4f
+27c847363e42cc4d3ec704171f6e7c3d
+27ccd61ae219684f2d82cd6ee659c215
+27e1571623eb2584e9decd03ffa7c687
+27e35e26a10846923ba50389feb6d52f
+27e459c7966b24e5d764464b0537cf62
+27e8b8a25c7778169b98395456f0b6b8
+27f08f01fb23a91f344219b5857d83f6
+27f340d1d1892daf716df0f69ba4f83f
+27fb29af88e4c1fb7a318fa9c8bb7bdb
+28021017aca172b4b8a467a7bb411510
+28046e2c0aaafac3625ee6165a2046ed
+280e65ac830e5c36df50ba1c45e85f10
+2810f4ed6228adda8c7f6b1ac8622c14
+28112ae8e36843b3e15a703608ccc519
+2813474b9ea7adc5605320c667bf4ae9
+2815b9305245194a4ef04479ad84904d
+28185ad43c5e4bdfc69b569a3de56033
+28219c3ee8661ccd951b80ab48acaa7f
+2822cc3cdc03d998e929fe0b4333eb5f
+28272f2ef5e41cb28266726793bc0eb1
+282979f66fbf53996ad511881a1b60cb
+2829abaf662901591b43f99ee4f51b38
+28313f401322c8c1a65697c0c527c398
+28323673060c7d786d8213f80f9bc8b9
+2833bde063f81e1651d066d2eaa751aa
+28393b1acbb84ed19ab965341daa5729
+283ded9349b57de1cb44d9350af8bfde
+284086bfdcf781d0a464e2ea7decb395
+2844e31409c734fb83d502723cad6d43
+284b5a83a122502cb9a5bd1740c28f65
+284d774e619c125a14177e42e81e4fe2
+28594d96a7e3805d7ae54ac85704dfa0
+285c16ccdb48dcf9aae9f766a8434610
+285e7f89c2653bf230bdc02696d0e77f
+286091ed30da0c7b77c9d2732c0db5d1
+28642291fedf80e854801f3328ff72e1
+286771e88711e66eb4f801c50f3d85f2
+286a57cebf40f39f75ba950bcd2ec2b7
+286f60a788a6c8b4b632b703c1645217
+28716bd82dca139ebc17ee388f029106
+28749a42163d3edee68ae55c7e61bd41
+287560099f12f3f7907280e402fc20b6
+28772dee5b8bd2b3d1e7d8d45aff71e4
+287c2fc0df8a468cd28c23e6c4e9fde6
+287f5940146f369bcfb149c266233f4b
+28820a49d6f6535bca25f260eb4f8df1
+2888d117f39632251f1817d1863b1b3a
+288d8400d5f457124d980373ffb533f7
+288daf9a6bc30ebfb55de1de07575cdd
+28923c92980c77a0ecf4edfe36a354bc
+28944ce2047e683d4d7a2d6fc0af0244
+2897f6a64d1213373105272033ddb983
+289b591ccdb085a5953285590cd31dcb
+289f18321d8ba6f54b82d0edcfbcbe6d
+28a4e294edaa4a6a3e2536b020675898
+28a8529cad3a28c26ec20f9d8acbf2f9
+28b7314e966befb05355023e12d6462c
+28b9a17827dd56ff2bce79d79fcb1ded
+28bfe14dbcb1afc2b5b20669588102a8
+28c9ea493c7d79aac77e94a15c757579
+28d610caef84bec33a19c864b4b14bf9
+28d79b60fb216c681e608d7a2966dba7
+28e1d834e441875ef520e1ff147a7b24
+28e210ae4101e6dd931a8d7909ced98f
+28e38af2f154332cac7bb1f06c2a3648
+28ebf5cac545d356e3fd3344387935b1
+28ebf70627158a3ee800cb3db9f48ca9
+28f02eb7926ddd24fbacdcc1e6f8ed3f
+28f3d12853f3a11b5308b513c31048ff
+28f59569916c19d7b164ba518e8b3a15
+28f74313f443a400308d463ef55fc7b1
+2905b004864d92207399605aae2ede90
+2909ddc74f66711115b22f81a7cee159
+290ae49f5ad1413556f0a20e3809605e
+290e0bcae7f26505820e5486e49aec8b
+290eea53a38d0966582663f12c491395
+29112f1fbad82a1fc398ab39af6b1900
+29114c861e2c6c1cb3690527f540da53
+2925f27909f08cbd91d256f000deb832
+2928dfcda373fd32875740f2f8b0386c
+292c873419648853276bb1d6470fb3ba
+2932dea4fc0afb6389fdc295e1ae6573
+29398a74c97780a2de31f2d892e52ebc
+293ae1845b27a38a63fded8e586ae631
+293c413d6524538306c8607398a173fb
+2944c8423c63f57a5733862cd312512a
+29468277b20b304aa17563869fad3b15
+29480b3563bf77652a92fc28c0f552be
+294ab43bff03956d3ad3251c645bbbbf
+294ade6d7b88a34b0db9662313c9163c
+294e70b1e3daa2ee44a9edab5f6b418d
+2950f89069ffd8d0531bca45ba4c5c91
+29516e0f135894a8257b75dd2c454316
+295427900bd77fa811e86b37bc8bda43
+2956b6ecdbd9c2974cf6a2d644889958
+295761e29a79bc18b89bc36d7e8f9987
+2959f06f3cebdec14ea2c5a88f09ecc4
+296515cbd46daca0f17fd1f7269332f4
+2966ac1205dbed991ee29c74bb7ff804
+2966c0f7e3acd67849da85779d1736ea
+29720832ba0d2a099f762803bd87e21e
+29766efc5a9d8bd7582b88529aa687d1
+297a5cd892836e02e02e75973e63ba0b
+2981b24a8ed5ccad8e5b77aba148a65f
+2990a982f0cf642fefa482c42ef27e95
+2991949b2a31c16b203a167be1c860fe
+2992f639ca33b74fa7b1704a8baf4e8c
+2993d7896c87fce65dc63cce52813bbf
+2993ee29e7594a37201a56c234f966ff
+29abcf4037998d0fccd4f31e7e260afa
+29ae3e8447f5b050b2be530db71609c0
+29b12655f8152067f058ad0f3a811419
+29b17e7519c831f893141f9542c833dd
+29b1fdf3bd9335e15b32f8d340fd0bc9
+29b2ae7b5d886e1fc0ead35e4e961e76
+29b4ac2f2e50627666d9db25b2b8b187
+29c14698398d9b4c9b762b45d75457d8
+29c180f6134f915643462ab5b3ed709d
+29c76624bc7c285acbfb69431c6d39f1
+29cf6c9fbe1dc84756bc1e156a3991c5
+29cf87a883a757be07aa893bd0dd678c
+29d4edb5e7b4f66e34a077142be4de65
+29d5abbf7b17ba018f8dabac4d63e60b
+29d8d1cb9c736293e765633c7d293a1b
+29de000170d2b1775c8898ff9aa708d8
+29e2cabcc23e73771e5db8da12f43b3d
+29e778b9cfe28cee9761d99b853c0b34
+29e8abbbc20f45e4a782840d4406b86c
+29e9c9aab1f226b44582a34b735c707e
+29ea392228fc2948f16d7f1ae1341a03
+29eb23f8f6d1db96342aa53f60912132
+29eb984d80340769870ff6deea286f8c
+29ed472a9736824c7d6040bb5043cb78
+29ef7e3e4592692fee84235712a603b1
+29fd6639ca9813cd680da5b6a9ed009f
+29fea0396096069a878fcab69b5005f4
+29ff336611641d962b5f1f6ad5254080
+2a023056e0890f785930bb1de6e775b4
+2a08857163c8b75dd22fc8799f83b6d7
+2a09038299e7a378f9535bb8d4215d98
+2a0e92bcc3f07cd1f68031fe8b21c4e1
+2a0edc9305cc16b928b8a4af70606ece
+2a18eab9f0c7d3fec2b1f666d96d72df
+2a2a1300871101fb39c48d0f572f0d52
+2a2ad2ca000851f07abf5823fbf327c4
+2a2d5190f4d626fcc8f3cfdf4a466f9c
+2a2df60a2e8e36f9c2e8e8ca5e408c40
+2a2f46c71390885363233839f01ac437
+2a32473b2cc50c371c23bbef61c6bb64
+2a3305649d8290803545bc61f4aadade
+2a3422316d930af63f6dce35c0612cc7
+2a3aaff72d4e4913aedb16f5ce5995a6
+2a3ab9a00fdd851278efa64d4df3e6c5
+2a3d0ca259ca626d36cb7d21f15da549
+2a4a2fa6abd1fee5b1763397dd67dd78
+2a4a63c56011d5414d177015907702a7
+2a4b1d376ac19df8524de9bcaab969db
+2a55e80264390ffffe397e1c0990c96a
+2a58debbaeeca30a29885337a72dd458
+2a59d1a99d9359790e57347354450f47
+2a619d84c777b4f786c7e72e4b0f9179
+2a6a04a5041cb025142eb697213b25e9
+2a7223396cb6b34996311281fd7be9c0
+2a729611f39d14d7a50d1e57063f9fac
+2a821bddc7636d69c4e3a8e14228c5be
+2a935ea55c7eb4a3262fe7ef05df2300
+2a94ca5e41290bbb7ecaf44d0efbd6aa
+2a96ce99e35d367489cd25fdbed3daf6
+2a9e0d97cc99e424eb4edce35080ebf2
+2a9ecac5ed7a516924c7ae58a2ee7977
+2aab49224e7be37817936dca4bee5aa4
+2aac8d6f8d78a800efa51ec3490847d6
+2aad92bd5bd3fc88b69da5283ec30d04
+2aba2b39cbf1fefe999667a410778717
+2abe82bbd8d32619ec0ad3fb0161e630
+2ac59730f0190ae55d3190920309ca1d
+2ad1d36e6f83e601513c476c5023e6c4
+2ad2a9feca6f045abfc5023c1300bf65
+2ad66171d913a813a92f7bad05768ae9
+2ad770e144c41aa45b44437ab9a92a2a
+2ad812271143c00a2f5694a804d22301
+2adb6370d8f5a5fea229a36194a89803
+2adca13c297a086a2bef248e50b34995
+2ade9115f354a6b7ebb3b2da17ef9bd3
+2ae3cd72ec01bd301a04d9c6129a26d3
+2ae3ecb46b2529ed43313faf996c3478
+2ae7cc552b34847e6ce8a42f4eb7fea2
+2ae9b15fc0ecada94d7cafd461a0e1b2
+2aead96252eb7d801d77e704cbfc6e8f
+2aeed25550ece65b93594b767f39b74c
+2af0d89294ffbb7d21162ab99ce17886
+2af25a39e19edf54a4f97b548482b0fc
+2afea65f6046085b40e2b7c3101bb21a
+2aff5f5053d631642eafcbdb4e3dd6a8
+2b08f9c3a6521a66194e0d396237b3f7
+2b22044a4f386e119790e8542664574d
+2b25a3e89f9182c7dc257767920ea7f6
+2b283d049c4d8fee28712730d72d9d88
+2b360db7f7bbcd813a40a26ac21771a1
+2b38be89f1ea60c792f8d5f2a75e3e86
+2b407f20df57dcb45ae68e2269cf3253
+2b414e626d3369a3cbc09db841e4ad75
+2b4696d15fc7614fd77e08060c11f52d
+2b4705432991e4569c37330467f1bf9d
+2b4d0afa254ead986408be00b7f4e64a
+2b51d23ef1a88398bc4623495fa19fc9
+2b57db5b5d39ecc648fef97ecb3a8b2e
+2b5ba6024f3cb6cf1e27685794e191de
+2b602ea30d165c9b4c1caf10037a31a0
+2b62270f7734fff4e7c678628415e50b
+2b8426928861c8139e2a27d296147ee0
+2b8675c2e525423eb858f0f437d53cf1
+2b8750099dd03aca6bae07545a5e9152
+2b8eeb41c39213c12f9247f21ca078f1
+2b936c06e1ea5bf07f6901e42414cd44
+2b953c81fe9fea51998b506d962a6ef2
+2b989b1306e18793015972134df6ab32
+2b9b1e8d8137b2ef9230f248a0ee46ec
+2b9b920d73092b83ca3112ea994dcfb0
+2b9e70cc118090e1a23e9fcf03eafda8
+2b9f37d878b2b817b317e026aedb009b
+2ba0174f07c1e38eee5c0c0bc44e9cf2
+2ba2dac14cbd28a02fbce180306a8b05
+2ba3f29944125f5d970201547722ae58
+2ba6b432d703f60d1912836348895c66
+2ba9dbb117b353f228c791a246fc694f
+2babe0d112a662c3db7951a2133e2966
+2bafbba911db6cb8d7bb46e133eba619
+2bb2c218eadea506dcfb65a396e47a9b
+2bb61647df445ba0d5503f4f16eec8dd
+2bb6343786315f1064988c6ef60a73e8
+2bb9c0aa9859b984d3fcb36b1bc5edaf
+2bbff074614338515c1dfd7764cc0314
+2bc104cdb97c8aae6392fff4602afa45
+2bc494dfd1a98cd6fb58c1c6d0bf0ead
+2bd09f8023736fe21eeaee1286fa36df
+2bd4b7ad70c35bc8d7f872d4adc0abbf
+2bd623037b0b987dc9be3076465cc986
+2bdc0aeee682b4d82414724ce7afa7e2
+2bdcb7cab60f6fd9bbda4aa850cf5827
+2be09c2e61b63aba07b5bea92c190d14
+2be2dd5ad04f87fc204b7cf6f630620f
+2bf00b52f1ff389aedd7c83ecf58110f
+2bf54fda87808eb490b0bb642664fb46
+2bf5bc6ffe94ca002b71e7fbaf31e662
+2bf6a3a5134b2cc7eccf28cc845f21bd
+2bf7069e0a401d0b3893af97f681968d
+2bf91ec9421a077577a796de32b424a6
+2bf99c263052d69c7d7473e088780aa6
+2bfc467a6955aa464be3892c644c387c
+2c0335d219bdc9bccd89e17ca3670f4d
+2c03a8a365976977e92f6d0c8d80244d
+2c06507cc2cf050056d8a42df0b940d1
+2c0f461230aa9448d60806b450afda5a
+2c108205dd7d80cb4350f4fc37b86168
+2c11080b640c4bf022f919b5a7b8d7cd
+2c1b1e6eb30950cf8171e36101da9d8a
+2c1b565043ba98542847fb051da3fe92
+2c1be22be32e18d8c3656cf2e44f92d0
+2c1beb65b541a94fd5d5981bdade52d7
+2c1c9fd7e45e04aab69409c1ef9a8e30
+2c2dbc42260a273909e67bd3ed9a3ba7
+2c317cbd838f6b6477b8412eb0e286b7
+2c335e4b849da52d33d48d7ecce7cf8a
+2c35ab8eeb437b44e5d07e5d31052feb
+2c3753c8b6731cacc7bda77a5de26220
+2c378789cd6bd90d65f83bed7ac561f2
+2c3797b7f89e0e8d7f5ab196f3772fb7
+2c393af500b22b476dea236dfdb01769
+2c45d73234078affc9e0e08f32791821
+2c556066b92e3022622e4e2ee38ede9e
+2c67d429e3d6384c163147b4754ef671
+2c6b9ccce0b5ee8c8c3823e3e86995a3
+2c6ce4653e886aee7c9a2364363f0c86
+2c78a6f8db5742a722e414757168cd17
+2c7fb74cb998b1026c96219bacc5947a
+2c83cebfde8dfd8ea697cf8ae72ada88
+2c86880e44117c4bf68e20e95036ef1f
+2c879d499efc567a8edb6f07c1f0c02c
+2c8df90ac2248ba8396dab6fea7a82d7
+2c920d747d8a705a1226dfdcd68e3b20
+2c92e80bd1e8f4cc9550f0c8479bdfbe
+2c94c84b6c3b34672a9136f945e40aec
+2c9d054317fdb277c7b1bcba6a73cb75
+2c9d86ead9c6c144db0c548833851113
+2c9f95db3c7ba3c4e226ea84a8859cb8
+2c9fd37bbb9762a2ffb7843b11ed27a6
+2c9fea923dfbb4e98abbd242f8500c83
+2cabf425035a89bb69f9309f89bfe33a
+2cae0df600e3fd618ed2a51c3b1e99ab
+2cb0a7626df3e725bd5440b64d29f4ce
+2cb1a6e9e8b70fb2268826d3c8bc235d
+2cb203b4c5bcb917449cb90e8b05083a
+2cb75e0f9b5eacef2859838e8e4d5a4a
+2cc09bb4ef5fc8e1eb7019ff18d03467
+2cc19a6366c2fe7ec62c2474f39b0b30
+2ccc5113095de4f946b900598a75d13b
+2ccc625da3e05524d8ac0cd049b8e3f9
+2ccdcdb65f4802127012b617ded4fd62
+2cd732100172620a6a04ed5eaab0890a
+2ce0c0e8d4343b728f0139c667274f37
+2cf17eba57606a8fc943795adbf80e8b
+2cf74703c0f4e5e88fa9e3ac0e3d7118
+2cfcbb282bc039defe22524e75f00c80
+2d038f58de83385739846d037531f12c
+2d05179316185319a254ae07fcb4c3ca
+2d087616106ccc3147cd472ba627ed23
+2d0da2c89c779c5d3cb8200fa220c28b
+2d0dc2b22c154d87b66b10c7e03fae06
+2d0e2c33675b519fb4f876f1ae1e1617
+2d108cbe2c02960356bfc25049afd225
+2d127f0e553f212986b3645d9fc638de
+2d14eebe65f5ee717630251561d171ba
+2d19e09a5848c47819f8d9bad74bae38
+2d1fbe352ad1e6fef98b13a306c0afb8
+2d21197ff9697b3598564ff2ddee73f0
+2d24ec1d204ed02a25d2aefd6b9e1777
+2d25c7fdbffc54006a6637d8aec7e1f9
+2d2631e17aa89e444e28b5f7b8fd9584
+2d28eb20647d4a84257484ed14a891ba
+2d28fdc698790e77a6fb4e7794c1c942
+2d29ae875fafa74e879e9bf3c31c2d7f
+2d2e05e09352f911df28eca9bcc8f46e
+2d39a7e23cc1e979aaebfe2f4af077cf
+2d3c843c0f420493d980e8904c5e68f7
+2d3f173418c36b889b231c5e718c1b64
+2d416779226b7f1a5c986f4d5d36b104
+2d43e81d9f7e14df872a77e649baedd3
+2d4548ae105b37f91802ea9660e66e2f
+2d46ac73fe4b37fbe7e1d2dba7118152
+2d489006d499b10b94b6f2dacdb664d1
+2d5508ad54959b041d8df6094833e973
+2d57c7fc1219eeaf8d3731cffd4c22fb
+2d591b8a0e51d577690d5e28e4aaaaa0
+2d5a4ae4fb0bcd6803918d5f6b3cb8c8
+2d6b82ff18ed6f3c0246d15dd0fa4655
+2d6c8de6b7cc362524cd10ff0cdc92f9
+2d6e182c8490ad0c0d48b584703525ce
+2d722eb49e0808f934ad74fe82157ac8
+2d74bd3f8186d705f8b8c4c1eb9c3bd6
+2d79a8f96863371c063f6087ed0d2502
+2d7cfd76b0d0cc2812808801e53a0fcd
+2d808561c772b205b05ed0b63f4f859c
+2d81e6af689d2472e807638b4e78222f
+2d853ab8e6aaa8e0c0857a82c5e81e1d
+2d9176b2491938dc518270966ccedc7e
+2d98985dac1d0bfebc830f2529bfebd4
+2d9aa50069b483848fe0d5aa71083817
+2d9c7b238554c3d95da1de0a244b8123
+2d9ddf60ac7abf311b072262ccc56132
+2da2cf7d5cd03bb86f94c24f75925351
+2da5cb0eff92d2bd17583246af03041c
+2da8d88bac68055cff7a52a8b8ace321
+2da908f9ac33a5c80f55aa246367a23a
+2db0878fdeb05b9878c351302528050e
+2dbd05f29c1938588c9998d194d604fe
+2dbe12a82542a2af060dc3517e5bc538
+2dc3dbdadd09244a747527308ed185ca
+2dc5bf2f7d83e97a0dcafaf5a8cbaa63
+2dc6c3d0783e8793e180c44261399964
+2dd2e8f6d97b9c290868c5b0c333bab6
+2dd3d63327fff6ba5d9623b9d89c6d11
+2dd70be960480bff4510ddf9e59e23b5
+2dd811df9c6874ddee85cb6a6175f713
+2dd847d7151fa73a39414f47f19ae3a6
+2dda9c87c4ba7cdaf1b12dce5f0ec4e6
+2de0328905a58b4fc16e77641458542c
+2de0853efa57a02edd6aef83e8268771
+2de3355388ae770ffbd8f9c3a72a9c58
+2de723630f060901e7b58f0c191f2bec
+2dea65a10b41f163a63b288b70d6e17f
+2decd5e5cc20316d88d44446cbb0929f
+2df119899886870c0ad65898bcf47d4c
+2df1e36bb9029d65c5d3771639246ea1
+2df38d901a084ad9a9035de4ef999f4e
+2df90d27370d679463b48b411eb6d3a6
+2dfa40f48e03f87c0cf7cde98f9d08dc
+2e0599a6cc8bcb4724724e68eaccaf11
+2e0a2ec7c805db7af8874f96011fca5e
+2e0afa00261d875963d514f672ab4dde
+2e0ce7114d9e9ddba278c85c14e74faa
+2e114aed45e6462bf56789a792426c22
+2e1646fba2336d1573d070263f6e3cf9
+2e17ad6372c31a697e047464b315b0b6
+2e1c20277931e4fc68aab2b90872fec2
+2e2654c5530edf4939623fc1ac5b8e01
+2e3527733a74071bcfe3a789f2842285
+2e373f43aeac8990d38d265e61a498fa
+2e3887849f159253d1e89d66667f9532
+2e3bf670aeed38a95af96ca49d49a552
+2e4ba54bc4ffc889824b0464aa0817df
+2e4cb506cde919f7d8f6143333764d42
+2e4cc638df49b3196aa5a627490788b5
+2e52c371cc6c1cfbef92836e08893b14
+2e57ef4d969ef87d4bd3f2724c9e1950
+2e5897cb031de4455468e3cb5e5ca7f2
+2e59476d633032320b310e42e12c5844
+2e5c027e431caf0c579b84b329c06e85
+2e618b4cc8121763527c43065e7eef47
+2e6568758009c3105156041fac890c1b
+2e66f56c815e10cb6be480a642a0cd7c
+2e673868504f9df3474ccd87b50bc656
+2e6b00f0152f28af4b86eed0cea8895b
+2e6e99b0983ee033632523d218c86630
+2e766332ddbeeb078e3aa5814adc7a8b
+2e785a113ac3fd5f54030870a12c00d3
+2e7cf4534e1a6ce1dcc3fd62a21bbec4
+2e819292e3ad53b277f88fd2d34b37d4
+2e893d9657300f780a4447863ce5c86f
+2e8faff11ebf0731bf5ca871daf06b9d
+2e92fc4ef7d5f2d453f1f6a2334d7fa0
+2e94ef3a88a064bc216efd0cc0c8d3a4
+2e97547500f35f3d7f56b9fc490fe6ca
+2e9b66b8dcf9a443723e78a19a3b2941
+2e9cc4a352ee4294736d18e131057f20
+2ea009fff04f7b432eccb4d3c100b871
+2ea6f0836d143772771baf0a031ff74f
+2eb197786539a6f580145187f1257106
+2eb3f9f115e8c157ce375be88dbff859
+2eb53225da743be8ead3487a1f07db06
+2eb6de024c6023e7b5e968a47fce1f76
+2ebb57ae3ebcbdf46afaf1e515326df2
+2ebb7113401900efd89d27b4b4fc1a55
+2ec1f8af92723b47febf9e675b4f951b
+2ec77bed5b3e3819bf4b20602c01b480
+2ecc3c58524cb7ee88724febbd03e3a5
+2ece2bf5c59dd1f748c8534b19bbb85f
+2ed0c3ef9f37073f5030ce73cc88fa36
+2ed326f26aac3f9c5f9550f1322e20ed
+2ed7b551cfde4283770f5efc86034dc2
+2ed8d8bec6707001203fa9ce8feccde3
+2ed9b5172ed95b6706d507a401009494
+2eda81246d7916e5f54e5fa3789eb1e8
+2edba639e025ea903b4760b6331317e9
+2ee217435e1838cb62241f8a324cdc5e
+2ee25c778e9e74a954b9f6977da9830c
+2ee4ba66c616084a2ba9baae384dc8e1
+2ee50f22118f33232051b6190018b9ed
+2ee6dcd4ad4740411bc7ea0d5c08c35f
+2ee9de63e39d8744240b6b103e27296e
+2eeaad7198b640ccd9a343533e2e7058
+2eefff6c58ae677411262cb79b2d7978
+2ef46e599ed03d25b7344a40f6777896
+2ef6e24f760c9fd4005bf21249e1138c
+2efbdc290a37816cd74b73ec9bf3b84e
+2efe8f87acf78ea4655337bd5348efd3
+2f052d957f7d44210f86261a55bb868d
+2f055a9e6c51892d2b29ff53528a1bb2
+2f06d67a8f8013952f2788ddb9ba296e
+2f06f34ca6c1cab6917e82241515e178
+2f0b94eefbc4e4713f2d4548d631cc28
+2f0d1c6b3d9e8210fc27fa3815edf1ab
+2f10e9d0eba55e17af159606665eb4e1
+2f1397a8a66e2efc790776703dc0c722
+2f162fd2d00a2cb3959b37cd732a4adc
+2f22110c34662c4fdf80bd273d2c46b5
+2f2572b575b8ecafd16370f930bed3b0
+2f2744cd8d032de2f73b7b55447636c7
+2f27f2f290ecb0f818236443e0d7662a
+2f28e98dc0420cd3be9b075e0ff1a210
+2f2ac717b9e92edb70b6fdd882654969
+2f2cbabf80a331e7cc4ed32c4d124256
+2f2d38ef28f69c02c6d51907a28a2ffa
+2f318ed61dce9b6816281c038488e3f6
+2f3860af671bc1592cc4ccccda43ae9a
+2f3b8ec36f532cb88b3b05d992e1ed95
+2f3d3d1e096ee47bdd2fac9bdcfa4d18
+2f42b71a001b93924bb885cf29e055b3
+2f4e5ca01d04a50c91acc22732235cb7
+2f4e7a1d991d884113efe43eab9c27bc
+2f50c2a810f0c1a60320e491e4b2d05b
+2f53e42d8eabf10ddc98a6529a8a61e3
+2f680745a0476c23154bb4840e3e60b6
+2f688db067b92a5f32742aa57af26e66
+2f7b0fc80de1b3cd151d6c858003f720
+2f7de40c00bc2c3ac26af9a7e1f09692
+2f7df3bdaf3e938127854034527e3931
+2f89411b3fe38ea818cc85682678b28f
+2f8be8082f45da5663f9469fbb77dbc1
+2f8fc53fd4e05369bccaaf037329f8d0
+2f940fa97832571c9e99f72d2419ed14
+2f943e8900b7f867e60b275ea1b6b855
+2f958cdf39f0adb6b7149a40ac2dd04d
+2f98afb5a7b7c7af013b1ae50239c0e0
+2f9f36e3e9c34041d25fe7b12a19c0ad
+2fa27383a22c2dedaaed7085d76d60ba
+2fb0137e0e4292b071b680df14ba2f41
+2fb1396f807dccfc1a956086a493c69a
+2fb5705a7a569cffd71f955c4fbc9390
+2fb64d661c0466290843f07b89f294e9
+2fc3307a828e885b3673e46626f0d806
+2fc49bd2e58de22f783b1945a0c43479
+2fcbfa84cbcff30177cf0df649e14224
+2fce8adefe9f0066a805557e8d4256ae
+2fd235eeb33435cb8de4fb57a607c1f5
+2fd4a4fa2cb67f29871a154476027614
+2fd7cfede746857c9ae82850daa770d7
+2fd927da3ef7e7fa2916ba807d590f43
+2fde0db465be5df32fce7b1ab3bbd090
+2feae3488dd9062950dc4a81ba986bc7
+2ff1e62a192ff56015af810b29064a07
+2ff7c9b205c706bb05b0f6582e230dd3
+2ff944dbf6d4176ae19c5333d25981ff
+2ffbf863c35ce438bf24017772817a50
+2ffdf8e004637650df48892f3e4f5661
+2fff28091befa4bd799c19adb68a88e6
+30017ba1f6bd892590eaa7b7e7c23ef1
+300b50cc132194c6c0f0b6e021a5324e
+300be4046f1f16cef6e713a4bf61d0fe
+300e62c6504eecd256994c56c5674da2
+3014705b256de967a69bedfa5487cae7
+3018d1bac8748b68340051771737bff7
+302c5e3f52ea1796ff5c4b4ee473c604
+302cb8dced187ee9b257778c8d642aec
+303122b30d511b6146151f9ce8dd1f09
+3036808661f4fb5f7053a0dd83c6b100
+303ff964ae168be6f8fbef34bb4a5ec1
+30451fae74165af2035080ab28102453
+3046b084630016263dfd40a2277fd9b4
+305000f9af933781e294cf712d549880
+3052acdd3939853b9926094d73290710
+3057772225a858f1c15e13a286c53c9a
+305fc523e90ab538543a2267bc189e2e
+30709345a12ca073f9153083945cf9dd
+30730117496ffd12e1f3d7c3cf6630df
+3073c6c43aadbcc6b9ae7b43694e25ff
+30765006b9cc4a17e55f8351633cc7ca
+307b6861ec2c33fe36a0ce1a6ff2763e
+307e529effa4d4b73014a9343e4a196a
+3083073deb2a4a1859c43e3ca13df5f9
+3086ab03babf17d0c61dc50c0b5d78b5
+308770d1e98e355d9df45583b2748b5c
+3089e44c22d1751cff5a646021c2ecd8
+308e3a397bb48c7cd1dae0a3962b2bf9
+3092fb40cb4544973187f350dd610383
+3093cb66cf28a993882f149d0d60185e
+309c2a4595305860fc4d7e850afdccde
+309e6827f7e2f1aa577dff4480a5e74a
+30a47b6be5705c45581a3cb34a4b2702
+30aab146ce00a97bcf54103b8a79d354
+30af6ec768c24824a5a129272fe5a15c
+30b3499a4c805ff0c9bd91122a16c9b8
+30bb43932a47a9b06510401fb58591bb
+30bf7cc634433e64f0229d6560fb75e0
+30c1c91f8e080d4a90e01294fcac0fb8
+30c28c08b133c649a8819a4b43c70501
+30cd3a88a4cf921f52382336d9de8eef
+30d50ac0d5ac7887007f3a771fe17584
+30d5172abfa33c439035ee0f297f413b
+30d7b59fdfbc71fadb55839455fb28f6
+30dbab96c2a256b9351930674e41dcf5
+30e5e74972d6402ceecc043f653a6073
+30f33ab12439c55f96a3f54b96eed127
+30f4662b3e9097887b45bdb8928674a7
+30f4b2897cbcdf51d984cf811997de7a
+30fdac64aa82107151cd0a46fb8de584
+3103884b11c754dd558d3cd5993070e2
+310e2462a106c3cc66d5b5595f1d057f
+310f7bedbedfcf7743fa418b49639e0d
+311d0ba7baf4ee3ebccaf347c25f5d7c
+311faa78873f752a9d8c18685c3f904d
+311ff64b872c2ecc7eea5c51fd3b0e06
+31229a551a2e1d7682228f074ae262f8
+312c083bde5928b960421c090ccf0116
+312dfa86f468e0c4d0b58977eacb4e06
+313118aa5280818f12889e9a50cb5544
+31364e82559fbbe21317bbcd43c79c57
+313a0c372174f69e9bd7341b14aaa09c
+313a35614c525d18e3fa17ef69cf50a2
+313a9b779c136b371259043cc755fcff
+313b11c980ab1e7617e76fb68b9f66ff
+31408d311df8fea0cb6843cae64bdc54
+31454b5c0d93b859a5ce99e545af8841
+3149d2312ee16b2343bd3a1dca4916d5
+314a039b5dd47fd2fd71c955e8118155
+314ee01d4c149eca8f8efe68d4afa6d9
+3157b68fd0e9a50481a9ef1451a86526
+3157dc736dfc5361029f67b6c144e30b
+315b26d79673d11760d42934198a6471
+316019a760a7e6d275a10e07af16a9e9
+3160cd7c0a67d6d8f424e81c375fac48
+316436643dee9ce3cee6dba2629b3469
+31657ac7f759c0c97a1e6637e187d029
+31663875b29c6abf1eecee0f2da03f2d
+316cd494d3370ab4c8b91720e32458a5
+317339ae51c4eb8dff6c0124a4d33fb6
+317b4a200dd974a5a79f6cfd974b94cf
+317f125d0ffe193a666508f0177bd461
+31849d44e121c56bda4b2739504d5c97
+3189bb574cefdde2c3b35a4ec9869191
+318b94d32aabdec9a8531347f58c8f27
+318cbec3953192ab9ee892a35c42d5d9
+319094cdd5a69a7be601ac706f01405f
+3191fa7e3b4fe580e2513b57f88760f3
+3199d25800a2849fde9bd6898ad2928d
+319badc0cae279a243b8bf667e70e59f
+319f1345e14e1e348d4929aa1e8ebbcd
+31b5ae3dee7e807212ac16d648f16e94
+31b617b6ef67eabe69fcab6cf3b73973
+31be90e344ac398ec3e0f921256735d7
+31c0aa0ae4f9cdfa501920a64455babc
+31cb2d32c77a8f90d32b0987d1e4069e
+31cd99a43da4b97052c5fadde57dddf1
+31cf2598fa69dddbfbd01146e5e963b3
+31cfe32afac7c4cb57a2826dd7798bce
+31d2a5d4299fe6ca862155ead1cf67b6
+31d51ba660e9336ebad0f157845d9e97
+31d784e7e05706a93cd67e6ce0d75a30
+31d9d798f4348bf5b9ecf8af3a3b69e0
+31da3d7304e52e33aeecd79e156c1c24
+31da9385d6787ac12ba3257fbd7da273
+31daf39d2abef27ac0bbc47524fe010d
+31de02e80018b719d02888460b83ec9b
+31de914a66869a04ed186a78b3dce1ab
+31df43afb9f8b5b858b48e4adc9ce4d2
+31e2d3bc32cd48e8f09c622974836abf
+31e3fff180c6c4f05614617a21097bd7
+31e44328b007fba20bc0940c66220133
+31e578bb3c08c6a0c616040e62d01096
+31e9ba55f561c35b9cf78a7c1125fcda
+31eaf85ccf9059fc76a562d9dec806da
+31eb5e87ef98571284dbf96df776f52a
+31ee0051b63f74c6925fc5b18a72a570
+31f0802978f58ea275fdcae4c73668f0
+31f147eac0fd1b51a66f5a98d7f4d413
+31f521717ea7d2d31058fd9f21db573c
+31f9b113f40a43af8152e7f1c24ab614
+31fe9140b2aa3076f429687d2f53682d
+320450e5684e9a6032e01fd0f0080a4a
+320a84d9ca581274a423cd7a3261cbc4
+320e8d414c479681d22dde47a1636a0f
+320f37ee55d76509053e2777b46c2184
+3211a705485e6b1d086b0f7f5eb14527
+32127da99983a2c440646b24595ebaaf
+32134e82fb2039a03f60fa565f16b294
+3214dd9d134293affc80e6880a8359b4
+32151e7ddc96b7e389edf6a4e0568f33
+32175dda8d28e3e0654bb75b77390b8a
+3217f18b0ddf1c879d9779f7821cb51d
+321e619085498a07705c470f58c43d15
+321eed276cf793cb42065150987d1e31
+322665ea8ec2db67ac2fd05fbe721f5c
+322ccd7434d8b90a79fb90d1746d9bef
+32336c8b864a6c7efce9c554bbb57a48
+32346f200668890964620f4d652ff86f
+3236c48210ffbc9fc91a2840b2384973
+323bffd361074397a9070f71a48b8d94
+323cc9fd8b82402f1588f7d020f8d12b
+32436cf47e61c43f3f248db4f40b41e0
+3249f5fd0cf1040ce2ab929576cbd22d
+324eb2eb38ebc11d31097673819a8f0f
+32519e5b810a99c0b6c7d7b59a4b85db
+32523230727d74d55fc0a62630cd05fa
+3252fc002e3269b594a70e03a886af89
+32563766ed07f305221ff3e59dc23cb0
+3256bfc839f1964541fc4efdaa5bd3ad
+3258b3a03136974c68261caa407bb2f8
+325e03478bde90548687155468e45869
+3262ba0f965a8053a6d15fcb67b26fb1
+326b2d4394cc91ec99ca07bea91d15ec
+326bdea0e5d48b3988dffe6d63f5a369
+326d0de4f7d63b27325f6f72fa076d52
+326f35d07ac1ab5353c5fb77fe6cb690
+32709c582d95a03d55ba6ea405c38fd8
+327355afb50e011aae4206e341e22ae4
+327a4a9285a2bd602cb7934be5fba00a
+327bcdab1f5defcbfa13890c8e4f0f40
+327bf349e3f32cd017b4fdd26d8989f8
+3280af1e343828bead37e644d6ba6c98
+3289696f2629286538a831eec3b4b802
+328d63970376adc4f079b09e489ee9db
+328f43e51d137d481a13723b9d9a52c2
+3299b8cb2ea307063a063cd75d833a3c
+329f4735b43dcdba001cd882629e5c02
+32a267d1c8a5c65008c01b30bad3d9c0
+32a3a7a92bba6e016836210609e7471c
+32a44bb33af90c3d4754a555888a27d1
+32ab242e8771e5c19dea1c61db24ce8f
+32abfe85c0ed01d6c5f18cc8c390d470
+32ad8968696dfa749d42c39f4c3e3a98
+32af1a6a310d18b80a0d487e87692bce
+32b51a88c730352458ba593d51426591
+32b5633959628235ae1dcb7ae1a37a5f
+32bb59b96b6bb1133fd48c17d1bbcb32
+32bc2051a57c264decc4f803720bd266
+32bdff6427d67633f8cf9c23e1495c40
+32ca4c74bc4cf19f1bc50793f1f914af
+32cfca4d3466c474331b2cc084f89531
+32d7c149692b51e0bfcbad0e13c2216d
+32d8c7498972c708f657b5ea38bed2e1
+32d9199a8b557a9b371b8c3322655e9a
+32f513f23650c2abc3e4f421c1d92ec8
+32f75e6866cfdcf3a0a067ce98db97ab
+32f9145ffd182aaf960d6e140bc94923
+32f9dac77034a9f4e4431f1160b87cde
+32fc4f3ac0d8574e54d2dd33e4c91e46
+32fce047cd81f4af4a39fe0f5dc8a596
+32fe1e82d833c2d4db66d542678b94ad
+330221c57712d67473f17ad032c2fa47
+3303be51fb901cb081afa70dbd4c0ca8
+330a79f103675ac3148228f1408b4f67
+330b984d7cb8c92fa32ead2a37a528c4
+33133ee7d85cef5ea5d27c3574ecfb33
+33146e74e7869e9b060e295ad7895523
+3314ff4e720fe2320b6c507b87d01719
+3318c7d48585d50352486d43a7f46bfa
+331ac29ff553fdc664fae5af1dd460ab
+33230d3ff03d411448a373882bbfe532
+33236ae69414ccf9e0be82148389a675
+3323fcc198d46f22381f2ff143050c4a
+332a8ecdb3bcb4bfd099a7fe35118d79
+332e53e8a1fd1eae872ba75adecc466f
+332f3482252a5122a5a6604618ec86bf
+333170f29dfe2e32bd98c3a49dced2b6
+3335a4a7f27946adbd96bb9fc6a6ca02
+333c526db0b6a5912c81dbee238501b9
+333da009ec5a113fc8f8d01576c3f222
+333f2bedaa8d3096d58ccfdec6ffe670
+334000a4cfcd4595cde1ac01a12b4ffb
+334e99958b55ce7b931230601574253e
+334fe89d5a5de4ba8965ac06e46bffc9
+33514d4c4f3d3b73bdc152115f0d1b3a
+33556e941af79d0a2f5383649bedaded
+335763c8a9be1b6b228965fb0df1131d
+3358cbfd250319d409abaf77ba10a529
+3359a38a402c407dc3c579262e3927c8
+335c1c22df4b662ae3405c0c84ad70c1
+335dbd5fb8c5f7270e73ddf6ee324b0c
+3361febba205c25cde05712be0881fa1
+336d8685be44ea171d2d5cc4ead3bd8a
+3372140a235444b9bce067bc1df63d86
+337a130b4c877e9781491b989f376630
+337aa44b96609568b6e32d15ef0f452a
+337e28285800ab9752302771edf2cc8c
+337f1b169e71a647d18f7203543610e0
+337f6c37f179ddd735b6fe168ede284d
+338893ba1c9c78f5fafa260d2530ac96
+338f8d6a9b598df45f36f252f55726f0
+339b9d8a59b17ed961a613c2a53d80a8
+33ab0c9986c4360792c8d22592b42b66
+33ad3523d90a1e28e5e402b9ecc3a292
+33b6f24cabfd01aa968dc83789dea5bc
+33b86df896e5571ff912a720966c9f4b
+33ba312306f0e2f7440857459a7fba44
+33c07caecdac9d80cac5b60669a34053
+33c4453fdb220e70eebfc0522e825ded
+33c8ee82a06de02be208af2591608394
+33ca8ea189eb2933fcaec25521f9099e
+33cbe825a19f8d77d4306de647a0c8f6
+33d30382ab9e0e2166549b25bf97f31b
+33d44675ab979a4d431c0b708449cee8
+33dff8be72089407f1f199e12703775e
+33f0665e59b906b10fe4841399589973
+33fc64bc9f6ee2637927a7e65cbbb114
+34053d381376369c88bddee412bb5c8f
+340c3ecf3de437289a9ae45697e0f2ec
+340cdfda2ac0d5d409b995b6ddafb52f
+340ddfed4adfaebde97dd533c0b248fe
+3410a6d7e04e34638f9c6c248630767e
+341469ecd2716d4ce77c18287b30d230
+34188d8436066552803795f193ee0c4a
+341ac10e38ad7950358de024568de462
+341bf8e089f6b2c43767a32f3ab25aef
+3420c0be36a54f6dfc04030c2099bcfe
+34297f5dcb42ede8df68716fdaf8280b
+34307456f8751502aa773c8667804207
+34397a71c2ebacb9ce7009fb2e3d150d
+343c520361903f4ba4b29fd0339769bd
+343cf6d64d66efcb58e8b8d13efde47a
+344132abc716ccb3ad96b1a8f9a49078
+3442f8577f4e65a15d3ef32192620ed8
+34442ef4a4461ef9443c24e12b9a00ac
+3448acb3d2b9f115cf3b9609f8413e69
+34496a9b1455e370827260a372d5b7db
+344e6bbae54e0835c5d8733be51156a1
+345221abfa7f6e3a1ac605d87b3c112d
+3456c8e1714c4fd98504f6b8fb292387
+345bb776cac061bd8019104b34d66950
+345c4dd5afaa57db809710e08e3ed9b9
+345c61e5cc080d6a4e3f4f332d86df4e
+346b8b348c6e8878ea8aaba58cbecc97
+346cc320ad855b4a6e78062810c0e9fc
+346f1e9db30918b2d1b8161cf9255502
+3470e90c47e89354b9a121ed4b2642f6
+3472a535b1d82588ef80b46b2abf5829
+3476e613ccca21690f66a17cfdc098f3
+348046578c5ea1ccf774fd2a83e64cee
+348152de59d1cc3b76e9955fbdd5551f
+34828006616d8662f52dfd80705b6ba9
+348324bc782aaaeeb8691cffc73f252e
+349ae66e9eb6320d358f87f948ea9c51
+34ad4b3ca22d8e78fa9fd16d386cd546
+34b1bef6f9cd2f36d0ad2e81c35b2e10
+34c4197fedbc180333c613bc74e60e64
+34cd54ed6788c94d0ee11dfba9bde4a1
+34ce66321202e0b7754d1e6fa6b945f8
+34d3c2198d4529906035d5666ecb0f55
+34d42ece079714faee7684e8486c4a09
+34db46bd4f8be9c0a8a940e705c57923
+34e05418b0d52e86249ab421f7c63699
+34e063f33e5ac96462ef244650f275b2
+34e1bab7711b1fa5a14cac97bd551c9c
+34e6d9febc380a19281ae663b6cb43f7
+34e9c1278ed8dbc6992e65c64f7e4a3c
+34eb0da7234fce20f108f9ce3712775b
+34f44e454ca0eadb7d9c91c43b23d9d9
+34f573363a5a1f945fd21e3b4ceab061
+34f9172b3eb5aa03545df510efb8bac4
+35053aeef556830c6749976336e2cdd5
+350578682dd9e664275c0eb49b1ff79e
+3506d92035030627dc893297f98496e1
+3507fafb4336bd5a17b0b7a886157dd6
+35088e3a64feb9fc8d13d789c20c7b5d
+350a24438b70d9b36ec3793c4326e112
+350accae2f68949905b3d25fde8ed97d
+350c398bfd3b267468dd60ca564491ce
+3512386c52a629b4edc5f495c96ef43b
+35128f4d255694e11a3b6e850dfc150b
+351da229e46656801ade3868ab68033e
+35262d96680866967722a810dff20941
+3531e183e4f880842762edcc2b649f59
+35332e0307dad58bad0650270f458671
+353385894840237623351e651d8c53bb
+353420c46978cf6f1fa2783dbfe5707f
+3536d5e5dd9b3875ea2d5618fc4d33a2
+3545453ae115ac90243418a89cb0cc48
+3545e0e5c1cfd1151cc87afadb78ddf7
+35468945cd3dc153b842773f9b1bec48
+3547a296f60b101fa83d70bbd5af7357
+354a3360f8d251c1325e0c07da19acc9
+35591414ad77cce9a68f44f79cf58d1f
+3559b54d3d55192e8ef41d33dd7b15e8
+355ad347f48a9528bdf54dca0254f11a
+355becc4d8481fd9a4b49dc8ea4fe108
+3565e14e1b295e6720683de39b1a4b06
+356af386a34daa1a4ad45d0600da3b47
+356b1463c3629377fd436d73e9f7f9ad
+356b7de6ab9db6e3328475d2543b74db
+356ead603654677198c3b05f61cf7a51
+356f54e4c38c913172cc5844c6a4d661
+356fb4ffc25aefb229b02c560912a14c
+35807b369ba6dd10455eecaf704d8dd0
+3583e55dbecd0c43bf46ae82c6ee8a58
+358580a3220a1fe1ae769d5a0b4e4f3e
+3595b555b52e4d284bae533a060dfb46
+3596d8cbb6383688d394e225f01db680
+35a399f6528fc280d3ab7423365a14eb
+35a50e7b3c35ceeaa432394862dbffa5
+35a6db5f924f9578edb20721729c88da
+35afdcc297f4b7050cf3b31d1e44534c
+35b0bca7b0d655ac188e5714de5099b7
+35bf2349ff6f24a34afa59c5567c36bc
+35d022dbf924569bdbe6c4bb21c925eb
+35d4340555c8792c541113fb626c7d83
+35dcd2f62a4359c2963823e3333aacda
+35e9a009803269c38adee89aec8f301e
+35f019cc4cfbd0bb398c8d80c9cda06d
+35f0e53bb283be5158bb00fed20d5fd2
+35f248c1518410144baa08924adc273c
+35feeb2f6ba92f1f5d7fd63674c3e4e8
+360334d7161e40c632f1137a7c4719fb
+3603d243177dee839081ec395b97b933
+3605da9bb07dafebdf800c5ffccdb22c
+3607db1b7c85b04483908aac8db4b189
+360ba6e92df37cba57460c88a0ac607b
+361cb7688ee9be369d62e7da4c57d7f3
+3620249907cbe1733751a4c820be402f
+36280b9d3f248f471ac6d1d0a3bb7b52
+362a08a514c962e04b742fe77cfeb6b2
+362d4eb46651184290b228d5a12bf65f
+3635995bef6c0c4868befa276f9604d1
+363ac4e99e74c4cf27e739fce9cb972e
+363b4ea76953b5941525546fcfcc66eb
+363e9f7d68f0f28fe8acd73ad8c84425
+364150bf99fcd801c2daa2bc3732d40e
+3641b94a2ab4ceb5b525c448b7333a5a
+36422c0231a049f9579927ba455a01ae
+3642afd134c3dc23b28531e8dcfbbcc8
+36431bd73da450cde5581e1e97193d1f
+36443f5b40be48a83a015eaabf46897c
+3644647c5bc413d130e1d1cc36c7e197
+364591cf543219a812c3bcbab729bc15
+364abccd40479337d04cd97d6c9bda6f
+364b1abf0abca92176a3413369409985
+364dbc58dd13a9d54b77a7948e0cb34c
+365b61584d9d77dcbf95d2b4b41db6f1
+365f157e4aa5354e10b1b4fee0d3effe
+36667c3bfa67c037166a5d4d2defc803
+3674c7ef5d6244b6641eaa0ff184cc6c
+367688e7770c0fb91ee0e1e8cbbf4281
+368274af83f344e74ec9212c659c409c
+36864a972ed3f19794e76d3679a83107
+368b9e89160b08fde99a90ba417f2164
+3690fdf54ebbbb26b77e2cb1ee8cf2c6
+3692f2d90adfdd0bbce24a3804803815
+369521f3d87bf056017f1f00d7dfed3e
+369b2283114a1170063f0c6405d9f5ca
+369c98b34082d5923a9e38d65c26a472
+369e95cc8a2fe5d4cf9cafb60bdc7dcd
+36a0badbfec7273e4a88688e50d1ae63
+36acacfc08e197db581d129ca0313178
+36b07189dca1530f15a804d7374cf8cf
+36b0b4dc1761a921a1d1ac3ae76575b8
+36b1e0d1aadeeadbb9d3cda1da02b48c
+36bbec6ccd6051de12e98a721884d9a2
+36be1e1e147dd7ade760ac9bc17bb0a4
+36cf14d72da46d182ceb165d1fa8a282
+36cf48d4f5d7a1d067bad4fb23d472e2
+36ebd20570c6d499e8a87ed2955bc28e
+36f0f09c84bd785dae5388fc5f36afd6
+36f634b240d904281999663f6e72717e
+370916fbc46d2681b8fcee7d9f4f8137
+370bca6ad73f42aec0b062bb87ec7d13
+371810c25e8147f5998f329bec527e32
+37268a02cbd52a7484552cf2646cc1ac
+3727ae623d27428ebd14013d0953d290
+3727d8682aa4ea256bf438117a7b8162
+373b4c36c80eb44320c2f8dddf4f7ecd
+373c150f5d844d37aa15a799b3cbc143
+374b908afc29568fdf716e19e2ed0a83
+374bf55c045b86220477a6119f17445e
+374df6b225de599e57fd764601e2e8f8
+37500659a18c1bc7aa06c60ea3639c76
+375052811c6d5b537c8780d763daf373
+3750842d15cac2e0064d1c9786ec03fa
+375c92acd79d52c574d0c2ad96d2b02a
+3760157d02865e8dc852ad2c16c4dd4a
+3760fef726c326cce48bac97d35aee8a
+3762a42809e79134d2a598b89a07a7ef
+3763392e529da1680b9f85d6198a583d
+376a10ec872bd19832a528044e708f39
+376cf9759983fcce7651384a807fbc27
+376f87522455ad5efec17f5c9357c40c
+3770bbfb07fad1f468b7fa9f130cc95a
+3770d0cb0f19cd8b3ccf4d668859c84c
+3775b5e2fbd916b88817df5343fac400
+3775f2eaca2f0ded7d9f779a42967d7b
+37789b44c7dc5153d3b8f42606a66e9c
+377a3e1be5e7751287ec22bb049ff44f
+377af71243d44c37ab3d8ab932ff948a
+377dcc7326523250a8ac4ed2c118349e
+3780f8c8785012f08ba28a7ea3d5afff
+37864a8687a5f167922bf0d86ea8caab
+3788328794c563f6a6d579b4c081cf0c
+378e6df2d3aac77b5d2dfa2165b74e44
+378fac22e64cc6237cd9d8dbfedd993c
+378fc0f343214cf1c4ac1ee1d15bf59f
+37909eb4df0ad182d28432caeb737f62
+3790dfa7ed15c540f96042c10c9bb038
+3791651de95a29ea9c1c2cf46b391da9
+379b4ef9cdcb22b8ea715853c6e737b4
+37ab65da231844186767c43803b0cc10
+37b2bb56533684c3642ed471d2185af9
+37b69abae8b5f216eeb9406911a8c93f
+37b9bbe4126f2dcd62e7273ff4478ec5
+37bbc06467e4157a48100a463bb9179b
+37beb6aeba28a6eff94835140a146bb1
+37c0800df62cd02e2f5377219c7b63bd
+37c1370573c6f1a0c935e1faf1b172c6
+37cd24035875dc17bf559ff5b963bfb6
+37cde8321b0b09adb056b9b174e8c3b6
+37ce9de96e85700e3a2ef9048b19fa1a
+37ced5ae39492dc5b6ab467e6498055f
+37d03f7f5a83e21f819d7f423da43f70
+37d29d64da02cd3a68ba1db46eba0a0b
+37d6e7cde57cf69996525c5949b29ca5
+37de99211282c476af174df0489289ff
+37df76f4ac6d83800e9932efaba690a0
+37e2249d03673d894d3beb67707cc2ff
+37e6cf2da160e7e68118bc98f6b7da0b
+37eae5f8d9ab516ab9e9e1ab85b86053
+37ecad7e162aa3b87b4211caf96fb11d
+37edfa54e732182ad321dafe3ca41334
+37f233ac5ce8d1e67a47057e78d9df9b
+37fa13987c274e6eddabe0b5d094dec3
+38067295d5ed9ed031933c0b6612aef7
+380871a1bb3bc2aed4b9f0a5c58524e9
+380c5e79d89b743c1ad09657d903b4b3
+380e92ecc06d063e8ef13cbe0df9b679
+38133035f10368a6a8e8b8d63dd937c0
+3818e5b55fb95308ff880d576c8e5db6
+381cc900e19dc17808eb818c90a81f0a
+3823ce333c2b7cdddfe5f9d677f26555
+3827a69a77d517f3c56220917425a3a6
+382854aa49127e8c5a40e6c1b89bb78d
+3828d02a8cd30483a8a9a1cd7969e1c5
+38311e31ecc76b3728ccd7b3dd8470ed
+383400e4f6d738ef993cc40b90e2950b
+3835374303556de0c2b6ee27c92ce931
+38432202be381ff7cdb9919ec4dcc6e5
+384473d074c85f4172806c42a1385041
+3845b7dc41356cc6c919d4441795dd17
+384a4eb0276214a6e24c2a7691064876
+384d314301425860404d40c30b1bba21
+385241904542b3cad90d7e70a56a4781
+38534288c49ccec0de9f89f8b9ca48c8
+38543f7a736332c1a595592d1f85280f
+3856ed405143f735c46f2efe85eabfa6
+386087bd84c21b3eeaf1d00ba186bad8
+38641bbe6aa7167add462a4e7c6fb1df
+3864530cff742baa812897fd8a848028
+386a2aad056e6d4a8b08a26f606e6563
+386d68e56ea66ebed95b4cea96b9dc20
+386df2f7450c639751c7539626bf3256
+387214738a9afb518321e0435a04c760
+3873e85963c3259bd3b84598d4f05794
+3877ff6a9df884464f134b056c3f187d
+387902a941657e9e1fea0c8d29def463
+387c868995c8a3b52b07e65209303b78
+388a6932bfbecb0fc10ffa55d4b0e1c2
+388f0d22a1b18ec5b6946df7215d8a36
+38953244e27777b89725a88c412acc91
+38a09d6ccc58e0683ceb75fed652b7ac
+38a2d86626977e611511705ca967ee0b
+38a34700119534da26c3e41efb9a6e95
+38a428ec47c89636cded57deaba497b8
+38ad99be123c02d3b8742c9a1fa5f6c2
+38adeba05c1d947b0b1ddf67566630dd
+38b1bb9fce45c2e2ba62c50b08385a3d
+38b9005a721bcc3816954f506b1ba273
+38c0933d114b36106dfcc5ff16aab35b
+38c473be890d122c98b9063e8d8fa68e
+38c4f923fd5d47ae0825466d93c4e2f3
+38c7e359c5495d5964b0c06e59cfa94c
+38cc528fd90a474c59627ff7e64ea08b
+38cf4edb1b7e3f90d208b32dc3293b85
+38d127c4fe00088989e39e779f7476f3
+38d8b0b84fafe6762d7e91b796a56f4e
+38dc848dc1d81fa39e73a9be9f97f1d3
+38dff965761a9f0f175b4135eb213b59
+38e0e5e826b875558d681b76f005b30f
+38e1de88ad8f9440ff885733f9667030
+38e64f17ec4f741e62a27030f42c0432
+38e6a28485336794c806df4f592f4cfc
+38ebdf40e1ad9d52fdcb08b90217de61
+38f50d4824385cd373926ef19f81d02e
+38f955e48333493ad96aafd14bb83c09
+39002a69a2f63706b5d579d8f564db8f
+3902daa847c56393618cfcbefdef04df
+3903a24714365f12dd9d9cc4c80e475c
+390792baf48c261728408df31f0244b2
+390e41b4170ff3fabc9abd1e2ebdd410
+390fd9c3bb478dfda6535cbec34901c8
+3911288eb8a975bd292555793f569812
+3913217f36c53e992cf01b97663bf247
+3918a7c7543bc6386cf2ce3da8933019
+3923ba158cd062f13fb363d9655e83b7
+3926b631de3e6a5721cbe6b58b7196e6
+392742a8e5865b229a4d96ff0a7c8b6f
+392cb94fe709675930abc29dc23d5185
+392ffe1dd7324d08d8295d45a5b99842
+3930b4510de2f1f8e130ac49908fde07
+39316b98ab699b1a416845c2670b5703
+393334c1bfd010d1b0151477ba4f8839
+3936b7b3a5a824d194686f886025026b
+39388b572d0e31cf1f7579fd48fd366c
+393f35196c96fd32feb01df0deaec14f
+39407f705a6902ec237fbb8cbff49d1e
+39422d454984ec0c166b6651ee81b62c
+39495df25e58468098f41ffe2d39265a
+3951355a60149f6ab15144855b2a5c9e
+3954ddf7e429173a5b4e17f4e0ee91c8
+3955ce9e3ea1f1b65a788d0b8b8c49c2
+39564351f1f1c406dbca8111bec945e7
+3956d65ab58114160ef4b31d862f18e3
+395f84c655f8c74f29a1b923507a85b9
+396ebfe1ae0daae18cdc1b05576236c1
+3975197a696ecf1995462811c0881594
+39770e8c679763f4607c6b206b8a3150
+3977ac20e8e7d188da60bae181e2c986
+3981479dbefbed4fa4aa5f2b4d54edc2
+39859a4ce83c7f0639c8da3b39a5f099
+3985ee38df2628379e3129545fb426d4
+3986f1040d1ac5be99a0837bee2c6ff5
+3995484da1f00d031aef6ca4408a22e9
+3999d7641d3fc150517940285ef33fb2
+399b31552f81eba91c77e43ef329e51d
+399fb160d5286fc2b69806eae1e59bae
+39a00217fea3207cd155c5174a44963b
+39a075c22d2883c45ec719c850990754
+39a191c572927c09f5472d5f75a1103a
+39a2882a0c4ed5e0fa11347bf2f0dba5
+39a345cc9fe610601b4d9d0066fd71ca
+39a7111bc91f027c2f51858c12228737
+39ac4187ff50379b4a5ca9558f8d0231
+39ac6e9d65ba069fee21b4604193657e
+39b022445fab87c2d8e00e4e1c79ed1a
+39b2897f34e8e2bd1e2a24f4794a148e
+39b7dfd4dab614763837b4ea7b1ff475
+39bf94acffbf40e1700a3d99ff1c0f94
+39c7d06a37aff7c848ba601dbb254475
+39c7f46d23e9aab70ca7ce612c855273
+39ccb06e496a4fac62fa124f83315e77
+39e33443f7cd308d81fc77c6e11b1bb2
+39ec45f9a0df1bb1228569f1bf16c640
+39f063decec0186efc32bd4634c0aac5
+39f16ba5200148227c0f60f9d62d36fa
+39f7024a15c13be5e8d88cb756b788d1
+39f743cae6ad6899a545a58a7202620b
+39f82a50c59cfa338ec6b38f313e7868
+39fce25f77ac0c5e4e07bc7806a6f30b
+39ff6881656172f2227e149420338224
+3a0271aa440de6bfe7bb1e290445091a
+3a09a0d6353bd6f1a0da46ba11deeec8
+3a0ff6c99d9d88c1061c5cbfd07cf4b0
+3a173a67ec6c77d2efb2bad964b6a2ff
+3a211f24cfe276e5ce189859d7f06af3
+3a26ecd8a19a179d0fc04af27128a406
+3a2743147b4372ebb65700a1be5209ad
+3a27bf17e85342a7133da5e8ee042e4d
+3a3084a9dc688ccc919b36694533e1b2
+3a31425c4afbc90ea28f9fe971b84ecb
+3a31a6ee30d322f75496d81698567eab
+3a3ad495ca040056e0fa2d8ab23f2da0
+3a3c4c1deadbdbbf26f602b0ead446d9
+3a4c962f7f68551c848b015d0ed89ed8
+3a4edcc8444f2b7375562b5d4ae0cf2d
+3a5b072d08e3ca77a44e7e2828571634
+3a5f418b41b15a3ffe6cf1eeb93cc00b
+3a5fe76ddf59d0ac8b1549fabbe8caaa
+3a60725ae776e3d7017469566650ef8e
+3a68747232efc550da0ace090987a76a
+3a6afc21828452d53e2ac1aec5a452c8
+3a6bbc4b226e81fc580bca6efd2dafc2
+3a6ee9d5e11e67c3d816f1ed8272b753
+3a6f925489d4dbb7a063af9d99400d68
+3a73dc9f458b9994355d79b275fdff6c
+3a73ec18a174bac2a1d580ea86ccd6e7
+3a78a5125cee5cba31500ae5ac3566e8
+3a80f4e044a01c70b0bc4e6027a6975f
+3a8346fa0f3d6c5d2a890a4d8e12be09
+3a848ce943b4dc20656f5f33bdf68759
+3a89811098f139825b98026da5f8bd41
+3a89e8576769f8a4a740dc1dc8338f0a
+3a8e23e2e0daa10ee1332ce1acb03fdf
+3a92b6926d67c622f663388ba6fc61ed
+3a9367d48778a157184388e47e43b0b6
+3a9e88c9be7cd74556868c0a82c81d47
+3a9f3e8cd12c5c86ddb098eadd69f249
+3aa6669452dbd6184cabeb67da46aeb6
+3aa6e047b6a695d6548e1ace434ec5ad
+3aa6f09a58afffe81f1c6fd391b6e7ca
+3aadb657236762da5b3e8a7ae1e85d53
+3aae840def45ea99e5e92a87f29a7476
+3aaf520570c69dbd3333917b059cbbae
+3ab3316e3c5f426a46961f7a065d6a03
+3abc409eecb30bee30a1a88a09699e4f
+3ac667af4b31c6580f390d02404d5e57
+3ac91a8cfaa9047d04845b167c87b04b
+3acc5f464286d8ebbb1c66b59e975365
+3acebc8ac46a6846faba3d2602256699
+3ad55af032fde133b721f98ec4300f9b
+3ad9a9e5444a23d5a5be99e88d14eb8f
+3ada0216319796f276ec2908b79ec2f6
+3ae403c69edc4d50abba199e93b39f87
+3ae790eb4ed906595a4e989d0dcc2830
+3ae8888372f0562991d958c78e7a0a80
+3af14b98295d0ca1f39c67b89ea2c1f3
+3af1a9370928dca6d28476a9c7587f6c
+3af1b86d1baaa8a13f624e9cab9eec07
+3af7289bca97fa75ea0b82c97aa73a5d
+3af8e8af7d71f5d39ffe6b047461ec04
+3b01083b32d1c9c4310c9e79b1ebeea1
+3b01e76a1c5e85bcd1f29e4b2275e848
+3b020c3907351b55b0ba558dc099849c
+3b05c7d9dccc31342d888de0d7ff4d9e
+3b0674a7d7a4be60b84d289af9e531ca
+3b0689437757c1b265ac8caf2be06c72
+3b08b7bb2f31bf537c13541f8887b312
+3b10c3b758685326fb8b0fa9dabad5b5
+3b141d5ef3d926be4a8dc49a82f91ebe
+3b14ed56a08209bd12b90c252f41e0ef
+3b17c0bce5f6c3fffe5d15713713990f
+3b1dd23289ce9a672de7b295ccffadc3
+3b232a0288353f9118c1840ab82bb85e
+3b2daa82154dded54cfb2d238d74d3ea
+3b334f7e730f7d835b0d59bdc862e627
+3b33823c69a3266982927254f7bff94f
+3b47db796b8d1ed64610fe7c919d57f7
+3b49f390693e5fb48b7e7f170519461f
+3b5492065772b0019aa2e58c3946ffce
+3b7631dfe2b8da532a4ee836f11d7872
+3b7952a65f91c133b66cdc0d15bac0cc
+3b79c08a1f5d1c836fa0afb1c70a16d6
+3b7ccf5cee33a00c51403085b66bb978
+3b82d8e20e63c42a2325a541b594b32c
+3b84f182f2d812a527f5be84125e1195
+3b8dba4b8bd0cc6a155187959b9f9917
+3b905a970cbe626caf135bca4fcef131
+3b92eee6edebfdc56483d87d98c465e5
+3b96abf0fcb55c771453e00d38000d12
+3b981c901e89d141283cbedfa5133136
+3ba198515bcdcd00d6eeaf152cae0c77
+3ba1b67db727736b3f29592302cf9014
+3ba29da298559fd022f3c4aa2c1015b4
+3ba7c64766592892a406d8e44531cc96
+3bb0d1c4c83e0d299ac2077d704ecd05
+3bb12c27955e2502a8b2571849056b81
+3bb3475e0f17051240b50dd3aa1dd277
+3bb3c85b2906531c261a20be2a2dc3e6
+3bb540bc22567f94ab2bd27f78a02d07
+3bb665ed6bc7137f6eb9ce3de733d788
+3bb785035c254f6a07d55f7f8b26b575
+3bb7ef95925d41876cb215c255f35036
+3bc1aa4203f9d63726a752406f2313cf
+3bc3187c3f76fbe15ef53264b999676f
+3bc37415c58707da8856f69281c0c5e9
+3bc73dae5adb310087470d3bb8f4653c
+3bc77b482b24186b82b551fabe9116a8
+3bc97705932dc2e81f1863598ae19389
+3bccf8638e604d7b97851f18fdb47f1d
+3bd016a11100db8a4928ade809a1e56f
+3bd4778c7b81b92271a8de5eca1dd7b6
+3befd41df2c9dc22564f111c622e6abe
+3bf3af3718d13123da499cc4af7a71a9
+3bf8bc79b7274a32e7f64e27ff8d3e49
+3bfa5b7f0702c3cc848b69df7818e25f
+3bfaf898ebbf008de767202186a61b48
+3c0389e02a3fbc6068684a8b584fa160
+3c0401ab0915581a6d3d4bfc936d8df4
+3c05854c39b99367751fb54a0dfe0c0e
+3c06e5c2de1ff0b9da9325797ba5d2f4
+3c07d6eaa59bca6377b38e90b7fabe3e
+3c0c0221b94b9321eee8cf74c9b98be5
+3c0d45d1f9edff689b0e7859d368af7d
+3c0d7a5f141a3b7bb8ba8a92adfd5e0e
+3c0f1bc1da419bcde6774b726be27e19
+3c168f0739056be2119650fec2e1b3db
+3c1cb62516603b26b2fcacee10b44c61
+3c1e4e03db5149a75b2ec6f79329f5ab
+3c21a7b882fd269c14a0aef55db11e7d
+3c21b61595618b17310f0018251aaa12
+3c24c6a7e0a8de3f8a90bff56406ccdd
+3c26a85f432a7069c4590d6d9e88eb44
+3c27522c464ba187ef8ab84869bb171a
+3c3693cdc74e0d32df84fe5a68a526c0
+3c38414ddeba374fb47112da2224750a
+3c3ec6e3424574afb2d9cfd3c863e070
+3c44a80e992c79802741a886a9d34d07
+3c4753a919e7d091343e4d49b131b1e7
+3c4de3178831c953408a4f61f3a94654
+3c514d7968f5f80cadc2f234cba205dc
+3c5c2a8f06b2c0b6eed6ec8146b5bdb9
+3c5c6156c4b343d4c75fbbdd549c3386
+3c6cdc2609d1a30f67f0d132fb0ef69f
+3c73a531e940b286bb46becd82087664
+3c73ac1a7a07d3869624bde75ce1610d
+3c856288a877721b34e68b0c12c8fc69
+3c884677aa9835e40a8458d3d87707eb
+3c8f0ab6ae19460bae98ad0b4258965c
+3c91989db0f0226cc0ca739f55fe2416
+3c94039ccab68c13233e615a0c0501b4
+3c9672f0b5dfa3edccd02e9a0e9a4a67
+3c996a0c1a72893f6429aaf1356af42b
+3c9ce4a5043276b21632da6308f4ed4c
+3ca45aa948043b665bcb061cc664230d
+3ca5adaa1a0b1c2059e7fe7da1b1da29
+3cab39fe34fa1d84ae0206a99a94e349
+3cc92fd751e64a6c5cdc90932cebbb2f
+3cca6c4a1435fc95f083895fd04bd320
+3ccbdb16a577fa870047883417490568
+3cd8fa6321d0df5960d8b2005afb9bc5
+3cdb5704ac0f167c86a41c45e0738ba9
+3cdbee13f550873cb8cc8066d5fc46fa
+3ce386941f7abad624f45b99352353d2
+3ce4f9832617c71b39d7164ac517f7df
+3ce7ff071e0df17efa0e5d17966956cc
+3ce8ec1b963585ab6dbe781aa976da36
+3cea5406163b5f2e2a56d64b106ee482
+3ceac7d9f30d846ef28cef1328dfaa5e
+3cf0728fed4a63b547b2f892f7e86a10
+3cf4a6c9027cd027d6f05675235c9864
+3cf653df8e4fcbc2609ff610feed467a
+3d00e670d35898f37365a5d7d0a8f3e0
+3d04eae10e1c0ad86000f1e7824e10c1
+3d087b670e492a7dac9d0b4b0a5d8c7a
+3d0bfd35d6fbcbb1d52b2fed1569fece
+3d0df6f16ac447a782a5ab55808412d5
+3d1952122716fcc229e9551f6e69f8d4
+3d1ce390a81e034a6bcf31be98a79e5e
+3d1d5642e200b9c873d55711e48fc365
+3d2834f5e417f68c61f9ad9cf71f2ca0
+3d3782074dd04f55c3dd47ea728b9cb0
+3d3de3721af68032c502270d55e26b3a
+3d42d0f4224340c239d8b630496a1ccd
+3d43385a5fe890d9dd8adc3418ba2c73
+3d4800eac042513f0e21cab2c9cbc964
+3d4abc82204f8abb9ab08133a50cf8af
+3d504ada6a3b5903886be22d1eb022fd
+3d53abf677190ae71c595be4e56bed8e
+3d5eb68c8fe71ca5e514241317f3ab85
+3d5fa0e244f6efe36d55a07c4cee3a34
+3d63f65b8a6818fc308d96752226cc2e
+3d6a0685eeffe1de2b66c7657bbfb0df
+3d6a5f25a5a44d545d500e7036c3f23e
+3d71a80ac34dd222b9da883b75601050
+3d77a820d1a5faf3705c17ab7b81ae67
+3d788ea4215854207262556cbb4ddc73
+3d7ed579aef715bb1bf95ad3de8da089
+3d865bdc8080f835f04af56eb440657b
+3d8f499cb34c90240bd2cc00d58f055c
+3d99b44bd87da556a1c596a7ab28b9a5
+3d9dae3e25aa1019496f004cf1c5aad3
+3da09c0d774787306f2856a0daa21e5e
+3da3bfbc73c859eb79cd704154f923ef
+3dadf9a64746f368c0c2d6f9d6b9428e
+3db69850d2f11f4c3e8e06780d569ead
+3db6d01d0f3c363b28e2341a58f1702e
+3dbc9150c5cbe5ec7bdca628cbd18c46
+3dbdd3d58d9410bb77f35ee6be7575e7
+3dbf3d7f80061a1ef2fac86370ab0fef
+3dc4dec8e9c6df1737c2236577371252
+3dc9e08f639c371e5c25ce103a0e61fe
+3dca5f09c1d825773a553149a934f71c
+3dcfb3f1b02bf3cf2f471cc2a70c1560
+3dd29b520b16cd06596cc74b0ef3c0cf
+3dd4bb8c17802d55ebcfea276043745c
+3dd6f4f7c6c93648a44c6ac1812a9825
+3dd7764caa5e715e107eaabddd8a62e0
+3ddae4c3c89fdd11fbafe870141eafdb
+3ddfd5e29648883d0720724fde8b0d16
+3ddfe9d2b13df4a4804b5a3403ecc8d5
+3de4b8eef3cbd4b3236cf69bdb44c111
+3de8b31525449071be8655cadc6125d4
+3de9622e0e3bbf930bb79e2aab7ad97f
+3deb5b21adcd57751e488c23b5221d84
+3defd5d062422531fe2cdd5311216d06
+3dfab7c34e1dda742b6c5e6463e0bb26
+3dfbf8f4034bca36a9ab927eba5bc427
+3e017515f5f5d58ac0b45edbd9347d4b
+3e018700293ea123b1496a9a3c1147d7
+3e02b99e7f6a9f3be7e210167b2ac1b9
+3e0449d4ecba8f08c1181abe85ef31b3
+3e096a04d58f48729a36cf90164c60b9
+3e13b7e5515e5b7dac5a637a44e5f0f1
+3e144846ebcd905bc28a6f1df46c7d51
+3e16986abaf0ec6cbfe7276a82327668
+3e18f8652ac45200f7c869c204059b59
+3e1a588cb45560f3a50f687e4a92f108
+3e27e355d351ec66118919d99eb1a53a
+3e28147a8058ef2f38bf1666f10f257a
+3e29d72d6567075a39f3a3b9f34f9553
+3e2f456317d4631b1c1e21a9bb23cf7d
+3e2f4cb3d9fbff406ce1d6ce1bfb17c0
+3e34225eb8b013d6cebd9495e36a2d14
+3e379abf2fce66fe66197bd3de7d77e2
+3e385bb38db48ce205589e04b21c429a
+3e41b6ece4871dfb201db6b2c3a65e33
+3e421e5726eae7b4049513b424e441e6
+3e4d3f30d3a6f29f250f6037bc70632f
+3e4eac23c982d671f93462b410c95647
+3e50b9d5fc0e52c137401a01019d3e12
+3e5e0479fd72aca1d930adac5837bc4a
+3e64dbe157108ced1bda1319b5a315f6
+3e653a5f841bd5ca46b1f7ddd4ca7548
+3e655a6d9b700633807519e6ecd6cb8f
+3e684cabede2737007c155d766e22bf4
+3e6aee6859a250d4705547c321c80866
+3e6d23b31fb6909cee241d53100c972f
+3e745e585ee1ea123894c937cebe22eb
+3e76280199ba98025f30d8895086a577
+3e7920f3f1709f2376778819cab23cbd
+3e799ab7a7ca8b8ca14fe437855cf51d
+3e7ab4b868f29a789a409374c393508f
+3e7c4b89a4fb3fa64b21606944b47041
+3e7df75d96ee71dba93c6af4de97c968
+3e7f889572ac80bf61ed5bd0617ce1c3
+3e84a9b9acba27535142858f9586badc
+3e96bcbd502e6feb33b5d0f779a11971
+3e9871fbee9421ccf32e0c3a029d396a
+3e9d9eaad98cfb19e5d95dbf660fc441
+3ea54e3198b4509396ce594940685ff3
+3eaa3645b6e85aa0385afc516afc0987
+3eb58b28537f15ccfa7a4950869aa210
+3eb7cf74f371b87a5ba5f019c89e71ca
+3eb996c364e2f02fc3b02acccaf48654
+3ebf274d825d273cffac4d8e2470da10
+3ec531bfc9d4b1bc60bb1c1f2837ac0a
+3eceb053ac65aa92dbe68c13411bcc22
+3ecf94d7e1ab604309242e72bcc57b27
+3ed17d6257ef9181f7e6302f06ffb645
+3ed76ea8de26c93b5f636c12099e22c0
+3ed87da6d667aba306945c59e8b36279
+3ee97772c9a900f5633774f056d4364c
+3eea27c64fd62eb3bea5d503e91a3c37
+3eeb961240056b10d2612ec0cbee22d8
+3ef0805ed8036ec769f120986495bd7e
+3ef2f00e77116b7bd51157e9c9023ba9
+3ef545f0b0acd9af9f145deba954913d
+3efa421c937f5739322cb19edb0fda73
+3efe51b603500f536a85ad5a0a4d1951
+3efe5501bd862bacfe7dc80f27bf3fcf
+3f047884e4a6a6cfe58c6363418e572f
+3f057c09941b292478686da07d569311
+3f07bb2cbd2ac1978eface84584a9b08
+3f09958d77a71704b97936705f02e757
+3f09acf4569cd3696596894d58575836
+3f0e5bcd0c79102b3666ffe078adf354
+3f149f4ebd3e4ce4a369c717249d6458
+3f18e7f3527f455bab21626165f69fd3
+3f2116bb42b1d613dc3edb5e90ef9d4c
+3f2232694e4610ca0a8b3db345e4cbaf
+3f24964b12f0ec214acd3d7a38f02382
+3f26251b2b2f659e5fa72e5eaaa4952f
+3f2d26dcd741945bbc008815220dfe68
+3f3011a724b58b5dedb0a4ca3801e949
+3f32b1174f0674892b53adef3bcda92b
+3f3418d5d28d34c069b55b5107598d72
+3f37930433ad28e06ef247dc3219f30b
+3f3f339f433df6ec1668c1fddca92606
+3f41fcca900a60a1444346350e9cdfc2
+3f42e114e428c9865b3949e144ae73be
+3f48443a5643ba36048d2cf251b5d1b6
+3f4c941f4e3d478a7bbd8d7397a91608
+3f4d019d9b5336585ce811e6ee1add12
+3f57621afe706440c8ae50f9e7efd5f7
+3f652abe93ac9d0c39c917a7e695f3d2
+3f68e02435c98122b7dad0533203e39f
+3f6ab011d1c8fffacbdbf8d9fe960dc7
+3f6e961444df055ca0e12a9a76144422
+3f709488ced9f5cb8d8765018e16bc0d
+3f807d59c1e6c047b90e0c7e44386419
+3f847cc93e19943daf982798399627f9
+3f863b92d8d41f8a6522725591430102
+3f8ddbac8ae9bcc9e4a706d59f3e0202
+3fa43937ea480320d1afdf564b078611
+3fa58d5df808e8b7cf1990363e266eb4
+3fa67ea4fbc892211b440fb18d0afdf7
+3fbbb6da41a46b5279bfdba9ef42144a
+3fc2548b18d2034935eaa636c537ef03
+3fc5ba02b7422525e1b2f774fbb4bd61
+3fcd0fbcef3d823050c123d0922998f2
+3fd1f53f6aee7de8f2200aa4f678ca3b
+3fda81d0a78c843cf54e98c2a1f8973c
+3fdedde385e9c69df33e78804a2d30dd
+3fdf9e34514e3b06c376ffc42e538b07
+3fe262ed347ae3af35d5ba2e50ca53a2
+3fe394e541a5be321b35e58e2e51bf6b
+3fe9987a2fa1263bc1b0b05c90fb9fca
+3ff0a3f34b820babdf53b4aa60b3a629
+3ff2e061c416e4bb9e65e82e8da09417
+3ff41df90c3232a8c97a448c1466b3f6
+3ffa730af5596591f37832ce34026dda
+40049a2209a906045c20c2fb9a2b7b17
+400a150fb40aa2c61fcd71d5ef34f727
+400bb09d5a650bc0dc09c974786ecff2
+400ef8727a0fd5ffb7760c37526f7b05
+40107bf0a74657aeb7f7da5ab2c8f9fa
+40112f04b89b7db6a5fd8464aa02a271
+4016a4927786d6e458dd68d9db758b80
+4016c7d63f07b628bfab6fcbf2c9d62d
+401c834177a2b90b2163d23d9f31115a
+4020352328ed7dd4b80831a7030712d9
+4023222355cb776c9e97bbd39ffd856a
+402666c16a295046e9ccea00e1041503
+4027fe4ab7b6b10c8bcfc10b9413f387
+402b61835ba8ab20423e00d454cceee5
+402f5ebbfbf10caebb07b86baf175a03
+403459402a1d190b58cac86e5e8d7c1a
+403a8388cde8f500ed1675db384a1df0
+403cd689d2dd49ced15dc3dd39836af7
+403d2b88c1b56474a428515160cc14b5
+403ea2737ce9e2604c665ca790d0aef9
+4041f435e23c509b14a620e7a0eb19c3
+404262222de184d1732d10095b8d378d
+4044c1ea878d12f3d7fa41120b0143e1
+40471c80c974943d5bb721b07268c853
+404d7cf77828e7b9df64e96be8593bee
+404ef2b16b595f16580a82ff5e533167
+40521e8ff349ab9a1c3ad0038576af0a
+4052a6e79b808cdc9e577bba851c466f
+405cb2cf3da45ba09918d46e84d6b12c
+405dd1389fab2c2f861c23014c84d1b4
+406575bc513688b7c4277e3b95f86321
+40684b24132801c79271366a657ddf04
+40689df8257b52d5a9e4039a41f15705
+406cd414b08c8e179a683bc92fa516ca
+407a5e580a5270b3f8b29666491d1b08
+407ed137051fb99fdea5c62cf6438553
+407f696569038fa1a4e8fb9d8cc6d935
+4080dd3ff8719d3b6dc18e899cd59eb8
+4088edc46187219368a685c6e3cd3103
+408a376a00135bc714032ccb9506dc2e
+408aa361f273e371684583fbc9494ce2
+4099a29367a6ed598ebc9ff549c99747
+409a203522da70662452b38e9a19c15b
+409e9cdde3c5aecfd853cacbeb6b2249
+40a1062ae8723b9212095881b9abc378
+40a7217e89618b959c9ad5258739b458
+40afdbc2650c0bdcf9955294fab4a89a
+40b0cad4ed3bab8d9a2175284c3d6208
+40b1832c39f132efab1536d7e543b782
+40b2ab591303a7ffd01222aee78a4be1
+40b3713157a5325fcfa4ccad92a59d4c
+40b53df1bcd59c0c4247c7381c4b2f91
+40b60938c2cfd86c8d5dad302b4efa67
+40b9231ca23a9f5851eb61e87fec6aa7
+40ba4ef322db3a9fabe64202c3a612ff
+40bdf5fa9ffcd9e42bd52bc36834c277
+40c3a4d1ae728c127bfcb76e5d235ca9
+40c5d990883e9ebe837e29a72413e064
+40c668c81ce79695f241bf557b06912f
+40cafffa5d03e48a918cec4978b99010
+40ce9c9d7bdf182430aea2eae3e53b7e
+40d117d31d7826d7d50d7f321016e36f
+40d17f723372a84035ba7228ff601de0
+40d3fa3c4670b22e8bd4d98f8b2f9974
+40d45ee25ba2901c961646811f31715d
+40d67c30649267fd9ef8c47bf8ee7f2b
+40e5f45f7edb5581771005483ac467e5
+40e66bb3e127718c7d51ae6d5ca9f5bd
+40e701311855a783211afdc43cf00434
+40f6b0c39d914a070a1a5371858772a1
+40f74bdc8e06030196428582d7fbc778
+40fb71d7eb9b5b251b53b356eacc26e1
+40ff037779278496af784fa52307e412
+4104132642f5a8aaf4be3c7487958d9e
+41064f90416c4896489d911f3222f73f
+4108dda267c497d29de2f3a46c266e82
+410a51df65d48f2329322da2e215e1fe
+4112c57bf460e2410192fe358d81e67d
+4113c121e912619ecfeb5120abf9a56d
+411422c490eaccaca77f31e077b2e03d
+41153e362071df7a1dedeaf5f6c1751d
+411ac6a706fd5b3758aee8ffdc8a610c
+411c0537bfca3dc63968875c9f9f0e5b
+4121adf98a43d85c1ebcb34b1ab1d4b0
+41293f156bcc06f76b7e06d552eed963
+412bc7aa78f2e9fa5069a403001113cf
+412d1843edcc217b11612136a49595a8
+412ddb95abd6de2c999edee2ea3c62e6
+4135265654bfe0e1d94f3b8008e7412c
+4136f1ee7baadeca682db3981d1e529f
+4138e5f698cba3b40b096262d44ab8eb
+413c1ef13d90cd86ee4015cc98e17001
+413fbd39d55dcabe40edb99f19feba41
+4145215cb615d7726e6b4f563dda905f
+414546e0cbfb5880c0ce9526d6a62e2d
+41479e2f7e6d2d6c69ee26fee0c23a43
+4147e659817d3f406ab2630ecc8fef03
+414a7836435d3bf8918d5a129ea67f71
+414aa1d8a65e1d12abee64c87b970cb8
+4156d09deef99fa0ed5fabc9cd068461
+415abc09d3752cb3a0b16ec54057b45e
+415dd58d63055a6a1560c2658ee7e5d4
+4160d3f3c315293195f70b6267b296aa
+41610f4f4771abd13e46bd320fe0f105
+41619fc927ff28676cd0cdfe55764d71
+416b1f6aba90a3743228ff3638be5c6c
+416e0292bbbc90c700a17565ea8b9ec1
+416e88fed12bcc8ab2cc69065344ded2
+416f79be45b6a9a9c2aa8e01bb90d6b4
+4171721ddd34a8f24a12a6b69dde6792
+41752fcd2505495a50c7777fbb17b61e
+417f397943dc5e83789d43cc2b262f54
+41852d280315f97032346673499336f2
+418ca751e07a9efca344d18a054a831d
+4190bbcd76cf8dd7a95d861ef07ae75b
+419934bb4e79f9b99849ab01e7f5aae0
+419e340841220de6c315ba9eaa8a6c42
+41a3214001b39a1bdc7d462d83f6058d
+41a7125aed71705e1cbac88494345f40
+41abec7e3166688c2e83232e8df9d715
+41ae8ba02e2200a3552e2efd0d73a3af
+41af2403d1c1519f8113b2d03450d6ba
+41b05bede067e4d5a7e6168a08c22455
+41b32295baf7cedf392ec149774093c9
+41b37fec172d5394c70043b175f71ab5
+41bc5017d7ec0d2bd96094f8a049a6fe
+41c12a4f2f16e77c6efb81d24ae75ff1
+41d3a96d629de25911c8a91bffa84c11
+41e4f4cb364d2dc779fb919e9d0a3575
+41e72692c542c25526dbaad4d412e031
+41e88a1e59acaf4b04c7cbd15b24a7e2
+41e89b6c5b863a8ca2c24fc4de68c0a2
+41ef0545b9a3d8f2fccde2daa1f370bc
+41f77b6c44e30897c9c169d97b659018
+41fa09550baa6720b89ad14a373171d4
+420354c617ba6a59fc64c0b340bf337c
+42042ff4d73237771cf05a81b590721e
+4205e410995898e524e7b79bf1da4983
+420eedc9b7da410f66948e7c8bfaad6c
+4210caa5b5afe2783afce20300e546f6
+4213c392331495b0a6b65599f7897b9e
+42173bafa1c1377bf7dafe5c902c37eb
+421db0aa5e1ed771cea8ea66101aa6b3
+42204b0f6a5906bd37c26065d5311313
+4223691d860b3cd478e86bdd8e679012
+4224e1f7cdede3b4d0cc83cc63da4c3b
+422555ce8189220b02fe1bcf1719edd7
+422821d8d2ad6ffc1a387259ad3aacbe
+4228ad1f0d19d1ed2f5dd22604aec26f
+422a2d2be218fc7d709d7269a2f52183
+4230526e7a2d70a2c7b71a368e26ca44
+423357cb5ac46ef48ad40acb58054b88
+42343166d37606ba4c8eb661d956f666
+423550055157fe0e0670f571aba8a58b
+4235c6a979393790d60c7f59560f7404
+4235f476f12e3d354fcbaf9d22f464fa
+42367cd52e67ed3fad82d7d11f0e1892
+424491c0de9f5238ee82ea0eb4dec3a9
+42493f55fbcbb5e92af2bb793b6f21ea
+424a1f26ac3d67dbdc1a8932f548cd1f
+424f7d9588065a8a1babedc2efb5cf92
+42563c077fb9d138aa3f47b01cf0a2af
+42632201a82e54ff11ca39a76c38c12f
+42669b2312606c5c76849bcceff308ba
+426a4615ee936704115998f4716395c0
+42744f233da2e79f70f66abde1d75ddb
+42787b47e1f9cf39a870cea54b8dc6df
+4284f656142bcdb95a99895036937f0b
+4287946be484866c95a04a4a9aa5fbdb
+4287fabd5691d26db3e863018d71a262
+4294fa7f8a7ca533c1eb3214a65a3970
+429919e08486340ad479589ff3809ba0
+429cc9f59b6a236c9202c6a3ac5dcb01
+42a48b36c46501fbc5cfecadd624660b
+42a6f7e4a402d5fd7740698562772722
+42aece39ca522866d4a81679beb5cdaa
+42aeddbf53591e60c1a4ddc32d5b5de0
+42b214f4618fae53e60d1685e0d61851
+42b3a5bcdbd19c00940c84f40cfaebe1
+42b43d3ca62e7c442387df0035ba5416
+42b4e0c3233a4b96188647e424c58e4d
+42ba7292964e7e9684d329a8f3e18725
+42bfe5b3298c8de0283d22fdf4d8e0e2
+42c034a5032c8eb74c9c00705ade3082
+42c0db1ed3799083e07e66bab363c377
+42c248ea0e93256bfc35f6db1477b751
+42c2babca761ea216d00f876f29d95cd
+42c3421ad246b3b727ffbf8add512d7d
+42c3884440d001e8cdf35c726ab8e274
+42c913157a0a820d7cb43b6b51c017a1
+42cdf4919c8520189572a1f2939b890f
+42cf020d0c8a9909d9be6404bf789844
+42d15ac774ae01f4e69ea1c8f26d0133
+42e1c81e6b64c988131b0385cd688e88
+42e4e46f14c8f98b060efab7dc996708
+42e70e85460efb4b486ffd0569f67cbb
+42ee610ae52f808f329369cc2ae23c0d
+42f353a43086f44f5c82f7d9a9b17873
+430598d4df2e430ef8f2a135359035b0
+430713217a7c78d73f1c6eb89b09f556
+430c0d4d833c604e3f26618929a418c9
+430d4abfaaf329c5a25ed12461303793
+43131e3f9cd25cde859adfd48da33bf8
+431597cf12bffd6f3217f44a6fabf1fb
+43175f3fc31e544a55e77271c9ecf6a9
+431b3455620f6c2998301ded60676b2e
+431d16d731a60ed44ec100befd5704c3
+431e1c3c6a6fa7668db0dabeb52f567b
+431f2609672e1b81e7669b4e767f2f78
+4320ddf2c0b21dca6f398908172e3916
+432469a4bdd725527ac11acd6e7155bb
+4324cf094c8ff59203a11454d749a2c0
+43260bdfc2aec27c4fe0e73f32cdc2f4
+4328168529801aad486486af8567b2cc
+432cdd3f2fad54675d12a1718d748583
+432e8d874f26dc2457df00ffb6de61cd
+4337a84a2895f550ed573fe4a06c591c
+4338546ebb26db1b28161c313de2fa67
+434c84cb70f856023ac7fbcb248c481c
+434f70472646c4eac1fd1a01c593e30d
+43659f426e4e19c457a92bd2ed7f5c8c
+436d21ea6ac9a50f61e370c04cb3753f
+437295b965d9bd2e5b4a821275cf5925
+4372cf766a55674094405d72dff17c15
+437db62b1872fce224cffc5cc38f3e90
+43837c5f80a1f9056edf8b89e83f08fb
+4393429b94c68f3ce7127c909573ba63
+4393608ee40c8b7f5fd5b44a06c1f32c
+43963dcba33a3ce7e3f95d5df3d921ce
+43981ce78ccf46a0ccf9f8e826461a30
+439fef7ee5267773fb4a4a2c264e8c08
+43a221c59352e5c4ed9b84085250487e
+43a6fb07cc4e158ea48b3aa06abf5955
+43a70ad9194fc0425529e5abe9845e9c
+43b6c80c688abc615d091b03223517b6
+43b891c9854d1a09435dd49172497073
+43bbb50f3a3704870c05f608945fa4ea
+43bcd47204c77586a115001dd7e7c234
+43c19ca7c047a86e215f3d719e95952f
+43c3808a1c96f07c94daa14d5832f858
+43c3a898f8be2d3079916bdac660d5a7
+43c3ca858f9f35ea701c88ab1e03998b
+43c84636144af3849713105a0566f34c
+43c85ff3ab172f71e2f479bc91a6a64b
+43c8642468fa77f61233eebc4975086f
+43cd401442da64ab6ddb4f9def6e93de
+43d360ec4148728021a3d815f771c768
+43d3dfe688085fe054dbc128d83d378c
+43d9afcbaa31c297b7c5fb679ee1dfdc
+43dac02bcc00fe8ab16d8e1b5a8f846c
+43ddfe870f096c8f448a9b142e2f055c
+43e7361b61c2174d0365c5c544c1f78a
+43f18d061a871ed820c7e6aa0b122f4a
+43f26f2f2525c241cf3ab6c88c335919
+43f5d1d3068d8215b150e7933daf018e
+43fb628fff034e92aad9456ec92c8246
+4400134a41a304c28c191ed89a96dbd8
+440124d8176b7a7a88689f4b73b03ebf
+441204002d5b67030ab89cbdb2fbb898
+44135a0ee35d6bc613e4f5b293aa9ede
+44148a43ff011633754960b70f07d939
+4417553d47df2fb06e2cbf506418c0fa
+4420cc90691128a89414c8182fc7e049
+4420d501d0bd1c0bf0056cb2e8803c62
+4421d5a4e307ccf31ce7128b466d62f7
+4426d3f7143afcf41e15a7e1f2c69dff
+4428e36d05eee60c8c3e2f934b475544
+4432931465013262ce4b85e918d8197f
+4432baaaf21cab35f667862d57cc1f72
+4438214602af1aa9f5299f3ade2873a6
+44391bf5e4d8dbc287404dac68c600c6
+443a6b1e66608e76ee4fe65d4c260704
+444fe0202e5698467228fe332e11aed2
+4450e51a64adb6b6b20562744874a370
+4458e3c3b2d2f79752a011fabb8a53f3
+4459a2070d6980791debd3d79e5d9d54
+445d07ae80ebd3577262ca0135ef8dfe
+446fb11a864d5cde75d4c4ac058a46ab
+44707ecf8747217619c3eeab4efe1335
+447a56bc0a43fc1a75044e5f53b28472
+448a55731795e17b004e766e2f47a6e0
+448d6f0355a0b728eeaa26181f0cd753
+449388b9efaefa176a39329ff23fd19e
+449a50cb81f60ca19cd37a3cf6f40bb3
+449caffcf0331486c8df5d491593e0e8
+44a17c9ab9116efcff4d280bb803c78f
+44a31ba21d52b17655ab3949da7333e0
+44a533e90428d80eeb5e7b84bae5ed28
+44aea46d57e6bfcc4a05ef32b8926564
+44b2c51e2129795af200b76de1354d6b
+44b7a53ff264a6452af3ef5330323b23
+44bb167fa464c8cea4182ff829ad593d
+44bf83dbb839468a9e60655b2f6ee649
+44c24036368765e60c980e062dabe4fc
+44c496474333968989d2404add15ba8f
+44c84902f9739f55947bec0caf314e3d
+44ca1b7c43f5828c7c13c4b786ad4f2d
+44d0cd9ce7413eb3a1472e94014cbd82
+44d25c626e92c0ce998c134d30367ca9
+44d4232b99207587ecb426993407ed1f
+44d4f0f6808a22ad71275890fa0b4838
+44d65013c96e605af4f986f3ffab5d38
+44db457435cd0c8a95ec022bed430d0a
+44e044a5820c3d29ab5be5c13ecfe943
+44e5bf503c43d1c1b2c0f849e62ca521
+44eb4e53cded2adbf129967ddc569538
+44eb5476928c0aa716b0727375e98086
+44ec00115933efd9c66b18b57e486262
+44eec755ab157adbf5d8f2cd00091274
+44f335d4b815f06c86811be7ad241333
+44fbb4c014ec70a3f3f1b6fc03d10e22
+45017254704dd17b0c3fa6823f72a9d9
+4504033d4292fdb45a6f92daa9551276
+4504999d921c9308e1b7b3acc596acf0
+45088cbb325573a300eb89869c404488
+450d1f5343489b9dcbe9dbf6d45cea34
+4510601d673ff508535219115c57e071
+45179d9f9d2568d614aa317459db6dee
+4519dd06e5371f37409c093efaf1a28a
+451b135443d1db76f04108524006b6e1
+451e256740fa9aa45cd8264dae3045a5
+4522a2b70cd4a97474dbba2657f41bc5
+45243f170e9fbba7c8707baf4183b0c8
+453b4600c4ece261e0ef33ddadad8de0
+453c8f31907498b714ddd931691b1d77
+453ee68241357ecb070b5e57695a8e95
+453f6fa7ef70537d6ca9dfda03d1c99d
+4540fe8437406ab045e89ab45c9fb70f
+4546727252bf58f4ce4a368cc51875f5
+454be8cdc27968096eee0e7f90acffcc
+454ce30a8392666e072e9dda5ce7db17
+454e74777761111b10d605bf77d91d4c
+4557e835d62267fc8f037ae5079f4650
+4558d7f1fcdf10e800c58e0f973d0448
+4563ff689b0b986846c4fc79bbef7dea
+456b28e609d2f3f127887bc2e55e5692
+45713d40feebf7e487c5007ce529f156
+4573d4488727cccde5f9364a200f5817
+4577786aa9f49dc3933cbb10f8ecb229
+457b84157c97fc0ed12ab5c849c3f4ff
+458592896cd20368fc2d138999207788
+458c20a11fc24f19be2bf57c639e4678
+458c4be810ef38702f5183f54b7363ea
+458e759663382ec23676c5be0c39d1f6
+4594f29588689ed2a192adeed7eaf437
+45969b43dcbbdb0091b176ef28b13019
+459a577a90c09131ad3832bfca60dc1a
+459e5b8e44a4b842507e73687a230ed3
+45a4c388512a3a1efb0d7d122244a204
+45a61502936314dd2fefe089580279d6
+45a820cba54f5799902b025d69f1a04f
+45a8aa042d7599ab44166da01fcacc38
+45a969aba8d88304649acb52c61a94ab
+45b0f8119d312778ccfa889718ed4fca
+45b2ef614ca475ad65d251eaded321bd
+45b36f1c559e8ae7d7824e8708627ef0
+45bc5b0724254f977cda3dd4b5f55be6
+45c33bbeae7a685c908b6a6ff165a35a
+45c37542fc32a2f80a81e0ebd26025fe
+45c811c490d6f0e377246184a518169a
+45d867161252779f3edd5c09a164c84f
+45db2579c0495ef7b88862ba3e0ac03f
+45e0030b9949a556369a52d150d26f54
+45e0c5d3916ed493f7cc425acc005905
+45e5278727ceb349c9774a6570c078db
+45e7adc888b33cb12eca02322b5b67dd
+45ead397ce775f6b4bb90be1f663bf4b
+45ec0d06cabb5a7eb61a0fd853e612b0
+45ed26ff43beaed41607ecee5ed0a273
+45ef807d604cec1b99dc16f10abd6e3e
+45efbe27f7faeb6db67dadf1fdc69f55
+45f36bf149298c20f297977e8bf2587c
+460a6e2fccc860fbef2bdf4b6d411cb8
+460b23c558bd5de51a662bed74e06c2b
+46277dbd8beba3289a45fffcffecb810
+462c642ccd7e9022a8d75b6fa91b3383
+4635fb65617564312a317aaabda4b1c7
+463937feb81c81ee1c4b3677947fa280
+4645a4ea725050f4bb17440803c1c5eb
+4648988abbc3433a5d1390ad253b3b13
+464948eff059a094c27cf540e6afe526
+464bb77f33ff7e1a38e7ee1f0a8269c9
+464e69973404f7c123efe3956b46a8ac
+464fe9cee3b77c84519ac4b8c1650aab
+465637dfaab56b8c9c1028923b081f8e
+465d692274c2d0b908fcd64825d6b4d5
+465e9119778e651b72aba5eb7683e5fc
+466130509010a6bdd4b7c2e1d333027d
+4665219fd8480018bc3999cd4d6946e3
+4665ebf0d93852120766d57250fc032f
+466ca353c78a05da085d107914a6c37d
+466e26e2b6f4361cfbeb920dbf44b7c3
+466f71aa284268708f03e269585252cc
+467c09efaa7e0c09f5888a4f944815cb
+467d314043a983fe5111553a69348874
+467e284a00c60953e482908d3054af9b
+467fb49413b6af1b64c0ff26d99bd981
+4682dad548bedf7420033aa256601a5b
+468c6b41d5706d0934bb4af48225890d
+468e729086d947d3c81647c064720a09
+468f62df06db6d227a7928994a752444
+4690609a0c86d83ed90063b2cd387df5
+4691c8c972874acdf9c0128544180c18
+4692d1e0a516cd4732c8cbf5f4422eae
+4692eac475e44de63727430b6cdb37aa
+4698a90d8af43d76d0434f2fe7ad034f
+46a336c0cce8da8cd58a0f11772549fa
+46a80ced56261e250f7f57e385e378f9
+46ac82126c721feea1f313bcad970b7b
+46af1751d1172d31ab88e50f9657438b
+46afa208083d609c936398370208137f
+46b0a098d347ffeef33d5abae67a870b
+46b598e6c09e2e0bd13bf7e40b2a4b6e
+46bc59720fb5bb6a03687a56ad924424
+46bd4b2de72f6c396e914b56f81094a5
+46bec85a900423ab4bc30109cb9ae494
+46c070f3c65f16daf74d91f481c1d1b1
+46c3d5db7c22343bd1aa06a40431f455
+46ccf323a1914df94d5453d3222a305f
+46d36114e5d892d9269ab00f4f650f5a
+46dab7d2ce3dcae20935d972e18776d5
+46ec8ae78ea8ec9a87477a9a1509f356
+46ee0f72266b1c86eee0c7152a880a82
+46ef5559ae123a43b8d4048ada6f1d01
+46f1aa877b0f11e8c389b752c40a3d65
+46f1acad8cdbc7abb403df9dcf3f0799
+46f25128a4f7a4f2f7ab7a9221fd260b
+46fce2081322010b5a284b2b6b243ff3
+46feaf33f06e88f668efd1a178fd3090
+4704325bae6f7b896ceba4a8e9cdca5f
+470c6e1cc5737b60b0b62c3d7d181b93
+4710497acea44a379727775d4f076e0e
+471a0562ae4fda1174921273aec5fcf3
+472ca3d3b145e6ceb9934c0242f6e8ea
+472cf2000130f8a77e3b4de2265facdc
+472ea38a6ea8b937b2b957356faeb06f
+472eb1b0e2872a7fb640cf4458606413
+47342fcb9583ba20c9c7a57ad068cb84
+473c57f1cb2f656a414bdd356ef4e5af
+473dfe82d654758cfe657d9061bd6343
+47478b25e22d9d4fb061989d2ae0bb18
+474c6b76e438e14227be81d7fc68d0be
+475153a8e8bdb223f44e9645bc533243
+47547e4c1ec13728ab4a2ec4e73cf483
+4754de24180da3a6652260e9df8f8ee0
+4756a0945fe4252fbbf00d9cfac5886c
+475d921ff6eb9d0795a2a87ee06ee720
+475f3e17a11d8ca1b4212802eb665cb7
+475fcd63b1ef20c79b2cd5ded67b37fa
+4760e0349237ab1566b2ccaf1cb41cfa
+476546fe28f4c1768088e9d1e2ae0686
+476bc4309ca662ce565362f5af7b1c75
+476bfbbd630829bda9400c4f77db1434
+4770e684ecde467d17232341a0977bdc
+4771115cdd6a5cee3f4c97abe3818b5b
+4773c38157fe6efef0e6b137907bc754
+4775dc9069682fa94b47f7c46d1d28a4
+47778e2338a215d38c70d958b0fa71c2
+477e393aec99d4146bd0e5b4f8efd151
+477f1609629dd7944ed97671c27a1cbf
+4782796c8abde35b98544fda9b56f0df
+478564ed0e760d108096aa8b520518d6
+47867584869ff8b710bd87aaa26b792d
+478676863a3d40c3852d45ce1ffef4de
+478a666d64da8c5973cb2eb5609807f9
+478bac549ba7eb9874aa3af571f57501
+478c1199bed0cd1850ce66b77ce2190d
+478d4ccaa1d29478275582520869c8b9
+47922ab1cfc7c82ac8ee4829b2900f43
+4799b7d59476f9e734165ac75dd3f722
+479ac6a04e557f86bc9dd1abe80ed4ba
+479de4474e4d624851da8b53254a89ac
+479f9e2fc9bf6066197568eb55a2ecfa
+479fc6c8bf9812d21f82c5a13565d6fd
+47a270ae0149cf2bde4aac0d1bc51aeb
+47a2a6e283edda57ce0b735e7c2292d4
+47a3440afd24e081be3cdab031721602
+47a462ad799cc053fd2ea9f00fceb8f4
+47a505ae0d8f28b6174a1bf41064883e
+47ac7a74efeb6d524153043aacf8dec5
+47b27d94a7ac92c13140f46cb281788d
+47bbed66125f7455686793764e865098
+47c2dcaeffb59fb3bd4bdaab6825b94b
+47c98b3bb79ae5a29dfd21aa46ee60d3
+47cdd5ab1b8d917e0195e35b34a69013
+47d003461bef85719e96d30845629481
+47d0309897bd64e01401f5d5a2b6864e
+47d2e9a3e1b8f838dcb4aee6a6c5f626
+47d303740ffa97772fd3dd7488388f03
+47dd32c7279938be5fac0d92214e489a
+47e2ef088d205eb838520015cca93df9
+47e495841162601a1d8cb95277ef6fe9
+47e8a3fac046b30da05481070ce28cf4
+47e8ba98786c1cb27164fe254ef51803
+47eb7b7c0636e8112f70323b9677779d
+47f48ff32b1825dfd60bf920126725bf
+47f8902a7567b93debde9e3e7aca3f2c
+480955590593db12435e30ce06f1d1d0
+48112d8f97018750ee7690f7284e0942
+4811cb5912789234e8659100db5dc78b
+4811d5b51e257ccb20a25d820a3de346
+481556aeb98ac839867df43c1a109337
+4816162e154fe84fbe0c7975d053ce01
+481a7fcb6991089f6583100b25e284a4
+481b60ac03fa57481aaf8c6a38d33b88
+481f544cfe5c6bdf353d21c6cfb3eabc
+4822dc97af8018a119ec87e9b4b1b43a
+48263ec33fd3119fecc8efd597ab0ee4
+482653d71a12ed8b567f2cc6879f205d
+482e30c8e8bbbce5509c2900d8a79aef
+4836da8f3bde1333b5dafd2d1e42cbff
+4840e2034697e27608737cd457a4d7e8
+4841a9712636158aa9bbcddd46fa7138
+48420e143062aa8119ac0ab8ca1bd888
+4845562e7a500608274345fe2a5077aa
+4848ccc6bb90dd81a3dddd37dc59bd63
+4849cc05dcb11e3896e116a3454a732a
+484cb95c953786c0c8be29d75d4f43fc
+4854a9c7060e3c4ee1baee60ec5b14fb
+485a4461ea8387a8b137b8d922e14397
+485fd719beafb5c9d06de31318187794
+4863c43fd7ffd256768a158851592139
+486879f2e69dc0043cfda81c8b2b8732
+48687abe0fc4a992fbd4d9184ca1825d
+486c475cea18ec07536bdd901d95dc77
+4870278244277de1e836a3662df13bcc
+4870513c7cea90fb2651c2a8438a8949
+4872288cfcd68aee28448714782261a0
+48725dea6d1fb481a2c743be69354d53
+487812b8d6587351d270b776cb8db108
+4878478b9a9ffc6ca2d20a583aafd850
+487c8cb44f801c091c7863119e49b9ec
+4882de33a82735d293090bfd4a57e186
+488b079cb62599544cde58c756c385ba
+488c831ad36f602d46f7be305daebeb8
+488dbd41f8bcda89d739b2b507972559
+488ef3f348afa9c4c076bebad0a74118
+488f5a61bb38ce5d09bcf32a9651ea66
+4894623ae7d51c01aac4288a1a43d894
+4896b53834c3ef657d4fb2d0781f211e
+48975e07ad417010ff7eac269f010df7
+4898d5a2cb226176c86bcde91928b489
+489d8f72be3bc48935b79ca2497636ba
+48a14f2b4eaca93355233c58a171651f
+48a49febec488f4cdea8fe850be7d4d7
+48a8dca670bf9ffda2dad7abd29ca201
+48a985037b9870335d2e31d1b5649443
+48a9d18c867b0875a2bd4127a36863ba
+48aa4471c01eaca67c445f5147aa494d
+48acf031af35453e291dd1cc7d47a279
+48affa43b9801983c105cff313d88120
+48b299db5a7866ace5f450017fcd8d32
+48b9933597dc8a007c46027b7c998604
+48bc551873f8272167e299041a7b3460
+48bf1f9402f10ad1d15938703c7b4eea
+48c1b98a3705da20a92afba543830ea5
+48c1eeafbc9186744f04f3b063365643
+48c56637cb20a182e5b44bc5ec796fdb
+48c5ba7dcd419bbd383c8731bcada442
+48cf0e2fe014059761e74e40f8656427
+48d47ffd24e340cae4992a8a69178301
+48d51795e1b4c15c8885d0331abf5574
+48d54b3b1e40a36fb41cf9b3bca0d69d
+48d751b5b872ee5475f18242fce425cc
+48d7e1900d7d9117dec4b53d55d58522
+48df5a9d3a0ef55ea1d25708a3e49ba4
+48e01ca6e4bb8bc6990b2f6760be16ec
+48e0a23a0c744b40e81e696a9265f6d5
+48e3c5b42315c6c319a16b1d59da4d7a
+48e7657aa76ba5783c2ee3c962af9c5e
+48ea1d9e1d4ba19d4e497125450e3b75
+48f79d20501ecf15d66f72eb19dd74c4
+490540cdb17bd218f1843041937c2f2f
+4905ee878e5bbae74d889030b5d5f7f7
+49099ac26c9d878472bcb57b4a60c4c2
+491232654eedc7b686fc3f345d10f698
+49127df7cb1eb3158730dd188d212441
+49149ca72946aa4c22a4771e838c0e94
+4916bd09c617729be2d5cea105d8f8c1
+49195a2247d3703506a3fb0ba2bd102c
+4919ae4e4bb7e8cb016df12f0fdfa962
+491a9065ed4d9fb611e74ebfa2807add
+491d0c8f21895f18f7d48e994d44de36
+491da9bca9a335daa064752efe3b60a8
+491fc557813e8a24cb47a82c2a46e43a
+49209d486336f8410e8722033c311884
+4922da9e3aa779da68f9270028c8c0d7
+492545f991be1f828d490529ecb6ed29
+4925ded6b9e79623b2bddfa46737b387
+49291b3dcabfe241ce34a0a3138d1569
+492f0c7e79bc61457ee63a1c6fa5c978
+49391a06447fa9cb7a3fcc8b2a3eaf79
+493af307e02ef17bb93e11f7afa48b84
+493cfd0b503c6b8d0d33ca13d692c49c
+49418548c4f6bd001775567e47d499a7
+4944c83a2339eba84332388beff1887d
+4944d2cd597e6d62e460140cda6cd43e
+4946a4f79b9e94e57536ca819538a9e2
+494b14c347d6734163e9eb294de3b8fc
+494fcfc4c06c80d8f066fd09eb6fe855
+49505e7fce96815ab031494595af3afd
+4957e47e824073d06b6b56dc4c35f268
+495e733742a32bb34a87972af139f4f6
+49604d62d0156bb291560423c540b8aa
+4965a2feb86ffa7128d82aaf97646597
+496bc6e829b97499ff1d8b565503d12e
+4972f5ca1fb892fa146627b1d5241b40
+497b95732dc479d211d10b453622c6fc
+497dbbadf503c2754e3ca8f4ade772db
+497deb265ce2f0116bdc534b3f994cd3
+4980ada81a0cf0ec9e8f2dd1d28fa03e
+498178e06d720459eb9019a310cce979
+49843aefad8415f1b3526ca34e0c3f35
+49886634c03b26635fae0aa4bb1e3cf4
+498bdb63e91e12418ab9135f0ac62c55
+498d363012544b9065486670301a0b00
+499319e5d67dd5beba629fe3f11f61b7
+49955f39f093eba6ed7cc3e3f03ebef1
+49958031ef035df5534c5cefc0c38f4f
+499c539731245c647d2373688413eb15
+499f80023fbb0a18896021eee9cfbbc6
+499f853b101d65a4ee41d3834d4ce68e
+499fb15b4ac58730a2b0c765c81babd9
+49a4399c1dadf993d4dddc6139feeb78
+49a541ac92cb5b462e5d4a9c89412908
+49a98eab2b020eb2b046927bfa17d9f6
+49aa593e02b5137d2819a3e48d4641f5
+49ad0f4440d68108709dd61df4c62ca3
+49b4a5faa9c9bb7ce584e7dcd8ac7805
+49ba50d324201db70064dfd5137f31e0
+49be9642743db4da19d851417f2efb86
+49c28fb898f882ceee81c3228fe8a696
+49c66331bffea2895a5367e6b0943958
+49c8e270dc8c34a40ca90e3c8baccf65
+49cd71d611b4d53b58561763b37655d6
+49d85e3e4c53cdbd0205bc46cb672067
+49da2851f659811a955301f8aefad57a
+49df72e16e261cefe68ba1727abfb4d9
+49e5a26a35e6e95ea307837cdb437ae3
+49e7fd3e1380de337c368d1e7339db25
+49ea9d70d883d911e2b19fe1564a140c
+49eb0fd47a704c986110ccf87627b6cf
+49f432576ecc02420a0c5a16b2172ff2
+49f61a81e61ac77d88bb382551fa0b03
+49fb7045df30df154c196b145cc98ea5
+49fc628514f8671d4c27c15824f45c64
+49ffe61bf66ffb14c1b37d58ccfdf7c2
+4a017223ebd66f64c732102ef8f684e9
+4a09b406213a78bea0d12561365fea7f
+4a13632bc0a3fe7e31958fb92c7f4a7d
+4a13fd8d8d682e93d36daf353b3c7df0
+4a17dbb556bf915f4ffa92e9b05ade8c
+4a1a8fd7061e61804fab62152c008403
+4a29b5784bc42ee795103192192b4b34
+4a30b9cd042207ea8ce712eef99f797c
+4a30c6779106fba8efdccb55e2faa881
+4a35b4c71dba7173959bc30515c83124
+4a3785fb28585d41791f96f01b0d1351
+4a387cc18d53950f83f482d3ac16f953
+4a395a367cd706c50dbe0ce3dd3ea38b
+4a3ef8674fbfa68563912c7602ab2051
+4a3f66428e721cecda1a0107582bee8c
+4a44b69de263f6cb771220d6d083c38b
+4a4ad7e1b4b7c10bc73f94a3cd55f16c
+4a5033966446bbb981f371305fffa0bd
+4a53bbdcdbb7a5b26ba0f7d101ca2ffb
+4a563ca215c3cb47170067c594cab78f
+4a58bcc937633183364d2c24e94ab44c
+4a5aec3904db81195762af51cb911b8e
+4a5e6159dc5a47acbc20255d1aae15e2
+4a600315b683240a53334a80e4d690d7
+4a6378526a669e26d9a768f35b989c7f
+4a716a171897e6bab54ef6451c7f4807
+4a7650b634908b499cef3ab34cfce316
+4a7fe5b6f0930798dedb51b33bedbe40
+4a85b834208ecbd7fc4b12b33e9263cb
+4a863e490097f31aae317bf47c945051
+4a894d1bbe76e8f37223923497c1894b
+4a8ad6abb442811fa53536bdf3af5482
+4a91174f04bd407a69d79995b155e4a7
+4a91eeda9d3798360cee46df6a3902f2
+4a99aa7495b8c641ccc1513404c2819f
+4a9d77a4c039b1eb0359772c6da59022
+4a9d77f1c1227b7d231dd2cf3819ad38
+4a9ebaf200dd40a563b81309304e989f
+4aa25e517e6089ad16d71ad92397e7f3
+4aa807d19b7f27808133882214e60f1b
+4aa97158cfb78fc2284af165183f5419
+4ab029c9f83553544261ecd5bfe3b4aa
+4ab1e88412202da1a83dae7ceadedc5f
+4ac00a35ff695b61d8ac8dbbf96683eb
+4ac7df7a7d98713d28f96fd099fca00f
+4ac7fd05e733f1d52f02996221618dd9
+4aca6e6564460a0dd0b9cfcdaf1d6ccb
+4acad7eea8c131d8ad2f131145b0937d
+4acbe6b9418d95b83ca258d6ea3328fc
+4ad0b70a064a75c667cc121adcec5d22
+4ad188a64dc2ffb6d8ec8d4daabe27de
+4ad27ec4873d9075e4ed8877b1db7a2f
+4ad32f6ece5afe41ca579e36535363d7
+4ad3fac2e04814eef5bb1087c9e28bc3
+4ad8f41c8001987de29e6c1deff123d0
+4adda6f7ddab9ba85f1b1de9871fe32b
+4ae1087d6e5b6561a03e563003de250e
+4ae41175fd78d6bdd82ad36411f30e0b
+4ae4281e4f443e0851c17ffd0142f50c
+4aee79171c490a5496c7bc94197970fa
+4af2fd4c69ade8ed705bca3c0e05ba74
+4af8f581d23b9841b0b15bf604cfa63b
+4affe98213550e8194e1e477950fa053
+4b014acd2cbf3f95e0fc7a78952716a4
+4b02ff02759124f6f7af8747ea810a79
+4b0667268e517bd47ca7a8f68f835838
+4b0ccc004be9a9c0f16fac0db6c48406
+4b1045ed7a4d0b03d4b08596d66aa228
+4b1542804d209e432d3fe9dae7c21518
+4b1e1ee607b3da4749b93218a4c4763a
+4b20b031d4adbb9a9199339013fc5db7
+4b27f013d1404f1c11f0c1647bbb1979
+4b28a8dfa9d96dcab1954732fb8c0221
+4b2f6768236d5ef33d380f1fed3004d0
+4b3071dd07b8cb88487ad6cfe9ea74c3
+4b32d939a682e33b857773c6d06b98b2
+4b32ef66e53c1759fdc4413b1754bb2d
+4b33d60a89e739483ab9b99d086c0f14
+4b399e6d3f181e7bcd116629029fe3c5
+4b3e2437f831765dae329824332c6e28
+4b43e15fa04034188bcd27dbc04f82fd
+4b46c6023bf4d9f6df879844ddcaef2f
+4b4a72e09c14ea3572ddec5e3dd7ccd9
+4b4d94c2547f02b926a02ec922a11be5
+4b4f3e8665632035ad073babf06bbb7e
+4b53ed9095cae3c19a7381ee53ea987b
+4b581a0d05465ce655e7de1bda1bed61
+4b6381bf65927048a5c2d95d50d5bd29
+4b675472788a9dfd3540a2c6b75cc386
+4b6953fb0c78f696131e16573e296ef7
+4b6c048a27bff0b610e908b04a14fa9d
+4b6dd5c9b55d1a8b37fb29d6e9dd5dc9
+4b7011a27383015496e8a3cd758165df
+4b7752ece14a65b1b5d141a4953a6c4d
+4b79b76cef26dfaff1d70c9bb778b7a7
+4b7ae76c7cb07c1ac7694252c7cd02de
+4b7dff265f7dbdc932a4a1910d833100
+4b8044e4821b8d648fa5848db10e5fce
+4b8c91bae122759d6f145a2e229137c3
+4b905fcdd146c682adda12bffd7513d7
+4b9df12157560e4748f8d80f2b736594
+4baae66b5ca488eed09420f8bd16d820
+4bad638c6498bc534e682f4e8cd79cb9
+4bb4a5ee3651f1696199f780f08da015
+4bb640b05bd32055c7a271a73f49e94f
+4bb678e18dc42db76c35eb93ec891626
+4bb86787404ed8432d1f6e3545ded1f8
+4bbccc181acad93662a498e822525e2d
+4bbcf1a510ac3b79daadf1c9b37d212a
+4bbd13671934749cd6cfb0337d58a97e
+4bbd354d08f3c4a6629645b35b5890e6
+4bc31e899c68856f4533a9d5bebbd9eb
+4bc37b0d8eff20a510592f78bea31acf
+4bc947c01caa37502e8591cd79a1a8f4
+4bdb1c841ff8630b3ffeda18667fd2e4
+4bdc1d18b6a76d3bf9bdf1fd567dcaac
+4bde32a7274147ea1be8198cef914791
+4bded765bf27a0fcfb2a04ccfeb34ab1
+4be172115bb8de25493eb2e0637d7688
+4be1fa005bff29059408144789ef799b
+4bed8c90ebcdf9d5476109c83995ec70
+4bf5f6387e2cc978aee95d0dd73b690e
+4bf8fa28e7af0ccb594832fc66b87d69
+4bfca25b324a305d1cd808dc0227f21d
+4bfe32633a8139bcd01297aa39c24823
+4c04493836dabae3f1fa427fd9a70892
+4c044e443e9b4ee254d4835fda09c7cb
+4c05c2ed401c585928aa3bc342d0dcbe
+4c0886e7691557b9795bd3ebc3a9f3ef
+4c0abdd061d888edfe82d1cc6054843b
+4c0f4953406764981bb7d24091da6bad
+4c106a4e2ed6d37112fea67f44d158ca
+4c18087648f3d0c8966d0574ad5d155b
+4c1a9efdb63ed59cf91f40218ca36f58
+4c20ca877bf4a94e17e2e87e589eaa7f
+4c217642f2e3de6a84742593bef883a8
+4c23a2ecf8a3d2b96d582158d5b4a8aa
+4c29946fb44ae757b1ec84ee95b0a951
+4c29c60a9686df0bb85f210a2f48320d
+4c2a64ee2540abb4e643170c71f54e2c
+4c39a86f9b85b23eb25cd5fe91b3152f
+4c410632c7e920e5e6ad44cce47d9417
+4c425905363ce69009b4cc24bada7be6
+4c44d8580a59820320a2067ba95aef70
+4c498af961a3dcf727653c31e1525b13
+4c4a97fc9fc73a33cfcbfca1172d2afe
+4c4bce279c5e2f29e2fe8b5eeacbbb67
+4c4ef19e7e5985d773169ba2c86087e9
+4c5aebb33942297ac2340c5130830825
+4c63336cb578993664f137618ae1952f
+4c669cdea35028744118d2d2b1d64a4c
+4c7624709bb2ee45ea657939300bbd81
+4c7e3dd11be5c87f4440ad13869def81
+4c7f4b4674fb274112b0a963f7307510
+4c84a7230f98daf15a944289d8c46069
+4c94f30ec4fbef1d723d2801ba3ecce4
+4c95521415a300fd2cb76d4f1551291a
+4c9774498589382cc9bc06f603cf2642
+4c9ec0e1ac824c5b2a3bb85b71b19b6e
+4cac765feeab6f7a1cd0196fe4959d6c
+4cadb0cffe22a7d95bc62d3031c1b129
+4cb55ff2a5eafb0c4d18c04cd4ecbdbe
+4cb84ff6e627cc660af81c8df97f4667
+4cb9b767bf5891b291df15f4e37d0b7d
+4cbfab5befdb49e4f48b163a1038b5ee
+4cc0e6b83a24c2c12104275a14465035
+4cc17f0c154a9c3ba6ef124eebc2c976
+4cc2380358e6730e1a55aa725c34738e
+4cc9323a149b02a969a413a79d19ea0a
+4ccd64ec88004d2b371f09635ea6ffdb
+4cd505461e36e6d41552c6b91b1b88a5
+4cdadfda86e975c7aae03efbad6e408a
+4cdbee7783747e0cb1911fd769210d68
+4cdf51e4e711681dad9927d424c50fa6
+4ce04ea860942900936d01b74b528381
+4ce0f915f67dfa44cb14fadf037cab16
+4ceb0fbf94c6dc4058eeff3bbe2267f6
+4cee770b0ca3eb320581f60b2dc1205b
+4cf2dd8b082c2d3e0bd7ff04c86f92bf
+4cfa4d023575d40222e12bbaf3abc112
+4d06a7c9e617cc392966b48f91700d83
+4d11b2943a2577d708f7ee43904c3d1c
+4d15fab596524d8cddd9a00335624bdf
+4d1742f36ceee2da405971fecc05e82c
+4d1c338fd39c23fe7f4983361e9b47c2
+4d1d97f08c3ff33977a59c584e64ec5e
+4d1dee9bf9d8df55bbc2afeb2dc05e4b
+4d1f6d73cb5441ee3d44d1c50740dcb4
+4d1fb2f514f2bac7aad362cad207571a
+4d29bf077250e94019e58f8ab584fd55
+4d2cfb153906912edce336c94425214f
+4d311e73bd7a41b8f29998b41bfb108e
+4d37c0e6fbbb0d5b5acc1d8c5fae8341
+4d400997728d4ce237247560088ffbcc
+4d41d83a4a49ad0b203bb528ad1433ce
+4d428199c38f8767080cc2d15c225d55
+4d44430f0f23fe647f8e9e1cb0d8364b
+4d444e028a7e0efd54fcd2b5cc529360
+4d4a17b8824e2790ce08b1fc3650eb3e
+4d4d1b7115d9e6629595c45df1df79f1
+4d577e6f90cdff2a150ac137d7c17d26
+4d5f5934e399d84f6b046fa9041299dc
+4d5ff5a290f896a5d51309354fdda5ba
+4d6301f612b77ed571bf93a96f934862
+4d65593c16d62d3136c692c239af298e
+4d6aa5ef2a4a28fd99f7e6631a3507a9
+4d6fa4d56c5a6948aed1ba9569eba1f9
+4d70c658418a5c7f96d041499d4ab1c2
+4d72b8dcf98cb15e221142264b80afd1
+4d7b199468a09b7500cee06565e8c80f
+4d7bc51e581260be45e1a43cd7766a20
+4d85d451d8560b2df535b7371aa1d4a9
+4d8e13c4edaced86ad508787254f4ec0
+4d8e8c5d8b0dc5c64af4a008430e11e4
+4d8f973b37ce704f9d024d444ac27863
+4d8f98cc0b8722354d1c09c990a5da28
+4d97992dcf9d59dd9d7ff74c5e208951
+4d98b065f0bfb5159f8a10049f03974f
+4d9ad559deb8d6081d39b005c78514db
+4da03ec8d5c2d9b31768e05204d9a8df
+4da4f416ba59bb4550fcfb5d18cb72a8
+4da9ef00bd691d80b6e367b0f34a6778
+4daad7e0904f6e4512e05896e1cd4a72
+4dacaddedf6449aef26f4113361a83ac
+4dad054b8e6b68dcb1bc0e207d67f271
+4dadc169a307baf0b06dba86bd1f4a23
+4daf4d6b6438a7df06e8056d3f6d12af
+4db353a04507c760474e6f07ab23fce7
+4db58b03a10f3e9e7e2978c0ce21474a
+4db64909fca43b4ee3163732b67f24f7
+4dbb9828d7c80916d98e97e26794550d
+4dc099d7fd49ccc6ba633f816fd8c967
+4dc2d61cc71e3e10b7a1e176987f8415
+4dc31d98c88aa438dd024d7c42ef05c6
+4dcbc6cf3b452f5d3762728d0bd0cc0a
+4dd023c313784e4e66454390f97cbb68
+4dd23e0c16e46a71d004f5e82c4d54c4
+4dd5b9eabac961a5ef057a8d1fa53ef0
+4dd6a220ade0bc8f84f1b85addc6d4cb
+4dda279b3fc37feab4ff3b4dbad6b7d3
+4dde35dfc1873e7de15abe105ef87b27
+4ddf3f3402baad0d5f7b2e18f93b50c0
+4de376a3e134c4f5f9892f249483f3a6
+4de5b934538e37e030fe6b6d911de5c3
+4de76a814a2e22e86aded25e3c8f3e87
+4dea978d5c77e8fbf11691c2f7f68334
+4debadb886489c480c69b0396603dd40
+4debedea61f602c94397558440a507f9
+4ded27870ed39c0c414d5b10b08a6253
+4df5c15adba7f1854ae00a9dce4b21cc
+4df6f9d653efdc105756a1c11caed458
+4e03122f142f7d1301a38c8844b11331
+4e08c12df4962152457e12596d308229
+4e0921e958833846c7c5efb1dd37ce5a
+4e0ecdbe2600d9deedab998424da4c4b
+4e107553debb6a29a8744fed6bff6635
+4e195bc4ae3eee34aafd0dbfb223b4b7
+4e1de1b5713f317ee955f08c60d4830a
+4e25127e33820bc620354eddacb23a6f
+4e252431d2580af8c9fa544a8dbd62d1
+4e2aed86bd5bae7a1b8eda758d4241b7
+4e32a56959ac4c9aadf937b24c9b03d5
+4e353e56fe8c6638c26870656f977ce4
+4e36bcad6a6027f1e94cb5b4039ab42c
+4e3aa28cf1982ad04625629348c1a006
+4e3fd95cc87f022e8bc274f022428131
+4e40222f3c3a3d2bdec894ce4334629b
+4e41f02b3dbcd7cd245475dacb7c83e7
+4e4991bb09c2f268b08efc328a643b36
+4e4bd8fa220b49ffdf828c17d5fe4911
+4e63a617105b72b89b1724f91cc1c9e0
+4e65c054a86cb5aeb169e00133d30815
+4e694cb858a9f6c1103f3a75c540b62e
+4e6fa82f3ad6be8fa15dafa2888af819
+4e71120b241aa9281ef0043850768505
+4e716784684d95017a8e08af29be1eeb
+4e71b7ce38325275fec06b095f92d28a
+4e75667e5160ffb53b8053020fdab865
+4e787fa16b24875a0b787e8064754e83
+4e79ed0afaa087123528769ae605967d
+4e825e8d3a661f11bf358fffdfb245f0
+4e856269daf3a56d0efc0398224365e5
+4e8ec4741804311dcf4b94d5fb951aef
+4e8edfc70eaba0639d71aeaaef153812
+4e92b5d85215c6872288d1673861fc39
+4e980edd76bc258df020dc000273ba56
+4ea263c257e700be14083d9d64f4946b
+4ea4656c51a980a7965b78235e93101e
+4ea8595f077974cd2977f6eb28f3a953
+4eab5e77386911559358a84907817dd9
+4ead46df9735ffa822571aaf129a3390
+4eadcece053cdf6b8385465929e73a36
+4eae696a74121da6e08bdb703c608570
+4eaf2e17dc2ec5b0c80a6e1441ce4cee
+4eb115db5200d6557c457f9fed434013
+4eb15f1306ccd70eaae9da483cd18d2d
+4eb4cbd425bf334f3fff86ea7b2ec94e
+4eb5b2fedefcdf1d4cc7839e9986f1d1
+4ebc4a5bc3046744b142eac03640f9f7
+4ebf4e7f6784762d877d0df9c728c0b4
+4ec2f7bd978b83aa238f0a20fd426fc9
+4ecbd7871cd58ab2c21dacce00cf4232
+4ed261c8e056a3eeb289f2848f2ed86e
+4ed3021a2526445fa90a1b33f2bd9fc8
+4ed7760b17f6c3cd0fbdc59ebd91a0b4
+4ee487a19482d3125c49276f81631582
+4ee747d9eb14cfe8faa5e98f7823e203
+4ee7c01f36c96faa56fae0dc200b87e1
+4eec341dd60328d27fca83e063a5ffaf
+4ef3250947360cb44a7f6ef4450d674b
+4ef3a11f4a2e992b3953423455174e18
+4efc3e7f25b64eafe8668127c72dc7aa
+4efcfbc5416a38ff1343ea9ba2ffc2b4
+4f055409828fcffa8ac15af8f8c875ef
+4f146dad770585a75a97f899df835b91
+4f14a71b2c00beedc763404b65885d93
+4f16e1a12ce201eb4ce085c7fff3ddbf
+4f183d85494388583b174c4b54f1c79c
+4f1b099f6294307da01621e3d158e7f7
+4f210225a01d1272e5818c88c4af1ba0
+4f22ed862e51389b7918da45e843b27c
+4f27445536fedc698bb831ba9be40adc
+4f29313ad46c093707d356cb3f29d277
+4f2988d667e946c5addfd09b10f19c56
+4f29aa56383c8c27cd739b95f1f1faef
+4f2a522ae224d5f051d4201559dbbd11
+4f2be320180fc16dce9c683912c93f4b
+4f2cd2ac3a7556f0f6fcc47b284df2fb
+4f2cd915fbe71ef1962a94cc511efe8e
+4f31e303571ac9dbace3eaf33859af00
+4f344e3e23a272dadc1d0122c4648f52
+4f36914483f8c621989e9a6a47b93cf5
+4f38f7016487e20d187347bc86c9c4f5
+4f3aaf0562fcc24063e0d5396892d7e7
+4f47bfc48cd69b10c0b995dfe625eaad
+4f48dee1786480e1057de71647dbbde6
+4f48e60858dc789551af56083b5839e3
+4f4ed1d1fa97143b866ca18c249e0442
+4f52f3fdd7b1d0ebf8938517ff1adadb
+4f55a6a69f4fa2f58de643977e532e87
+4f5abe53c16b09896daab13ae221ebe0
+4f5aece007e1c4719f1a48e9cf26a166
+4f5bdf578e059ef6f30bdb772d022680
+4f5cafcf7ffb057b9382d4c8dd17d281
+4f5d0978dbaec80477f46405b260150f
+4f64d6a670aa60104481b55ee889c58b
+4f66fa624ea823eb116328b6816fd5e0
+4f6e5faf600cbc11c28f7c139d6943a4
+4f7476ec7fc7e81a18be156c556e7058
+4f76f76c7340b2437831bab6457a60ea
+4f7839e45a1f67150cf314e972e1d5c6
+4f7b868f7d6f5366037a65c15c3d6e4c
+4f7c418b0fa6eb8fbb05677125b64966
+4f7ee34e9deab9f670872bd088b0954a
+4f7ffbc0a42825a6db25f9adf1422401
+4f869fa2713344611338a84fc6d626b1
+4f888cfbacfd53389cf07fcf020b577b
+4f8f1bc2295f0d3339c974bebb403799
+4f9030ce41e05c95a588128d2118fe21
+4f91f47ad4280a66378d0922a7ba30c3
+4f9bf2aba5e6dfba7f9da70a44be9a53
+4fa098e48d8415a952ea73e8bdc06b9b
+4fa37c81cac27c9316d94e6206a030d5
+4fa9f3120333ebb5cfca1783851df323
+4fab7dfcd5b14066ded7c03293c1fa22
+4fb2ce6ff72241b33c7a25194c15985e
+4fb594abdb8c3a5d52e3ec7fb0e159b8
+4fb94b6b7266d19fc0e8a7923a136708
+4fc61108651c0fd466fccad318b08721
+4fd0479ef34aa0347b35b7e1fa3e28ee
+4fd050d75e8a909322918f111c491a3e
+4fd2dba6ffa7a9a22a84a331c3b046bc
+4fd355e1c8dfb45615b15f64beaa2871
+4fd4cb601693ee32a21f7a4ed5b4f4e1
+4fd58aa59ef497460af721698fd4143b
+4fdcc0c7b0a5d2529b4b0581903adb47
+4fe00689acdc3a03b950737789bf4a28
+4fe47a878c6ccb38367f1a3e0faeb1ef
+4fe4f23d343ff283cf8980a976ba9a02
+4fe947eec101fdefdae4019a0e0da729
+4fe9aad46f5d2e3208e3943bb27f6152
+4fed079bef01af38fd05c55e76a0984d
+4fedcd0d97b7e39eb42f4651e9ee2c43
+4ff4ef60fd607e78b22654e21fdf680d
+4ff6a4046994a6e48a7ca7114ec7653d
+4ff7194fa6d2800a77e15537dde4d8f8
+4ffaaf8a88427771155f1dd191cfe693
+50028bc9550b6846beeffd17ebcc3d2a
+50033fc4a214d5131764338b263721e4
+500720bab658f8a75adfbadbb4ac6f9a
+50103b6d4e10f18666a4924fff3e5e0f
+501bcf6680f8f3eac0e6c2b696b803c1
+501edf56c8a17f509d495558e66132d2
+502566308dd75fd8a78a755ebe9fc396
+502760a1d18c87651ca4f53f89e56bcb
+502f4c4191ecd2682c7e3920ec669651
+5030ff731e085d061692a451cec29941
+5034ccb4c08e19a43f4d617f058eafe0
+503f69e62fce3aca7aa4cf287d0a086b
+5048d8f3abd2d984195e86e44b82d6af
+504aa04bca7fe1364daab11d7a290b90
+5057a4f8330d1371260fb28630c34bea
+5058a98a6446693d64158ba82aef377d
+505b335cf161c2be74d2d9803f3816b2
+505bda1e15ab0ff92703f248c2860d8b
+505d0cc414ff9f4ce703fe95a303e209
+5061c1c0470532b6b69162bf4f0b034b
+506597dc9e330eaf61840e915e446d84
+5067c75fb9ffd5dba353493eea89d0ad
+506a0960b6ca3180e41c6a70fe2f74fb
+506d93d30f6358aee07a415ca6dc0c14
+506fcd465c6586439d5cde65f70af9e5
+5074661503f1ad716578b442f7c937b8
+5075c31ced93733f46878cf2725bf3cd
+507f5f74dfb8d3678d739ff3c5a04922
+5081222ecd02f76358c0a6b064ecd7ce
+5083a6894808501b742f1bef241c18f0
+5087b428ba745231068295e219f7e5a2
+5088cee84155ef6e081aea9cff4cf39c
+5088d369235e78f30ceb5a851058789e
+50943902f960ae3f1d8f220f692644b0
+50963b8af6c435561150deea2df0a65c
+50a5781812f9208f3ec6e68f378d0d0c
+50b07cc6b81aa969b6f354ed32926f27
+50b0d3d792379dfb2c22ebe6cd3ba2ee
+50b7d0acb6575322679f80f47a663e07
+50bd9efaa24805765e902c7e2999b4af
+50bf0b01ed8b442091a9e9ded8b99de1
+50bff042f7fffeeb5a236f3d331bac1e
+50c5635a5fe322fcc5d9d794863e07f9
+50d05716026c79d30a92e78ac35809de
+50d1de16973f3be118568479ba96b9cf
+50d5b2945cdd11e492547b9896926afa
+50d6c60e488dda4fca99c7693da0f4af
+50d99671b8d50d08c754a0e93bee1310
+50e7ed89c27732b8f45e462379ed6541
+50eb76dfe6246a704f846371d1926d6b
+50f0281a3312f994e45ed637a6e84321
+50f15ea61da0a225661b9d45c063bb60
+50fba0b0b9d7cb1a2e655fa16ce1a78e
+50fe8137b900e1335b2b1cf1de23f311
+50ffce71f24edcec31d22c88a1555a53
+51025779cd25b1d5af94ddab19c96570
+5103c86f37301240ee9e2895fe70cd86
+51042e0fb2cc1d12672b2e15064988a7
+51056dac3be674cc6fac108d41a64aad
+5108a46234af5dfe0bd85aa7fc623b50
+51094151484506345802a8aee722ea5c
+5111fe0515e3734d76f8b9400a329146
+51142f139161c15026799d0df5cc2fca
+51178f8ffe267a4985df5b403ce23830
+511dacc64b45b3c18d6d60326924c7bd
+5121fec93edd43c587943aae3d4ae7f2
+5122b0130e2a51d0ab38f262c442a0e4
+5126b518cd85559bc29dae91fe424339
+512715e138ce7064f554561a4aeee189
+512811b8d5fc13ae4ac1067136dc58b3
+512fb55153cd0647d415e1afe604a0ff
+51374c799ae60f8816f51e4a776fc05a
+513a0f26a252667f62e549ac035f5093
+513b1c35d914c99316b348199fb79ec1
+5144c447e129a36b7ae55417884091bc
+5146c455d7eb63ca21c75a130a223aa5
+5148c0ece381d5633eaef9fc2e36f183
+514fdbecea0f3f40544c0aeac44ce693
+51571da43e45ec568dc1791a7897519c
+5162d1510d40fa43643925c3c01397ee
+516631f2ef2bb8bd50dc3a86db14a198
+516743ccca71e93f76350517615c6066
+51684b7807ff0ab7ee9b1be2c986880e
+516ac427994880370839088bfb3d02c4
+516c089665e6f5f5cc2bc99c16089dbf
+516d19c362729c70b377f1e8698bde4f
+51768902ac94452774c6d03de394dab2
+51792c5275a43c870749b9294e8fedad
+51795e003c12aee8b7d69897e0c842e1
+517b4eb64c2725c037b13b096ee06ebc
+517c2d84efdb86583a810330ddc12297
+517e0f2b2b9af39804d9beac25f7ea4c
+517f89d7aef428be8915adb8625c91f7
+5181476986315b78a69542560e66d8b9
+5186f02aa7c5c9460ac6656565be4f69
+5188cee5f6224418f7499c7afd0990cc
+51912662690fed540cc6b01e5ee022e7
+5198e5b2f5b915f08e9d528c63afa149
+51a1e213a1f488022511ffb053263afa
+51a421a7200cc6be612dd530a03375f1
+51a46f9a4caf3e0048c5ea5e29a985d7
+51a6d41031db861288ff378ae0bebd6e
+51aaa1f686a164af20efa5a230b52c2b
+51b1ee1dd4ebe9c3d229cf8874ba553f
+51b37ddc1acde6bc6d7cc05597f58f14
+51b697f728e54a57ebf4beeb2f7f26f4
+51b7b75731d08a8e8803f5768e7b1d06
+51b96c618fca2bd539fc2e56ac46ea06
+51bc3fda6c506e444f8dad9b2677c14c
+51bd383240fcce841f61c926b89d48ee
+51bdd99c74a7dde069fe5d2bcdb8216e
+51c241d2b43722d95ccb945a3f2fe8d7
+51c2d0abd424f88f6a112d0ad1f8005e
+51c6355005ea0ac3baafee3517864c45
+51cb55861f0683b8eccf6df914499b38
+51cefe631e0cf345bed91de296e0907f
+51d9c95bfb0feecf6c811f94e1a337e3
+51e0fdd432828e255b47240529d88dcf
+51e15c63c35ae5673d7fbea36ad63382
+51e3be019889fb2d8fdd7fd5d69cf43c
+51ea80e2310e96729f81979a1104302d
+51ec8c9776461a7b508bd6df402103c7
+51f9388c1f661e9fb33cfe5492e99174
+51faca51e5954ca26d39c03c8b77d581
+51fb99cd928c6cdc55a78112d326fb4f
+51feb9aea43db7bcc0c5199d7b9a0f7f
+520171213451e1ebc54e03e077477377
+520278815ed992ab3265c48249df8d5f
+52030f2c1c050f59e1520802fbae01f5
+520962ba20c0c42c5fda41013418b8c2
+521229d81e0e43febd04c5481f6171ca
+52253b4f7559297827e115007615ef02
+522c8df73642669bdc40e75b52a5e0bb
+52305cc395699a26060f98dd65eee5ea
+52354c87d12e969b613386856880c13d
+5235c6c43617b8853d63b41f2e38d8f5
+52361b25793b0d3f0b16b5217f9cbc9b
+52390f12923c68231b6d9efe5a725d47
+524106c64938f8b43ea5edc81912effa
+5247ccb31145d2cdf6ffbcefae6b4d04
+5250a8559197aa274efe356bf5e8fa1c
+525580ffc74e679d5a89530f497af735
+52583beec4461481f7d507b246d290b3
+52623b84258d4dd55b9eae1f81c1dc04
+52623fe019424df170d19c54d78cfcf9
+5264ffd54b8c5dba90a0d55b32cc93dc
+526542b8f5ff7b958c0ba60df91767da
+526a4df188a0b75f070fa0f0d310a44c
+526c7a69b160b1b0f5591b270d4159a4
+527ab8144dc197e572b53a3598b6e62c
+527ba9cbbae5f4bee866ae74b170dc88
+5280ff760b526f11342020f4c0a51d89
+52813ed2bedcd1dce4159c7c3a38b4c4
+5289ffc88ff0442cff2dcfce0532f4ce
+528af8a5498b754a2c59e692e2085631
+528dcc70d5fc6d5476353f36fbd46365
+5292158bdf359b4a2292fd84e4017af5
+5294e4422b391ff4b9bb39147addfa60
+52986baba17dc73806912fb20055333c
+5298e1d28d03607ac5be5407d0961111
+529980ae025ae3c1872a5dd191174817
+529c79325149834aaece1ec426df1845
+529dcee6d2889fa0e578faf96301edd0
+529fddce0401d4505a483b4aebd5c5f1
+52a20121814b684f5dce8a31e0f485d0
+52a45cd0730585e90c54035a1ad7ecce
+52b11d3ce5cd5ab64703448f2530e202
+52b6610bd472bb80920c30667b478f5e
+52bb21e21d13f52b7d89b9927eacb152
+52c2e59c4e0d734f34efcd6da6e1919c
+52c61e25d8dc5f8e88b556a7f499dcb0
+52c79013406d0a93f30c90f6428079f4
+52d7f48b80c63212f4c6493922eb32d3
+52dbca5a4b893c9e09d7947af221c41c
+52dce9141629b846a65c960c71da4818
+52e53ab4e55dddbfbf77917738f4250b
+52e8736d940fcab3e3791f31286ea081
+52e8784d0c814a3fec7ee956e9f2f841
+52e8b464f24399ab2de55e57477a2ae2
+52ed12cf809934942959bd2fb4f89db3
+52ed9f33717f5dc78392dee4c7239c3a
+52efb8571eea24108caaf6e491949f60
+52f1e52c8cd9310b50edcd65d6c40ca2
+52f48947b31205a9851cd8b27aa1701d
+52f73fe26c0964bb5c7588b0c41d393e
+52facc9975c3d6f367d89d9c91ad79f6
+52fce820d29de4875e4b3738d56c2b1c
+530081e753caae0086ef39506367e8c4
+530a386faf89b113b9e04a97e1156c5b
+53131effa170643046ba202544d925e1
+531469f71846d228a70aa476f42b5d68
+531681623b8f8eba0c6adee9d55f10bf
+531bb4d4df969511530d22776af964a4
+531ecabc0fed5473645b051d767cdf6b
+531ecff8de31fbc423efc16cfc3e8cd1
+5321d2ce12f5cd2c2f2f5a60481e5706
+53223f9302cafffb98caa53765ed456d
+532662d31d64110b55c15621931c8453
+5326c29f98cb866578a7cb6e36c8c128
+53272f2b6dc727c3fbcd4938ec9768cf
+5329bcc1eeec8aac4badd596e03ccfb3
+53371b9cc4f2f6caa5d8137b239bae10
+53396ada794e714b5032c850c9eb6402
+533b392019de16bdbb6db8b6710ee621
+5341155db1201d5364b7f99517e8d49b
+534389a161ad2e6c3f7834b5963ca355
+5345d9b7daf3ac5dcb6e93ee104e80c6
+5346ce0c82e65625d16fa9b7dfa03dc5
+53496a760ae53cfbc03d8f595cc58221
+534d172c210a8d9673bda4b510be8402
+53547354630ab0c3835938e2b06c130d
+5358b771d7e52f1bae7884e84f795335
+5359d6bbf9b2a66226f5bc42a8c6963f
+535db42b77628804619c431f52e44797
+536374159acaf11a4a8803e7dad5c9b9
+538056f10f2ade7d38f70901772ea9fd
+53888ff8f214ff55b258b2c7e741f5c2
+5391641eeb9a825f9c6d3667432f5492
+539357ce31041319ef83705444e9670f
+53942efa2784c0acc659c339d0cb4f0f
+5397e49d5e8ec597f90cc9a3e7a64721
+539b94014beb121579f09dc027ecfa06
+53ae21343beb14657400eb23f048355b
+53ae223fe919df6639beeb47fc118520
+53ae7835c7e1d779d3337579db81a3c3
+53b03c928a44f3ddfaa5ee60cf8bd4d3
+53b0ff189e6789dbefed0dab7d2bc8bc
+53be2e73951710bc59200fc0bd2b2887
+53bf848eb80e550ca85245907373e1f5
+53c030c294d0b45c8860d39030ded8a3
+53c15dd64cbdda6c667b011cd27e1859
+53c26115abd47eadaa21bba11cc454ad
+53c667aa6f4ab98054edd68f4d0e1bdb
+53c8160f576f30b2bd9ce3f3ef981758
+53cce88f1a657d98182c71f316cec5f4
+53ce39009b21f8e9b70a8bb9da63b8bc
+53d2798824494ab1c454b26dd1b3fcda
+53d44e3031d74239d0d72d9da33965f8
+53d75ff4f8ea9d54ea6c483c657b2323
+53dce45cd7acaca425a2c45b8a499075
+53de747a1223818fdac428ae5462407f
+53dfca3aa478a61a4c126f0b742dc677
+53e1133d7e1c99e1ac2f746441173d96
+53e9608a90becc92bcba836d49e53d84
+53e97e41b7c84f64e47ff91e24242017
+53ebe73e2e3fdac0b29ef19f5a31d083
+53eeaa0485cfe23d9b7801fe3a1c4cab
+53f28ef075585357c240c462936c5ace
+53f57e34481b08f49e8b9baa23d7846e
+53f87b556046ebc22351544423cf1794
+5406106762cffc23d730a85af219f7f2
+540cffe58619a93f753bf65363808109
+5410a8fc06eee62d37b79109bb821a14
+54129ba4a991bab79463c211db2bcdcd
+5419d043b9b8dd8ce42b69f571579218
+541a57180662e79556d5c7fa4b53aa4f
+541a940fb6a2581093c026737dee418d
+541aa601c2532fc734e817c2ce74b518
+541e24028c54bc86ca92d7c6a825525c
+541ffd6007edee91f305b3b2b8791d4c
+5422a54ca63cebfc7f44303f5c1e2038
+54263f5df1b2735eca863be84f584a8a
+5426e73f66b0a97cd30f4187c6ae3040
+542b277ea9c67b8d9fb5ff7cae301c84
+542bcdf6c8644280b19d4fb5121c39d5
+542c8b6ad4a627c4d7efc6687ff8074d
+542dd384f16a5a416f9b38e2d262adce
+543abc852feed5f00c78bc06a95cf543
+543b73f97cc9a1ba299fae06761fec2d
+5441ce1bef9399fb06e1af2e6e98c8a4
+544874826a38150b18bf554403a03357
+544b49682cbef132bf0c7368e70290af
+544b5e3383aeef3ca37b66eb42feeaea
+544dab34a60f5278fda8c81711d9224f
+5452ec712198559fe9bde995b713e26e
+5454d4616b6404c3275aa070e833f006
+545917713376c36f2ace6ca0c63c1c5e
+5459a21046acfb11ee7fedcc780dd535
+545a35273134f06cd9b8dab5676053d2
+5461950392606b482e02f40bd486ede4
+54635bb47c051529ae7d152ded2aa0e4
+54748318f231637a08e74c3de5997427
+54778753bfb8c8f43b88e5ff59d6527b
+54794b125d1e856b3ecf7f99df279245
+547dde4f95392dcb0a5347fc98b994ab
+5484cf4c2514f58775a89cca1b99e8a6
+5486f169bdf6b77f46295b7ac6e42be5
+5488e18fe1949cbb013d3c3a34190bbf
+548ace16315667caaa8b73495a6aa539
+548cd3fe9714b9ddab7475bdccb0e41c
+548fc9fdb7afb49fa28a031242d61b9d
+5491264b7508d8f931ef84bee81f6548
+5495c4ed5e887af948dfc44a61684524
+54983de79329d8666abc9f07518e7e18
+54a1d05ace9e002edaf47242f22202a4
+54a6f4b8fbb1b11a388bda7650cdebcb
+54ad1a4603e8f64cc35b16989622f584
+54b2c22268938d7dfcf18c7b78bd41d1
+54b5369f5a77917add593a665b9d0eba
+54b58fd9b62c5dd4f51c1d363c4536b2
+54b8b3b60c48f22cdd1ad63e73cb2962
+54bf301c7115734cfa42bc4a95cdc286
+54c1ea0ae506468148a67d2ee08f54de
+54c3d8c0028b4b2e82c3bec29a99e9fb
+54e48986eb745b8e7235ecdf535a9b5e
+54ea295267ffb15eaa8807b9258c8bf4
+54ea403c70c882d2fe9725e2b12dd22e
+54ecbb32f20b78e0d78aa0dbf401b0ad
+54ef3ef3b3cf31e027e8cc2fbf597391
+54f4a0048f4faac762b3e4f2df6c113e
+54f728ae8857f175d0a1171e81c2ef30
+54f76c570b84421c277e8ced16936792
+54fb1e60887b49e4f195d114b937493c
+54fc71d6f67a95be39bf65ce7734110e
+5500de1b1be9e36958400e1cffeaa7c7
+550545d9662a70e6dfbf3d645c95d8e9
+550bb34fbf8ea5dfd4ebadf10fc1e666
+550fd76ed53908f848c4b05d657fa3bf
+551409600861579fed6b245cb2a2de26
+5522d25714d30cf0a0ea7bfd1b878dbb
+5531ff38e2c64a06a65fa6a0e21ecc8d
+5533562773a81187d18118c00b635d63
+55385bfbfd41d60a9449047b46de8619
+553b80297605bef9dc80803fbd76e6c2
+5552d5b1aa1508fa03f8d554f711b7f2
+555436354ff6de6b00771c4ad6b5063b
+55589833e4eb2fb7df0ec44a16f33125
+555fb32a1654992fada46e1dbc2bf76f
+55669e3db0aa117a6a5a5e7c525d45f5
+55684c8932717d7bfe6047bbd8b7ebf9
+556aa2299955ec406478a0813a388e88
+556b41826ff1d56e432c798ec8abd7d4
+556c82c10c337cf6f09432f177f64dba
+5573762077ad9f4e29acad78158f8671
+55738694323e7c3996af9ac33b70ab40
+557b3feec8233209520d2ead467ab938
+557fb020cede10823aa29b8c01b67f3c
+55818fd2d2a57f1009a145846d614927
+55867393b81d9ba98867defe458291c6
+558ac6c5a0de70867a690a722f25539a
+558e41e1d103d6edf46176efc62b6ae6
+5592b01631f75138c5f18880493d5334
+55962e1c8432d1fd57baf041a499a011
+5597f0f7c635a735c9d54d53a272ee4e
+559b839f172f1af414e3b629ce9750c2
+559ccb30f0d466b5d731462c73709f99
+55a3bbd2e86f2ceaab95290d5581fc6e
+55a96734f6489b41bd27fec987e01b96
+55af3a91152163bd2c574d99a17888e7
+55b084848e36158ce383628a3409674f
+55b53bf6afd2ca1660302916a321b8e4
+55b56c53cef94d700f3a25f98cc45188
+55b69ca2e426fac5ebec7fac289f9536
+55b865da7e1c71aee1049a85f8c97a38
+55ba2818fa030db9d87c999b33b1c687
+55bc46f70cb4aa303c12196b128285a4
+55bd1fcc901a27674a747c26a802e525
+55c10db1f5acf720604da2e75c108232
+55c2f5a0ad4b2e6614c9e76739905af5
+55c574551a4770a5f9cffb40b4990a19
+55c790ba962945bece51d98977d221a4
+55c7be0889b68056e11d91cdcf83198e
+55cf8fe27a84f8e1ec91804c1af9181f
+55d0dc4a97d7e21963ec6a2ed2bc0ab9
+55d27b05bab7756c24a65f833e450459
+55d5c5523f3e6c47f09744a030c6803f
+55d6fa5162c51d2884e9fbdfcf367c27
+55d8fb534717d087fdfea0fe4468d586
+55da13977b34500d72b81fb43de25dbe
+55dd33bc7bd3729f22af3fe72ef4074b
+55e9c3ba5578404f43d5030cc3d10601
+55ed517a2b39f80a7b1ab398e1a8537d
+55efa97004f99776f51d66fbecd72a2d
+55f29408aa3485c0700f160a9ae01b12
+55f53d5a8e1fb0292911a9ffeb56a02f
+55f9565ed0b894023ffd7df5199ba8d4
+5602234f75430c79153572b53a9a2ab6
+5606d8dbbbc84a30854f4d97dfac9a8a
+560da424a58920d930e96af8b2197b68
+56120b114dbb8a52a234e1040b0761eb
+56207c5c25b34ef673ff37c94d4fa3a1
+562ab80b49f2b179001a3cb6454e8aba
+562aee029fa2f61f2414632cc426e136
+562f38b0aa672a4d876fe333ae87db6b
+56387576fc46b7ed5be52259328a0100
+563c9c1d4711aeec931e78bebc4f594a
+563dbd7a848a333f34d759e65b8a9b6f
+563ffe952443b244bd4d3c15b623a777
+5641c6582d688cb3fc61ca4cd2c7f4af
+56448db25ac077d75c32908a30edb4db
+5646fb25fa4540f2579785856fb0c93f
+5647e8746de4d9141a0774664441d63d
+564df56f7b38b93010ac2b3709490724
+5650607c838795bad6575a7d0bd141c6
+56566ef04debca10d2d4e59cb4b73219
+56588093a6b112cffe162f155bf33be2
+5658a8971697f599c78941d430631960
+5659e33538795b8c827ebcfbf2407f17
+565a67126581cbc0448b4944af586336
+565d7515188ae19d70879bfef3dfdb0a
+565dfd0ed13388abe93befae65ae5e5e
+56674a7749fbef97ec6473ad88dc65ad
+566ad1bf7aa36cbf7b0aa50e2a28ca4c
+566b597124e68a1a9b6ae4ce7f646669
+566d8b8a093b3186432f3fed0fd39a8e
+5671a78d913d43e638f73d1ab9e44323
+5673c38c5861f2e85e142f79ea37ada5
+5673f20f1e6934c8cbf3d67b4eaf432f
+567679222c8cc4415fe91ad70327636a
+5678b37c7fdae89c37a664bf46d62c3f
+567d33ce9642537b151550829e4b1c42
+567fa1b91d9edcb8892e8fc3f4d4463d
+568375788543615da622637a2a1b1580
+56876a828d7258c7c47b466d7fbde78d
+5690be8fb3e96498afa993bdb2900a8d
+56926c181985900917e993e63df85f6c
+569e280f3a8550196cf8587211fb9b99
+56a1ff2719cb7b61b0ffd22defbf79a6
+56a31f0ed48ae4627a9b9f6a26ed30c1
+56a43d71ba7f4fd64d52d64b76cfbd04
+56a6179b84671d7722ea81d23f28837a
+56a61afb9855d17985006868df7b37e1
+56a7fb7d08b6b826c9353608e40ae245
+56a8814c63cca0af0d7128be50da5aa0
+56ad4eb8db1e1cb7d44b083ad6b8be27
+56b4b4327aa8f6922a0242dd04f54316
+56b4e99c0bc92262dfc8ed85ede44b48
+56cb8b2efbbf32cba853821668e0f18c
+56cbf072da6e9436470f727dddc9dcb0
+56e41ee19e424365761b8f73652f06ce
+56e48005d6fe7420dbb86d1bbf1f27be
+56e767e74ea699523fc603454ee5b299
+56ee1c1ba186799af88c962deda3af7a
+56ef97f21a5be75ca0aba5e2c578988b
+56f06800d1b61f8095853234deaec9b1
+56f7103325c186b673c92d5faa3549b1
+56f93a4bbadd417026707ea23d200188
+56f960a4b583df33ca37401c5dd5378a
+56fc17b46b5f8aafe03f7a7fc1bf1129
+56fece784d09a1dca5410e01ba18a71e
+56ffa3d20aa1abc277f07fed624d2f0b
+57050c5d926347b7fc7fcf9b897926f9
+570a810adf599ca3c6bf3aeb09379773
+570da4aa96052e51c7c30af5161d556f
+5713f94dc6201bca0f552bd2c167001b
+571eda32c9d1fdee1fab4661f5a3e7ba
+57251900fd828915743b5dff6b15bf59
+5727b5ebb1ed3e37d77f77093887d43e
+572e7a1715475001818ad896337de268
+573039a2f258862bf4492a8534f0baf8
+5731818e1a4fca49032b71645789794b
+57327fea8be7df7c7ab34d73064f5d67
+5732927789a8dba77159395b53144ba1
+573417150cf9d6387117521194c194ae
+573f37de7614d2496405c51348d6043e
+5742cf7e0599edf7c90acaa7dae547ff
+574c35a2a1a3cb942bb7dacaf9cc389c
+5751dec506f7c66df4bdee121b04f7f8
+575efbed7c91bf5048ff1e05297a1b8c
+5764320a12fdcebf5070c858ed822291
+576567127044204335d34838e93ad057
+576e042a3a4689b337174401b21d391e
+5771be44211ebccdfcfc6f7d475fca43
+577584137361687ce48ea7f4eca664f3
+577a40648ecef340878b5b00840de4f7
+5786261fc75f6679ae09692aef84e379
+5799f8d09a4c06240166b386e9d834f2
+579aa7b58f67e217d0a4a21ffee0e7f2
+579d136f566ec7a523272f34cad084c7
+57a2202dfc4b13c94be6759ff57ae010
+57a8c4e564ea9abea20ba83a3f3910d1
+57abd0a7fc79bf6d69dd50c8f492a4c7
+57b928766c3e8e94d42ef9990d41387d
+57c5c78b56f8021533757742ed7cec0c
+57cc8439bec971e72232cd9875b4a74d
+57cde13b7f7f2e61c5b8e971dde206a7
+57d108ce1a2a57f8ec9cae69b4c1613b
+57d4ef3c65ee7ebcb90bb92b82e05824
+57dc84a0ae91273a5858373d965034a8
+57dd0296d054fa368c4d9f9e6c0abee9
+57e1c1cd7604f52a373b6ff9a6b90fa3
+57e2ffea352002a0a725d61fe8dd269f
+57e7921420eb3b6bcf286d711e3c1f90
+57eb7bda8d41ff0e4dd3d5a889e2a8c3
+57f7f8bf5b6e316dcef12db0e89a69b4
+57ffed54104a49025a5119ae117a3880
+5801ddc339cbc4ce4efe632a0e3616a7
+58026195f60bd6b6dfc25a110e12c763
+580ec6d054d939fbff8d51146836a980
+581113f47be6f299836b74ff7e2103d9
+58136259ab38d07477bc5e275f3967c0
+5814395da4e6846eeb7242e92c81e2da
+5815490aa8a9c5229779965037b457d2
+581ccda86a8daa0b9d47d9a7e6f5e47b
+581dae8f64e1b92fdf00c172c5957058
+581e58f8e250946f7ff0078734b217f6
+581ef0b82a594ffe5f99c6c392b1c9ee
+582096af1b06a06ad8180450c640d582
+582855fe2526e5cac250c3ee1ee7c7f0
+582a6679c87b34f0698c96454fbc5132
+582ac2d3796356c8bad13fb6763d0d15
+5830760d5d69ba23232ec1f3f83842f9
+5830cdfa1ef57800a0b72a3ffb5befd3
+58357c8c5da853a168c845628b27bb79
+583628e868a6b38988eb68538eeb7c89
+5836b45ec0cf29436c447a5758ee5460
+583a153d4a18bc39639f371ab4b5adef
+583a95e38f86acd8d708cfd1bf9d819e
+583bc8a53b0e9f6ef06b4b3c23bd4fb3
+58409833f3e84b482990d6def01bbc6f
+58418935eae8c34a00c2474a5a45ccab
+58418ba11b58b4b13b0514f915c72acc
+58446803d8c0f9b1ee0e22bb13c2046c
+584643528e061e2994c8027daa5201ab
+585b3c14938928236602483cbc796a74
+585c8071bbb44b779904b5e125eac8fd
+585d254dc25ac76b8593e5c1d3c7054f
+585ffe37cfc32a2b8172f5fee8032c63
+5872074c337950d5f9ea9c33b924ac86
+58729458318001084ce059280c3bcef3
+58755e06097797b557589e714c0f8b4a
+5875907102ffda7de155fff22ec028da
+587c81868a4dabddc0c99a616cb68abe
+58844acf169cf903507b23d3e7071489
+5888c1bf19a1a31ad8a3c9c1aa31fffc
+588eebc25f88211e7e0fad2f666e132b
+5890850a4bbadaaaf40929ce1db50455
+5891f1365c41ddad50fef34c08b8b179
+5893f9925c79fa288b385529b19869cd
+5894f4249ac1f783c23e8126fbd297a2
+58952e27d74572dcdb276c2e0c2c8eb6
+5895aeb8d81c2c84044a40ee1cee60e8
+58990140537f6647fa694ded29ae721d
+5899467d9879223cef91e5111f54cf61
+589acde08b57ae755a478b2ae69f531e
+589d4a52a0de00aa0c0447c3087554b5
+58a062ca863cfc51c3f2811aacefd609
+58ab3d3b5b0bbe4ba552b130dcba28c3
+58abd6bebd1b6032db37ba1c9270d703
+58ac457cff0f82b7648691cbde55516b
+58b224d16aeb4d733e98e874ffcd9f53
+58b687566b4e1a1a68029a3b90aaf019
+58b700513e1454a9ee475c9b6b284236
+58ba26bfcd34c285d982c9dd34e0bf2a
+58c069752503a00305078bc462375ed1
+58c1987afc8d5961e309c41c4f698c71
+58c616da2b621d77f3c1819494db68a9
+58c6367fa0fa718e8bcd6b0a782642d3
+58c8cedaa2cf007121aff2bf2188c56e
+58cdd0e3d79fbee37e3d85cf3e8dddd3
+58d2eb47eb8c504ae72dd7896892b5a8
+58d351fea425c25f308876099ba1effd
+58d666f7a65ac4be7ace7b821db42fea
+58db735337e0db4849d12e3ca7a9ae27
+58df5c51fecacf8bf30a8ebb3566029f
+58e837f8133b426e98c449b441e521b0
+58ec280e1c3127def18a187193dcdaaf
+58ece7f05b7931e940d3cf1ab6fedb97
+58ed844ec72a88f7806d01b152dbff5b
+58f47cf46cca8969561ce56d2846865d
+58f84cc070e6048ca8f5fe8512b4e111
+58fc37a06de2e1b0bc824577d32cf632
+59021d2479732f3fac0d82fd89898b6b
+590fa5fbf3075d14ce887d06ed81d4d0
+59114923497f110e1fcd9924258a784b
+59160e3c5515f1079e6166f12c43b20c
+5916c830f23cecd581ba4d7848f6ec12
+591870a48d9eac24580251f5fb94dcd1
+5919a83ab512548be873610a315602cf
+592a22eca0a9cc480316f400416a95c2
+592b32df1cebaf19ff39354b3efec6ae
+592ef1260d3105f60ffc633121674668
+592f5b84311a04a426d065e84b6a0aa1
+59338f1eadd06a4b0a67fdc4dcb17f99
+59357288c79595d99df3914cdc29fb55
+593f091df1ebf00ca288f3f266daa901
+593f1e088e6f23ab521fba0ec78645a3
+5940deb51ffecdc2ee6a54333c23460a
+594814a1fede9fa722dd0674099d3997
+594d2fa080cb24927b49029d3cbe8dac
+594d58092ccd5579627365c88091b62f
+594d7d9cfe6d835ae3bd0c670474179b
+59530c908967f0e63b6a95875e31ec13
+5955476d34fd9fb030e473ac47884545
+59610c1cdbbea7577e512ada7c16c64d
+596280812c3c8765952a7ea5c17e5608
+5963f6cacade1e2192b3f8c0779006c4
+596431a846b9127f689d11910f0b0c51
+596a244d85b83386a2462fbcc7ede21b
+596dd3778f753bb0187b871beb6cecd5
+5973910eef764dd80d57ab4f11f0c838
+5975fee5c7b38c81efb5d7f1facb50c9
+59782cce3f505d86eaa15c38f3809960
+597bec145c3f043444f1814ce238a697
+5980f757fa9a4653ff51fc47ec35b1e7
+5999359214e8b53898baff4ac51cde55
+599b76545d5f77f36d377f029b94db2e
+599f3e2b59db1fa9be48eeac55f0a6a5
+59a34de450e4fd6808d6a50eadc9f526
+59a40940d13f68d4334b3bcb12c7fe86
+59a9029323a37b693ab115a4ae43b34e
+59b290b97a89ffd7f9762c81e5e45d08
+59b6817b5374bc71d557ed9808b68c26
+59be63cd107c4d6b4b06a8cc24a5b653
+59bec1a62110af95570302bea2b00232
+59c23767a7501b08a14c6a85c1cc2468
+59c2a5534791865d4820ba165727d666
+59c81aaa939266c819d7209800fb9a9e
+59d1ac4682a26e7d6a425ac1f04e142e
+59d7d1bb29fc47cbdd1f9de9e9146f59
+59da134c65330c21fe2af8166e10cff7
+59dca481f815627a9d8cf328aea426e3
+59dea5c357fd04d3505cb4f0e49565c4
+59e36c0a55c2fab89dbec1f96a4bbe9a
+59e378193307ab19604473b541b26cb9
+59e5e6aa2bfd7865a49ca63a9356b033
+59e9b7d39828f59a093dbc7efa2c10d9
+59f3c58fed0be9dc40d4bd04f496c13a
+59f802dc7f2482f332cefb26bcdc7d27
+59f83463dfa9d898a2c164c4e6963a4c
+59fa6cc6f9da4cf2d590526819bf3272
+59fdf2349a99b3173e3051834efc563f
+5a05a8b2125998c37e37ed287e818850
+5a060ca0dd29f238249440018262b251
+5a08f6e598cb95569d0d2090457a228c
+5a0a0197a972489d4f78c3b8ddcdb16a
+5a0e44cbf83cdd11fc9e99bebd06cb35
+5a0eb624f6a6ffb5d4ac571252a5277d
+5a13446555aa1ec79d0c3ae55df809bf
+5a18e5413e34fe2d3ce64839069bd124
+5a1c6e65ea51073499f99fae5dac6bc3
+5a1ca65541dc947e90c713967fcf6c3e
+5a20fb3c73b658607ff8a85fa745f7c5
+5a232c1669e47ebc33afb3d882427256
+5a25919331e4fd58faa97fb40d41f9d8
+5a29366a0a53142daf43b51ace1eda47
+5a2e2e581c5e66750eabd5d536797a38
+5a2ef4f0c4e138ab3039429354bd885a
+5a313e0547519e3cbe0d478b792debb3
+5a31af8d040f4e9b530fa5f77b1ba5ad
+5a3c51243391e693176cdfd5f6476e40
+5a457e7bbb8538c6618958e837ded122
+5a489e79701bb32096c77bf3c45fe212
+5a48bc8e49ef8671075ad0dfe944a255
+5a49f8fedf56d66e5814685802fcd11d
+5a4d645772f83d7f012751e37fb288cd
+5a4ebb5dd95ec4958d06d0309eb9bba7
+5a5727d8be17fd7c820ee29e6adb70f6
+5a5d06ebefd75523a43d9bcc616d2f9d
+5a5ebc0f5890e7a8b9bbd8e17e90dc14
+5a65357dd2143c7e7e510ea154e71a84
+5a669ce92d95b27fead0fe13733182ca
+5a678e0e9740afe99b4d17c435f2395f
+5a6e2832cf3add44b8ed8f23966087e6
+5a77a57f441fe13ad1eefab995a007e2
+5a7bd9b4e432fc72a24392c3940dfae2
+5a81b6ef8a91a52fd0f9fc717e87bb7a
+5a841949c35a6f134c5d7a53495abc07
+5a8e20c5bc40481b4a3322c07559d0ed
+5a92852e261d11caeafbeff9a563c016
+5a97765382ac7411b74752f935edd585
+5a98c3c93c2b2abd8ecdd3d91880ddfe
+5a98c5b1b5446cfc2d1f94a6b606e382
+5a9e8cdb98194f8aa10e91cac1a5f788
+5aa0d3499b17a8a40075b9b8e0c17724
+5aacfc76e53c0c7e753bce2b83f0ce8f
+5aad85cac3ba5339a30c90b8fc1b2cad
+5aaf764c9f31025ed1b9d69d7ce33706
+5ab12db9e525075796e2bafeabad6160
+5ab6ae5d4cc60686800d81d9c10218f4
+5ab7e5f3d4f5cb7bb9f11cee62273d6c
+5abe6b62722811278763ab520f7dd688
+5ac1d02eafb967a15ecd72ca20a690c7
+5ac4bba37463f79651a376e8696dd361
+5ac51f84df9f3ead73d7264a698f78cd
+5ac58e0630205485766dea32239484d6
+5ac783979abcdaa843f9f84f6ccbe476
+5acacab80bb2985cc9a0a75fc53217e8
+5ad857f6874cea90cc2e562fb01fd9c0
+5adab1ce05350e145619b457a1efe50d
+5ae896524de3dffc76dec23ce6e51f74
+5af135f48232eb30e2d50cce60c56961
+5af1e5bc2091b8d85f9a30285a03ce1a
+5af2c1d2e351a0bb7ebd756621316b05
+5afae651e26969e7bb0c9ea77daa6181
+5b037b1c4e0ad2952246c2294093575f
+5b04f8f1b26aafdc2428beb0561e1ebe
+5b05c6f97918ec772ab8def1e1af6464
+5b0d615f1c251d9de9dd29416ee7eeeb
+5b0f13ca002837e82581ef103f6d679e
+5b138cf0f415f34c367e6ccd0518098a
+5b19b83e3e5bdbdf18cd3dc565577c7a
+5b22fffeeb2c1d8505bd904608413ff0
+5b3449b95d3f74564097002636524067
+5b36f6c34d05f8904ed34b13820bc705
+5b39fdb609218d9e51135bc651fe49e6
+5b3fc65ec6dd8c3ef1c9c89715de1726
+5b453945de590ec89acc7639e651d59a
+5b4d0185f2e9b5d2b0c88c52bcf903e4
+5b4f1a919c6598b2b2c31ee662707bef
+5b51865b217c41b02f7c9dca964a782f
+5b5802117445cc3855ac25d5ab51e243
+5b69af95c853a4a6081669f4076bb281
+5b736a7e66f433d7406d113fa0ff3fca
+5b78581dca647062bd70c44ca6e4c879
+5b78764169bada39057cfc028477703d
+5b81a31e336ce7e952f7439df9a305e5
+5b8d6a787647bf68893f6120aa2a250c
+5b9444091a4dc7bd1c94ca593b268893
+5b956080605d9f9120e51408e067d766
+5b985c508f9d48c6cbc2b4108d7c8df1
+5b98caca62c76006d88ae6e98fb83d09
+5b9b9ff424c95259ca18a6378432ab41
+5b9d2e53113c837627ef1ec5c495d166
+5b9d72051ecd0084dac2ac9e0629e090
+5ba0b9c44fc91b68c0f087b0e1f7cfe8
+5ba4d7dfa091a88cff1c9bdceb8faeba
+5ba4d86c328682643ded571de8efc1bd
+5baa411612be294e38df2ae108ecca27
+5bb3372c2221710589fbfa71ccf4042e
+5bb3bddc2bf41c57995d3c93c3113e15
+5bb5670957b605823aa474707472a4a4
+5bb5fec7bf7b879f63f94deed4c77d2a
+5bbcf37929dca9fd8066b0d0bfc428f1
+5bbd8a4927e273f56cf1b5e5e3fc2002
+5bbe4613e54405c50ee77d03a1622e40
+5bc602a31825c0cca6f60a51987e1d5a
+5bc8001ba1751258ae1ac2ae5e381ff2
+5bc81824a65ed1ea9d1f4452cc3b97be
+5bcce7448e4d755bc0de8bf8cd17f76f
+5bcda44521ea68bc0dfefcb2639cfc64
+5bcf5c59fc1218fff63159a80058ebc6
+5bda53827ae0b5ad827a48595789d60b
+5be39f303bcf5b19babd063905cbc612
+5be782808a884f86563207b3318b34c2
+5be806e563a02ac26712fd4cc71c44e0
+5bea6b437eca6dfce4f92129ce1ce462
+5bee6c53ee159292ba415db8082b09de
+5befc47ee7c45446823a7b3bf7b18133
+5bf33bd5e5cc6e701b592eae65b5ce4f
+5bf432e5e36e1618a35357b8fd090ce3
+5bfb21a1fadc4164e75ba6b55c7c0e6f
+5bfc99ff3124c4bec3c55a6d4bc7c8cb
+5bfe7045ba325993590663f6ed166f22
+5bffefa1af06d89b52e6fe127c711600
+5c02e329b26758c011b839494c1abef6
+5c09133bf45c852a1aacca73b7329d05
+5c09a6f67271275ebe0df6d1962bbead
+5c0acb8a6cd92af6ed5b4d6d6e04f498
+5c0c50336ba6061140dd253b74e6dba1
+5c159b3401b013f2fc119f470e08ed2f
+5c1b61fc81a6c1d8b18090bada20af25
+5c1f81b333c99f52f8427d081d6b609e
+5c20bb6e12bf19b2adfad70a818c3ea4
+5c215c9bde42dcf129ccbad0493c5689
+5c23005a0db463b4ab216e1d18e36694
+5c2889683603c384791f62002191dcab
+5c337e0cd5661a410f87ab6c9bfc8f2e
+5c42b40b302dea1f942c455d3fdb3b84
+5c4bcece70de961bdd5df2353b2ab3ad
+5c4c234a35138f857c115da817c2d387
+5c4e21a37569a48d343e7f9363705b74
+5c4e2f0455f2d20334f5fdbd4a0b3305
+5c527140edea52a1b93a198186283d37
+5c57baadd4e4a25f0d2dca6a87c50972
+5c5e74bbfb0543aa3f6e58a312c4f0fb
+5c60b03f5ed9ab7f559e84226082ffcd
+5c63b144a03d8ee19c69b4f1febe3de4
+5c665ce26c7312ff5e0f36b244bf0b5a
+5c698fb72c910996006df40b508e7d29
+5c6e89d52e01ad93f7769d717f2cb818
+5c710387304d6f7dc5c0f295f9e345c3
+5c77cec33e2d1e5e2e9fb390210a4dbf
+5c8135aaeeaf406874e4cc6c5932cffc
+5c8290333ca51a5ec230bc5966d3e152
+5c84910c62ec024c62117bbf079d20e4
+5c85688e2e00aeb70038f24a3f142f61
+5c85d1b4d869a923a36deae91626580a
+5c8d83ffa50c5b31dea96b7f96f70162
+5c8d8c18ec8e1ee1c47a8aef673be05e
+5c922b29aac89168838d740d1fa30fcd
+5c964ab3727365e1a1803023753a4a75
+5c99402c57a1cd11e19cce64dc8d4951
+5c9e314a5c8f2c49af252827f15c6187
+5ca03248c8cac7b08f5fecccd5bd1aea
+5ca2892ea4ae82af8600b5b91add9a2c
+5ca39f3cd509d22ea05b1d4253799b4f
+5cb15b4a6a2718c90e8513bf4cb6023c
+5cb91518ad37652017437b5a689626ed
+5cc027608e203ef90d9d45e4596ac569
+5cc3bf3867aac4b8a105857c941d2d42
+5cc51ff3407569a994b7aa994feabc07
+5cc5f602175c872b771466d08e3dd5d9
+5ccb2944bc825c0fdc894d2aaf40288d
+5cd0317cecc259d939ab282e7d8043c7
+5cd15830de7d5c2ede110e7156de892c
+5cd2ba155200f3146c14f73f1461e904
+5cd2f9a6e3b4845c9ea315d0b9ac74db
+5cd405b3f7a12e211aab69977239cea9
+5cd6f2391ce1ea08c19fc0a85ce501f0
+5cd7a35b147b7144fdfcdddea734fe64
+5cd9d9b4413b3bff707040e719e76288
+5cdbbc4adf724f7e3025d594a44b2c86
+5ce00be4be11c656cab911a24a8d8115
+5ce421e7d7e76eafb8e322d3c5825834
+5ce5d006651944ce1a70e15375c6e287
+5ceaf7e749787cccb9c58857ce4f9927
+5ceb2bfd215c45d2f3d7ba4c85edcfb8
+5cf1af512ce8067bdf248dffb0d33048
+5cf2aac5f0403da4b19f5f9be9721a6e
+5cf2f99d6dc8f7ab6d08f0e62657cc82
+5cf348a63d8e712c4fb962cd05efa4af
+5cf4ccfad5bfe255f4af4735e3cbb452
+5cf5b32f9e11340e26c7a1b09aaad95f
+5cf84f6ba61afb3890dd79b521265d75
+5cfb5642b8b9e455f458dd6676fa2ae5
+5cfd807b2f5f8e45c80869e2ca85374b
+5d00d1faa8ee907bf533b40028910b88
+5d0ed9294da1be8be5c92f8f117fcad8
+5d0edafd728467f5da441f865fe031bd
+5d13af3bb3d10adb4b4bcd7e0ba2b076
+5d24c14930bc8bbb2970784225e84668
+5d26b88a6666d7eacb85ae3e391e4c09
+5d2976dc1cc5651d8b20e2e8c766d624
+5d2f90e199e040277d36586f44ab99df
+5d319e19fc5055853721e15e7c6f683b
+5d3385811c46b6d6cf9a4ccced1dccb5
+5d356a794029b611aa15afa259cf5337
+5d39aa75dd8aaea70bb59f7c506e5a53
+5d3e1caeff0e85b88a4bf99b8b75c180
+5d415c585a4ecd0e9a949b807eea4c54
+5d495a76bb15de81695df2e5aa578626
+5d496f15a3888a71a33f0624d3b13501
+5d4e7fe2d82198354e408704e7533d28
+5d52da859594f095d1a3b7e574d41e55
+5d635e7bba585a1444f433eb85bfdccc
+5d6673e25f6a64ffb8fc114149d6b05e
+5d6938e98e583a50a0e17fd384cc8808
+5d6a76cbc1968e24c7ab9074e3cef4d7
+5d6e43655861042d3aa4b3ebf9e8e3fd
+5d771bc95d58f22f2513a096b13820f3
+5d7d51883011cbfde65292b0730263aa
+5d868443185d876c2645352ea152c389
+5d8a7e3a69681d8c4ade22f284a01032
+5d91bc5a51a724c5e73936471dbb2bd6
+5d91c5fb1024d876d4f210f80c0b82b5
+5d9a991afa12f19c92acce953e40165e
+5d9d26b2c6cb7aa4fed549a470aad2c4
+5da244d6e8458aeb2ec548a8ed3edaf8
+5da45672ec37e58c10a4640c548c94d7
+5da7df36d30cbc85e84313ea1f1313db
+5da9d421c0b5ae5ed35deb3de10ed330
+5dae60e9e7188817574d3f8bea9d9daf
+5daec945e83f8d8aa62429eb09b7a9d6
+5db475c730f7987e1df3f116fb70b69e
+5db708ec090788200424571feee7a35e
+5dc2105207dce30b39f309480f197ab5
+5dd0cce4820023fe487f4129373f3740
+5de3abb093eaff5e6c807c85bac7d0c6
+5de8efee2d9636bf29aa630dbca9b9a2
+5df297c85d7753c4dcb2d0a408d55772
+5df2a7e0e1877f13f22ea2eec880f8ff
+5df8b59a7b2eb6e9f835b6bb454d30ec
+5dfd04639bf91236b4528a41ccf06d9b
+5dfd7efbdd345098be2571c60ea45166
+5dffe29e384117c689c2b89e62cb4923
+5e04696794cfe56a6fbc3e4e8834715b
+5e04ff74d2c60e13717e14dedfc4e3d6
+5e086af6bef5a437cf72ac423a4c457c
+5e0a7bae859838952c1878bb940b5cbf
+5e0c79a54cd258e9dde3d5663a3b0351
+5e0d70ebce5eacd2d19c75f428aa037e
+5e0d82135d89d5216e7bd13ebc763902
+5e11cb88810a2a595fb199fe51f99375
+5e184bf3a25e86e80d7f45b5e38f7aa5
+5e1a083b0db1d9fe0647aed0e7c85d42
+5e1ebd340c9698efcc8e5e0467a236d7
+5e206267810e3f0c952463fd42edc9ab
+5e252b1206716ea0fa0eca40da6fe507
+5e278216502d5828f323c7e3689e9980
+5e29c7f6e408858d46c9c01c8ea45e44
+5e2a3c9fd3cdef2a56f8a1075b4775ff
+5e31ab98969a09f5cf838b1c5553b2ba
+5e334cfc14800cbe82717cafb66c3227
+5e378551cb037ba53b6db6cc8925e8ce
+5e37c72552eb748993b1cef6c52272bd
+5e3cd6424220f8885447730b2e572531
+5e425bada922ce53ce3de8115010c9c4
+5e431674043943bc2dc5c91485864790
+5e4398445684ed9c83e45d7b9b0f6621
+5e48fd69c7d9b8ce0e4b9efacc691583
+5e519b71bac98302ebaf58884318ac10
+5e56b3e74d3fb72e6feca19ffbc800f0
+5e59022f6fe36b2b8f93b130cd033832
+5e6533d3e1b898332651b1c70c2c768c
+5e6cdba295e166163f38c200b37f4ea8
+5e71ce876029126b2fc06b9f132ef648
+5e74b92d4f91e9ed1b3fee592cb22635
+5e74f67fc8121653b6a6a801b86a49f8
+5e79a7eab3b2c2c654b0e420d1348991
+5e7ea177fcfbbfc4d4647f2ec854a4b2
+5e816789e6db69adab4e516321a718ed
+5e8353e468b45cf08971060d9660b373
+5e849e09221670f35f75c4d34cc145a9
+5e86070a356d2ed4a036a28bdca8e059
+5e86b84765be8eba76e7620b1e40e931
+5e8d7345618f025a78644962b0ec28bd
+5e945f28c037d057178e3c40b0b08fcd
+5e94b2d405497f422b7aef152e0d31ec
+5e976d98a1bf3bc86920c51e09b4a3de
+5e9872159973f42c3c6ca127f910483e
+5ea4aab0882ee4864ec36eb4e07f2606
+5ea53e34eb494c2fc9cebf3c73b2ee7b
+5ead7b232f74da6a12fd686a6c0c807a
+5eb0f8af6eee1b2a42cf4b75823c026c
+5eb2ff20daba1d57135c87f6afe7763c
+5eb873e4994dfd64f9b83abd363f3ee8
+5ebcd9e3a56283d09f42b6e416001644
+5ebf68e418f4ea2171110db0561128b5
+5ec843d67ba52f02d22281c4b7d7d311
+5ec844669aa160cedd91448ca546566c
+5ed03a5c35868ec35ef79c908b731f25
+5ed12f1ab1bce46d4b1fe2c5606df155
+5ed620a92aefc63fbe66a7e6b7900b46
+5ed8b85057924bd2a6385e3ceb8d37b8
+5edccf52eca8033b46808e7fb898b7d9
+5ee8fee9ecd07b3dc5de009b366bbdae
+5eec36b769b94d5695d50a6a4665b50c
+5ef5f0355f37507dd8a9f7edebf7f59f
+5ef97aa69c593aaa051c8418b7c54105
+5efb1e516bbfdb665868fc53a3af0de7
+5efb72b067d51bbbb6dc8daf3027271c
+5efc19eee8e088301efadac44b1c32d9
+5efed65a95588a524432f4e80f57ac09
+5eff5f75ba4bda60838d557516b99a12
+5f047f82d12f21ff793e7214932324a6
+5f0954d4e13c571366860df1fc43eea4
+5f0ca1dddcaad709e845cef806801504
+5f0d896da4e13bdf192bd237b7c9524f
+5f0d96744cf75c55fdafbe63c8e61289
+5f109d7f4a883f0b7a69486860f394a5
+5f140a216136ce86e7a559515be7c08d
+5f2684044900c9ce7f435b959b975612
+5f2b6110db206466481b700c0038aacb
+5f2e29815ff49057bbc0d4bb392efae3
+5f35a63c8f18d5f5b1061bbbef18485e
+5f3e12db7ba8654b840c8ec0295fece9
+5f3f0835e92f75bcd53218007f6c0db3
+5f4fc57ec40df0bdbd4aae8fad7195dd
+5f53892f891cb0f1c1d07fb49e2a94b2
+5f556a7336caeca71507f36504848672
+5f6d16e5030324c1da9ce229d13f5e5e
+5f737ebc74fa734d47f9e35ca6e5fc91
+5f737f8dad0e87cd6cb449ce8ce4c885
+5f7769f7e9ea853ed9f3b5dd4e174435
+5f79e08ee586574fd425cb9678c751f9
+5f7a2438c9467597971f9086e8cabc25
+5f7c66385d9513a6f17aa2c8b05771f5
+5f86313b2e10abc3980545b82c68bff8
+5f9037ddeb6b4fbef938218fcc2e86f9
+5f9577b1bd42108ea5bf03d0ab8d2457
+5f96c751eb0c2cbbc14dc879a5ebe620
+5f973891b458c733238ae45f6396ff30
+5f9e2b1870dc9d0704573955ccc740f8
+5fa0ab184558b0c6b7b700bc0bc012f0
+5fa35219c40fa4b9577b5624d02782e3
+5fa8e41a64c6c964017557bcb3debb39
+5fae322992aaddf35b0d26e21404c0f9
+5fafd3381f3642a4fd4d49b8803ae996
+5fb9a6bfc156bb4877990af0d18db54c
+5fc54f761f1d3e2b418955c88db80e24
+5fcce5c19d2e8d1ec5796a8a77f4e431
+5fd115ae834b2471aef74f2cca747601
+5fd280e5001e721864c0f567c6be6e78
+5fd7a10d8b3ad7b7be2122302e738aff
+5fddcd5880f49b725d1fee3eeb08c0f2
+5fea1a958fc0400dc7d4b297b345d93d
+5ff21c36a612a3f82c52d0c118ea63dd
+5ff31072b83e8eea6ffa8b5184583b92
+5ff94fb90ade2960aa8c30a9ff3ccccf
+5ffbdec60ed3fa3464b5ae154bc47b8e
+60001b1061e883c274f67980fb8a200f
+600a088394fa930a7cef8fdf6d1fd7fe
+600b45417865104be16c6b7bbeef67d7
+601011e3fd5b31fe099fa77f132b779c
+6017f623128671b434bfa2c84b37dce9
+6018c71d46c79829f48d460d025edb4b
+60251dfc78cc5b2eefcd9aeb4297d109
+603013fd36ce956035126258572045c5
+60354c6cca5927265d3ee190b929da77
+603e4c40af54b1173493a8412a6c14b0
+604158a692d4965e9453780b92dc79ab
+6047cfc909925ca2d88b999a306a8595
+604a914ad26cd42f77b6cb50578bf99c
+6052cfb72ba49e91debfb407ea53c6f3
+605bd214e925d5f6923e7efc38aa25f3
+606e49a610436fff15e413fcd7a373b9
+60778a63a17fb5285a435073e8df40d7
+6079222a92da45819815ba71afc945ec
+607a2d09d75b34b9278594c9649c4340
+6081bf5a7c2f3395ff20af01fe9cfb99
+60832b9cf45b9f60e543feaa0ee663e3
+6089c33226633c9358e8b142d5387d30
+6094bcaec290653a83a4d70befa28304
+609b1a670973242802c2a1fc2bf24410
+609d9bf9d3b8431b12e8d1b165c0b300
+609f2f18e81807e1f02289cda81a2865
+60a00838c1e28fb726c14c593314814a
+60a329b9eed91a5b8ac14d03c73ba674
+60a91542747760d4fa8ea28238d5e4d9
+60a9a978ee5d1be19b7ee106790ea09e
+60a9b787fb248ba1d0f3dcb573eec325
+60aa1a11cee4288f071092c43c8068a9
+60af626e389aa3fa7a2aad20ccfa918d
+60b09a21bb210391d7f56a9c1b95b370
+60b7620d9526d967b62dd166111c04da
+60bb8691c19ce98401997c0f8c55ca37
+60be80263062d433b9f2966b40e5d634
+60cd01d839f76493fe805cbd08fa8699
+60cd1a58db261d5747871a2401f47999
+60d0e93a1577100b4d18882fa296bcf0
+60d37aadca821331d76c7b5c2682b3c1
+60d60cbe705db060c63e344a63d65413
+60d89860effc0d9d584c21446480c6e3
+60d9012f8c219237973102647d1b59ad
+60dcee357d820a71732e3a04b21444ed
+60de2bf77d24d11468163772305339cb
+60ef3180b60f8f975807b506a061c6b9
+60f1019dba8940a284749845a10940c9
+60f385958e08bab5956b5b51debb66d9
+60f657a4feec53e1d1337fccfc098b4e
+60f817faa5394abc022223676cd69572
+60f953c8e503390fba20ca483bddedb4
+60fcc1e3ceccbf559d6e7ff3d71b502b
+60fd8ba3607117647d84be16b311feb3
+61087474c5bf1a7262c8e2ec0b6c83d2
+610e0cf098d04b52220d3da3a17b0ed9
+610eb86c6194e0ac01c085e7091108e9
+61112beac342957895d1d5468cc949bb
+611283d79722ab8d8c4b9d7854428a9f
+6115cdfb1f925d7e6d07e0d83654d55d
+611de7232fe220eea186a3480f0fd59c
+6126db0a3d41685083266d8b69b27abd
+6127353cdb7929b354f18b8ce75ce245
+61283f3d2c6425e80cb1abb8db76a8e5
+612e5a80989dc7560bd5faf9b2f4bfbd
+61325acf66e072e3b875c5120b7b82de
+613464c69c66ccbfdbaa7e4a21cb16df
+613f8c7caaa6c2e1834add719e00783e
+61458a00027930173690bd831144a152
+6152d2443ab4e00b716345dbcbceaf84
+61547ae4990d98384b2b0d12f51d31cf
+6163c1abbb26896255286b3d5c5d67c5
+6165b5e1edd56021aa8628aec9b58eb3
+61735550991373f20a9f6b431deb3437
+61736c9445d6b01f11ec3f84dfae96b0
+617a79c7ead107b0cd9a40966f47e1f7
+617be0fafb7abee054611aac170640e9
+617d610a3b923dab9c34c114af627941
+61853e0dea1db36b3306960e86d1bb63
+618a932b2c0baa9e9f4b3cab76dd26ee
+618e35685d2f791a00a50b1d5d6acd49
+618ff6e760b78ba6fa09f80a911daa09
+6193bbbc14a6d5a4a87c606394548f3d
+6195299d433d2d7b7e4526b2684f4253
+61964403a082163896cea6cb50ba0893
+6199d5f062545eb44ab81b0c07dc0e48
+619c4159d21f34bf69cf90648ce774ad
+61a406ee4b79b035ed3edeed7f533a07
+61a6437b2aadcc5256bdbad9626b9f1c
+61acb9bab5991a2656310bdd772adb2b
+61aead9e5d20a9d431a47df92da08194
+61b5bfda396b42fc77b2d055425bbb5b
+61baba42ccd9597e67c71978d9391eb0
+61bb023df8dd5087ccbb1ef332e74e6f
+61bc6b0ffd70577c89f13611aeb2dab5
+61be8a5a02582aa1df311bf2c18adcd0
+61c060a7b435f5b313b0bf151bf83fb4
+61cbf006ec5baa41eaf7a9e57e0065ea
+61cc9b5a249c582e4c3122fe7214ed2e
+61cea9a1bd4c0fc9895677e7d284341f
+61ced7a8164ea9cf16ff2b54deef3621
+61d2b7cbcd9b69a462c4352439adf03e
+61d2eb311736481473c88621c58f0d11
+61d58f031364bb4355a9e881b6381a54
+61d843e673ea5fc5c8e1878abf6e7d06
+61dc95c6833d4a86e0e6236c1434a460
+61dff17bf11ebc0087afea293609a10c
+61e39d2a5d28fc2bef003d26b73c6a1a
+61e53134b982c19f4758f4ea4a25d47d
+61ed3c07ce1dc11404b7ba241fe6f30a
+61f4681707f33c7c73c85a9e0fa9becf
+6200968dd17e6a6b43accb378b055e39
+620c34d90d8d46582e835f70df88db99
+6210c681468317d3d1fcddd098a0d812
+62117f7fc5a1f3350b2476de6c00cf39
+62127f24a9b9811e4c1e6c9d4afb8655
+621284b8191669248df7d9d52baf75b4
+6216f84f74e843dec67d3a210f49dbeb
+62182ea4c491117eebf10d4a2ba55b99
+621cd7041fa5a2eb476f60509c65ee36
+6224de483572f59a37d3d0ec48415f3d
+622ff1d78b93bef482622eaed87e08eb
+6230f1eaf664545480b0983372e283dd
+62312e4e7442e4f488595f718d231553
+62376c9ce959b42a512680a502045dcd
+623b903841786fd9fd992c2471ed04cb
+6241e5dab66360578daa3da18902fbf5
+624365af6f40e646762e81d1c6dddee1
+624483c3b39a66fe023c7d60993f7b00
+624d657aeee9474abe010245d332591a
+6256691603bea509a6274dd99f521197
+62572164e55569a3b207529c3aed1770
+625e2f820e367f84fe22d7f8e1a96482
+626023d31030d2d4ea784679977fd1e2
+626b2d894d0930e649815820c74f82e9
+626c3d600313bbdb4930e9f94da7965b
+626cf7a05c102bd0c8f75bd7a6e6778c
+626d5684b2cca5b86f58d33e3fdb9dd1
+6279c6a9560f0cf88154e021e59e9f57
+627efaa6496e8238e0714b3161d8b5d1
+6280a64c1fab3e69f0fe37a7aeefaa88
+628212f6800bc3c2d339babf38b06180
+628308e43ca25235cc8cdebd79a4e303
+62883d482f62f6c32e17ba2f8dd505e7
+628ee8cc820ab73df9635fc46dffc247
+6293b20adb50d18f51076c0408a5cb33
+629aefbd846e3d660e7185bb96811a01
+629d8c45a19df46617bea7f44eecc141
+62a7c4391e5da8c9589a90c63d439a6b
+62a81f5ea56f352248023f24ecd57efd
+62ae5276dccf8eb0a1427c1677b03e38
+62aef5f2fa7300fbc9c8fe3b222ad20e
+62af4d1c0d0742bf4ad1b4fe864329bd
+62affcb77b09b6abc8f5ac8e7fbb9ffb
+62b142ac3fda19210fc88d6c48da06ac
+62b9b63af083c574d566022687ca1269
+62ba1e72ec6c141fd1d714f47cb29466
+62c0561aabf989db4df6ed023011f312
+62c107f3d19915a3debfbb1d487ecd36
+62c74b97a44b3743b5724ea5c9b1065a
+62c8189c8668a8aa9b7147b381646ebb
+62cd12b33de6a095171fbdcf5be32521
+62cdcc4f89199bcb2e2f5e93e973c805
+62cf52ea6b0eae23bf26d29f555aeac7
+62d58c1235151c27ea499d9b731fd907
+62e197a86f8a7819a713537cc06b53ec
+62e7e9f53460133a170f3bbba0546ade
+62e8e879240e9f1766313df442a27630
+62f277f8dfe84d29041187edde69aba3
+62f689a29bef6fe8acbf07e163da1535
+62f7c267b7f0d5dee96813c1d46e3f84
+62fb76c9a9fe17060797805fd8a9c338
+62fcb9cae74bb89f0042ab75ca9d679c
+62febbb14e2589dab413c75dcc9887c4
+630072d5038b40c9aa87a5218762ab91
+63060325143d33d2d019e4491c92a7bb
+6308f83cb5204d41980c922f2b2f5469
+630da14030bf0434a480762155380900
+630e629ae99ca0f1099fb1cb379286df
+6311522bf92fb666757c17d4a039e9df
+6311e3f10285201f9208c1a5513829fe
+6317f48f55038bc84f32b0edabd37968
+631b84b88291584ebb7e718dafc5d103
+6320e43a8fe7cb90317c133f60816f1a
+6322eeddc6aca19abed546ac3d09de52
+63239c013345b6915c5493e0eca08ec0
+632a86f1b2c16fbb4365e0faf28b946e
+632c39c33e551f4d71f696b6739a7bbe
+632c3d480855e07615f7ba490a342765
+632de849b6243a525a2f04f48deba75d
+6334c5488f2d3a72ce85302522651af2
+6337ee76caea26f655374c1dbd68ccf7
+633a62b9d270ad92f1b2971a7206f2b4
+633daff3369f4a2a487d0d15f69483fb
+6341c3b0a9febc53de05e0bb420f62f3
+6342437eb7d26c249fea7122f5b4a76d
+6343c8e3cd472fa3f21a98b18e187f32
+6357523aee3af7bf91b6974a3357bc97
+635aa4d771991bf7b90229b08535126e
+635cae325d49679e13aa5d2d011c7e9a
+6363fef4a6e36ce75c9fb01d536348cd
+6367cfa7eacfd7134ec256eb07c23080
+63689c477f25ddda11ab457850c442d0
+636a19d912fa7361c99795baad27348e
+636a2b3f4e4486099921f4c5ed174b79
+636c80bed4a106dc80f82457a0cc98fc
+63754385ce7e4f4d52fb14f667bd0f3b
+6375b6d0a65f6ae2df972c3903184989
+6375d25cda81268ee43388878efed8ff
+6377e4a491e9ce749f71ef1f3445481e
+63783a4c27f3421b0f2b94a6105e3e7c
+6378560610c8784dbb3349c59e1db800
+637a41add14d531f1c550f15db3582e8
+637a997966f3884185e309cfdadaa6e3
+637e0a03c3445ae376d0963110f4b923
+6381e551008a356862cb8003e83794f6
+6384294a7883ac653dc374838294dfa6
+638d69b5bc6ee7b15421d1aa92e09894
+638f7381ddfd1280970f094c1aba5d51
+6397d6f3f0a07387459b51a9e03ccc7d
+639a42e8cf3d7661ca9c45813a8855dd
+639b4911ce792ea0ab9be6893845b762
+639e43cedb3b4b380df9c9181480e963
+639fff585af16beda029304a85fc0573
+63a7339478f9a70a1e316993f2ad1e05
+63a8610c1e3e636e27ae2ef350d151e2
+63aaee0edb53bc3842636dccf7516df2
+63ae0c76069444ca1d935444050eeb3f
+63b64d0ea30819264a09e4f1e32d015a
+63bad3e4b31d2d8201117e5c62f13b0a
+63bbba2a727a9ad8d463a8b8297b943d
+63c243ca80a9da8e748a0d2ea2c5a78b
+63c4d323a03bb8da99d0ff4cacda7d4c
+63c8aba952a723330eb1626674b8c3ed
+63ccebe769c893d6f94b9d435fc30b74
+63d5188e34cef30ee68389134c57142c
+63d899120e2a885670f7b02e2e7c05bf
+63e9743ee6f0c6211c4afa09ccce102e
+63ea0b07d1e18c6436d95a6309070263
+63f59c03c3a0450b68b900c088ab057a
+63fbed8f5e8dcb8b4e8c5ec3df67619f
+64011746a0129ade3ea7202eb3e30f5e
+640302787e5f55bf5e00e1a491319a42
+64037ee4b32a99d515afe31b8becc04e
+6405029263b8053f492569cc9bfe116d
+640b9e714377d1c520cfb7c6a647cc6a
+640c147ceb298a1529e0293742f250e9
+640ee5b4c56ebd3f4db4c40df0c484e4
+6410a6c5640559ac95ad09e6d8755289
+6413d57471d7c5208f1a4ba53c5e6026
+6418c5a8f34b53efebaf222c8615485d
+641d12d1fc3ec72139e421ea1990980d
+64200ec16f14c00bcc650f092f95a9be
+642098cc0c5516d8161a0b31f5b8809c
+64241e025668118df9e704a5dcb22c78
+6427b754d93204a45dbb95f0f0eea6df
+642b300b1aaa5dfdd7772a1cb78ea40f
+642cec039ce4eab4158b87580259ce5e
+643ac78e602c105e4ca453a08f36520b
+643c121a066e361facab00134653103b
+643cc924cf21e746c90aae3645402814
+643e2fe68ca020bc0fb7abe5781ea771
+643e3c4590206e455310c5688a1d245a
+643ffe77569245654f293fec82577f91
+64416e9b6a62fa2d58e04c81bf1e870f
+6441eaf5c46ecaccaef98350ee1e1bdb
+6446da7e20c8f6f1c828f7c0b0d6813e
+6448a059fc8117ad8d4eb9e79b533d00
+644a51d6c8bdee0ebea63e077741e2ac
+64519dfac522d08720cfbf666ad89285
+64595feb98c2e435db9c16086346cfee
+645e5b11649760de461706d41de72bf6
+646041ef861e4f0a13eede603f1b8777
+6468a1f13ef9809907e6225f92c70be2
+646a54e3771759e4dfca94912ab2dec8
+646ae148cab6b7f102e83d0bd8f6c122
+6471f318e18c9ccd918c0f0ce681f597
+64724d9404560ea4bf8b890e9370abab
+6475fd7b45f59633cda95867157ed9b6
+647d5119a5af51382060a0976fab45ed
+6482eb800b727e773f09ca5ae5da10e1
+64845e0dec8ab59e35fb42999ed7c561
+64917da89289b39342a033072cd0a84d
+64954ab5709e6874b016011fa17c98ea
+6495710e496dc63a70f4e08e2ca655cb
+6497e1d8ec365846fe4eb8f7e71df28e
+649f9623bffa2613ea9aedb5ce48fe30
+64a2087a31b712a293c721261990ce14
+64a506019b537078db5b918f007897e0
+64a5d6af398763080f539f344974a16c
+64aa24359a6df3a85be234baf7ce2ed5
+64adac12deee5e538014a84474ba4d0c
+64b02ab41c31c9c06da8049c59b749db
+64b04c1b70996491673626f918cdcb36
+64b6bc39324267518016803e1f1acbcc
+64b71215b860f52f08a6665d5e43842e
+64b7247ac0060206bf40ccf1f059d3a6
+64b8ffffafdeba587514135a9986f8c7
+64bfc2420d9eb925a4a6927391717fb9
+64c60e99ad9a082d267b1d08f21eb4f7
+64c695a9fff9aa8d101871b0256ec339
+64c8c4a69c1524644c8ad363fc6bcf81
+64cb2f254626ec3a9f1308ae98f17719
+64cedfb72a72da333856831ae6e410cd
+64d3506918f58db727ddea8c095c73cf
+64d744809ac084ebcbf60ce80608c090
+64e5354d2ddfc4479786cfeaf74f43d1
+64e66fadf0d2664b74b0d7e4cfddbe06
+64f0a393a9fac5e63791de4a445c5600
+64f5dc442dcd886a00a91cd464bcd637
+650186189ff0630080f0617fbf200736
+6501ff62498261f65d58891371c600b3
+6502781f3107899bc94d9bee82dc4423
+6508090cb65da9904a526be8095e2cf3
+65091b5b727a9e84fdde479fcc218e7d
+65148de6f02eb3534bab5342f39df111
+6515e764955423aa336d1edbd08d2d94
+65171339cd67df9ba4adda44d9ae123f
+651d0bc173084b33701060b4524e3e9b
+651ece6fc6a3f377b222ef1185c249ff
+65292764e98e4bef877f85a42c50e0c5
+652dd0b146156258bad5fa1e851e3101
+65381acd37fbd31ec7332d91c24b9e62
+6538af985e7b29789a76b974e0b904fc
+65448a50c4bd088e94e7b5e0b9f3fcd5
+654784806bc822ebf7b5eb176ea9f563
+65481673794949305aa723c0a4837301
+654a2ac52406b6130d1bf5fb0cc30568
+654abf702e82972ff28d21c261c577be
+654ef7f4b1152607473ae359e8a1b0a5
+654f88c5e09e407f55d7ca7ecfee55a1
+655174636296643d5c5aac71de1667e9
+6552620c4a43006d58462ce7ae797534
+655c50ddbf41474ea1d3e3063d1bdf1e
+655f5135f9fc413464730d6c0faee7d1
+656087bfbe999dad408e45ed938b9e1c
+6570a8836ca4117872776d60306d8083
+65749271465ec3d9187b35c2226c501b
+6574e47541b54e3ae908ef4613d5cd34
+65779bc8a253b01c0924f0640e8417e7
+657842e763bfd6802fce5fc855e93c58
+657a14b7aefb2b5b30f07f70d40afcfc
+657b38f223f56232e57d077572162c4d
+657c020512a17bd7c66561514cc98923
+657e7443d9bef6e3f931232e4ee5f2ee
+65832128ba4b6e8dd00240fc473c374d
+65897be195eb7fe9d6bf1eb3ede1bd0a
+658aab5f4949eb44ac349286008c45d7
+658f980406ec7d24655c2565dcf9b3da
+6590c446caad78c319f7860857215f0a
+65944c8d6430d1d882c179c7d3ec7eb4
+6598c6ea38d69d69b59fb28bdaf56784
+659aa65725a6054644cd1cfe49635d1a
+65a27cf32d4d8376066ac2fd30c821be
+65a3ea8801e6685c8d83595b5b4abddb
+65a63f96a392e262298a58e0bd315263
+65a6497ca1a3af9ec34b41288796b44f
+65a78d1161209e83a31633fb25b8bcaa
+65ac1aba745857cd13cd851e75d6d832
+65b549da8a525afa377e9d75a615ce61
+65be155febda2f0246bd163d170241a4
+65c5c5904e47ed634e3d5274a97f410a
+65cb32d5dcacd10b9ccab96a8cdd4c01
+65d235134d6ab01abc8286b435613b51
+65d61f095d9522d154aeb3ee58a5fb0d
+65d77eb10a5368e84eb9e300bd0ba843
+65dd66f4afe435c940ce2ce11b0c59e1
+65e56391b362fd9914585deed803b029
+65e63e67a1df9aa8b2f4a12a5b727c94
+65e6fc8f5bd331e1f10b292b29ab2f9c
+65ee7faad42c3b99dd28fc1433808a62
+65f5cc2cc26c93d8b7b98126581ac63d
+65fc2744667ce55e4cd2a598c49f8181
+6606bf470076976cb33bba5b3e16854d
+66102b17649b814b7a6f8668de47ffda
+6615e4048a20987e8351fd9f375eb8ea
+6616979d4f673416a4196715ac336f78
+6618ab0fc78c493a5161ff17a08f7f67
+661d74fe6b394ac715d0f7c916bdd069
+661daa090402d07ef0c27ea0aa710b32
+661e656b3a05989d24f514f56e7eb3d4
+6621bd9fa03d5e7ba5a44c21ffd46965
+6621bde5a4c69f191540f6469a18d5af
+66221f0d1587da95c68ce1911c4a7511
+6623fd69a4220452cb3ec9a19ec46d7e
+6628677c36afbcaf9a151ce65b773372
+6628ff366ac65a911a211111322cc332
+66295f145de1fbb9aef51d08d7d807fd
+664250d0eba03e4291724c7024fc3974
+6642ce928f659905dba610344311b257
+6647f15889ef674bcd8240214f323d6a
+6651499eb91df180e3f81c193f4f0f72
+6651c2d83bbd62e01585ecaff6a7511b
+665440eef371f38ad0b4dec0a77c8546
+66544337f7e14bce761c51c1dd654e49
+66558804cc47b20f5575f3d47b2349f0
+6655dbfad7b6e0b607b1a27cefb72f67
+66610b3822cd4e1e7d793037fc08f1f7
+6665ea8acf16cc1f7af1c1be4667625e
+666650c70f8025972353ecd8348f0510
+666fe6a63446193d91a1e9220137b0b8
+667142b1005eb904761a9a9f38ead918
+667b33aedf4bb7d98759f2a8a864177d
+667c2fad5fafd6b869fde57165e8f816
+6680a7593b53deab949fc893b1081242
+66823cdcae40219c88f5a1da74f0fb46
+66827bbae3057e9e4a1cafca897b5364
+668957e4628c38c2c61014aeca4f283b
+668a0378dec91781a927d68fb642a4be
+66983299fb4e30741f875351dbc3e2a4
+66a06b9e1417e26c77f3916146f72faf
+66a2377f2b67f9134b206c2c4ef4ccfa
+66a447d3b4ee3605caab8e7271f453ab
+66a7f4575d76fb99e0e765e56315e1c2
+66a803a42cb11aeee596c6475373d1af
+66a80c6f6117f7636424d09da6a6c0cf
+66a910dd8a4a36c4a97e6a0952143098
+66ab9ca37b0221e38233fa0b0983c01b
+66b0282b24dc1c1aaf42d06d6014708f
+66b3ae0f238d0da08e796e87200c41a3
+66b726a84de8ea226de6c8efdb52b967
+66b9c0026c80ecc96b1b31cbe52af4bd
+66bd56d93072633cd7b68a8a0f765fdd
+66c13eb7b7b68b0596ed40e2766bd36c
+66c1b45c49b29e376690c943b6ef7c22
+66c1c196e8353adbf5474376ee2130a6
+66c217c4ae6a533c0427b3cd6886a87a
+66c7e02eabe081eb4bf81026d18f4767
+66cbe9bceca821e05e6b8e50a4405955
+66d4225411ab0f4e325148fabb229bf7
+66d8ed87e387591cbcc571299cd26cce
+66d930fa9fc856d0e6b3b2a030b71d48
+66e03bee0dbdaabc5aa949c097e03964
+66e64fca3c833fd875292761071ddb63
+66ecfd0e211ebac37bb6dc72a3432436
+66ee4cacee05f8209e0671ebc25cad23
+66f38d4f9afcdb6d0040023f10ab6dd7
+66f4f540f91b4eceb0c4a5cd9900549a
+66f7f59fbbb600cd0b5e272a73e53317
+66f98d0535d8333746560b3a3fcce87f
+670333bb5ee5c2bbacf90836f011837c
+67039ccdf1254d644be3fa40c1082f0d
+670c68f729abefb7b244aafc145105bf
+67104b26cf89421a35703fb278633a01
+67123c6781e4d7ebd5f113d9a3de322d
+6717437d4ab2293aa17da8e477657e9c
+671c5ac82cd2d0a754ff5124569585e0
+67206e8721ba079f7b837f3f0c5decc1
+6722f4c1dd14f921d3b4a0972fb905bd
+67239caad1421bb920a3efa8cc127452
+6728effbbc4fcc38e53f74de04783c64
+6729fcaa7eca21499cd139222b604adb
+6733bbf3de196badd04f02ec6d40c903
+6736a0e0d573b134fef71b0b905f3103
+6736e11218cccfe695052643de9393c2
+6737fda83313b1dadde371a784f1396c
+673ac3d7a6a04cad22a9f9902d4702be
+673ad86455d01e530a4a1b496f7d9bf5
+673d168b1117792c5246ad22ddad4c0a
+673e04a20ae1bbcbd78cba2604f1f7be
+6741bb1e273fcec12e68f885e27e06ce
+6745eeb71a3f6fe8b6e72f609373b085
+674ebbce748857abbf63ac872dfdd7e9
+674fab4a97ba9378bbf8cfa0bccdd671
+6750e5bb0b956a66acc418d6db008a41
+675242d6afce9b05aef088ad7223e01e
+6753222290891910d418786d4b16c5c8
+67535b9207e1c7766b433ed1f5d6cf91
+6755e02daef4f809b4294a467dcc672d
+675857eda73192a383a78498cc90eb69
+675b651eec66f13b07233fcaa7791cc8
+67622d98662b8d345f7ca28692347eb0
+676295c7a01aba2471b24367a090d2bc
+67635d3371acc553dd680b0eab2073a0
+6763befde2da8f68490395bb6dbdeff2
+676428476d154a5c905dd1aba4802161
+6766e7fa68bf27e8a9c81fc97572d1e9
+6767dca03fa4646e454c3a4297c4d9e8
+6769f7415d5c4e48ac985ffc84c004a1
+6770ee75a86fc2c79ebb17e50a5bfba7
+67762b9253400e636420a4e374cdc085
+677685c0eb658fdb48074b4e89bfad71
+6777d90ec99189d73be8b817a3ca7803
+677862527de3ee3a29cb3894534dacc8
+678875b4b8b7b95d9c72bba8c59a618e
+678c407b9d99c9fd9728a45a7d0005b4
+678d4c6c3eb5a96a6e4966852ebdee0e
+679b390e4e14fe8f487b074a0eb75abd
+679ca442fbd0591b564d8a7f011ab155
+67a4c834e4e95e0cea47ea22fec05411
+67a4ca56fba357552b1a6b9313962f60
+67abd1ea9889e6682c8a9c988d98668f
+67af80d4e70d5937ec8d5bdd16fd5dcd
+67b1a62ed76c0d17dca93945bf076448
+67b23e4164b79e09a0e2c447d388a93d
+67b5e28f9412a56ab54b1fff5ccb1152
+67bab17e574e41d28d1d6067c62d1433
+67be6cc7342657bedc6638fa7ced0a53
+67c061d3c354c25bb8a70231f69a759d
+67c1948d16477990be951efb035fda10
+67c30ec41f4679a777800b9cef483730
+67c4d1a0e9c35225306be1f023622a49
+67c75023a5a77931e77acae9cfdf6ba3
+67ced3a23e5d29840b9ab2b8619eb28e
+67cf8c10276033a74409efb370f7f2cf
+67d12342898acef37ba4cd93b0cdb916
+67dcc517493769425cd48c318d2a6254
+67e53e28d32b59db4e65841a6c1c8b5e
+67e78af6d77df71324c23a91ff8b8d63
+67f6087cff96a87878539b9ec59fd6b3
+68037d43360c8747a40c06b6f9d0e0f8
+680ba98799de1d607fd97c478f39702a
+680c4d5cda8f8bf3f17358da5cbf507d
+680d15d51e6bd11657e631ddd2c2b8b8
+680e6003d92fa1e3a7705b952fb13ee5
+68115de82d1d22e679eb0f8da2a49dc8
+6811e14f1eabe5dbfe4e3f1389ff6cd0
+68123af1d52e59984a710c426476de29
+681470a5fd6072b2a727bd2bb63e11dd
+6815850f90d972d2f8c4fbb5aab0462a
+68188aa6c41075ba57a179be9c185e32
+681954c88b7cb251c0211411dbca2433
+68221fda70d6b7aabbf7daa57bffad88
+6822aac5584c5b5d08f049c78ba48984
+6825fd67beba95fb0135e0dbda446db7
+6827c4a54cf3b935732608f6d8beed48
+6827c55cb45aca75fdbceea955bb4c05
+682ae9883275c2d210957b23225f288e
+682bee4522c2812638f3a3020327c8ff
+682cc9943564daaa499721eba56fb927
+68304d6d538534b19fe12c4d3797f16a
+6830eb4f0c6c62a6b49541fab61b5186
+68336c99960f5568d66b67c30e5977a2
+683760aa6da31fce27d08932ea495065
+683ad86039882a1c6cbab46c75eb23e3
+683c24b13d409c97d720770dc6804c0f
+683e42abaea3dbf877902ec5342be316
+68465db51faa6a5ba825a9e4374ea592
+6848c38185ebe64d3a3aa9cd8460954d
+684b77bbecf9f676ba9cabb9b713a84a
+68550206633b243596c5b268f26ede54
+6859dfb5fb3e8cd2041d45057cb5be3e
+685c89226dfa5da6fde3deb35f5da7cf
+685f39c68eb697cc32d6d2eacd4fccd8
+686a2bd968179d80f23a801317351bd4
+686f23f3d65ff35f1565e5b48328d08f
+6871e01df041d90482badba866d80719
+687318df41118869610915998f406b53
+68732620cd99e9c676fb61b2831c0714
+687d3ee55fffb00fab1a838907e43f96
+687e724fa5bf2b175f949d08f019dd08
+68820d37ebd80607113d45684fdcc486
+68864aa8bfb2188fa80ffe4e4c830893
+6886bfb0e1ebc4ad28b6d37fd546e633
+688ab0d391a92dea10b000416519d113
+688f96710800b3b505b6bd1c01ce41db
+68951c9b67598a73d694b8e3bd326c42
+6897816192adb30bdede2c30e6bcb91a
+68991ef8ea0923f129b482c37b0ca6da
+68aeced531a9cadb91ac7eeeef23986a
+68b1f564ad2a298c3510e036d334ddb9
+68b268fecf172bd3ebf20b7d711ad139
+68b8fb238e9f1649e96992ec8259ddca
+68c0445e38b9628ed04118a9f3e21303
+68c21a1eff9f299d176668096c7d2e89
+68c487dfd58bfbe4f380fc124bc45260
+68c5c59c0fd073e080080081f410c38e
+68cba8759e21db92facbfdc870e1fa42
+68cf757e04c3461a28b08d999056210f
+68d3bf12946cb08fd334c0312032f1ea
+68d4ac182666ba14318bfdfdf552ff1d
+68d4c9c5066af6c484caba5a3ae1b3f5
+68d60ad7ec6faa9cb314653408e5346c
+68d930294b08178f3d143fc17ff11394
+68defe203dafd0f67f5187a21e2233c5
+68df25a5c43783f49dc9172cde84aeb7
+68e6652e6c0a21e7632bb35657fecaa5
+68ead957ef0484b3c0ab5689625771e7
+68ee9359339c7bc8a311c77124799edc
+68f17cc3682a2b804b024f3a23f33ff8
+68f3b2a2d4bfa2eb156784fc5eeb1b55
+68fb55b385f62a5a3c27b7900662d4d8
+68fe427ea829f62f5a358cd92488daa5
+68fe4d1106e5d5d6a3ba33caad44f9ad
+6900b45aaa7a7df78be624ce551720d9
+6904b4d84dd1ddc289f1a60a07aba1d3
+6905fbf78a94098850aadf62f8da4398
+6908dd6ffa078529400c2714c64848e7
+690a2cff94fab90ed552fc27cda5c666
+690bcfd5b6d53511afa04a895a0166ca
+690d7c3d12c53e2d56fe7efb583587a9
+690f8ec01bfb7c8af689aa887378155e
+69147ee89844d876da980b9f7f081817
+691bc1e42ac28c31249ced51e2944136
+69286ef418965129a4858a28b52b25e4
+692ac69cad3fddaa91b20730dd055c1f
+692f54ab6969c06688848561cb79bb08
+6931cb0e9cc8b4bae90d47d12f2e4de4
+6935860c0290a88b6e0cf70860d008f1
+6938aa9c590059d106570e5cc3727735
+693a739d09aa7e9984e3ad496e3780ac
+693f158d557aa8ae0858f3053858e389
+6942fc929759931bf2b68351da45e5b5
+6948c7aecf5dc72cc9831672caafb6b5
+695056b81b578931910021c9c5955059
+6951805bd57588459905ced7e95dd08f
+6964f7fff1346e82facc15026de838d7
+69656e40287954c5ae46c5003647e288
+696c1a59db8138a585ac243730dbd6ee
+696fa2e1dbd1dc374d05dc303b3752fc
+69702bb28e88cece3216789d93043aa7
+69725e935a3e7c9ab3370862b33f6730
+697285f312b25d17f05ad8d30ea8f0bc
+69766959fafb8982d39b13c86700db49
+697d2f8a8b1922e000b640b2904f55d4
+697f097cf674811634fc4bb6c8457041
+698010a64d2b2661c0219701fe1ce0ef
+69873fdd95f4a1b8ae2685ad6a29a452
+698a24d85e8c5f5e9333bc66733a354d
+698ac6dc688f69b35d86d2c39cb49cd5
+698eca99112291fb1862d679c55f20b8
+698f2a13c20d442547e53c91234dec38
+69928dbbd60a2d60abb39690a10630b7
+6993e328808ecf97a504eb9d436fd995
+699b18914659ab9a64bba894924e70fb
+69a036c59fa2101b725fbd5cd65fe5a5
+69a128fc71256fc48f9168d9fe221b32
+69a6c422cdaf3bde60b11fc815152476
+69ad9db8a9f8c9a4d76524a1eb7af79e
+69b0452c395d47615225978a4d070cbf
+69bd3e0d4d5eeb7da26b99b75543302f
+69d04b33baaa2aee2ca0c8d04c254e8c
+69d06c604319a2687048ba28a2b0d278
+69d5cfddb5d3f746b8c31b4cee024782
+69dc2ea9ef60bef771756260283c253b
+69e5e61f392b138b8a60a0e01ff1111f
+69e95d6d4f14b098368ea7f635010783
+69f3c7eb415e82bf4679270d8c46ee6d
+69f613dc54f072ca5e96ed8555c3d74e
+69fbe8dc05378835e36e6da3e40ebef4
+69fdd5c56f8b49bc6398023b27e0bdbe
+69fe34952ea1abe70f1bb2efb3fb0f56
+69ff093de53d2c42ff6b723704e1934e
+6a004bf7221ec4dcb00f2d07ed0696a1
+6a01cd6902194eba8e1ce2264e00fd7a
+6a01e0a85f4d8d7e45f3a6ed24614e4e
+6a04c13cb8328d89893304012831022c
+6a0817a09796b2d4752eee6b6d1ab314
+6a0d47fe329905c5f35d2c6d27a9786d
+6a11110dc559e8a23bd5d5d2a486fec2
+6a134c24e4035acac5b4107aad732421
+6a1ad3b97e47312103b1ce20f5faa81e
+6a1c3056256eb2acd1055a87b4377370
+6a1c43cdc0a2af5f28240a743282d8fe
+6a28482a2110fb969a037a145f9addd2
+6a2ce2a6b507054ea368049c48172d33
+6a31e57059f3842dec60d7ea4a501f31
+6a3b46777a1a769a2c279f4ddb62f4a1
+6a3c5a60e510272e29d5b94cb4f35f8a
+6a3ec7fbb8aef2081c806813775ab399
+6a3faff798f73e6a618f7d78fe98ca6b
+6a3fec32cdc00dd48d7e493183ed2519
+6a4a9b5ba1867f7c9f9536e54a1fa22e
+6a4c63d9a7f5285c2c10ea3c1a63c2aa
+6a53bcb2b6079abb1b8412e195bc05a6
+6a5700d2ff0556ea908e60e44ea3c4a6
+6a5e0ab1eef1d623a15b0b235175d0a2
+6a616e4fbc57b64d8538611a0bf0a423
+6a624ccd9e0ae51727292052f2414861
+6a670c9ed095706958eba3a2f43291ce
+6a6fd9fd12392f7b9b20ffcc99bf7408
+6a71918f3a5fd75f7fc8a82deb9a15c7
+6a7c627c9eae25af1f2f8dd16252f5bb
+6a9001fb65f21b07d0360397b502929b
+6a9185b9e61fcee664fd58ed10fb7596
+6a91be077377eae1087e595cd2d5f0b4
+6a96f2c2c1b4e3122d66523af44e924a
+6a99638a4c7393f37002260fe3b7e81a
+6a9e86b37e57229afd3fd1fa6cc6e681
+6aa01be2b0246b53a64e83bf121730eb
+6aa1d7988ed1133c8a41369ceb1d9a22
+6aa8f591b861550931eee1d93790261e
+6aa9387158cc8567d4a792eb528aeba4
+6aa9506b49d02823f402f1e9e9a7fda7
+6aaa03b03d99227ac43f3bc9a2df472f
+6aaa9ad9267c3f7e5a5641f8e747a2b7
+6aabd57b48f9def28cc68f6e5a8dad5e
+6aac9356dad3d212289b463f7d9e7717
+6ab339d6971964fa44759636aaac6b97
+6ab3f0c6f0f9464061b9bab55efa325b
+6ab585343b116a6513debe6ffb8f8853
+6abe2a657c2043da4bcd4582268bb08f
+6abf1592618ee73bd78b34a3c29e1832
+6acbd0d5e3c9a399edce1c382fc9e329
+6ad7dcbcca1e5a9b5ac4476edcdc359b
+6adc0f24d020c5307fee7e0d2fb93954
+6adc7942dfbefa422356c00d11277e3f
+6ae0c7a85c648b90dc2eec269818d6fa
+6ae525df67765596679b3c04f294d797
+6ae5b77982b4708996b0433d53072fb0
+6ae6f4f0f166bfa2fa4360c6331ebd4e
+6ae8990a3783dd6e91007cb5ed232858
+6ae92f58541067a276380c23c76eb466
+6aecdf3f8b468f195592e07cef30631e
+6af006119a36aca9eeaf04abeec9ee7b
+6af406f684ff90ac88f7197960db5680
+6af5b105930dd8e238da8ace6690f077
+6af68094045ce396e402752b857b685b
+6af7facf91d029ab0a07408e420e142c
+6af8586727426aaa8f58bde386155dc1
+6af875167a459f14aec22d4bb6cd734c
+6af9b168fabe5dfefcf00f1f7d8d1547
+6afe51d6feafab74e3630042333a7a3c
+6aff5d17c71c958fa5047799faca018d
+6b00521285dfeb11d4392c7d9389987b
+6b02c9c4ecbdf3d3c8752fa690854b3b
+6b02feef4c83945a1d7f3d5f37d091ac
+6b038439ca169313085bb4d0aec781f9
+6b118016b4aeaf714f6f731ef39e3369
+6b14315add69df67574a85e12400de74
+6b1587ea065b5e7505214e830e3a00c9
+6b1620b3990203d01aecf82dcbf7024a
+6b18a2881d187fa58c1fb920f6480d5d
+6b22d627ba38c711133d7143081e7edd
+6b23106ba977040914bac9dc7a1a97c3
+6b2842e1b33250b65bfa28b7974539ba
+6b2a8957de5cdfe667ae14b022eeb944
+6b2bfe71ff803e815d5081f18310c14d
+6b2eb6a0bed750bf4f8874c8abafe12f
+6b2ed598dbaba0ebab411a8232fd3bdf
+6b33588375d2ec88864a33b48508c16e
+6b36217faf4250cff6df8b4596b65ead
+6b4650d2d1f361c3f76afa8c178c7b68
+6b4a50c0b809116c3a74ef18c2778b73
+6b4c11a7cebbe7a9000ac9a5979ffcc7
+6b5175bb3d322cc5795c221bea2376dc
+6b5551a66a6e0383d6d97b76ce41b541
+6b565bcd388ed4a2708093b8e2c549c3
+6b566fbdd43e02e337afe7f9baf3a909
+6b58bf4ce290a7554d65749eb4ed5336
+6b69dfddbb682a7ecb334bc7e8a10627
+6b6eb66fdbef789077b5db61e69e36eb
+6b710cf511ff60f25b73dcd712560a42
+6b7b95e05a7a2922bd7f22d40f52f23c
+6b7d3121899a03d377248372d60b5f14
+6b7f0dedb7c66a6382dc0b6f659e2d45
+6b839cf0130457a4dac7cc24e5039ff5
+6b83aa0cd4b31f90dd35bf34480d86bd
+6b88e542f3c1766a949ddee931d27b98
+6b8bb991367aa1cd2612fd2d2585ed92
+6b8d84441411270998276c8387b12a11
+6b8f0fe402c4999cf22daf7979bdfecf
+6b9111b9f49826fbd0873edaf96bca5e
+6b96b6107bae6a0d85b0831267e6d1c9
+6b9c3b0b55f757cdf3a70d35892b7794
+6b9e58a9c80a2261bb86d15178241c01
+6b9f32749b8c7645d1d86a9451dd0fda
+6ba5c657530a89d4730975ebfdf7f210
+6bab3b3458f8f4b8b722e8ff99c58dcf
+6bab66265075dc238d94860b4e2856be
+6bacafb91aaf70308040d26c551db87d
+6bb724a1b9902ab2880f949695d12960
+6bb78e2eb7376ad77719384cb4a57bfb
+6bbee55928265a95f9815df4032356d9
+6bc39c69b59a715fbff2bcf232de12a5
+6bc72ab7986b472bf24ddac073d65307
+6bc8fd58be131bd5c864ec9db93515ad
+6bc9206f1876db2d3f9afb5f850b3448
+6bcc546507c3dcf0e5c4df35a667a2ff
+6bcc9b2c3d4d41230e6457f170e02e37
+6bd12a8d09fac9dc538bfa7b715c16fb
+6bd82b4ebbc5ff9367177d38b9d81972
+6bded9e0a8a10bb4d9adcd3156e7de78
+6be04bbb4a2d74af862ce3388acfe46a
+6bed57435a8dd22f6138ef7698916457
+6bedabb65155e967422118a4392e199b
+6bf348fe9ae9dea0ba33447b5db6bf77
+6bf569aeb41c6d4dbf447630eee52365
+6bf5fb954245cb50a89aff4e92e05260
+6bf9e713fb27e24dbe124e0d8503458b
+6bfc027794c9f72f417e10e4713a5aa3
+6c0c00d17f1c1ed64dc7a6154ebc0753
+6c1142b431d305efcc6ea8da1308d164
+6c130ba270cb3d4c182f2986b9cf3ab1
+6c1e0a5c6969c08abb78d4d078ad445c
+6c247ea7a91efe16861b2a1453e8c4f4
+6c29e4042f33e4b08044caa12bc46227
+6c2ca7eec1e8ff465658007941dc7934
+6c2f19d0cf81ef6f3be35242c22d4150
+6c30b7fb38d14c60d9e8daac0c1a634e
+6c329cd42cbaf846302d357f7e9ee3a6
+6c35e56c2c66853aa779076425ad0621
+6c3bbc425ed964d050ba119b9d7ad610
+6c450b8fa8aec8552ca8f62bf1d43fe7
+6c46faaf620e1e5d283a6a24fa60b57e
+6c4bd0d7c65373ef125fbfaf0b82b7b3
+6c50d5933cfb83cf35bcabc95e705b59
+6c512bf20ca7641fc6a7a57d237423da
+6c562d0dc6d4248bfc846f87bd091431
+6c57e383e232f4a1f1719ece7f6529f8
+6c5a8a47b8b2e8e73958c2b4c08315d3
+6c5b354dc3c389ac586de8fcb94a2392
+6c648a98859c609df0f23f084088c7f4
+6c72b919ddac76d122d82f4adc61ab99
+6c74635e39e85c31d020a8ff2c501321
+6c778c08bb6e9a8191ad49fc15356ef7
+6c780b642ef67aadfa48e7e96dcf6f8b
+6c7abbe3bc3df8e1abe314c00c794604
+6c7b17954c905905c6d0affbd67d816e
+6c802883140ba8fad2bf94699fd0eae2
+6c84e10e5666a5e8c214d057146de9a4
+6c88a8fc3d4ef620d1075eabcfea627f
+6c8f752ac32515b8975b15c00e68b6ce
+6c9946aa3f2b24650f11dd3f82892f4e
+6c9e4e04c844505f9e5820833f4f4e24
+6ca00fd41ad9615351a47b9161a19dbe
+6ca464a6216630d5a6407e0e49ade257
+6ca93f483bf4315df9018ec3c32de5ff
+6cac4eb8f7869475eeaa8dfefea77ed7
+6cafe3983e3e1037069eba41268abc11
+6cb597f9ca168c1f5e4291b5b01410a4
+6cb747f4d2307aa2377f28cff4b3c68f
+6cb7d44fe9855f0aecd06e1c0f5f1f3a
+6cbc209a23896b517138943fd042c4a7
+6cc05ffc2b875424cda9ee3c48b83d71
+6cc4dc4233ff9305a95d50666084873e
+6cc83694280591837e342ebf5bf45377
+6cca843e133cd053b79229bd595d23fa
+6ccc8278dbdb9452430ffd780766d206
+6cd80634d97a8cb858e7d1f50de36e0f
+6cd9af9edf8b35680aae92272a0834b4
+6cdc299fbc1aaccad3edb54644177ef6
+6cdd89b1c944245d773ac91b91699068
+6cde49ab3d7fba7526b9c00c3bb172de
+6cdeb7b1c2a168a0972f102f721abf83
+6ce6aab593e2b0b7b8cc24f0eed75b1b
+6cf4f9383d193e09d37bf58e9c887ec5
+6cfe982d9fbe14c0ea70404e73e99374
+6d0491852b1348c99c8aeed7f737e88a
+6d0a13400f91bceffcb4ee0ce5d5b358
+6d152f9185aaa7267188145d02ea46d9
+6d167077ea49de07212e30651b6ea3d6
+6d168fe0b4b172203271b3e2cb82ea6c
+6d1c8c7df4e04ee1f5726775b81bd34d
+6d1dbb6712d7ef76a659d56d43d3711f
+6d1e016f565af8f69bb8a09bd563d84e
+6d22d052e545afa8b6aac07d626ea4f8
+6d261755821e376a860d8f7df02ef1b7
+6d2c5045fd20f1689cc912dda8680046
+6d2d6f4309c21b5a5ca1be8971b0ba98
+6d2e403c78034ba6444718626b063ed0
+6d307b61c62020dd5a9f57679fa074f8
+6d315b858c9b1b383103d18e656f4775
+6d35814974dbd37c8ac2df2079d34fec
+6d368a4e7bb6a96fa1704be2f0f7e74d
+6d37f4a2fa064b8fd0828856a06c8797
+6d3eb1d55fa3def926c79afc34e221e7
+6d3f9369dbcbbe6f833f09ec9df95831
+6d3fcba3bbfc06bb0caca79bdcd63c73
+6d434f160bd06a5adff0fb974bb91534
+6d440cf78846bbbd678f8654f383b137
+6d47bd32e6c42a59de10f887f4e154d7
+6d4fb46c50d81d28fe6ad005d3ed7af9
+6d5e78acc718252d273e4c5b717bde82
+6d5eec73b6541206f43a71196674c79c
+6d612f119504b16d83896a1911b5a538
+6d629ef4936a7f7239b7cf89f9415e72
+6d6613ce9108869127ef59a32f74ab80
+6d661a4cee4ff82a6cf95606b74288c8
+6d6654a1152d1bf09445a5abf17bf026
+6d669dd8d31ee153ba3e03ac5f0b4115
+6d6ab4cdd7e2858320840cd3234fbe43
+6d6b4099c9de2a4e02cad5d4fd2c795f
+6d6c2beb8d4a417caa44ea9bce10f9d2
+6d738938b3d69bb46af66d6971072004
+6d767c03520ff13b11b5d18eef837bd0
+6d7858d395da46cd32c425f4737a4615
+6d79c2c16c5562f8164be3aa4563bc71
+6d86a8492f95c3b491d4aba349601a64
+6d87237d40fb24e33bb059fa0e4ca984
+6d885a37c66a40487c1d0d9163a54e27
+6d8b1cf6206710541fe1b3bdeb5724e7
+6d8ed7e54963f4c8d0c73e648076ed69
+6d919199271a1b3283f4d19c0b1239d4
+6d92d48f4c3a62dfdf3b7f770d08da0a
+6d93c745a45ef2d05a8dadfa6b0d0a61
+6d955034e0a39e50e549b1ed16f87152
+6d977162409b60814c07f59a78eab717
+6d97c408c49b83ecb1619d4146cb8d56
+6d9a496417581ced03617d2bc2b22197
+6d9bce27a89e366cb504eaf2215514a9
+6d9edf21820ceebdefe2ac5c1afb5233
+6d9f1cc7c9822f773eb6968346bcb24c
+6da2c728b45c2e8650f8754cdc3499ab
+6da3866489cc43f6048408ad5fc45fae
+6da412357d5b6360e3104fcfda03a2c8
+6da8e3b8f74cb4180fb87811f8903c86
+6dac1f5b5d65b886bcd400f91f8caad2
+6daddbabb49772432c908cbc897f1078
+6db13cb0d2d2b07ecc1519519b4b56c9
+6db8fe2a31703c954afeb5c84d0e958a
+6dbcb3185eed907b36e1a89b090e49e3
+6dbda9432f7504b50fb2088ee034d968
+6dc37f14b78fcd2a0c6a51797482317f
+6dc70e0b7a629636bdb288332ef62117
+6dcb042af1f3becafaae52f4c7eab416
+6dcc7c538b4f6bed902082e02f83d282
+6dcff581d897f573f66ef72a25d80efc
+6dd0e6f00174e5c0cb64964d5e14da4c
+6dd70436550e94e9c287c42f87e34507
+6dda7dce8f347158f375e75710a04c24
+6dddd7221d781f752cc696168bcacac4
+6dde6109edb758e38b94fd87e786dd5e
+6de2235cc21ad5bfff811d7cc33bdfdb
+6deb5c904df3c8182c801a8b43470eb9
+6df6ab5d1082483040cad79cbce540d1
+6dfa337a70fa817ace4f1b4de1bd0d51
+6dfb78366fb41381d05cba9fa8b814aa
+6e017069363d2fb85a8f1d5459e7f612
+6e04bc04f598cc7147513148e4e5f5a2
+6e0acbfe8c30838e138b3563ebe9f36d
+6e112018c1d629b8b29ba40bbbbc12f1
+6e152a80dba19ab8e8eac0ffcd422054
+6e15ddaa0764200dc5a609fe115c5c2e
+6e188b06f5dea26cefb8b3536bd70541
+6e1935be1a50248a64d285bc7f7b96f5
+6e1f7953208ae370dfad1818458f0482
+6e1fc31b8c1d428da3fdea1ecaa81134
+6e2dfefcadf5183f280107ee3e180651
+6e32bfa906ead2c666d9574e603452af
+6e3b826641d16549056267586e95657f
+6e3b8f73145e6a36a50f28addbf5cd41
+6e3c8c3a8650fef386956190cab4648c
+6e3f1e1d9376ad011eef2477e9e0a3ca
+6e43a0f950cf67d1f17b339cd13234e1
+6e444d73ec1489bf3fac4a0d9fb41680
+6e459e7e011eb33d5b828d47241d9bce
+6e4e29e23d1e07dd3095f03ff5f624ee
+6e4ecb20b3e8429af2e45e0ed044369e
+6e4ff8a672dcb6e7a85c93880c802f83
+6e54cf7b22f7f730caadf8a53a236db1
+6e55d5826ca850f2a97570674dc12d97
+6e5bbd88c608789b7802dbd3073ef03e
+6e5eb13d4564bf66e3325356f307e7de
+6e65f4022c5cee3d5e420348979e77f7
+6e67538f4108989e0f53b6b08371a40e
+6e69f97a1a4127232fc4c9fde20eb0ee
+6e6aa60e8912ec05d69013e9ee4f4ea5
+6e6e60018417ff14809bf5a6a78a50fa
+6e6eedb54c4330103ca60845c3014fc0
+6e7292cefda5953128390c28d9c208cc
+6e73a963a7e609fe0fde50aac48687ce
+6e749a4466dbe912ec56b4b854fb553e
+6e75b52b74a192f7a188d6bf07e882f9
+6e7e573c74884bd5550e1bde013a1d25
+6e80b985b3f6cda4c0aa0ea210b803b5
+6e8494853e1905e124b18a6f9b0bf9fe
+6e8e290c2b39b1b38cf0f185c6b42e84
+6e90561884e603577f5f4211ae10d06d
+6e90e334d900d53f29fef6b92bcb259a
+6e9add5c20e92429f89c9b57e42d166b
+6e9da68ce4f84d91201963d86993627b
+6ea151f9a8df0d85be5cd7bfe4e25c06
+6ea43e5f895c5e100bb95b06fa394ec7
+6ea440957a656b9fc55a5aff56cd990c
+6ea8438a823fde80de9373315ca22162
+6eafcd7214bf791967695f62192b5627
+6eb45226caf1b5a299f02afbe069e5a6
+6ebef3aede68bd9a94fd474e9aa040b7
+6ec173af5aeec1eb93efc7b93a6cbe1c
+6ec5512689d76ad807bad4cdd38fa81e
+6ec625a47c1dbd17532b802bfbc5995b
+6ed18b4a3b4aa81c0d3cce77880e7eaf
+6ed743bb8135e90cc3b7157a4bdb17f8
+6ed904a7c60d842f061bb76be0a4c456
+6ed96d4bf928fad2b6811ad330879d2a
+6edb2c310e7f6d6bf6b6f57e77b9ad9f
+6ee75b548682b182bbc2ab228b1c014c
+6eec03906aae0ae3ea0b05a981255ee0
+6eedf6293039c8ae5b99f8b439ec5505
+6eee166520141c7450e37ce57ab195c8
+6eee52c3a9bcc4d54289ed2748217e51
+6eef7eea5fda71323bf52c4412cd9057
+6ef3bde666d6be0be7638ebb7cbff32b
+6ef4f6c00588421adcc1cc19c729cda0
+6f0401f3869bb53614a463d9202469e9
+6f065f30eb83550bf82220159df49182
+6f06a25f3fa8a1317c55e99f261bc066
+6f06ef9b48be8f296ece2c52f888db7a
+6f071efe4f46a82c2906ce072c353b44
+6f092c305b789be568f99247ce7f3abb
+6f0e899137ba559c704b63ca531eb135
+6f0f6d2cf70b877c22496e40c28c64b4
+6f21c085649b355098e2991b77dc67e4
+6f2e25d6e5ab5b38d8a021d53d8915ef
+6f2ec87be1ad2e852203a487bdb826f5
+6f4399b6db0255f742584b4558cd0376
+6f4425a3d6ef85a7115b6ad306b54974
+6f44397602357803081113dc23e2aa9f
+6f4651b15377f0ee5fef353294885192
+6f4cb867fd2cc360cb99952d4fb9ae62
+6f4ee309a8a9282bd90d450bce333830
+6f5122a5a62bc65a118e41ce61c180f9
+6f5563e6812df346685fdc1a89531e94
+6f57d5eac5473a1d1d2dcbdd183902a2
+6f603b51e015a20bf00a1e1f08d2bae3
+6f63211e3a26b73d2359d27f46ff58ca
+6f6cb491bccc7343dc60ff8513669d31
+6f756ebd34fe55cd37b13e9b6284c8a3
+6f78cb5dcd627f774c2e12416722bcfb
+6f81d178c3a2d2f87c3fb422927eaae3
+6f842c1c2ef7ceed2e6e16153953668f
+6f85f3a21a714084e72086781c6ac9af
+6f870212a109d84d3f147ede87d605c8
+6f8cce7239362d713fdf8dd058a712cb
+6f8d2eafce61d71b48b3c089ff427f68
+6f94b258c2fb21ca0264ddb22950b851
+6f966f906e8a6468e3b92ecd9293899c
+6f99e60f921c65d210c5a2e1624f115b
+6f9ca348533c0d41018464bd931012e2
+6f9d0a26895959564b0dd1af367d99b8
+6f9dcbcbf17073b32ae49b72be6d17c1
+6fa088b9a43c3dc6a92f2d9420804fa9
+6fa230407961f58ef1ebd2db0b12d8a4
+6fa29360930fc5141e8a3108114194b9
+6fa59bf9b2efb9348021f7d3ca8079a3
+6fa8ba9c0ff1d474bf71ef56431c775a
+6fb22a4c0a694c56453796cdfb1ddaf6
+6fb3d250e36030bc0fbfb21e9f6ea7fe
+6fb4c17a8aa687b22518fac921d4739a
+6fb860a65a8d47ce0d0e3f9f8c0a2b84
+6fc80f4eef6574e0234dabf6e24a3df8
+6fc92a6bea027576445ef81938e8dec4
+6fcb46d78059390d0ebf2ac8d5f8020c
+6fd0bd65726a4ce6eddbb6bcd6ee72e9
+6fdb74b4c058c2e22c1ed00f4bc63719
+6ff465194b7325025cc57ba339367f0e
+6ff65014ec474d7fcb88d8a95b73579f
+6ffa4bc9e779feed145f71b857e647b4
+6fff70d00ded4353883a3ac908ccf1f8
+6fff774cbc0b3619b6c00fc019ae52ec
+700104cd34cac9ff93aed895691fe2d9
+700a09d3ec6468b6b00153d2b078829e
+700f0050b3ba8bc916f20221bd6642db
+70101a433f152122a6322395da9c40d2
+70134adb3fcbf1638886bbb9d8435e36
+7017f130e76951bc939aa63d4a4bf0fe
+7018cd92fe2494f35e94cec0cc272a86
+701b474ef1dfc6e5b60fd416f19a1b42
+701ef72e0160ca9a4efe923447e5c69a
+7027fb97a1a17c9e996b8884f0b2a93d
+702884f588846cea9e4e44f350ead097
+702b74f6c72031f985c046cb92966869
+7031b15143f93d0f82e83b20ae0b8d70
+7033899b62be00587c5032aba905f1f5
+703a4123dacd9178153479c4adc99bae
+703d92b7508e3bc61b58bfffdb226a89
+703dee7855fd99d4bbf48c928b0e0ed7
+7045396789edb33a54b64de2c7b2a520
+704614cafa5bb263657e2150b0733f5d
+70497cb1aaf0d0913ae972e0d591e178
+705941aec673e91431d272f6608a84e4
+706761f1b4de9859a9a04767a33fa14f
+706c597ee2103585d6326b79fbc4d3bc
+706d66e8bc0d850b8df04efe5c9eb707
+7072ad2830b796baf734acd1db243f6f
+7075d15e64218993fa763c24148a5474
+70783d44ba7f85c37a0aa6c3f720dccb
+707a107311012ad210f099515a24dbc3
+707c86bf03a5f916c2fe9f0effd658f5
+707d4a2cda3ad1f1f2427dde457644a7
+707dfdce14c970d578ade8e2cdca2216
+708211472d4555f7284efca3c027ccb4
+7084a82f0b0ac0a31aa3d568f858e2fa
+70870454dd9134026e2de497f447a91a
+708d97e840f30190e2aed2c3ebd2cfdc
+7090e60276b744c64306c460c7dc53b5
+7099a174f4724670025ea3337a3e2b16
+709bf18787b6f19cab6135d3e83997a4
+709daf1e0ae96bf32a89e13a4382ea6b
+709dbb611ae20561a24dc22d7cd2ea70
+709fba765d524b7335f085fc92156cdd
+70a1fb59a0abdc6c950e60014036d42e
+70a4333014bc14e74ca36830e4d2d765
+70a65f091aad0edce23f887a0dd377a8
+70acb7f045cb0e67265e14ce399e4bb4
+70ad12ce765bcffa07ff30222e30b3dd
+70af9d0a4e8f9afdc4e85f561cb2fb8b
+70b1976f379e70ac287ef33f4183b184
+70b3c3d69433a9c3a2aa8d2b7f1701dc
+70b6ec7c726c17c15f83c4869befecbb
+70b965b9e0cebf519e3c1b665543860d
+70c62a999d32b5e132e9eace511d9a76
+70c77f897378a1c0d6dca67cadcb6b45
+70c79aed0c1c1f079d1418d58e472713
+70cd3c7784ed6c63084740451b3354f0
+70cda0ec549992322848971095f99a52
+70cdfdce881159f4bc101602fde9b547
+70d7488bc68328e8796f2aa0cd3afa1e
+70d86b98a08dc492123f75237729e568
+70dab77265f0c683fee45ee22bcff9a5
+70de180a45f8a93c47ab4ae59b15cb3a
+70df189c6d2d1d56a2e510b940e341a0
+70dff34eb2cacda75b2433731c93d47f
+70e1c291b400d0458cf5794374b261b8
+70e7de2331a28b10f294a60caa4c3448
+70e9f7964791be94566a9c3873140909
+70eabd87a9324f25862866fe063d0a58
+70f0213947aaaff89cdf8baf32b6bd40
+70f8c381b84ec5c22c5eb18ef2e7562d
+70fada3eb4a9ce17e4e16fe77cbea696
+70fb5bd77b55f223cd4ae7ac95b06b44
+70fde0b461fd979e928d17e413e46e1b
+71011fde4873d26f8828e6d4681f38e5
+7105cda114f00ca57742b006c28ed2c0
+71080e5f0a951dd28a2fa3f48eb7429c
+71091a4bfe23b654e868c140eabcfd9a
+710fe70a66f5c8b993f1906dac3e5aab
+711ba8136fd9cd7d2e1c47d49475db49
+711d4cc2d6f51b1c02cd22df9bdbde17
+711d6b567730f09a576c2ff9901f82f8
+71253352244cd5442ec9bb74bddfca24
+712f8bb544fd6478a6d2b8bbefad14c2
+7133fb60d4ea3f71cc9a9e13caf4bccb
+713961ed7b62099ee54e5d8fd3639bf6
+71425886d5fe44e61c7a3a078b796bab
+714896c3fd4610aa99f49d8909fa7dcb
+7151aa2035d8dffe075f41f144d0db00
+71531e5b26e95a152dfbfb8acfe5aa24
+71587fb4377b11fae5bf26043b65c178
+715f0b0c40b783538e9dc79ff8062cff
+716a8d2addac40455e1fee9110a15a36
+716d60bcd312df8c0e9819b9876154a1
+716ff5d0608d5e6f65a72f26515c18d7
+7177325a8f63b23e86b2f0226f3eb8ab
+7179179034cfd1988e314d5a18e45b8e
+717a19b8a75eb4d5a0ef50fbe0055d3f
+717cd0f4480db332f70a9a2d150f2382
+718d4b398d3f787cec72d2287b77c805
+7193b4c990cd0a595faec7180a77d49f
+719d4ddd91774551d4041d0a348b9551
+719df82bbaa486042444c3da55215c56
+719e9624e234e991b0f4ca6def98e5e5
+71aaf3d79f18467200768b036a5d6bb5
+71ab2b9c0cf76f65eba699af50456e3b
+71adc40ab17e42461f21ffc544485bb1
+71ade3c1ea4a0604ef336e1180e83f72
+71b9623f374d47250ad4ea41b70d82ae
+71bbcc4abcc6ae1d93a7a833bebc471c
+71c9eec3ed19a02514f42e160b09e5c5
+71d3c503bea1c983fd385e0f66288632
+71d4b403336be34c06a7dcbf0ad4c580
+71d58617236c9cead9905416227ce12b
+71d892aeaad97670bd09961035b0b97e
+71df931fc9b74f86c5da8f6be022ef1a
+71e436fe5bfe338b68bc3ad35107d73f
+71e5636bd122d8835258e7c0857deab1
+71e8c2a9a897f4684e5a5a30f44be029
+71e9810c8b14412404958ed5babbaf8d
+71e9ba7cbeadf07bf553dc70c04a8a51
+71f08e2f92fd2817c7e73b255a5d8b32
+71f37d66cbb17372adedfb172ff8f7da
+71f4978cc2e697678c4d8465b65842e7
+720a2e634987bcf3a0fff3ae5ddc7e9e
+720a47281c1bf4c490ff1f1ff0cf75a8
+720bcd05d6528836d40940740add618b
+720c0139e74dc2de830a2dc0535adfd5
+720e0d545038ea2829901b4d44505b74
+721c3d75bc6e7eda26203d8698a5e6ed
+721cd49d150b2510cdfa896b870bb39b
+721f7f57c3ba681df8b9bbf92a77e4e9
+72238ccd26fa8c3e8673f87ed9a52527
+7234e0826737360e571b032dbcfdee30
+723c9815e63441d80bcc9a41753d379f
+723e1b8d54931ca4dafcf440a1250d92
+723fdbe07081e9f27207108622c7906a
+7247d62f558f9ddb3f4dd65849d583d6
+724e625a7c2ec23928355d600f65e567
+72549e78cc3272047ec138a497f295b5
+72550b8c08f9841c683d50722f7de465
+725ebb1e0073aacc8351ff8759cce795
+726663fe880d0c649db0e57e6142d3c0
+7267d918a8fbfc981f4dc359ee9143d8
+72687ee1eaef2cf32f965b297eecd226
+726d3be11975be12af84e29ee168fc69
+7273b6a93c656916fbf2c81c15316084
+72753393f7bc51584a59857c05a22771
+727988817c973c69480535dc896e6599
+727a22289c6c0dbc42947dc8bdae5046
+728eaafa6eda22eb3360889855c4c136
+728ee387f5fa4337b3870d5e59c514ae
+72917eaff4f85bce53e62199d0155bbc
+7291db7d186189d1ef6fedd9fdc38d9a
+7291e550cf2a6d8a4e63554507b25ef2
+729aeff05953e73a0aa8e55f43b1b714
+729f0cf1b2b7a57330993a3b0e6f7d95
+72a7f5c6b9ff389e88c7bdae906ad969
+72acffff520a019e47f64df0fbb44de5
+72ba0619f2bc73258b1c2d99423f1630
+72bc732a19dd7a6077b124d88d0e24fa
+72bcc9e8b74f401570deb71f438a9867
+72c7565d910534bb3357206a9282eefb
+72d731ed6fb3747db31bdf0291ffc307
+72e14f9dd3fcaf2f11e00c91e755b55b
+72e3188db1f00747889f249daa890495
+72e5027c97c04838dfd4b590e2ec0eac
+72e5360a8ec09995ca3c852e28d20eb6
+72ebf0f6c9b3d20bbac909d6a51e5cca
+72fc9cfd4ad6445aee55c0cbd61380cc
+72ffd3c559582fc06763c6164aaddcb3
+730a3abbeefb2422ad12e2370280d79b
+730bd7a8d996e33e6182d4ef655e46f4
+7312950e52097750e7b672af8fb29823
+73166173b2a6eb77597e311e02ff7e2a
+731f50f4b8e7adcf70bdebdc6be79dc0
+732cce3aa1cde7a210a8db3a35657ed6
+73382b58a1cef711286464c280c3dd3c
+7342e00ce8e78658bf0675bea21e717e
+734a9ce4726176d9a3d228792af2a144
+734dde6fd79bd8a577962e4f620d1e48
+73539c08377068322e1ddb8dcae92f59
+735edf9a87c1c16d4ffe820c61886f37
+73603bab56b0188946e193934bc48e3b
+736188a49cc96c1967af1598a6c694fa
+7361e372ca679264d0d7c637b678f551
+73621e462ddb3deb864a17f8f192185d
+73745a54d4a424feb797fab8de627851
+7383e0e501b513991ce21d82e37c008c
+73850859bfd341e80c5182a26b1ee6be
+7385421fbf5cb41ecbd8cd5e87a80e19
+7386dcfe66f95b17e33e091f8265998d
+7388608d57046211cf195292ed886716
+738b34cfffaaec1fbf09ca82e9f56eb1
+738c5bf18fe78f85bf1ff57d26dcb81d
+738dfbf4885cadc6715b59568a70dcb6
+73923e67457ed90a3c87529b606c1e1e
+739712434749a89ccf38f2d4feecfc6d
+739a0f912f3db4e7b9cca41a6c5298f5
+739b5a34d5848250c2642fd2a070c817
+739fe886398d3993d9362a07fdaad8f5
+73a0a6b5d8f24467a34ef321e8cfba7f
+73a631da7eda99fb1f5fb9aadd700bb2
+73ac5b9f81ad6ea075429b33fb3a8c11
+73ae54bd8a8a735f97907e8ad1e20abf
+73b4568b316fc30424f09d31e145199b
+73b633b067dd8af0b7cbbfefac274d4b
+73c11316cbc71f67980a577b288451ce
+73c854693644cd41694b5d55f8e5e052
+73cd3a1131a26315d5185ced1fd1567e
+73cdef0968d451a70fc7358c2aa7bf40
+73d2685938ed445fbfee036d73f35c35
+73d76b1354a940341aeb0d36bdb107a7
+73dc5f64d89b534ebdbb00b54212144d
+73dd8f76e0fe8196e258fdaf0aa37ab2
+73df0da3461d00492b51687c0d382b8a
+73e54edf0c9de4fcdb396393e793af8c
+73e74501142e471610fd11d626945683
+73e8de6af8c58de2499f69d8a52879eb
+73ee76325e7e66dbc823d4320684d0e7
+73f6c0e2c3eae7d75d8f838f6428b938
+73fc418ebac9d06d37998d3ca11bd9ff
+73fc523908a5f110b34ca01a29c45cfe
+73ffe2144e5025b16ff89f1ac6e3d8fd
+74025f5321d3f2b8860ada325a2bb6b7
+7410734c59b85af83d0261ea6f97d11c
+7411b8c5c4e77467eca34627196495b4
+7415b71dabd10766174f8848032804fa
+7417c3943b3836aec1ba0d06c4af2d53
+74205614b5645047b0df2d48d3b6e463
+74219b088ec2890a32eefd5175b1ae0a
+742afbec7a00203f8683e5b15d6dfb25
+742b4e6179edab9735f96a7ef3f58358
+742d3ba3050255ff05b60c905b83bcfd
+743f80356df5abb9e73f386609d67fdb
+7441fed93afaec98d1a9c494d4904ec6
+74434e11445fed550864b86b1f25dac6
+74460f924a476dc8c371d10b0ef30e89
+744a03ebc53d45a54485e54ed3ede695
+744a927c5f628c3f4bd0e4c8f0a00f1c
+744ba0c389c58dc64a3f83ef913b32d4
+7451b0324ae648f9cf76d0bad16ac2a9
+7452ad5e492daf35280ac2f4008de755
+7459e9572301cad87e35ebceea164d46
+745c51669ae05fa2e285e1f81d992523
+74627957863e5f1755b4b288f7923786
+7467ada3459d126e92f9e2d57e1075e5
+746f3572965fac5dc67507565a63e1f7
+746f58a34a5c43bb28b5673dbc5f9419
+74703c91ce77bc2531e4793268157d92
+7471bbda83b7a0b53efc392765b19b39
+7477dd1f4b47cffd13052c320576a5e0
+74782ecbb7dfacc4dd88533a6be54c56
+747baff0e4d6145cfc40696b2e5646bf
+747f4b9c5fd7d13f1b2611732745a589
+74850be58d8daafda6ee8fdf3d864734
+748735160895517fa79a565f4395ff21
+748d8de4a8048782dcf9f2cc8f7eb817
+7496569e48dc3e578c1c9e165d6a129e
+749bb3b1088d4f5b40865b3e7e5188a6
+74a1f583ed3eae0053cc0f9a056f24c8
+74a2a464ec4e50c2d24f79ce5486753b
+74a2e6c29f5c426b2852bf4f5ab5876c
+74a3257bf080920e94614f2bddf6dc9e
+74a51e2c08838bf786ff0a4a1b631a5f
+74a6149cfe776c091b7e6480f687b550
+74b216776a185b60b889c138bfcdd8ce
+74b5b1cfcdef5ad6f9bb7f2552456711
+74b677479b37e69e511ce9fa5f892f83
+74c087ac78640c919782870ae10c4184
+74cd904c8b8c0546af153bb38ab7a202
+74d085fac55dfec3c672e7c75fcdec96
+74d1fa0e17c04403e12fabc2cb81a110
+74d208edec901939d09101893c6998fc
+74d581b823fd7e50898b56b4c72ab6c3
+74d5f64471119715be7f4e8615c3c539
+74d6d7ddb327b2a408b81ea439850cf9
+74dc835bd5ab91ad948280e85a4c3a38
+74deede98ca8606028e83a4242074170
+74e118f76612c372d01b6e2c3dcec774
+74e41883e1504136a4ba0f2e4158b60f
+74efcb4a0d188cf1d16d9b68d5c4a1d4
+74f02efaae8165e225653248a6372120
+74f18374515f699559876f76aaf0f0d4
+74f7f489c15494eddf736e8b360c1d76
+7500a349828fa323e5341dde55f93502
+750188bb2b5acb75aec33dcd44da2e03
+7501f7bee27212c6cdc20eacdae53612
+7503ac5557dc643516810bfb87232741
+7509fff59eb32f2ff770cc95ff605052
+750a70e327e769a9dc31686a9073cb6b
+750f729c8e2a6a6473ae91237f29af25
+751164187f6f0d850f4e5af4168fdb5d
+7514345ff4f7746f7fef1c158c58a888
+75151762895f5afbb598f406d5de78ea
+751685187432e011a09f02935aa2dcdb
+751f1dec5d5d1b4dec62c972b9b37960
+751f31d4152c3472d275cc5acaa24bbc
+75223b15ec0bbde4410ecad4e756f196
+7525d4deb95ad651fc5231e338ff8a59
+752ec87ab4834fe2d143d254e1a8cbb1
+7530d73a182730e5ab7ea73fccbf9f26
+75328cd04be0b83f68c1609d134206a8
+75392f32d496cc16903b15950212b912
+7539dd3fd7f256fd9d902fd12d29913c
+75427a8de2c3207430ccb38a9aa732a3
+754314fc5fb0e5226b86188383184d2e
+7553a7fa946c52504ff53dcb85de8d62
+755404bef5ae044ffd724b84d6a35ef9
+75552b80ab6ca4b8427270114b721d66
+75595cc283bcc77f7f6a4b9b4bac191c
+755b9ff3a8b5b791e83541482a825c9c
+755c69222245b9b6f158f514a93a34f7
+7560100107cd39300a037634781e6230
+75610fa24304cd15d1f11dfe7d2dc2d3
+756141351c01ca7c52c800073f7c691a
+75657eae2727d6cf4dc34497389d74d4
+756ad34f64ca92ae1186bc2dd37f1634
+756aead7f75f041c2efb75a52aa6907e
+756cd6ff439c490a164db526800cf6ec
+756f1eabe53576d749b5203f60369c9d
+75735d793341ee9ac6cb0619f0fd8083
+7575433f7f06e586dccefbcefde64b94
+7576275bd45b56feed62e708b71d38f2
+7577696a33a283979a5d4d5b79f30393
+757a65d5efaaa42468f02df51fdfc9a6
+757ae7ca6517416abd02b50c0bd12383
+75862842c95b9f534bb90b45d71ed95a
+75965f3c30417806d1def37cfb0cb3f4
+759e78513fefb6a335b942fa63ff25eb
+75a7eb541a3cb23e38663cae0e5f5916
+75aac3311bd5fdc8666024407f3403d7
+75ac19cf952334ea660defcae70b28f5
+75b42d7a2e160cb2c92b1054eb8f3986
+75b519fc70615de7a1e3a634af6bd6bb
+75b62fdfee732cca7de5d308eeafacd4
+75b6e3c51ea9f7b87096a380d16f65e3
+75b7f9dde35ab9c5328980525e6eb354
+75b9430e87638fe94802cfc968b50278
+75bb54960ba8ad5e6ee95f23e7d3bb9b
+75c06283aeb4b0894bea403cb66772c5
+75c82f3a9f2c3cda3bb20fc059752d57
+75ca77c3ea1207b79b8d678fc73bb1c7
+75cb7d1b8c9a2742595c4b96edcbbe0d
+75cb8a2378fda15577cc41d2ccf03660
+75cd4f2c648c08ee65fbe9fbba414694
+75ce461672f7ffc5c366b545712c4eab
+75ce772c3619d44df32f1862f9e1b2cd
+75d5f129a46378a474958e14e07c4dfb
+75d7ec5211a938f0a072f6ce0b4684b6
+75d847c133501f39e4a4b6599b590e30
+75e1faff31da4b1d1d07341548f784d6
+75e5746071a09c9c2156fdfb5626b6ec
+75ea88592f7586bbbc2778164e6c6d98
+75eae2100b15db737369ed4168cecdfd
+75ec5bcc7162dcbc9b6f9dc04dbe494a
+75ef31d6d1e7e57f05969dd1a5dc07b3
+75f26909afc1c485a59a6b7464ffad0e
+75f4c55f0aa2297ab2ae95d6050acc47
+75f5d8f6e18651a54575d7acc19ba59c
+75f6e7e0f401d311e9b21cdd86a1560d
+75f84f68e5f5daf2c952c84412a4596d
+75f8fd9ee97eee2c358f2a3c9ed6cf39
+75fa872f3e9531ef2d0b8d765974b89d
+7601153a4b73cdd4aee9991a32644967
+7607394e421df6e48bebfb127c072ac6
+7607bc98b05f11ed9d8a7f7b46c828dd
+76080fd492ab84d5d1d6ce0ee076411f
+7608cb5a72f95d9cc5f3cee825988ed8
+760e8b6af37e2a93c62ace3d144797ec
+76198249db02529642f053524b4e6470
+761a27089e07282c78943359968eeabe
+761d18b7e1e16db1aefb118966b28951
+761fac49aa7858693deeac7b58cb7578
+762b055b60a9af079841ea320c28a4b7
+762c800b0beedc00ad25bb08ae2d727d
+7632f441f07e4ff0ba342138423fdec3
+76365401ec0a14cfe5d430167e60f793
+763696ee1beaa32cd87d51434cbedb14
+76451c5e0156643431767fe64113f16b
+764b91ad44767e67b5582c6cebcdd84d
+764bbee44c40b4b377c245e40846ec1b
+765368d75d8e89a971e52949193507af
+7659e478620fa04a6d8a55559d2899c0
+7659f5dd277732db2226727790c1de92
+765dbce76e64f5e24eea46fc89a9e380
+765f2d1848f5f9d3c8ed63f4618ca0a6
+76607325dbc512bae1ec9ff6e926b517
+76638822d2c4b1d5860e1081467ef8dc
+766505e7b08068bc5f62317b74c8bd41
+7666c7c68e986e2ecaa651b215337530
+766b2e79a4adf32cc3c5d6fda95ce9c3
+7671a3ab2381a854543f8225ecfb3773
+7672e8d96e407cc7064185d7c66fc0a6
+7676751b74ad398b2b8c4ac5d10fc9ad
+76815e64e14401342b1e852d09a4cb1b
+768328413075628d8b02697e91f2c294
+7685b53ff4cbd20d3933f055c6db2421
+76867e1cfd205c4aa7e3a33ddfc9aabe
+7686f61dcd48553bdc5299e229ffc273
+768899e1c070ba8564cc45d595acf897
+768abe1f43fe2c55f67f1142d2e36783
+768dc8863736bb679c9a35700fe3014b
+7695790b05e4250102672cf12803c31f
+769793cf60614ed827114eae8486978b
+769907303ba1e0fe4c635df229b7268a
+76a0a218486a26d486aca6e5e450b081
+76a2cf20ae22842cac67c2b84f692380
+76aaea8d7257ee97823d35e0d0ade2d0
+76ad9bef19347cec3ef2dc3e110e5143
+76b4cf96cf96ede42de839f3791488b2
+76b89820dc7952e7f29e56ac01f48eed
+76bad596317167e08fc2e1048dea78f5
+76be668f145191fdfa9e06916a5a1340
+76c1b9a08eb7545c7c5bb20629405872
+76c279f72b97be96109acea635db0a27
+76c77734877a35e8a186f93bfd8fb588
+76ca5fc8aa44ed7290e8b3a6f498615b
+76cdacaae25015bbe5abc9cbd43a088c
+76ce2909146e98dda90a78bc299e70b1
+76ce99f35e6b96149facb47f02d07230
+76d3203cc086e312a2b0af637832b4ab
+76e2da5790b186836eb26cc8ce76ce44
+76e92715bc6377df686d4160cd7e0e45
+76ea08f5afc8a51e5a9ac665fb94e912
+76ee85a4a08602abebeea642b9f8d08f
+76f1a068de3cbd433dae7146775b6986
+76f1c5f700dd6f573b5757481381e50f
+76f509576ff1f823ad0262b6234c8d86
+76f5a4673b7d0198a5b7964112fb4ad5
+76fdbda2bfb22b239079a8b346a9746a
+76ff567188b793f04622bd10346765c3
+77090bd1f6939aeff93b51f948445d63
+770b7a9e7eb98ae9c543b142cfd8c689
+770f76b682f2e28e36324c643fac7037
+7710054c0952c134de1c5cfc466f8040
+7712a75943c6cd478273cba5b1af6c9e
+7715422594b72166ec93a5220053c941
+7719ba479ae6ee85588e649cf11b4738
+771ef84bcbbefb37d2675e2b2551a827
+77230595b9d4b322d0c4ad42ada9cbe9
+7728bd7f4f530b9ee80049302e983dbd
+7728f5d0cfe258d130c460a5f637a021
+7729720472d5d2bd0928fbac485f3787
+772977d188e0f158d4532028d9d2ec08
+772cc1843ac897dfd5900c4861c13515
+772f34a6c476709667030675dad36612
+772f66885643a7c740fbad203f8472fd
+773250f1bfc439fddb9ee4a8f00cc44a
+77346d7992de3a34ba4f0f6b78bef2e2
+773a8196a84a459f7238d8e0fe91f6ea
+773c1924ba24ca13864d0387bf4bc81a
+773f433d7ce0dcde71061392d0f7eac5
+774d9c42c7593d2775cbc4c77036a712
+774f2ded0e126546c215258d2d49c2dc
+7753fe5b0a70dbd0b36e95e90faebcfe
+77577297a448b6c0f451b258fb2642f3
+775841e8fcacbecee5ea87141d64daeb
+776239277baa147728b48174c301bd19
+7762eb1aac8775def76b5e14c3eaebcc
+77642c224df5fc38ce02c37af4fe413c
+7765c8af5bf85464d549262086b135cd
+7768a32007279e2387090c589197c0be
+776d36fdfa6f43d3b00d79d319d4f3b6
+7770fe7ef3cc7f2661943e1c1bcf30dc
+7772104b6a48d0a964eab08c35b1e4a4
+7772db192e29a0f36e81a7ee1f866fa4
+7777ff7c9ece94b24c685daf078827fb
+777a362eea1fdfb519f75526bdf30286
+7782e41382ad913d475485f23556b6df
+77892af404fef357f6d8878e347d4727
+778a4206c65c60b96c7bf4558f41e3bc
+7791b73de84dd70b0d820a27c1ace434
+7793c6dd52b1cd8a5a6c2caa2bcc242a
+779732893f44dccc0b0b690a16b4b89b
+779ee912ca8d4c148174ee9c990d58e9
+77a36ff89f19e5c117e17e8952d536a5
+77a575ba2c666c3e3382d701d4a8b033
+77a9e1612cd750b41fa61757d4d68877
+77b4659485c8c0bf671b14ad659909e7
+77bc4b354310e95366576cc317775f79
+77bd0cfa9deecfb90dcbbb3b9b76434a
+77c52f354b2202a8f94c5b2a03788801
+77d03d27b69f931b23a49d2f4ac51aec
+77d22316bf50a026848dfc7d7d9c9bbb
+77dda55b96f8ededd8363bba6dd75378
+77df6e8280eb6ae7212cbe3ddab11087
+77e822b8495472ccc3d78a6aa96db11a
+77e9bfc85482f66956f87c5009ab1c0b
+77ec2a2613a13b96aad36469eada6642
+77ecf85647962b102490822ee8d4e069
+77f29fa42e74b78abffb0585ced007fb
+77f85ef553a64b9eefb399de742de714
+77fb4e91f977a000b417cc5a44f99680
+77fee2fd1a000fa4186186bf989e026e
+7805986fab6c7f4137febd105079e668
+7808662175d47e184382a36a20269865
+780d1eb461415bbf30520179f459a2e4
+780e625e9dbdc2dc0cdd92a93670cc67
+7810ca4e37ef6b311117343ddde8c163
+7810d9ca371ef3dab39e36a825cb087b
+78113b832e0b372a15c9cda136011556
+78113f4e4b795c037102f1522249fb9b
+7813454108d5aa6af2a0a3683cee9058
+78137ddcac84db12d14a7acbdd0ad3d5
+7814202bbbb01913511f9a8343d6b797
+78168e511585355cafc891fa8cf63738
+781b0fe1fe8a7825cdfcbe6fb3c6371e
+781d65e987001643304f7e684f883b79
+781db07c11c6461fb96e8cf9fdff003f
+7823351a0010db45d357816d90b3e096
+7827c944f5c2b2ea78149b1c1941c28a
+782ae383ededb9be3da7c5027292f39d
+782bf247450224831354cf237c56c61e
+782cd8c2754b778ace4856cd85e3f711
+783354fbdd57ffb2a746ab263778b1e6
+78366cad4903755ddce9548e7243ace6
+783e54245957f75c9b3a906d111950c1
+784294e2aa48b75df41908bffc5dfff8
+7847759b14cfc2545e295ad5b4fd248e
+7847d20db0bceb94f93f0e87ba96fdc4
+784ed53fa39f1b8b234fbd5f125af206
+78517d982ee511293bb9e5593f7da641
+7854aff7d68d4a5aac52edbd496cfd8f
+7855ababe4ee7a53f8806835236a7b77
+78566f74caad6f98d450b6e7134b9e7a
+7859b7f818365615e243c6140c7020e7
+78628a802d679ba83de1fba9016deb52
+786410752874111937bfc838dc79ce9e
+7866670e83fb8dff959db686c1ad127c
+78677bef2c8c515af57c83a4840e1993
+786fa7d62c99d8e098f43eae734048cd
+7870b85ce4f5c3028cac7e5aea212e70
+78713fe73f292c6a56ff755594e68516
+7874c378896ff89ae7508d2b47639e81
+7874f4600e41e35a134170e32a6c7739
+787fd0c866c6f705ad3ee228cbeb7997
+7881f34a7f3ec531d7fdb3b998839879
+7884c67ab833bfa586f5a1be415f2d38
+7888d24a01d7d3aec25900775004ca0b
+7889b11d99a431bdb7ce64a5571e07dc
+788a0deb0264da6ea8e8c76585cc18d1
+788a131a4603338ffd99640c8ed08919
+788acc82e61837142ea96a0fe18b861f
+78938a2f96ad676ae0b8539335e12c7c
+7896578870ae75025390f0c11511d78f
+789a15f55d5c2b97b1ba91bfd896ec29
+789cf5f6ed9908f013f7a730982db529
+789fce2588a968105e9e7b13b2d8e70e
+78a523969ce53bd58e6e82a0541a1b1b
+78a659b6df16e3658dcead92475f5120
+78ae96c8a50b35fcf1eeaf8ad9de25c7
+78bb8f5c0262014ee68d4761af92c448
+78bdbae06fa818f7929bfa307a12bcc5
+78bf751ff25197cd1ee8c29fba66b6e0
+78c7c5866e70153cca255926573694c0
+78c924ca1e152fdd88ebc772a84e4524
+78cb7c7c31c9635a89b0bd13feb257d7
+78ce5ad040e06c58cde4de011db7552a
+78d737c8ec70ded91442770af85cece7
+78dde448e653e6302809233ec0cb19d6
+78dfbfced373358f7b4f536a85a13d04
+78e216828ce758827b96facc5b9c2419
+78e2a6946a6551139a899f159d027d24
+78e30137b2326e5f91150384337ff244
+78e455e450bd2861258e7d597e444fa5
+78ea05a60010cc035af37a280637f134
+78ee1bf4e43182c7b49ef0d2b329e63d
+78f648b3f2da9663ea99318220b92631
+78f6d313b33098cb63adbffd942c2692
+78f749dbb9635b61d95fd77c654f09e1
+7906495a15f82da59bfa79e1536e4457
+790b72790dd5d508a42139b622912edc
+790d9acf7ad26d4720ff09e27f8c050b
+790f205af1a17dc5b7cdc3ecb997409e
+7913cd130e18265104f42fe4d4b9c0ba
+792048a14a704532bca033f1ffd0cbb0
+792640c94dc6d8a13b70af1b22a3e88c
+7928632cabeba99de781f50ae909e9c8
+7928f8035489a286786827acabb980d6
+792a38c756291254c57999b6e7e285a9
+7930623f70c285c27eced62cf1ece718
+793f8ce4fd2fbbeb14f60f3e27ccb17a
+7942d3107945a73c384dad5bea211654
+794c202c3b281be505998080bc7192ab
+79514b72447649610db18e0aaeb53dbe
+7951f18200e920faed16bcfa80e62c0e
+796491e43f8aff2fff0790dce552875b
+79736d63ea9e5bc07e4fcfcc54346fc4
+797987c43e057f0aa673cff76d3b1d4a
+7981087e629805464fc0040cb9a48c60
+79876b43065b114161a2a2a00b24ffca
+798e5ae737c3e8b7840f5a0775d06277
+79933e97a568811149beda08c6992bab
+79941d9494aabc0cac79f17c27936fec
+79982b35df1834ba003d463b4de60a69
+7998832a321e24c9be118c333f4113a7
+799940916e52418aeb24d8d6c871da7f
+799cef9d3674a62fcee7801442a90893
+79a1be17f5491ea6e95f6a3c16bee3c4
+79b1b21f0950102da33d2591b0f5ca6e
+79b36e4458c293a6bf93e7f6e8c59184
+79be487850dd3847acd02b450b2c5fdc
+79c656c62c3385e06cd08e8208837da9
+79c8815548e52747dc904dd6b7bdb336
+79c9ba5237eec035f48f5a3241bf6aa8
+79cc18458d3e03f58bbaaf921946a168
+79cc5850b3f222816c9a760fc7aa7948
+79cfdb9408fea80210183c8d4d97504a
+79d3e41597266298071355e8949c46ee
+79d5a4fc7abed3fbbd89f316ef4a7029
+79d64eaab1f5ee502b4bb0305100cacc
+79da5c23e6a98075706e5d784e521348
+79df27edc8416cea8329d062cb7be46d
+79df41dfcd5464bf21f0adadf059b9a1
+79eb9a4e97f876457942b1dd86a5bca9
+79eba5fa7ded7286acfdd19bcae2643f
+79ee162c6849fe512833ae10893aec5f
+79ee9d39961a70f6bd8637487797b468
+79f475feb2a98845cba93a7cad958823
+79f8a41600be68ffe89fa83b5075e602
+79fbbc22e665960207b2ca0464bdcb2f
+79fe92f82a8f71a6ad7aa60badf7ad42
+79ffad0d06b1044587297400b2d6fbd1
+7a004af390ce64b63708dfa65afe6e20
+7a00d83d51c910292d3b97c753534b7e
+7a047d89c889154be8dbfc794f163f12
+7a094a17dc374d06f822e101511af3b1
+7a0edaaf0d3a3074e3113632181b5114
+7a0f89ce9fb46fb3d71828ba15ed1e51
+7a1ce4ea19139a68f6831c9141e2c63d
+7a22805d92d5cc7c02e85998d25ff458
+7a22c867fd1d5412f69f5f98e64c1936
+7a22ea9304af8065d8c8d588872eaba9
+7a2e49987bc4eacb879b692f70bbe5d3
+7a2fa297f6f748face2ceac77814c5b0
+7a31ec289b5e6a3e15b7cccbb7d44f2c
+7a33dc7bab012c5b51aeab2fddbd7d5a
+7a34964d0397ee6bc784a736f1a2c569
+7a358636acb27d54e77d7e2c6176abaf
+7a36d81e2c8f7b96de864a8bec1ae8f9
+7a3e1c0807ea6c4399ef18430caf66d2
+7a3e7e046ecefe38c9e68cbc64b4e833
+7a42ef1eb19b571a47dc201ca8519317
+7a434519c78d96a1f82ae6cd1f824b19
+7a45f297a70a14d867c3d9eb310c4b41
+7a467a76cf1ff1297115becaeeb1c589
+7a48cf7cac8790f6d4866ae9cec8eaa6
+7a4971a3005a07d4ada01c42ab52ce81
+7a4cae07f21b78111e1aab10261d1270
+7a5420b968b6006b403975182cb4b613
+7a562dd0744ec0f5e6dc3e08122806c7
+7a5aaba6700299419624e03a312ca813
+7a5f40eabb6cc045075a1701d81bbbba
+7a5ffdfafc23325153586b30be1238d7
+7a720f93c16eedfc776315ddf5b825a7
+7a7776ef60b6cf8eafafe0b61e1ee2c3
+7a7f10b9628d5270c8dbaf14dc46314b
+7a882b4e95e352dca2e595b76bdd2d60
+7a8a71ba52af2199bf56a16cbb0dc4e8
+7a914c3e8acdc4fb1fca289d9d831ed8
+7a9164a21bba9867f4fec396eaa8f481
+7a9dd700b977733d196204430e748c4e
+7aa45d9d7c325b8dc1545762eadc1074
+7aa491075903c739890aa9a3f35b4901
+7aabad2470955c493f8e23931412ce81
+7aae04b7f01a0dcfde37aae4eba08a31
+7aaf11e04738066d17fbc953ee472b84
+7abca3f5e7219532aca6ba989662c01c
+7ac071d80c5d733e5fd02215777ca92b
+7ac3e6a92877ad59d5baf53de27a1ace
+7acd8ac45a6fd2ac766612491f2c9d07
+7ad0d488837f31bd9df4b22d41a1629e
+7ad339a8f1d527be4bc8c34ad6e2a389
+7ad46ebe0aef62c6650def37251394b5
+7ad6868e5ecae31c98dc9bddd59de89b
+7add00236520952f7368d976ebb08473
+7add70a1a7abce9d26bddd418791ddef
+7ae36a06049dd5a66d96e41cd71e5b86
+7ae8a46c1ae80a7e94030af67706341b
+7ae9cc169e9ba57b02bcfa11c2ca7b57
+7aeb5450540e0fd9490d550e59ca26ab
+7aed2b672938c1a4308b235be468da6d
+7aeebb22769a63dea80368fb1563c123
+7af3cb643b72f45870ac32a53bd3450f
+7af7dcb71f74734be0ea396a2c436000
+7afd50ba03ba3ff3e574554e15f25874
+7affaead8e98a6da6d0c85c5142692fb
+7b0140b840ba6107bf1ffb314c9eae61
+7b03b578854f6bedf80864c770ae5f06
+7b05f3e6e9785cbe01c653dfb28e21e8
+7b062da8fd54c145d543f36056b0095c
+7b097737166e18fa941adaace7f3d86f
+7b0c892896c3f7354788408e8a2a455d
+7b0d03a6242fa31a6af47ce5f76362ee
+7b14594e92d6f013629df4c096758185
+7b153ea5acf5ecf4e892e03f0c23b0b5
+7b154424762ba40d24eeaffa7cb39f81
+7b163de3a892186a19f346a203d97569
+7b17fa6f55b82524ce5e3d9574e136ce
+7b1d31c05ba22180574612fa4a241d6d
+7b213c4efc03f0375381c8e16ee8f49a
+7b225685ee3edf502656f09256a2c6c2
+7b22a4ec1466e66e4d89fa49b80f9960
+7b309fad7ccd301c55f2ef4914d435c4
+7b32f2d8035c00b6edcced99a87ef1f3
+7b3588f0d983994e25688b44b795bf26
+7b3b672ab3ea1b3e46e23e45e31a9401
+7b429043f2415a0b44731f5641504b4d
+7b442b1334b98ea3e5f41168b4ff558c
+7b63cc9360fd77b94c7e47e7ba1ae88f
+7b6702b1b3faf33021cf7f360092d358
+7b6967cfc8216033b768fef9e11dea1c
+7b69c2b1c13b5307ae124b9a0feda140
+7b71cbbd72e74c19ac03c781392e3f08
+7b7595e06263fd7f46c2351c3b9f0dd2
+7b784bbd7df9f42031f2576a0d7c6bdc
+7b786a6e77c7813cae6cca340e1c6f59
+7b7b33ca337880f158970b09f5fb529e
+7b7cd584f4c78636466e82bc1341a1ff
+7b7d6e7858c8cabb93c911a5d5558c31
+7b7f950034c825544a6df2cd3c0f64ff
+7b8947446b06facfb6a4c342815edd31
+7b8a920f0fb3536848eb0359f5b7fb05
+7b8b41fa08b9c075f750031379e4bcdd
+7b8c76094226a32f3d8d77bb4c763f96
+7b8d2b1ae1174b437d498096c0c9c007
+7b8d74175d798b077a60e7bffcb88335
+7b90d21217515a211b91a6f8a6a419a8
+7b935b99ab33ad2c7347b49aff084148
+7b93dc69018654419ae0b8f593251ff4
+7b94039042e12a295b6385093319830b
+7b96005cbfdd5aebce53bd016d04f563
+7b96b7f1c5649bf66bf90255e5bebbfa
+7b993ea3c8a58348daeb125b2e050a32
+7b99b23d805faa9ef0d9fefa6c279ee8
+7b9c965f70072c2e34f4cd10fa8cc870
+7ba28a6465643b9262e97cbe00a1f1c5
+7ba55fa28b4b8ad8effe6f640b1a5f78
+7ba5b52ef1a4554d4f7b281ccab01cc3
+7ba871d7091d7a7d4afde47fe1cbb3d1
+7baa1392e03609803bbea9e5659d1f16
+7baa6d9dc521db9b5631b265ea6b7046
+7baacd9e63c7b6c9247ed4ae3dd0e5bc
+7bace45e0b7d8b7baad0a8d65ac3bb72
+7bb1284c19daad261e9c65858fa57810
+7bb48ed058aad494a48f5e8ec836bab9
+7bb52906af96bbabc0abc3fdaed78281
+7bb9831a4363fe3f86ee54b070857038
+7bbc27e30756e1599cbfddbcc7529e9a
+7bbead025c086daa9e99b9a0277516e9
+7bc3bae0f8766c419f48a57ce4cd087b
+7bc4316933330f0864d8591a16b426ab
+7bc50f19180ed63af24c5835ef97af01
+7bc74d8c9c00e0d578b991f703b8cc26
+7bd164bef2c79504eac96acc9e79f100
+7bd21b193bf2efa103aef06120ebabf2
+7bd620bb7d55c0d7503d17844ea24ecd
+7bd8c8013161148d3fac2304d5acc660
+7bda13c1e80520b45b3aa45c5fbfd562
+7bdc2d2e5935fc3c90568c47ddfb6824
+7bde0510f4cf964a46997604b10ad60f
+7be29eb361348f8e9fe2d74ca12b1a87
+7be8e454ec97b36718ab542215e56560
+7bebc5928a98f5b4d65bb78f20336093
+7bed540e84c95adda43e0a2a999ef46d
+7bf0151cdd7cab73fa668de92ec9e9c5
+7bf491f9e1c779cd94f0e329b784047b
+7bfa4fcb9600173768b0558e0fa37825
+7bfe072992413425f3bffe156cf3423e
+7c022193abca976b2efaddc5f52c6730
+7c0243001f7afe60d7fdbe20d70813a6
+7c04e0f26314183e3797cd340ec00fea
+7c0c63d1f3147ad29ac5384f54acd4ab
+7c0c84f0a78b11c35a29ec24a5b8e877
+7c117e7f592496e55accdc82ba5bba4e
+7c14e0cb788b270338323a30b8356299
+7c181f12c53899fe7fc01101929cbc66
+7c1b3182277453cbee001f1c62e9c475
+7c1df6bd892f2e205f5285467644bb9b
+7c1f465cd71296d72ddb6379922dfb64
+7c2004ecac7364540b93297722915718
+7c275ba67b5da741b5174736e3f0c812
+7c2c3d69010499ab56b2af4564737440
+7c2ed7dd1602af288bc67ce15cf27687
+7c2f8ed908a6a029dc87030b3fbbf270
+7c2fb12104a46ffcf6ef034bf3a17567
+7c32801eb8bd44d694ef1df6181cc0c2
+7c3f198d2628523c4d9313f7889341e8
+7c4550174044ee51063c779668e4ff7a
+7c485d2b5ba5db2e2b9d8af4b0910d15
+7c487ea71379518516c5a6e0aaf693e3
+7c4fad76b8919f008d6d2958e902781f
+7c51f03d368f03528840e3eded391048
+7c5f38aa81dfbbdfb9b037631db5fb58
+7c6432951d9287ffaa6cb0be0a896cb7
+7c662c0887ef4a241004c5c5cd5fecaf
+7c6855910d0f8e7f702b9ee862ee36a0
+7c69a0aac1e6b3ca1b834aa323221321
+7c6d7d06beda6cc724601292905177dc
+7c6f5d58c555fcf8c5a5ccf484e5497b
+7c70fd545bb67a5a41b11a50ef1406a4
+7c7b38b7f361ef51683a941e3ac74d2d
+7c7c3c60f3c1897bc794b203e6c07935
+7c7e705871d824b9855e11608dcb430c
+7c7fcef28987003728041a594e1ece1c
+7c8735257fc745058fc5527cf32c3734
+7c8bdc0736d73c195d8cb5fa6ab514f6
+7c90210ca8a0ff3098dadf031e979865
+7c906485a529a0f09081550278ce4b09
+7ca496c4a3bc4f12e5470628cadac3cd
+7ca6b0af93757a202cf7a2d00dc8569f
+7ca929c64c3bba0a7e75a019a151056a
+7cab085bace31474a39a2050a4e74309
+7cabfe9028a3c22ba123d0e785ee66f9
+7cb2eec90180c45b6fb351dfbc83647a
+7cba4bc14fefcc7ecef1e49cc69d514d
+7cc6e45c91c27141c61ce99fb9a78327
+7cc904d7dba52b02251ea35404e422bf
+7cd643c3967a3a7e98df49e35a5cba12
+7cd936ad1fd9758d8e9e060d38b20486
+7cdb12d87a4c237284f8a8fb58b7a0cb
+7ce25770cf735f7df22447f021765bbe
+7ce35ed02846eccce84427996ea78a9d
+7ce8dcf826f5226505119a99cbe40616
+7cf7cdc7d475b804dd4d9ec3e6725323
+7cf8a7d3b55e1814ccbe24caa9b8bb29
+7cfeed2cb2775b9bed1a5568eed0b118
+7d01a58f3e80e40c30736fe48387c8a3
+7d02c477af05f252d667532b40b448ee
+7d03828c0d62e45765bb8a31a73f2c24
+7d0b1693f64e67feb23bb494d36dc91f
+7d0f866069d416aee5cdc8cb948436dc
+7d1076a092137583f59cc7c8af528b7c
+7d107741f7b851a38c5defea6cdafbb2
+7d120fea98407d573233ce1a897cf456
+7d14312f7f6fef0e7ee131168c63652d
+7d1610b11e414874301bd5b2f31a3b6a
+7d19552148675211ce53569ad1db97fe
+7d1d22cdb2bb4323f2b5d9c462147d03
+7d29482c7ba014c985a70498f1a2b236
+7d36f243fd925f95ded82fc12d877fef
+7d38ac588599055780a33fb5d624a864
+7d40d0e5023392d60e051d745c0b1fb3
+7d45e5c223e76a51194a7d509352764b
+7d46a579dc564565cf031f3d792be1dd
+7d475835844d9c196f778cb2a99d51fd
+7d492c1ee6600969ef90d3323897b760
+7d4937b51be4a4412801459175721969
+7d4a580a98be59ef0369a08d7fa5ee77
+7d4a8ba92e4a0d41f4824baa65cbece4
+7d4d462e4c77ebb093492a531be792ea
+7d4f9e48630e6370f9c984bc8e1ee055
+7d509f22df2fc9e864de96cd9fbec691
+7d58fa1363834697f3260d264dce4185
+7d5ecb638014e7eec7a053be0d20912e
+7d6bf54ce106e7fd6737606210da25f6
+7d6f32e195b1015951c57b84733b2230
+7d7338fb01cfe9cc26bc3bde96addca3
+7d74cb5610f31679c9d58dbe85dc22bc
+7d76fd8281ccf27b44da699652cb3976
+7d83380272eaefdfcd487c9db960f8b3
+7d835682beb54f37a9bdd4d563bbf365
+7d84a7615e85847c0e313a63800c8944
+7d89494402442054b5b805d4af80404d
+7d8acd079b6578e89e051eafe016f7a8
+7d8b671f459920e4f62e0d64f975770a
+7d8d1326178c56db49a1062a75dd4d2b
+7d8e12aea17e381ad66c8e5e8cb8bf18
+7d9448d6b37a5308e41f2f186ebb4d6c
+7d9f1d858e07414447b68acb966606ed
+7da786c3809c8e8bb93f5eef1ab5e926
+7da7da1b05bf5e9045c62823f764f392
+7daf8798b34733b16500d25ac861edbd
+7db3e5bcb7fe1bb380af497ed4156b3a
+7db57c0acda7f2e2f19d9c07f7157c87
+7db69cfc1e33de922c049ec66685daca
+7dbbc89fa915b6e207cbf4136ea36387
+7dbc01a15448ba5ef4a418eb635b5a3f
+7dc1d442105839a87202877702db7bc3
+7dcbd89cd4413e4619f7969536acc025
+7dd00f5b0572b7021269e12d9ca6b55a
+7dd0b30e4a9e6ef27312c5778ef42383
+7dd177f363113bff54be0aa88054e1f7
+7dd5bd725d7c33445a142874f690f3b2
+7dd95389de2ed2bc53978911e6dad680
+7ddb0bb6187e0e3ceadeef1b51191cbe
+7ddd00725d2934615a81a0c1db5932f6
+7ddd8ed803905d958d2bcc6c4533a6d5
+7de419fdb5788d46df45ff679979e1eb
+7de5d596b690088bd5f3eb7bfb43ccc4
+7de5d5b8d23becbb3933201ae48dda56
+7de7725ce59a63ffb39e4e0179810a97
+7de7f2d1e482e4c36b984729e87f973b
+7deb748571fe156aefb17646efb436af
+7dec67cff5b030849ea2944d36913cbe
+7dee78437b42c41f0497b0cd34b373c1
+7df5de076acbd57eb34245f12847695e
+7df8445189cb8e6833140cc492154d47
+7df92f6ae4d6e1800afd78df5bf0a8f1
+7dfb4e598c9648702924e32daacc58ab
+7dfce21465098790210d8eb02328d85b
+7e066c263bd9654784f3dab76a02d26b
+7e08fb4c8c5eaae327c2a4b2cf9f97ea
+7e0c5eee845b76b7f2cde01a564af3f9
+7e0d647ad1ab16691ebf163b7d2e65ac
+7e0d8c532fe0c5eaf5580dd3335b9697
+7e0e20d17d88d03abea88c55fc5ab7be
+7e0f6bcc73b55b8431ac605b63bea9b9
+7e16cfc654decbcae9c3ff5c4cffa554
+7e17587b374f13391b8c8ce502235147
+7e17d9bb1e6057ee99ebad2938f8b7ed
+7e19022bcfee9a05a81dbdbe90dc99a2
+7e1a58ecf42d045db8218643f00cabfe
+7e1ca8eca3d90342e91d0a5ef40cb50b
+7e30a4226f50fff94d46493f9badc7a5
+7e36a094e7f0bee3757ebf262ce09b8e
+7e4231aab014b61847ff6d7146bffb38
+7e4984ba28efe20e81841ac8e8d7e4c8
+7e4c76b54145ca17eec7b345ac072140
+7e5119c004ea79acf99a7bd3fe36ef23
+7e51d111c63b0cf63ef22958a21226ad
+7e530645c6d5791549ae4a2938bf97ec
+7e54973abefb8f48aae539e1a317f0bf
+7e55bcca01bf50b97eb2c0294b4ff641
+7e57a2c83c76aac808eb9ca926fc9e46
+7e5984f8662299731197dadf924eafab
+7e5a1866a33214f73c5ff61c3f176fa3
+7e633f8aaa2d1c505c1863bea4904f24
+7e63666438a42705caac112ab974d625
+7e63ba578bad3b6cded92973f95620d4
+7e6957b58e5cbc1c53e823d96c183ed4
+7e6a17005e88e809ee09593170007b48
+7e6b29fb7684214958d389db42bb1ec7
+7e6e5f3435a1faf7aa83b55ea1454ebc
+7e6f19357865aced17373cdc81fcb2a6
+7e713862c587a85cb7eb472070f3e7b2
+7e72fd328d79c8415ce5c6615aa72dbb
+7e74c34e28e020e8f5a12e30512f16b6
+7e7d25932c21ba85c1b4bf80c7b942f6
+7e928236febe9f2f8af192c042d941df
+7e92f2e356f0152f1d87a569244d2e1a
+7e935a13dcd27febbc1671c139c7e2ed
+7e94440e7fe7cd5c17c766c2baeaa1dc
+7e98a1d4d7dc18c49b553afee2e9b8ff
+7e9dcd2e118a6533690f2c85192c1956
+7ea58e0a8a9ffded9f864a3ad6c46abb
+7ea75b25b2132606a2ebec7b64aaa17d
+7ea99eaa46e88de99dcb2dfc4242a210
+7eb46cdc187f6a894046bbc7eb316462
+7eb7166e568408f75d4ebd999881ecbb
+7ec07e5e47a8b524ec939103e2f8d1b1
+7ec61b4e98da0531914ba09104ae9ee9
+7ecc0aa0f5b2980243c96a284abe608d
+7ecd5068d551eea9a6f18a3f978400f7
+7ecf740ae7e653b368aec4af0ffe6bfe
+7ed06acbfd5018d1b53159ac69244b42
+7ed6093f020145d0224f995b998b534c
+7ed60c743a0cb2664a610b344b60031b
+7ede16faa0ec228c4dd2cd4f7a91a534
+7ee1bc37b3ee673cffd539f7afc3f8c8
+7ee51476a27e4491521cf4fb94ac7122
+7ee69227e0c0a00b613a59a2b28fc6a0
+7eea5f5746027fc9f41b889f3592ca75
+7ef2eead9669efb6360552398388b4ce
+7ef6341d0b6b2d1cac54904cc9118bc6
+7ef642387f4068dd741deca3237c6571
+7ef6f91fb5e5d264f163bd9daf8abad2
+7f02745e23cab68d541999a3569799b9
+7f0448e52822992594828759cbedb60a
+7f092bb782e336d2c68efa46d2804945
+7f09f4e093868971632310b904dce074
+7f1414d4369c88ff5fda12fcd1e49407
+7f1ca31f953e32b78fa4517fad7ff8d7
+7f211e173f10bd3a017352864f4c6080
+7f23b1ccbb4c84588eb439c3599dbbe2
+7f28b1b162157fe95bc0cf3a97641e62
+7f30d0748669ac4f2519e2c5220f5290
+7f351f31e1d2e197e33da2e6c25ce361
+7f364aa7a3d5b8967b377d4fc6a348c9
+7f372ddff28b7d71200607fa68dfef59
+7f3e3408910e2e8666e6a368c8e61612
+7f3e97eb822588347157fff87f00f941
+7f4075bf17edae852fe2c35d98a2135e
+7f41de15f5a9153edcaed9ffb346452d
+7f44ae4ba139baba725b61418b3858e3
+7f48e85c62dc2744c653b56a54f98ec7
+7f4bd6994308225799bc200d3f2baf37
+7f4bd76498bf16b80849760d4076e483
+7f4e8b760e5929cb0d277115160d07c3
+7f5523ce9fbb0e2ea819bd46d58d6ea5
+7f58855b59ce48464c7ffd1eeebcedca
+7f5a034e1cb0ee910f62e7ca0ac153df
+7f5a857341cc8eaa2a9e6ec4d6f03dfb
+7f5bdb3d3f923be256f39e78760c08af
+7f5e48107e91613a352f561a0a03849d
+7f60b43c85d3c449273b7545a82271a4
+7f640068a36ad5bc4db04c58f2131af8
+7f665b1a03c5c19bf6d014d2c39d236b
+7f6e6235f201aeefa74120b549f680f8
+7f76602c63250d2d670db96f35601b27
+7f78b7608a63fa3bb824bd318c5b288b
+7f7ad84aa903b91bbbe7bc70821f9035
+7f7b6bb7cf38344704855f1d71cb751c
+7f7be49eaf54c2458f271f605e847661
+7f7ed6beac93e5b1cabda04ff2154fa5
+7f83dd79375b017c760b34362d71e5fd
+7f852535345209ec5a5d81a1253273e4
+7f877c0c6bcc45f6bd2762f06d19343e
+7f8d7877f9d34c4b446a0b76989f6d7d
+7f8eafc748f99eeab5b19b9b347ca9dd
+7f923f6ff6949fe8f1b909fe62803c49
+7f93942ca8967ce33f89e6270e9d3080
+7f96d5b954677b2c1c0168b3f59cf110
+7f97e5a4d01c68202602a43d27d6d231
+7f9d82f64bc8d7c4ebe7e3f0a5a542e9
+7fa5c478e15c506de7ce2d34411af327
+7fa95bb2cb629ec59f3b52f1b8adaffa
+7fa9d731110fb509a959ae3fc92e6f12
+7face646dd54b325fac515858c9e3bf7
+7faef7dcbc425722e0f121f819d9953f
+7fb3241dc87157df3a313394c4ccb2a4
+7fb3ddda51df501540fca7ac22ba4181
+7fb93ba66476316381e6cefe88d1d9e6
+7fbcda6087bd27d9f955e413c0d63b55
+7fbcf0b82dfcd72b59b8b761978d9b23
+7fbefbd4adc895023215b48dfc4b93e3
+7fc095dc97070eb4b1a5284792f1f777
+7fc0ffd9006e94acbcd5d7a9aeca74de
+7fc260034ff7bddf7f08dc94a8d7f419
+7fc9396f2d064966dc8f67f141341a6b
+7fc9434ed5160a58217e363d755f619f
+7fca16c35c5011400f9de0385eed69da
+7fcc8134508c34e9f478363ccbd66bfe
+7fcc9c2e49e4acdd4685696948b51d81
+7fd72ba23910cd9790dbdfd7bf36d862
+7fda81a0c965e32e85dab6496ce8e142
+7fdc7bfb397683bd83f6d98a2075e98d
+7fddd775eedeefc9fccd444dc813ae6e
+7fde123967cf7e708bd2cb2a4e5cbbb7
+7fe3468481fb452b1ee8c7fe043cefaa
+7fec93f76087d8084f0ad7901d775f78
+7ffb376290cc2fadad89a98d2cfde256
+8004cbff78666b12090efda2ea5b05ac
+80081e99722f26e6e0e33c04bfc92262
+80095ba0f6a1dd0f4227060965a39153
+80107750e9cfaeadff8092e4841a0ee8
+8015f00d13087b42c97d8501c216fbfd
+801716a4dea2ed1b10d5877c717fa898
+801887f7c94da94cd497e5504a61c5c9
+801e758608bdc95206156fb1b9f998a6
+80220c2dd88ae3237c984ec1a26ae3fa
+80260467f4f593b0d30693d1d8a80fb0
+80262e78750d20341279525ed06741ca
+8029888f7c47c2558a304b04b6b9fc52
+802a5dccd22f62dff1e3b61174da6131
+802e2ec4fc39b27914331d0301965968
+803d5dec8058efd9f0434ba3e2bb3fe6
+803e7ae7c3c1e87701de86745fc18962
+804bdf481c08258d248f4696124d8d1c
+80518c73fa54eb1288c5dc540ee7fd6b
+805cd1fa1e874e070bb73e6613e49c79
+8061a1df47839e059e4a581ed747d779
+806332b347a672b9e22e024b92354acb
+806436a4b2126229c389c47b8fe3b191
+8067da87e7e8bccd6038a23e8a387a93
+8069a735e38d17765d96dbbb8202611f
+806dd637ea1bb04ac603d8501ecddc8e
+806ebc06fa9439342007ad05d27cd77c
+8070196f6b7a0ec7e3f1b144769cb3e4
+80706506c99fb6f35bac702f4fafd647
+8071198535d5ec51bf774f8b1abab311
+80712ca660047c5b536a40f181c425f2
+807268c6ed79f1c9f9d51b12a4920397
+8076a0e0b45f14c834ce1edf48bef455
+80776f78fb791c4d23946a2ff446e163
+807c477fa0f4a350d52d91a90a3764dc
+807c92cff297ae3254d38f9de3048393
+807c9b36ea559795914fc229b6f43665
+807cdec4dd3bc9ed334df05d567bb7f3
+8081c4bc8b5aefb7ac624a814ec1aac5
+8083af61c3c03e4dbc649df83fd2b4b1
+80856fcf38fcd8efe7492b57069881a8
+808578b3fa6fab92a3925e150afd06be
+8085b9bdb7d66d56fa2861d2ee4bb623
+808ab962aedf140d6c1a6292613394bc
+808b840029cd9c979ad4b22011f48375
+808bbecd06941a8f8ebd5a5b54169a2c
+808bc9b9aa5c539e483b53a1c7bb02f1
+808c7854a38e49a78aeefa0205f6a012
+808e2ba8dfff961d0c435e36eb2c52c1
+80948f42637c7908564f0a209a5f4a2b
+80952bfe4b9341f7ea6b543d820cc322
+809a1da3afb36cadabf978296798c9fb
+809f21a913774f48bad8f4ddf613c3c8
+80a8118a1989392238ce9d9558e9eda6
+80b035e7165e45e5855f5ddb64e34b98
+80b204e11b6faf07f542a410021946ba
+80b2ecb2a5ed4246232f6c20aec6401d
+80b5164257e7af08cd638d5adbe42d54
+80b86b2438d41327435761a559a979af
+80b9e7eda0ac67eb5618520fb2d14d8c
+80be88445069c1db1091d5be944a6fb0
+80befb4e9bf34560b46d753ee6115acb
+80c3d596ff5c17de3ecfc1d61805339b
+80c751f7484ae209e9032d404c1b1e68
+80ca083b96b41ed5219e552239be1158
+80ca3694a9cd1260245bbae93d8d22fb
+80d35979301e9e3014d57c99796fa481
+80d5f0bbf371af1bd3f3fb4b8072acb8
+80e071040b122f6a28016ee67bb2f088
+80e4cbde28611ff4696222b0fb7b198b
+80e6375d85c678bbcbae72bf1f2a5a4b
+80e6515e8ff466adb395fc5b81e6d668
+80ea3c1127d8832c1293fc56bfce0ebf
+80eba0ad3cafa219344b9e60d11d7335
+80ebeb440addfe5ecfcb69951e577abe
+80ecee6f8d1cc5808ab37dbcedfc3b82
+80ee11fc8f4201a5f985d7f007131b38
+80f5a5df22356d1faca100de372c4638
+80f7b5a4f34bfec121cef5972775ab8f
+80f7db73a2142d3ce3928b0c3efedd6d
+80f8c0f70c00570b9412189438dc9a30
+80fa242542da2426ede716f2344326c5
+81002f4bc1db9b19e45044eab0fc8ca4
+8100c9a74700239cc09a87bd0628e129
+810586e3b0dcf0146c3a86c4f2d859db
+8108b360c510c7bd0e39c754211d1077
+8109c9fbc1a8b898d832b79d01669a87
+810e45d633f021cff90a0cb58ab2cd1b
+8114676130953f8f4d9c9f32a90c2911
+8115032be418f62bbaff2bb5ae66eb09
+8115157d5770a9c80621206b19fb56c6
+8117dd281cf613d3941ef27da5b6cde7
+811967b67f2048ba02b1fb069c72e3e7
+8125330d73deb1a51cb820c64f6ee52b
+812a39007380376a4badb7cc8137ebf3
+812ccfa6ec942fc28cd083a78a2ebdc5
+8134b06e914354ad8af23a4902a1ebd9
+8134e52adfd2b79407fc9901ef83ac34
+81364ea67ee13b2eddacf5447a0626c4
+8136d2afee51d6e7dbba6b99e6101db1
+813d30c1454f6794be4b6bafc518bb26
+813d52d31ba09073e5ec18076ca9511f
+814082e3494d833081c69529f206b7a3
+814a8120a219ff6729ee4a248a5e195d
+814b604dc153bfede548725b246368bd
+814f4c5e5d8be73616c76e8361335952
+815789d99a81344467d6d83587f555a8
+8159d54e44ba8888287b35191ab74774
+815a7e4a0f46ec1ffd8f87db757bfe81
+815da90d1d45dbfde242e857f9335cc7
+815fd0f5890b565f77a435545228011c
+8163fbea55d60facdfbb724b520c7d72
+816883dd09c7ce3a6b66bbdd0f1a06f1
+8169576874c298cd355e115e39004243
+81699359642b77e2d30bb5a56118da55
+8169f80244df9e0bdf4affb8976760d1
+816d5242066702d5ade063ff244a994e
+8179f29d1ae06906ed15389424f26703
+817fd5bf020baf7a24f2d794b893f1f5
+8180b14e8f3349de73d84369eb4a205b
+8188ea14a7c2435a4669e7798ea10712
+818f0d073d87adf2362224676071066a
+81902ae22e8ade62b011a493b910719d
+8193df93a298556262d45c6b50524ef4
+8196cfe5b0c065b6abc0067ace6187b5
+8196f664df340f45e0b7e9a22c0a318b
+8197bc93084e778a1933ca6904b252ee
+819a281fa37afc6e7fefc02d88411e5e
+819bb4b421fa00354541461f1a535c49
+819e53ced881582795d79cc9d357e8ae
+81a0d603cba3be4b4fee2368f968c7a6
+81a135c8d2d1f26e9788752f0d38aa6e
+81a416cdc8c39d3c201b2d9276976d46
+81a83750c765da4341d071098edd72df
+81af23316fe71904a19be7044826eb9a
+81b0eaeb439539b7ebc0bb21a056035d
+81b28dbaf46f619e71d445684ea163d5
+81b58a0d64d1f784936a5ecd41d60f24
+81bec247515eb0820569ddda3cb7edd6
+81c26e8fb560ffb12fc50345573a60e3
+81c2870086830ddd4abb499ac0a6fd00
+81c617b9c1906597820122e9356ec825
+81c8266ad029d460dedcb2e32fd61028
+81cec86c6edaf5993f1823473dd044d5
+81d3aedacf97aee71d1b40c0c3a7621b
+81d4f9d8076717216bfaeeea3e7fff7d
+81d70569ed6b35bf1fcb65e6ba2a7903
+81d816ec0e15fcc0502aacbd16c1da67
+81d8b0702d68a26f29034f56162d2afe
+81e8fc97078d940854911f301a46519c
+81e9ea953d78d0e60b58781a2a0bc742
+81eb0609b2386fca330d3f1e95bcc0a9
+81ef9106ae14f48c29d9d3a3ce10bdd4
+81f6f56c4cd0ba64d85a7d1b565d789d
+81f723c483a15b361efd3a58006c47f7
+81f79b5d02885cfbb0fab1c7ea9cf20d
+81fad47c334aeac99fd501edc6052634
+82015a6dee9167d4b6a4ea632fb71885
+820a1b42bbca1a1c3dfe79e23e219b37
+820e91577fb856c3daf785f7cbf30d6d
+820f356da3b8480a5c56f52f8389ee1c
+8213cb107716013405dc8449f6bd9700
+82144ad445cbb2de6a03fb642f180afd
+821609f309343282fafe9a64a1b43733
+82183884d167b3badcd6433d9d8911ec
+821dd2e4467cc269e089421fa7e5178b
+8223021ef8c2b88a53ccdb3b0715ae78
+82241bdcd43b7ff8766b8103bf839f1a
+822982886bd316fb09aeb8c4010e5595
+822faf9392fd41cb0fa791ea951ed04c
+8235ccd805e9bdfbcdec7c07659f7ccc
+82382979242e5ae7552ae2896a4b741f
+823eef9ed3138bf4758e0cac90587874
+8240973dba3a3527a130e85a7b3e6c11
+824500f3f21f7475077d6b89f2902e01
+82596d97a6205f8f07e1574243e35678
+825ab3fa130effdf149255c13b70d928
+8260462976391b769d990108aa24d5e4
+8260bf2fd7da5816e2252599ac2275db
+826a3b959f7661e0ed12c51ef626504d
+826f5296e27d787f4a92a102cd044d9f
+8274ef499cc6940bd85feae096049945
+82768ba559840008989191ee84a674e5
+827de5f08e8f6b93a396aa883e137460
+827f3aa024cf44471a16f97ca795fa65
+828b55d3591b5d342f3ca92b21d6e9ee
+8291f98902958a95f7f0b0575578a10d
+8293b497f376f115de7b05609c3fb4f9
+829532698561f1a4ba52b7f4b076230e
+829aacd812ef6b9fd4e64bfb3a3a587f
+82a46da7fca6cac23afbf49696b49500
+82a968aa47d9744ae3ebef61b55908d6
+82accfc009d48cb484e8f5c20fddf62b
+82b1db8f2444031d9f49d9fa34a8aca5
+82b3b6325b217c939b7d0654655349fb
+82b65fba279c6e1c10502d5579fd6eda
+82b714bc6299fc30fc4459f8b192ec10
+82b78e0ff8f4f1d43f140e121df5de8d
+82bd8e563033b6e3b7a07f497a061277
+82bf9dc62ed88c3aa4d06af9865ed4c0
+82c02395eaea970f78891979390c157f
+82c6f2117fa87bd19ce87d6bfab7c8e3
+82ca74509d25520df3b613709a5c4a07
+82cf3fda6b9ad2cb92fd95901cc54db9
+82d227076ae755438e2fd8d6b057cf6d
+82d3bc5da153b1f124c126bbd5deb113
+82d5abdbf8e204219a87e645168bfafa
+82d87c1410121ce5699b321e5b1d52df
+82db3af749a27f51a89e73182b08628c
+82dc2e54f2917715e11fad672e1333d3
+82dff4d298cff11bf60a5141c4823a26
+82e6bab1ee4bb8618760158ddc75d21d
+82ebf7786291974323bc383ae33c1417
+82fd78511c9e8a28ce7e2be2242d468a
+82feca66471232b224790fd6fbaa904a
+82fef80d609399159d6a9b0a5e1908be
+830458baec3c72845bc10e6574c99448
+83088737aaebc275c8e83f30d9580e31
+830947418b71054df4c0cb19b70bf909
+8309cc973fdb6ac83ea6fc4375f1680f
+830baa817a8bf5fd177df62165fac5e1
+830cee72b12c5c97ee090f94911abf3f
+830e2e695dbf4319c95c542a362f4bd9
+830e68f7d77fd5089d2522051ab2812f
+8313a1430fa7b292e2c454acc0011331
+8319f4d68d7ef8162914afdc83c773fc
+831db29a71f891987a4e181ec647e19f
+831db8368e8fe4d103355a178e47a03e
+83248b9adab21b1cbf7d2d56e0fee145
+8325c932bed746f9f9350fe5e3dd8585
+8328796fac20e8d372b62e183afaf1d5
+83339e6e18225b8ae0fc486ed9092753
+8334163e7f7d2e5c1daeb7efe56381c3
+833a4f00b5b7899de5cd04546515a2ef
+833c5593cefc856726603bdcd3d8faa3
+83412498f484678211519538d2bc13c8
+834162c3378bb09a3f8bd2c55283e6eb
+8343a2f2dff7355c258732cb7d1c63e2
+834a51b85fb7f2bb75a15fc44074c300
+8352210a4b07c4c585460cc19c1fe049
+835259d2c13bfe0e1c27b4a1f044fdde
+835aaed3c22d08a196d3599545fb8586
+835caa24c207708dec43c98cf9d56bf7
+835d104ff8c4256f551094be8e26e7cc
+836786ac31e394ae0deb26c50819c97b
+8371b99770e36222752e1e9b0f4c7e4a
+83742476ff35fe1c3b7f157bcb93767a
+8374c1a08fcf3776f2677e11f02fcece
+837533363d12628c9da230574a3fb9ed
+83777024c32952d97e66179926171ab5
+8377fd7056a587f4a518034fcbc8950c
+837810020643531478d4b91a6acdf459
+837a3db3977e6c6d37d1df240e30c6fc
+837b5942f81fc2ee464b92aad1af6cea
+83821ce457ade29f4452a7c59685cec0
+83833c66cfca9a1d2a4f40f03548324d
+8384d5169312d50e505c2efbdca14355
+838575406fee6f53c8bc87ffa6e5bc54
+83866ce35382c3be6c66e050d7620704
+8387e4b44996bb7841edb697237957de
+838d4da0dbc50fe734f8224cb13b1e0b
+8391df712c2007955fbf651f6f291a7c
+83985c3e5f2746d13bdd6f54d2acad89
+839a5ec02beee88df484ca34135c55a1
+839b3b9f5e4bbdd550e8ce6d882fed9a
+839c8ea920f43d942d1dbd85bc30a84b
+83a1d9130b611c5d8a35782c3f1c42da
+83a78fa5104aafbc822fcad682687066
+83a9a7676ad711b8229dbf65bfdb7420
+83aa35f49c15a68ab4b58d3e85766f48
+83abce2f06a43ad521cd372197c22e96
+83b0a45ca34b495dd155c85ac07ba7c7
+83b9fffc8c19b0c259331a09680ef062
+83bb940190f161eb67407eb18a13d91d
+83be20637e553038ca1af7c84b856632
+83bf3c6783db25dfeb78af9730097917
+83c1aa3be4c0e268291f7b204cfad920
+83ce4329272e62f55640af0b413cca4a
+83ce98517a9c88922d1ce5d12e250fef
+83cefedc340bb78e43350544940ecca0
+83cf0aa31d59c1d227eefb7213d1d8b8
+83d0abfdd5a06e83ebf150e1b011c422
+83dbfed22a3e8ce86dbb2100254d37e7
+83de20d2ff8acfc8cb42a3243f4bb26c
+83e73db25d59ba44293b15b5d275c65f
+83e835d5d8abc7ce422f4976182c0853
+83f6537afcd024ec6fdd5eae4571f5d8
+8401dea3d964afc1a1bea6a228757356
+840a409a046b6f8c9018564f309715f4
+840b16010485e56e07c9567eaf709579
+841331a3ca7c71849e729294e37ce621
+841359a891bff28306d0454c9a3b82d7
+841383bb17acb88d7777fafbbabf7948
+84139ff3a182c17a9c6c668e12a1fa1c
+8417ddc784be7461e5373d6a8a3fdd85
+841e012379a1cad8530f4d72937baee5
+841f40c5a2bc72808f1f583d804cc6fd
+8424d98a44dbea364f7fbf259e3f8e07
+842555e6a7e7d92db0dc25d6f9a1c2d7
+842c2d9955795953faa9de49ae14985c
+842f5acc10a66317338eb2cac947d888
+842fe4d90ab902e0bd4db7282ecfd153
+8436310c286c32f5c98b86ebe0460a6f
+8436733d1bf8e9437ba7da6967d118c5
+843a20fae4bee6cffdab7db5372abb75
+8440864a49c574bd75b0acf123c07b98
+8440bed23fccd506e6220e7395190df3
+8442c508f0280f36e67f7eabdea016f0
+84446027eb293d9877c38f86dd09be51
+8448689cc009bc14dcbd3290be2b7d87
+84524673de6cb7015ac353c0522a0ec2
+845bc71fc764fec4d3f9dbc48695c897
+846a4abb1dc93f26dc8078ef37ab8271
+846c034de0d88610196d0d7358c724d5
+8470b1419213b93a86dd1bbfd805f879
+8470f35b3da24283e6c0e06cbb8014ae
+8473a57055bff9858d01aabb05693f3a
+8474699d240e5791781bc858346927c0
+847a469e6530baa12aef2d1409e83440
+847c9e63db01375a5013c79d384cbad5
+8483dea2af2a8ce01bbfe2060b0591b8
+8485ecce3c5ab8f2f97caa78cdab36d5
+84888d512efb1ba0cea0764498941e48
+848b8e875737296ecc0a541ca2ddf3f4
+848d79aea0b62c632e660a59da4986fa
+848ff93398fb8ec0de7cefe9a4678961
+8492cf112d95a54ac9c75b9b286a9a31
+849d8c1056c8abd8d382c6ef92f14ff2
+849eecf21071f319d439a666ee10232f
+849f8d2eec6c85360f8142ff4262ac7c
+84a46f8b2baafcda5e3462eb2c0107b2
+84a4cb671c4dc215e9e855aafa956cda
+84a70b559ff9c3476396a1fb835bec44
+84a78b96b3550d10a9cbd045f1ae99d3
+84a955b89dc1a3e1bfd83050887a4efe
+84afaf1772d99efd889ccd47c918e7d8
+84b2a437a1f17aeb21956ec5f43c1af2
+84b77b1c2db89ac7ed1e5a3cffe52dcf
+84c229260f2470ebdaebc1c11eb72b44
+84c735d55de9382e392270e2cb41948a
+84c9c3db92022d1ac8483e18cd1e94c9
+84cabde851a86191b2e11a45980f8401
+84cacb5c3bc09490b736c7b83e89a827
+84ccd983efda686e8ecda4dc86179ca9
+84d0d246820cab7c35aa74b52aff270e
+84db2fbecfbc11473efc61e173f2473c
+84dd0e5c64f27ee83fdd36200b2458ba
+84e0977853336adc9ea69da5fa7446f1
+84e1251954012c37a7d9d1390b894ab5
+84e7554ef8a152b1f670221a879d08b7
+84ed2966f4571d53eeeb8a089eaf1e9c
+84ff0e9c4788b3a2fdbd1f6734d4643e
+85003294d819aae09247b4f0591597b0
+85036aaffb850d7251171d6dad6ddc6a
+850813262cc2af06a7c86413f48e436a
+850a91bf2cc79a99948148e47f3d9889
+850ae021176258cc0b42be3d53ec4942
+850f2629c7716fe4d294b2d4f831a1df
+850f7582ecbf7fecc56aebea5aff9eb9
+8510ebb5d162766d83a1bd1d2443910d
+8511f02cf4aac0e8ee5a7da1602879f3
+85135c3decb9d925621de5d89e2999bd
+851452cfab69a1b973f2d38babdac5c7
+8517f4fcae991fd54fed35a04eddcf01
+852166b9d3af257b33ac8bc86aaea9ee
+852a20d7ce2964c422f78d80bffe40f0
+852ce2f8dfe5c60918d328a92b8c260b
+8537ee3eb9850fba65a6b1ab6a2c0fe2
+853c5bd80ad863f52000c263e25d3286
+853fe955fcb0e5a4a6d8fcceecfb784b
+8549e4fd9125e1b91254f4ad8dc5e618
+854ab2e7e5739f7e719d506504c87a41
+854db32ba58bf53a67bfac3755f379b5
+854f42986f552edad42c25520d3ee8cd
+85551f09c7da5506ea42b8203952d6f4
+85569ac20d46a4abecf5a20578c52cbb
+85654a9d0a969b187d3c7492c1a679fb
+8565a58ba3540373e507132443e06496
+85683bbb130d27f52d70820cbe962206
+856e3798b8c00e865fd153317bb863c8
+8577ff1b1a6e7dd27b80f3d4e87d073e
+857afad9fe0f5afc937171d4ff656843
+857c2a95b0da3d7dd1b1ac6bf359687b
+857dbbc127f009ef525e90df073ba296
+857e6821d7c79c38fb72e65dfa763d71
+85857645bd72c23db465d4cb5b63a4f8
+858a4eb6106da7fe4f235697a06ee7e4
+858e4ddd566270e581cbafaa1bd1e3e1
+858fd33959f4976224a6790126139d9f
+8590949f1aed4384a8952e0f90a997dc
+859235ac9aaaf82bf72f3a1f56c523e5
+8595968995563145ce91310cae9b7c64
+8595b19046d6ddf114f746504ee16a7a
+859cba2c4c07bfab9d196d1bc1daa319
+859f6fa1e02a0bdc44da2ef614b38257
+859fbdb8d3427e3f191cc5e29c5b14da
+85a17070331706428703fb1d02261396
+85a4e3e6abd7259b71cdb2dfd2ca011d
+85a839757cf77b0cdf3910b4a91a6d41
+85a8ff1b6df262b72ac9d814fd67fef5
+85b0d0b83cab7bad61cf0fb191c755e0
+85bad1e432da7438b5e5c13da4809c21
+85d05b647ab3be9b221d24de81960970
+85d295b532a904280ace1f0c945b6869
+85e1bc302f308448012ef72975af8e3f
+85e1c6c50de43efdefdc48a76e772e14
+85e289aa04ce07feddc6c37b7867b93d
+85e597ea6017b70d49db82d48f2ff15a
+85ef0c6dccbeb0f45e6aa4750e857cc4
+85efbdd16d11180ba3ccb78328a4dcd8
+85f24fabab2464452e6de5a6bc153f16
+85f2a1f53c4824388ce5cf47a45d5834
+85f3357e0d8635b94f20143fd5e8ffe5
+85f35f42391d4b2c4e9a02a580bcfb0d
+85f39c76ce7ce0ababfadc984e22e9e7
+85fc208acf7016f851f6a9eec21e9ad3
+85fd87d05d56e553a2d55689f03a0fb9
+85feb6b1a990f51aeaef7adaef6aff44
+860012cee25223c013f31616d04f1271
+860328ef8b19a83f32afea63852eb064
+860c574d09b4682a82396541be0c6160
+860ccd24e795aca9724758b32b36002c
+860fa354049d314f93bbe907f4f2718d
+8613f7b7b2943ce57131db2c8be26076
+861553e01c6de0d93eb0f10afaccd1ae
+8617094f5d6917f6d654b4951db76c1b
+86171fdc5709a49d63c721a56660ed48
+861d27610749ccd7fec1e38a7ca53a3e
+8620fddfaec3de219885aa2b403dc9dc
+862dbd3f1ee5e10b440e5056f2da01a7
+862ef1007018cbc0320ea5a87305ef26
+86365b8b8c34a7b2474affa9af469840
+86393795d9f5e201f94815cb88ef2fca
+8639aeb10bfe3f8a2b25ce48217a5179
+8639d79fb13e25db04b9ddf976a166ba
+863deef02938a0efc86650ca8a0e8246
+863f48d8dc0044080a424292f54d518b
+864232c07cc73c68289c2fd2f58f1caf
+8643f4d05d024c9cf3eda4e135c0e9ce
+864df149d409eb6c9837686ac58ed9e7
+8653c88ac7fafc4a98d53342b447b436
+865485c3753da5f5e343d2c434ae327c
+865a8e63843778222352940f78118d79
+865dc03a1bfe5b970057975f213be93f
+865f8afcbd6ddd7cfe39bb2679ca610d
+866033e74fa5e001e1dc2e19ea447d24
+8662a2eae9f9aedcb135120867a701e6
+866670e09867d7a36009f4c383574ae1
+86677ead60d5e7e0ca8eb0be2238f501
+866b1f697b1de6febac3760a93b55538
+866bf0601da06e7790217f985de865e7
+8671e9d3e06f946090bc32babdffd81b
+867241d55995f5f8f6e9ba7c30746a8a
+867245882a7bc622cddb829476b353eb
+867383b50e58d6e374568df31beffe57
+86749d8b570d6837a96872deac180ca0
+8677114fcc8cc04ae79df70e009a2d0c
+8677ae53cf03c0dc854d0af7df2392bd
+867d15963600afff2a935ad6ff131ed1
+867f335ca7342ccbefa6565c90b56439
+86807cd7c7ce3eda2396ae92198f94b0
+868d09837d71504a52d9ea99064ad80e
+868d4bfc5164ae0be6e6976c704925d9
+868dc8d84cf6d6d82b4181a909ea1102
+86953c6267858d3058be32ce12c1fbec
+86984658a05591915fae12cd5c9c9674
+869be2446ef4dfaf057564ccde28ea27
+869d1155363bc57711da4a35d322fd1f
+869d6f2b56ca354774092889d93dde7a
+86b418f5ffcd92e89c186e5643b6518f
+86b731d0f4a55150239cb917c8b0f5b9
+86b9eb76fca4780377a1a72c9eacd9aa
+86c073e06fd70e5792cb6262cdced9e6
+86c1b70d5e06c03d0d9447dabcf799cf
+86d0b897973e32ba209359aaf6103596
+86d2678e5bbc4e8b57a2bdcc65074627
+86d3e3af293567b2fee44f2d56d2349e
+86d43b5e496a4acfea9b1f6826e1ebe6
+86d719c682846e957b817ca3a8ac3e9f
+86d8f20d84fa36f8dd842f3dce27323a
+86dec86c4c9d67b2ffca5940d8f77c10
+86e4fbba2abf29d2503efe40cf738b5b
+86ed2c95f3c7beb69ee33950862f904f
+86ef728fae4763b0de753e67dacc3ae3
+86f1df1f382669385a6bb1647d707150
+86f6b3754b1dcfe5f0935a15a315b43c
+86fe3cec391eb550a6a28c0f025f00ee
+8703bf7f81b6c7f6f40a090d461a1ca0
+8707aedf7d7e91c95b95f1f3a1ed761a
+87081376c2ed97f20bfb324d5443b31e
+8719fea29173fa9710aa2d2f97169380
+871a249088426849bd13bde2e9824f5d
+871db9609a95315aa842431a546d7a7e
+871ed5187108c3586e5e84fe5df5f73b
+871fa027399e020db43350431a5cc9b8
+8720a773c5243e9a2c862d4973d77864
+8722c9c453411e7fa6f369b8c96b6865
+8722d6cf8883f8449fdc94216ba965aa
+872bb22090c3592985e5390275c3c570
+872ca7b22f07e423f425707a2e295b57
+87399db91ab92178ff7ef28092b17e7b
+8739eb9e4deaf9facc531e4aebd5e13a
+873a10366fd532b4576681ddd8b03080
+873bb7f85eb40852ce1ddbde4554ff16
+873ca002042a50f1c110fd06e1ae575e
+873e5724ee139da6fe844a82288a1e75
+8742fcbbe611aff3bd1b2386d8f45e7b
+874400b6023e564d8d7c74e6d6077313
+87456cd4c2279e2a3ed734df87b6d8d3
+8745904f602bc1034904265bf237327d
+874609de4ee126c73c404fc7cb733407
+8754b87e9ddfa4935a35706c475bacbe
+8757f421ecfe5d2e4b517ff5f394846c
+8763b63b9672568591ee11c751803c91
+8764b38186519e6dbb5cdb029b1c5ce6
+876a8958123b315712d6d4b51e9b63cb
+877274a90d34b70274cec078def7908f
+877400486e4e75d2e901dc5b6528fdec
+877579c6d30d077edfbd2bd05cb98b27
+877b08e05a647c0cb3201721ba4d7218
+8780b29f10787a6452de38e603eaafa4
+8784a110d3a5ea6077ae6298989be163
+878af3581d8402fba256703138d2734b
+878b308c6e4de749b59e77708e04722c
+878c448a5ab2000ad4169c968c6eeebf
+87906097355d402b3c223a6b6fe38913
+87917525f38c049eb4ae3fdcee2d0cf8
+87934d725d0fe38cf68052c06b352b96
+879e0f4da97ac5cd06a4ae516a894349
+87a08dce9020879b1e2b48f3420ff5b7
+87a2cec408affdc8fb82fc1c51ef45f4
+87a6afdb2516e73875c60ffeb40687e3
+87a90dbb648045b7ae2b12cbbc38da0b
+87aa0bb3be7c303a63f5e8fc2c4757f4
+87aa4448b19da378ebd376274f7f4402
+87ac57e011995724e4298a3b96791a0e
+87afa5c51f8905bc1ac4f9b6475eab3a
+87b2069791cd8ce4b5db983a3e067e65
+87b5e8a7e600ef06909863aad5818546
+87bb3434379553a8f15e1f59cafdc374
+87bc2f2b8059523e3dbee9b30829fe54
+87be89aa0dc7f8ab2bf0d13e1aafbed2
+87c688fff57fc5a6978366f8065b4fa6
+87ccac55f0af63fa8557bda648292ee8
+87cee6e60c2aff13ed21ac185ef4a929
+87d0afcaf2ff06435dabe43cfb1d0926
+87d8db9c12bd47776bf14872f0f73c7e
+87dbb5c1d8aac961a8e05628ebefcb1a
+87dfbf758dfb9a6191f8e46978492663
+87e1ae3d3d2ecd20c87bad3a5900c234
+87e25d632e125b1bd084709de744048f
+87e57d8502932eb0d6c9434f0110d94e
+87e62ae02742b3991775ba5723e0fdbd
+87e8625178bb4d6c32750fd8127b2c8f
+87ebd6582ced5b5667e5c19eec52fcbe
+87ed03ecb9b8a4f4d7b1d92e3cb85f3d
+87f9e0c79bc510e7b44e1533fb49b66e
+880689d1de1b2458952c4af24f37655b
+8806c7cf328fc572e38963be74e3ea20
+880c0fd0e344c7b51231be27ebed29de
+880d3e089035fca27de7934badfe4aaa
+880e9628ad07d377e052c665c7c56b4c
+880eba2f30fdbf0f5277f62709f23a51
+8810da0891d2d64aca5aeda872ce2f4b
+88155dd939bc65bbbc4c826116c0539b
+881b9669e81d55d4c8b5f4fdba6185e2
+881c413f5c7a65a5e9f74f95689bf628
+881c4dacb44c30345a714aa46f601601
+882003470f1f893b68b9a18680d8bb36
+8825dc29df68b90b40aa584fbe337bc7
+8828f062c209668797fb239ff8b47181
+882b952f24a599c88fe98dd2dd1a5970
+8830405557f66111b9e3d036e5ea6554
+88305642014bd46b3986470da85d30d4
+88319fa9c655d926bf7540eb60d95c32
+8836ef1ab01d31c060738f8b7813ceca
+883e65b36803f022b7bb1c7e70258422
+88413cd3501820cd2ffcd69bd9c14f49
+8844911451d1383740575df568233046
+88465fb210dfb8d19370095b3d49238f
+8847164d9f8ddbec0c8067f053755f81
+8849b592b8caede34a8b47670d196ce5
+884a95ede3816f1ef2e0cbf0441ab1a8
+8850b15cd17bd5cd5c3389718b590dd6
+88522bfe68c7ca3ed0048d0a18583123
+8852866a81f77d712e51cdeeb90ac031
+88542ae381e359609d2dd90f22c9832f
+885a80dab4aa63f56f5033de1b571b0b
+885d59cb3c92473a257401cd918dd9bb
+885eff2ba360ad1d76047af739cb13a6
+886127b7185e6719dc2cd63663b9ecc0
+886b0fbadbe374623d2e8f156ddc15c9
+886f47ca01dd1ae949c33dc0db68b37b
+886fb225990449a210978779eea8190d
+886fc587f5e5821396e3561e13c16844
+888122b7b2a72e83079262ba1e598ac2
+8882ccbb4a67e789ace53c8d3c754d26
+8882ea5ec89b7ed77ffdda851f7cbaa7
+8883409243c91b0b3ef658f4245171ef
+88878e5063c6c5f63c7a644a6e2f69dd
+888a47422e5b5a079b4e3e50e0fe087c
+88905520e38773b045554f74b0d3a3b5
+889439543eba60d1594f6c8ed345aef6
+889638aed40f14568f27d3b04ddf1fb5
+8898f01342a2eb77ce4851d3b16ce826
+889e5828a79b3ae48c06e9321d561c1a
+88a445d0b67b1814e2756a877dc4aaed
+88a5e62391feb4349b07e9592f8887be
+88af338a341853c75b40eb48e76f68fd
+88b2b892f9333e9a58074ff67980e23c
+88b36856a0fa650a28deea1e39f71a7f
+88b414cf95de36f624a006b0c3c503ef
+88b46cf24a7a3cd1cdbcb1029cb0c6e3
+88be702d4ffa3b0b0226d3017cfb6878
+88c7a699c9a540f6bc330398d63ce71b
+88ccf23d5ae87bb032e25020d53a498f
+88d15e718cba0db954beb39da982c69e
+88d7f32bf195921f2310e2984c2fbce3
+88d97e5a067fc25d6d113a484a6c9e22
+88ed9a579cd578af80172c15f10049da
+88eea9cf9f747f822042b4fbb928bb69
+88f38f4992960ea60b45f7b5011b54e7
+88f66e5d4b4ee8f2ada07af1aef35acb
+88f813613b42a3e201d1e6fabc651291
+88f91c874803ea18e1922d3373116b8c
+88f92b9510709860762a15d59c09d4bb
+88f953bf631ea9cd19a42da0083b051a
+88fac3d30efd15cf0b2621cc58535c1f
+88fc057e114065963ba75bb32b17cce8
+88fc9cf7bc9aec29bac7c598648ce150
+88ff118709d6803b96be6e7222cd4c54
+89044f83c6d544bf31013c77654fb2e8
+8904cddde57510aa1b92596144e98c74
+890c6ae3ef77b86025db713c45d3cb71
+890c88426449f903733265a9e61daa4b
+890ce5fe70b83634786d9bd2c35eb61e
+890d9b962e9efcf8c395a2b53665bc1a
+891270bdd8276530f2e78b7d964a1c39
+89143aabe005f474278ff736e93ea5e3
+891ea05219b8c55e7f32d0c73b28ddf6
+89224a4758e97ecd119431fc78cf3c4a
+89273a96cc0cdb10cc11e2b384f1a643
+892b53dccd474dddcc0f56e73f3b9bb4
+892f8f2dd1b23cb695d739b7e03b2bf9
+89309ec0f1e6531ff832f4358fcec008
+89324fdaa12bf9d76c4e7915fe39fd95
+8934bf0f1e082182c8db75a93532eb3e
+89358b8dfe4731902845de1433dd4800
+89359ac56f0892cfe9315ca09209b620
+8940230479a1a957693ea8980e46fae4
+89456516276cba595d7d43bc1bd1ad8f
+8945e049337dfb4f375de77c84ca9095
+89466348a1d8d9db84d08faadf1d3320
+8946eef725eea6e9dbb251835e7902d6
+89475674c1cec8d84362745dd6254f35
+89479a895d07e9fc801b45f934b95ecd
+894ce878f4a36c41880b92d5d7e2bca0
+895231c8282f4177f379bebca640265c
+8954d96c9da27703f0b4e437b3f0017d
+895649db5a2ecdea98d975f1d8d7c9e8
+89564d089bff68aeb6643777f3defe54
+8958e3398038129d27fb1e30a42973b0
+895c31f6beb3a14c6fe8e141706ae7d0
+895e567aecb864208ceca2c9fdec6b33
+8961a4f41f7b9f825b0ad9feaeb22ee4
+8964d9f18fd72bde93424a8dc4eba4ec
+89664040418e4791d3cb7984d4524228
+89667ce2925f44e9e116ca2705d40f91
+896b1f65beb853744594b1754c04b419
+896e122abc6550636354b3fe5f5a069b
+896e98ab0059d6cd5f1351498cd0dde9
+897b435a43d828ec7e4d2855d3f1fca6
+897c8acf24d0cf87cdb1af2afb5a3072
+897e551d31ab084265116c4c1e53b9ea
+8982066f06b0e98140dd23b39afbb653
+898d2967cb03dacf73293fca321aa7af
+898df540b6b561b19606b16f469907f4
+89929cf65e777782b053e3343d320b56
+899332ccfe991e9b5a4521b87d37a956
+899966f86867596b36562d55b02fb546
+89a0fdb1f8b3a5002be819a6f6acbed2
+89a603e8f4328f2f18a4c815fef49e0e
+89b13d57a72a4bd93bcb01873dfd263e
+89b6b0884065833b2957063c8d337e2b
+89b82a5ebc5d44de2bfab8782a1fc24d
+89bf345bd8a04f1a10a39c6c09cadc15
+89c27806c7a69b987fb5d469658de7f3
+89c5660783399e48904fdc87ca9ac1ae
+89c5f0b4d7587e038f6fd0b32b9a2482
+89c7357968c87c9f8683f4b3d3a1bae1
+89c8451b2ae033220320a503027eeff1
+89ca6ba30351ea74142d454dbd1119ca
+89cb127aa990f4b83341e02c92a5ebbe
+89cde0c21322884208d02a71f17333f0
+89d199215282a06ced19c0d51ffbf618
+89d2fab57ca476915e32f1a1f3810884
+89d625eee9acb4bce54980d3a7a04f70
+89da1dfc3a5b8e447b9b940f2f5a9365
+89dd2d2351ff7bbdd92226d121d8c7ca
+89dda8eef07ffd29633e7c043a4178f5
+89e27446774c4de4ee7dc50a5e842e57
+89e4cfafae505da5bfc19b2f8a0d64ba
+89edff3df70ede6919d3c3db4e523249
+89ef08d3897e162bd2e6d7168205f855
+89f1983dfaba17a2fad564a2773e3cb1
+89f4e90b4ee68090a881f04a32d4b6c1
+89f5f14ca5e52214bd284d7957c865ab
+8a0160cd26cc5c398447b1448a096040
+8a018d2297a672db2173d8e648d01f18
+8a057ca2ce5b2075e936c111f4dc9638
+8a0bdfc6406a1a3a84d62da2a7e962f1
+8a0c21a83267c397265405f1aff167fe
+8a11991893a319fe2c40ee7a18954e36
+8a1848d4a03a7df5b64ccfee0152caa9
+8a19ec97333f9f8319c46b03b1ea6f63
+8a1b558453e693b13600bf46ed99dace
+8a1c026bc010a5be14e36fb336a540d8
+8a1c052c85a3de37888ce81c5c7daf18
+8a1c179dd32739f31e09c12d751ac000
+8a261e11651154bc60630d6728fa22c3
+8a289fa00cfa390dfc2f7be2a93af629
+8a2a10b40d8715fe2a88044e9f84ca11
+8a2b8bb91236a9c6d9b444acd8af649b
+8a2f2cea60501d3777c5c616edaf5943
+8a2f3191c88bcdf6962d5be181b9d998
+8a2fe6dd445ea0c6a521a6bfd9302063
+8a39ee05b5e1429d2b8049244d49e11b
+8a3d8d8ae68efc5cad12cd28ee4c5af9
+8a3e37c501a7268cf6b2c5f61e815492
+8a41bf38597848cef0154ae05f301de7
+8a4a231f34cc02e85d1d3d786a54b678
+8a4e21498812aaad165f5dfd4e2a78be
+8a535becd8c9efcdea2220fecf376cb0
+8a56d47c2c3a9b2d470f0499baa369c2
+8a572ebabc35b161a197ea078f2adf8a
+8a5afb5d559120d90e5b84ae10dfd102
+8a61aa2925c1e0dbbc2f951d564640c7
+8a61ae4abfadac1f030aa9f768ae7893
+8a64f0584ecad5b98daba1fe66145838
+8a667d6e92d9542e4cb69cc5b5bbc9e7
+8a68dc19a258d9714415312236d81363
+8a6b253e25bb0697a4935e303075345e
+8a6b853f26451c455129673bc4e0911a
+8a73be28b66ad0937433b2ae2e846c51
+8a7440aaac7d5976b54ca776d4245c36
+8a7818951a457abeae076af4ef178709
+8a799cbd54e4c0ce81d39f31033250d6
+8a7af7b1770df68688a073da8ec7aa82
+8a863f3054d3c35d5d6dc46967b39b0d
+8a892dafc2d26fd64235093d1b228355
+8a92555883a159951da4e1e519cff22e
+8a96bb224d324fd3d99eab204be84ddf
+8a97a656afecfc0a13065edb24e1e178
+8a9d4dfa11755a8e5775393f74ad78a7
+8a9ebb91e0897950256e0fa54bc1245a
+8aa2d1d4fd9126a3e1e8cd7453e9dea3
+8aa5c7b106a968d7463865d3b9b2c336
+8aa5f6eb3dc49d9cbd966c46a0b4a54a
+8aa6f836006b2744a7f2e506457498ed
+8aa969d5028fae05cc68849138ec845f
+8aaa9ebbedf6815884b43207fa279714
+8aabd687628beaabba70bd115ae379bb
+8aafd1d3e0b0a36d574752afce381d9a
+8ab14aa3f05065085e60cca474e424e6
+8ab5cf434446562ce8b783735a2c8b1b
+8ab7f61287f73359f9d1fb226ed13d51
+8abdffc2469c1b5df727e361321c3145
+8abf67f14e1ba0656ed6737f12c03c2e
+8ac10af6dd050ee6b0322d86633f72e4
+8ac4a65b87e45dbf63144fc62a315f0d
+8ac9579360b645adcb00c7a92809ccd9
+8ac9ae4dc71aeeb9d1f6bd4b543862a2
+8acc5ec7378bfd8cb109e7b1b41de5c8
+8ad4564a1daee2641a4d66a04a604023
+8ad97d7ba8379b12b745435b849d33e5
+8addb6d816c5fbab2645af75ef42c604
+8ae3b15149b91893ea9ea170bafff816
+8ae4b36cf19b30b3029241fe90915155
+8ae57edcad71123777922674ec57ab45
+8ae698bc0e6e27fdc35ca6304c7add83
+8ae99a8183fbc23029476eb77dfde306
+8af235481608387e49ead9488dd3a695
+8af4dfed145ef20d7ea6f0a9056fdd8f
+8afa4e0b2ea23e1956a15be594204125
+8afb37aab6ea2d898619093707c2c912
+8afd19891a1aa4e10d0873548a9943c5
+8b0ea861ec8aa0443dd3f5ca40753c5f
+8b233f4a0d77ab5dc6da0d38a543c02b
+8b33703b9b4144cf814f3ece4de14f47
+8b3b7052cd530dee03f1133c5871453f
+8b418059afa7b2bdcc560aef94d7b199
+8b41f556daf93d810c884da29b0c0afc
+8b433f760acaa0fb04611f4c812c2953
+8b4629ba761940bfa1a9cb17e415a03c
+8b47f79ffd278517558cc4c037559193
+8b483b47c9d08cec5c1ce1413fe58f2b
+8b4a0533b673290fbb8d7b0b0fd8c85d
+8b4cce257592e3642c7b870aa73193ee
+8b52c4d0ec972b72048acafee5994c3e
+8b59a6638e98e9c3b638f7483941212c
+8b5c870399c4d683819f675382d2296f
+8b5caac1fc15573ea354aa5db05e09db
+8b5d1a997da00ca395d7be81ba021886
+8b5ed3dc115ccb7dab209e24edb9ae3c
+8b635abfb386c6efd9053fda9037525c
+8b64ab727581942bb7caa209bb2c5e0d
+8b6969880d14eb3bcbb266fa88ddd26f
+8b7027b606d7f140b427dbbd38f7a2a9
+8b7bbb4414afe313c84749bec55017ee
+8b7cc8af0cd71319bec1e25eee1ce114
+8b801427d14ef0b1e7c289eeee4e0567
+8b862dc598c7b3f4f1cc110760189cb6
+8b8a865a84ab9507fd7c25c0fe87324b
+8b8ab4aae35f4da2bbd84ef616509efc
+8b8b6b0632068c153f6d490865d90dfe
+8b8be6c831b165d0affa0783c36b06b3
+8b94ecb0a9965908f785dd968f489a82
+8b95a036ac6577336f69b0a1c4f33ef8
+8bac64659fa918bf14edb0007f501229
+8baee2f82e6e7e1c2debee214f3a27f2
+8bb27be0429be86bfa61a98dedac95c1
+8bb5244f5f0f8e7300bc2cdff21b0664
+8bb5b588da6c0dba3cecd7f1db492f1c
+8bb63cb33e7c47ed9f2b4cee709c1b2f
+8bb965578277c895a15b6be96886fcbe
+8bbc024a1b59881eb0850ba6ac54aed6
+8bbcadfb79be01a36badb667e5795df7
+8bc6dff2ee45be0ee9d25a3608d37f9f
+8bc873396bffc3119cdd5c3118adbbb7
+8bd2f4bc3cdfae147288fc62fd79e326
+8bd4546cb622ffa2d0ee2c89944817c0
+8bdaded1230876f788aa9634f1538830
+8bdc23cfa1e06cb6a625bf8a12f53931
+8be606a833649276df5c7db55a8ab36e
+8be964e0aba26d47f049ccbf6c3d3cc2
+8beb6e2c52cd946a3fa7512d7251b3da
+8bf05546826a31bfc5b787afb714e926
+8c0358c59498b15e3d55f13b086c8ca5
+8c0696053a40112ff61b20be5efcd8d6
+8c07011c105c96187a9fb9005fd2e96b
+8c0b933e62ee0781777697c17c0d2053
+8c12bd5b3bb8708f27aaab1a006b15c7
+8c1824946aac4a85c3d5a37a6d26953b
+8c259fa36c9f53ed55ae82a65a66ac11
+8c2d4ec65e5c72a25aae2f00d5e46b84
+8c2dfa7d855f61618ebc4e3e4d61333b
+8c2ea48a155bdea73fb2e4c40c7a6d94
+8c355b187218d356c1abdca8c5f422c4
+8c3b9059cbf9644ad8a72f360146300e
+8c3fdd225f12364e94b0ddd245f24dcf
+8c4c7c3de220c8a771d0421d583202a1
+8c52e3950463af2503f20e1d72532d6d
+8c5943d95dc7fbcf7ed7ebb403e447f7
+8c64515a8f2e858653d974e4b351ceb0
+8c6477653bd0adb513d3c345671c80ea
+8c67ee9cdd5596da5789230f8d197c25
+8c6abde21bd20320c36a80c31149a0e8
+8c6ee2d3940dfbc38cd191a8884dcefc
+8c7780ff7e5aad97f93433cf96044059
+8c78cf2ef0e6932049ec9a7845692f9a
+8c78d889fe496cf530e926bf382ea990
+8c7aea267c12643cd7d3ac9d09fa70c6
+8c7b147d5836d6594350effe134245a3
+8c7c34995c4df6ce090d449b8d883a31
+8c7f91edc63e23016d8074b0fa6dd16f
+8c813755ad8612a0343d88d26a2e7528
+8c82a84fe17e48dc021fae28b6c21cb9
+8c87ff6eb943e4723a9e80a28e40d3f0
+8c911b33fd0e7353c50a243d217a4220
+8c93954715236f748a3c4046f5d683c4
+8c97e81724ce91debce866cbdf92edd4
+8c9c2744a3617c558af1db20df4d59d7
+8cab6ecdbd3b5843b112b0837b991a57
+8cae910c1c5fb2a8ddaf2e4da0c10f08
+8cb33f31192cdd3fde9aa9a6a97bb930
+8cb3ada88b206df46a101e3d00e53c54
+8cb64fc7168f637bc313c3bef3fa96e6
+8cbdfc05d921f2b83fee125df0630cb1
+8cbe028ff23442522e32bb4c0258e81e
+8cbe1dcfb1778f1cd9af93249fdd734b
+8cc488605e7dd17b98941416d78ebb51
+8cc880a20c3f1c1f0d87cda10cf1199d
+8cce4b6e0b7ef9cdedac88bc8f15c70e
+8cd4a926ff21a7b845c5a46070d343b2
+8cdb78ba7c1578e72c7b7d9391df4813
+8cdceb79e12e7d27071aaaa989889996
+8ce0a1ee58ba3be9d93a9b49035e74e4
+8ce1a0d2100d307812bf390e53c372de
+8cebc5e028aac0e507e133da8ae83e1f
+8ced2a25962ed0e842df4c55873f35ae
+8cf021cfe7ceca3f054004eb273f43eb
+8cf0fadf140baf991d11eebe78a55ae6
+8cf219c6c2c5e261c9b2a06512cbd3f7
+8cf62f9876be9bd1151f1863b3a57758
+8cfb4996fef7b5e081589b3f19f649ea
+8d041caf4dad972a1e3bff481e65e968
+8d044bea68932472655a623ea1a606c5
+8d0609533abb0b68fac7f4bffaefadc1
+8d09dce4cd60516615ffe7233e368164
+8d0f2dc4e6cd3e2031d7bcdf312acfc6
+8d1fcfaac59395212f322bd790b1f429
+8d208ea370b796a08515b90e1d8333ba
+8d242eaee558592397ba1d577723b1a3
+8d2b1304e979aee0a292faf9a8579ee0
+8d3153a1663840647ed50e821353cd53
+8d33ba755807d49ed0bae51a91ba3fbc
+8d3583e948e2ac463725f1287264124e
+8d3609c232f621da53a7121d5ceae424
+8d37e821d2df6589b88ad04fc53bf6ea
+8d3dcdfc13295d7c8d24f029979f324b
+8d475b590ab51ac4f1fb7a7cb5475c8e
+8d4bad225c98b4d19f03c23f13b40aa9
+8d4f211261111265d91291558146b1b3
+8d4fe5f378fabad0dc458cf844d18178
+8d567c13a05e682ce74e7162f6e16e2c
+8d5cd25d6dd0c81ef89f8c590371eeb3
+8d5d62e989a955bc510b5a844f6f7230
+8d5dba1ac484bee0012e72ecee7ceb99
+8d5ed8b719e33d95ecbe15a299268c7d
+8d61ee1350f473cd2c6232c5caf619da
+8d6b516f104588e8898fc40964b33501
+8d6b7100b78085754dfc0d330b235993
+8d72f5883c7d47f6947f7fc6c37b9ba4
+8d78e52033da94cc0b335aa01186a4b7
+8d7c4ad83d47386360971a7bed959cb1
+8d7d837da0dd5bca172a6e04946ce705
+8d890151cecafc2cad37181dea22212f
+8d89d9a7a69435b7e07b1d7af3619e79
+8d8a1cd6a65a737a40e60a77bbe00737
+8d8a48446aa1d74296aa07fbb0c7fd4b
+8d99109cc6f0940841b8850331b716af
+8da870b1d850914c18847e2a57e5b519
+8daf49dcd2be2f1798d036757d256bd2
+8db54250cb1bc9f024435889ab582a71
+8db55b67c0fc79a82bd3e53756559c89
+8db7b76f63867a6469ae791b9f366788
+8dbec8287723f891c3d548faf7c75a6e
+8dc1388173deb626ac65e89f8a18e0fb
+8dc2bd536230dbe0d6352d1c0e2c0958
+8dc3fa60a38cbcfebacc41885a78865a
+8dc8eaa2a95bd562d6ae0d4c45c46b40
+8dccecb83c2b354c8ad75abd36393aa9
+8dcec7f91d7414d40472b759f9f65407
+8ddfdea4545adbc47aab93f1cd1036ed
+8de19b2071b4336f1c89ffb1a610e518
+8de7dcd887225964a1c1057835fe60f8
+8de9a01ba286e96406b2385e2d362054
+8de9c7d78652148a3bd1dfc6361ed8c3
+8df7835d9ab748416280451f45511fd8
+8dfe24c1886ea3fd985b4a9dc347acb7
+8e00b586267fb4b08e0b1a22c0927c4c
+8e04f31b976565043ce74361b597fc03
+8e07e76e7c0be71dcb6e08e8efe6c0d5
+8e0e8629e4b85cdea88da485c0862a38
+8e11a831d45a83104f5898a6bbee1c12
+8e15e9c7bf8eeb71bafe349ab94b3e6a
+8e1c596c88f9df3de33487bda03bd8f9
+8e1da1a3bb697d92433bff919456594c
+8e1e32ed1b27e05e2cc2e1f83b5bfabd
+8e1fc6743830e75039556aa30b81e849
+8e24443c0cc133e136d87a96199f8e31
+8e2d3e579ddc4f0fd7c5e06a44544388
+8e2df3499fa05ce52753650d2c04ad95
+8e2e90222bd202b54a04d18c74e5be46
+8e30d103bbd45f2cb961d86803d3d718
+8e31d6658ed3f4330f545236a8e32734
+8e3aa245acabaf2fe0591d17b3b78fc8
+8e3fdb154f099c8e5b20e0117ed65346
+8e42379da0124be2742febd38433a3ed
+8e473263a9b74e8c84da86443454ad14
+8e4915f7ef5666a4e42cb34c9738da60
+8e515015595f4fda24f541bfd93fd816
+8e52e5329ef1a0359fa2869a0b41287a
+8e5b7689804defb624a05ed62312f2a6
+8e5c2212da7960a0280a7f7f89f16c03
+8e5ca0ae8b56a36b977e8d41abc99579
+8e6028f72569eff2dbb92fd62a10c4eb
+8e6824c01d170a0f6896d5fe1302a9cd
+8e6bf7e819cc60f6b55231d2ebdf7d41
+8e8a05f05f7df9df6bf4114cfcc86eac
+8e8ae389ee65ad3e610be0b1c764064c
+8e8c831a4deaae5323e6a708d212547b
+8e8e888bcfce691e554157a14b69e95e
+8e9ad87b3e5bddb20d03283c47b7f016
+8e9dd5d70386370b323b2f3a7ae77f08
+8ea30cbfbb0982cc1c4826eb9897c541
+8ea3d7813e21c03aa861c07178835c55
+8ea6336aee6dbd25e0eec48c86b1bbd0
+8ea70044976072f057a4f9366ab37f2e
+8eadca9660c0d8c28494dc138bb19177
+8eaf6852c44fbee4d5686bc31bdf03ef
+8eb466259e0bb022df0cdfc93a62d72f
+8eba7cf00ddd5d7f4fe521815c257320
+8ec32ea72a76b68fc7db9800a8f17e30
+8ec3f7806715044e5e07b288721bc2a1
+8ecaaadafaa4f8f0f173cbde92a27b6a
+8ecf56191c0548bbd5c0956efe526081
+8ed072d33439a06fc8feb53c21069595
+8ed7582a71f5e017c6f8a52ade39db8b
+8ed8d462a869723ba32c791fee77f612
+8eda4f1ff0eade046cff1e8721972888
+8eda5af05f34693b5421d4d9871f82b9
+8edbaf58eb37b0cc81e96d6b9d1face8
+8ede2e92a7aebb469b7df500713c7d6a
+8edeb6d11f406d5c2fa9d7b65ad1e4de
+8eeb0a6b0f0ab01eb3ca0f4cd1fa7303
+8eeb5a76d7234fd543e48010a5415742
+8eef3bf21fee20be02163b7cf7041b41
+8ef567913c918591a18f8a9758225197
+8efdbed41be5e34b564d7f7330f94e06
+8f010afc6ce27f997c483303134d780b
+8f06e96bea3cef4a8ed5efc694594681
+8f0a569574a64a6430c21825ee741ad8
+8f12acfc09e45c48cc9c7945e32a10bf
+8f1cc6206fbb4b6bb2c840e9cd36101f
+8f21ccf33342422550123741773742c7
+8f253aa1e98173c7cf091b1bcfdbe5ee
+8f290db0f882b04989047693b33b09e0
+8f3783b747e1399a858a18541226461a
+8f37b3171da9e29842183ff086e92c2a
+8f3ec3587752efd663fa30d9643cde71
+8f4913596356008a2aef90dbed8a9cab
+8f49c7ab0568c1c323378803a250886c
+8f50ee4c49d2114500edc6df0971ae79
+8f67b3bd87f65965872240fa684c617d
+8f67d1694bb89280d1302f17dc6b9e4c
+8f6845b06b76d37e4e0859e06e780e29
+8f6c2cb48bce2a0cfa9dd85530282c59
+8f6e36bc22ffee9347d27b63e25f972a
+8f7069841ac5af6fe46f82370da2b067
+8f7247346dbbe5c64f2b89ba4f01ea6a
+8f770d14fda54dd5bb0b88151b976017
+8f798ac2cb1fb634ce9724fe0d6b83b4
+8f7d721d7bf0e3d170cb7ba8604b774f
+8f83a53d333ffbd203ce134a32c63aa3
+8f8a2706708d7b978434bd1b6bae54ec
+8f8ae3ffa10b3de30741ab8209b8a70d
+8f8cda8e252dc360c6f3eb24fab8f72e
+8f8f7e89e1a28ba32d4a109088248a15
+8f9c9e2b3f1e4481a96bfb74e894bc61
+8f9d70fcdfd052d2d87ea88471f1b6aa
+8fa47d1a79072e7cbd40fe1f37a0cf49
+8fa66e66b9e5742fd2a85ee9609fcc44
+8fa79e45c02e289d3cb907ddabb363f1
+8fb56baf14013de5c230e1fd9e8e9711
+8fc076e4425f30c9b0736208fe8b0dc7
+8fc74ca90d5d6c1808534f1aa0e84f26
+8fc8decbacf64638d74c8f74a5d2bfb9
+8fdc0a1080b363a8799335215075f63e
+8fe19a77439aa79d03f6df0137b7c981
+8fe6f718cc488237f9634b8f759e3a3e
+8fe7ebccf14502220be74377b692bdd2
+8ff43001bfa0790801809f3380cbc6b2
+8ff95c0fecb08048a4f11903d821486b
+900274df47d4e505dca881754bb5d5aa
+9006e07b4d3ad1e97f3f5eb1fd48851a
+900e3b13fafa6500b12b88703a1f0c23
+90139936cbd39d94b6b2416d9611f4c1
+9016a2c72b46351ab733a9084ac92a30
+901777048ec9464dae0f41bfc195faf2
+90189010c22cb6b6983f7c8c09a90d2f
+901e7d74b4fe4c3721da4b15c7d8de01
+901fa22595e69be00eba9386b92458f1
+9020b39d7fac5f3ac7e10f6f7adb3943
+90219ac9602e20227f734c9f78311023
+90245a412ce28da43027c69af071d46d
+902ef7ed3653fe5d590dc52082e42c23
+9034f3515ddb27dc0b7910614160ef1c
+9037e21a3750fab30a3654e17a1e84de
+9038f9d79febdbe36d0b532cd79d9427
+9039ddabf57192b719688867654fea29
+903a2079b53668b0c5ddb66c7a8e5114
+903c7804573c821da6cf7ca754d2062e
+9042e1a2c33d1e6b569e9e4bd63501f3
+904445861e305194ab7ec532bb5a5da7
+9044547c93bcf483b3913d148650ae5a
+9047da6f77f7c3004a4b2f96aa1b0b43
+9049757eb53543d528be2f5b26da9c18
+904f826fb200ca0a540764a0ec741dde
+905b9c778b2f955fa49a85eb8adf830c
+905fff028c0a0bc315adf0e783da871a
+9062113f2a3d990b82121f48e8c9a391
+906330a303b977258a40032bbfa38a4e
+9063f2370c14c154cfca9234885c4a69
+907d228225cc0ffcf57942b0e308ca2d
+908064bb3af304fc9ab0a38d8f2a6adf
+90849b8af9972c20995ec8264845052e
+9088f9cb7c1abd4e3dcbe3e97f780e61
+908d52a24a4c95926eafea098d6fb559
+90969bdbad7d09361557a70462b5b2f2
+90978aa5b82e0b4bce17109e614dbc41
+9097effde3a1e4f835eb4fc75aad65e5
+909af4d61c5d988d14b3b96727f72d51
+909bd2c856915de4c1432f06095ad347
+90a43d930b93befe7693d0b3fece10aa
+90a952ca43e04f7e289ddc5b62115961
+90abd81df9f214bf39d6ad08b26e31f6
+90b3505c4a0b05e9c0886a28e1705d99
+90b4e40d14fe3f7ae4113389b4418481
+90b55a37fb405e9d27fed9e286bed9c2
+90b58ff83ab87efee0cb73f62ad75314
+90c487fef2c007e430ffd88099321613
+90c93067c632d8e8735a332bce14702b
+90cc0edfbc8632ab7af06128f160c33c
+90cd00a685fc54fc3acdd4c244c53d4e
+90ce407d28d5705a3eb35974eb542e24
+90cfaab6b35ea4c580fa0f4fcd9ac221
+90d85be82eb4abff58b5b9aace28daaa
+90d89de66e0cf44ec34c61db369b45b7
+90da5195818a765b3bc2d3c483938a92
+90dc05b61e06ca2f4a447a85b780a3b7
+90e3a63f91eb2a29d89410b2aafeb1a8
+90ea59e39966e49d6f7839f34b6dd660
+90f1874de26e9ae12f99679837d372ec
+90f216f22ce6c731dd9143ffbfd483fd
+90f2441259d0881a58f7bf896f086913
+90f896c32f442a2061e65c4ae9213055
+90fbdded3176e4471bd124a7928404bc
+910874ca9b6b932bcbadee4c91a1ec55
+9108dc0c2da0eeca73cba59e0566f418
+9112d1d05f05d75fb23d799b36316f71
+9113ef531293a7ba9110d6d9a2e2509d
+9115c46bb98720c98d1f8c8f853415b3
+9132b0fd15ef5233a651f928984f1697
+9136d8b1e9e69cdba1aab4ad818a5fe6
+91380d74e1da667902c77284a62dec28
+913a89fbec23003dad940caf52c349c9
+913d5903a9fae8fb1b56e68c700611f5
+913e1d76d0ab3514b70d70e801cc4388
+914bb39e9abf7d4d9da9669a47272c63
+9159d7e66dde47386f0a0b6e1357ee50
+915d6c3439a0ba60800c6dae4797113d
+9168f5252be58d05fb0529dc58cbbb27
+916e9a0e9aab0ad38c240c7a75418373
+917115dc40cc3dacb72abf2952129861
+9175f323276fb6275836aeca4b228777
+9183c2674f84d031640fcda087b89dc6
+918876434598e5002f2b051d5a5e63a2
+918a81f2455b4e5028d40337faca74dd
+918bc9c5ca408c47df5b2f83343d678e
+91946678096d57036b68ae27060642af
+91961398c6a1e1da8d27e1a272727e88
+919afd9ef35155bd013ca0c0b214747a
+91a2e44a8f6db641ae68e5a4d00e8259
+91a557310da4289e0027bfec1aaa427e
+91a79288dc973ee6f803779b721bbea0
+91ac4f6677563da4acbf06935637ddf1
+91b4fe75569911ae520237bbeb2eabfd
+91b82fa02109806f5181ded7d41b3b6c
+91c81b996dd382db282c1fa59e9751e7
+91c95ff4b8d5f9e711a71e3cd597b467
+91c9ca3fd9f7f7d618d65ac2cab0d96d
+91ca4d098420743a07d6579fa3daaab3
+91d3b782599a36bfea56c85f419ecb5b
+91d552ec6072c9e548543478664d8dda
+91dcc2ee059fc3bfc6144de24ba6768a
+91dda87e90ecaba02eca3b50fc42126d
+91e80267b96e6bfd55eeb63fb1e68adf
+91ed606b64e88e41a15fdf317f7d6187
+91f08ad481ab7aa7c85ab7fef7ad6a6b
+91f19c02e08cfad6e36810e60d132367
+91f3bc7d3701e633ed343cca7ee423a6
+91f496a941a7c76f307da0ee26856317
+91f7d79c85db6be2d66ab595d0a1a845
+91f9f2eda30cf79a3e677d9a1215f5cd
+91fa5634c761846a94136ed32860845d
+91fc26b3bbdf5b9579a37513003a22fd
+91ff0ec55f1100fd30638fd71b93552a
+9203d41c547f00c21e950c68161ef9a8
+9204a4beba7878ba0f4d0d74c82547a1
+9209ad7f53c39aba9cfed276bc480b27
+920ec0d328ed3874cf6f61b882cafbaa
+921a12e1bf6579399ea1feeb5966d5b8
+921ab370a90b2357605bae838ae54919
+921b95f850196df41b240905618df4c7
+922feed288785b0fefa3405f67f4a613
+9234d943e1d83c0bd638696f62a3de64
+9236bbba829b2d069f7148fef9abc264
+923737699969e6f9435b15d5ee4a95dc
+92388653361918222a0aa0da1c33fc08
+9240768733b4fdb8833fba4a5724dec3
+92440c86f9ac2a081800e3babe1e163b
+92448866a30a0ceec7c1efd907d326fb
+92462c46c5e3c3d8ef2a033c6a657527
+9248f5db79e8a67c90ca0ad4ade91799
+924bdabc2ebf48a51ec8a89224e90fa7
+924c7c31e33b0bae559ec5091d991a67
+92558c8a8d6beed0cc835a688e092e4d
+92566a71f5f86ff71bf15ec6ced0ccc6
+925e25f2ad8a3f866fcbe2b9d5ec4972
+925f714b59f80360c2216e351bbe201c
+9265756b9834fd66baa76c5f52610795
+926bc9540f5de489278f2122b376842c
+926df9edd92cbfff4acef79ce71ee222
+926ec7c3df28d92daccf5fa47d72bcac
+926fd7fdef736921e92e12f1097bd575
+927354d63e839b46893ec8d4c74a6055
+927408ccada9cfb21488048a991adb97
+92764213fb123a13c3a1d663ec8e94b5
+927646f37d12520a2740974ad5398667
+9279771e81aa5e215f35c796075fe99a
+928040daaa04d8777a57c5f81da3cbed
+9283f06c7596a332cc416af5f35c1143
+9286a5479b522aea3dffb20f55302ed1
+928ddd4e23c1772507b34ecc88408909
+92947fa4e9e659472208100887d86427
+92969c92ec38bdedd7dd31c85826d268
+92990a24ffae160918b1b42415f9f663
+929a8573f9f69c172fb3cbdb1931e5b6
+929eb260791837b6c64c12a7eed6abd1
+929efcb17b11cbd0599b347b5c8fd4a7
+92a052b67e5e0cd940829bd551b098f8
+92a856ba24eece8d37ff32eb62b31be0
+92b64b9960af990a09b348cf1890f9d5
+92b70ad63af2151b6476b4379f9775df
+92bd5eba2fc0cc9731d8377204034d74
+92bed906e3519b0ab29e537c18592479
+92bee067a187e9003a169f0ca6768e89
+92c20a2dc5fa66339f34d28a84c80fab
+92ca5c3f1e95634ba0e7d057d8177a11
+92cc1c96d19bacaac8754d7027190536
+92cc81ea83bb641c6039e44359bb46a8
+92ce22d54dacbfbf249df37d3ada007f
+92d33bf6d5b58d26adaa100f4a6fa0a1
+92d85c8419e344a168760550bb84ffdf
+92d9fce4b13ce861dd7ad4706ec6b878
+92db1ce2b982fe1bd04894fa92923ae3
+92e0b55c049f423c27a2d2a6c3dc3006
+92e0db778c9ba7d5f7355e62949b0859
+92e8348bf1955ab2affbe4873cd19723
+930e1a7bdb1b4f181311db2ffea21ae3
+931240d009b84da67fa1ee7e551dc271
+9315f0648f29ddbaba4f62aa793448b9
+931ba5a196963513516e390ddff68166
+931c0a852a0d953a89fa76cb69a9e65f
+93241cbb9a583e8e8c8de670e0c257ea
+93266bd72751b4f542217c8453f00f5a
+932cf249f0b7fc30b4e6e293f3ad4331
+932facc0273581febe60292ea07e6cba
+9334f8031d855343b2fec476c0ed7c45
+933906559f6c2d466ba71f53eac099a7
+9345ea7ed31bb22b264ecae9a0ba5c0d
+934776c941c5dbe294eb21e5746951e1
+93571f86d3eb0a5d1ec22fb525c645d7
+935db2eb3b1d51a040fadcc788702fa2
+9360e210e7f6d8c4ffc3e4e8008f3dbf
+9360f5a2f60feeb4edef047a8753c599
+9361567ba48d4da25caf0859efddf48d
+9363f3a7a91d8fd21918125343afc332
+936e013b89a70078a80ddafbff8ec029
+936f1baa4e4fc9bca398fc6fc5b91490
+9371974c333accb09fa466017847e201
+93727b5271da8e236eb12e947faa8298
+937357301142d440caca96bb9d700c3a
+9377b4da61033a14ef84576279bb783f
+9377c2f69e9b6f793e03499392301fa4
+937bd72f99ecf41bd8725369db7ea36b
+93893788bb959d3a959f60440a8b5930
+938f6fac0e28907620e588e59639dbf1
+9390e0932c478f9aee409fdd48b91159
+939b484223fd16d444a3279b41292e90
+939c550b4ce776fb50e4a5ca69c6cb97
+939f2e9d93cf60c9055e7d295baaed06
+93a0c9093f097fc53c4179dd01cde90a
+93a8860bad9f442ebe8f32db068db6f1
+93af1ea89ba5530ffe57c399a54fb811
+93b0f66d51601ff783dd2639b9471e39
+93b266a74e0f7c876d7a674236721550
+93b2bcd61c9a9dad1aad0b358045c2b5
+93bd9d6ed3eb8ec532c03a30df3a5ded
+93be78ede6240b20d81b76148d12e1a5
+93c6a43bf364d236e9c5c6064db21b2c
+93cd15ea1cdbcd1e19137a6c14926368
+93d12dc41f485434426942eec7699c8a
+93d24049cde6d1c822e6ea823ecc7722
+93d5c2f73f3f09d2386966c547d9b702
+93d83aace85e574c50acd45f4b8d53bb
+93df4c0ff19d24f641053df578c5e553
+93df8e02f13353740eea882e0cfcfd84
+93e216d9c5b5aba1ae1fbefc98e77227
+93e443c47a5ac9fdb8923ff179343b29
+93e48654708960e25631eb3fed231d04
+93e9b75ad50462a4dce621271b03e5d6
+93f1d6f9bee5e8462fafd7b6a29ee149
+93f37167eefb615c9774a3d2e68e1e6b
+93f4517704a286507646bb6dd5043b2b
+93f475927714445f199a200e34458c3f
+93f4ccf92f05aa86365bbf33e4c6740b
+93f59f428114c83012185a1eee9be70a
+93f722ba149f123f93fa7b632b04a20e
+93fb852a3ec8ecc1ebd5ea0c7692b225
+9400618bc3df790bdb4fa11c6e570634
+94014a826be5662f5bd094fddab035e1
+9403f378ec5aea1cbf44b4e4bbad8c4a
+94075987f8db123edc17bdba27904805
+940adeb70caebcbe5c73bd0450ca86a1
+941dffad0588c4b292fe17b3c3fb7893
+942ab2b6e6016ecc1ae90215304d09a2
+942d688ab776281cbe1d9ee4ff77699f
+942e0057fc84d2ce34873407596fcc24
+942e459ae28f91e703979d1e11e1022c
+942ff960cd5950d8a297ac8abe3e9811
+94313e083cef8a45eb1570fe01f4197d
+9434e6f004570c73c1bd34e89d71e6d5
+9437d0b3eec4d150d987c8810c37b079
+94393b12529aa3921d8d466c2ea8b062
+943d82c81185239d756d98bc64d33ab0
+943dde72b5afbebef1494c23fcb54a01
+944060319841cdc449f93e376a160ac3
+9442a8bb48d6b66cee00bf7a5b1a1599
+9443487f24f43a532685f480d9f5924b
+944f9b0a14f27e361aa1189467400d4f
+944fe398346134774ae7095d8237e3a6
+94563fa32bbf3e04677c78f71682f8d7
+945676fa148668daf4d7676a4c0b7eea
+945a1b974238b4b2710c53344e80a399
+945c7cf7ed6b9972f011634d5b05da65
+946105a2b83870897915c7e5bb2420c7
+94680ee1adec2063dedda657d098db94
+946c54f7cef97b0f61600571e5c2383f
+94746e5097cbbe340de7d48e146fcb7b
+94773eb1ff628584ddc241aa195106ce
+9477bdc5e8f6ac36adba056e1ae2affd
+9479f97165cf87eee2a6ec50a24a0200
+947ff2ab617be63c08f00c77eef488a6
+948b71a10028f539e29d60dd45d37d43
+9495a944f7cce258c09b1ceba9d980aa
+9495ea31975a5a8f03ce9cae1866b8a5
+949da6c4c6c896c3a7692c2afed505f4
+949e1cab9625367b8c1a30b5995defbc
+949e5ba84dc8acf97ee6271b630ca5d7
+94ab78f0626943fb47b0701a1282f29f
+94b264ffe8a9048706b167217228f190
+94b2a347e17a744824fa165f60d19ba0
+94b4b7a2f25852649b73e34322259679
+94b6ead678277ed64e6bb3f67cbba2ab
+94be132f4484f24dbef167a3a206ef0e
+94bea96f3fd5235307b6cb9c8e57552b
+94c100c6b5866e42de374a3285491d3b
+94c24fa17e31040cfd7f7acd42d35f2e
+94c7603257d0c004c559f1dd5f336ef8
+94c7ad7262786fa4904a8b068d556a68
+94d4441fd25a121df00be95260bf3c37
+94d45147b6c2e18842a2410af79adec1
+94d505de8bd81108ec78d5f1776dac6f
+94d6b63d66d5426e8a53807975f5dfeb
+94d8c5a640f61bf427c756f70bf3dc3f
+94daf44ffbb463be0cd16e683a0a1da5
+94dddd80a3ea688cb44d7dcc42c40dde
+94de6dd8c01c3e04f4bad25a160aaa48
+94df8d9e8d5c48662c6fccf72c2db5ce
+94e22cd21ee6e3d00de342b9fe3d3664
+94ea25775c150372ffeeee8e123f3514
+94f1ec892671db18137d6b88ad065ee8
+94f56a15311c43d3bb2a739bf1c23858
+94f958ea32b643757e13d64f0ec91c55
+94fbff43b3223c2f3d73190c36046017
+94fe53bf2313ad8130d05e1a727a7ee6
+94ff062d68daa28832d806520bb1f44d
+9503f6dadba2b360d8f8d57d4c5caad8
+95048037ed45508470ecf6eab23c5f6b
+950e52a5cb3812ffbc5a0ec7b355d52d
+951706454f0e65d189865e67c5a77b06
+951b2962dc4d8fe0f7cf7de103252ded
+9524b7040c121289f60b645fe5287dfa
+9536db8e9964e1c4b876f593b1e3e7c2
+9536e36db830f81e1ea782693685c00f
+9537eec49f9db9908f2352a0c6311982
+953b831b06422abe96859fbf55c6c3a1
+954184e454a2a6f00af4942be79f1e37
+9547b712351a4f7b3434e3d10f85478b
+95517bac9905743f6562841a7cbe610f
+9557a40d962f06ddbfccb4e716670534
+955d4fdffee53e7481f22234bbcf612b
+955e447882e800e34a1fe42d9fa05669
+955ee7b607d73a439f85b2e8570b941a
+95618abee5ed2560a176b86c831e288e
+956204b9d79593ac96a6ea0537d66b43
+956530908dc64e040710c4b15ab479d2
+9568a882d43cbf6087a821e97e512f0a
+9568f556a1a5cd388c019a37891c6215
+956c205bd60918942974ce977b628bea
+956cc29895abe7b4cbd652e4ef9dee2a
+95709416186b211e59643efe69678a55
+95726306daad5705522ff2da89a2d5d6
+9572d6d669df79bf32aff0af4bca8f6d
+957c4a5ca50886aab9f63fd2a89d7a78
+957f4d2e2ea05f6fd6752087e38d6e63
+957fb41fd83989fc566367acb3c6aff1
+9584d88b6a7351c209474463b22c67fd
+95931f7707ba535ee7ad380c74913fb2
+959a1acbde11ed25a3b5009e3c4c2e43
+959deb22525f32f72882ef46d48f1364
+95a14fbe774ed423e7ced17638412500
+95a8c0afe13c4a5ff30cd9392eabe391
+95a8c4e1ae8115cfd5498c24661ea57a
+95b3e927e8dbf51cad1a046227b2aab6
+95b8f1409bca511c85df2e1955401c0c
+95be85b4bf59b5d2be452e9a0e45ce33
+95bf4621fd05089c985f25a839cc2d4f
+95c01fa830be857714193e4423de3abd
+95c251b92a448929550c9ce60ffd10ca
+95c43ad21780e807708797819403508b
+95c9e9a582fedbcc84c66d7a5a31c493
+95d134677d40874142d2d4e8f9607933
+95d2a6eed9de3c2b3c21818873b336cb
+95d9b3a85c62990da03e29da0f49cef3
+95e274201101f216e8bd92e62c77f6c1
+95e349af5f1d42016da0eaabc869f2a1
+95e93253a619126cced4cbab5a69e33f
+95e9efcba1cf43a5a8e904189f1ca84e
+95eb06bc411c527628cef89509d068d7
+95f5b72a4331a3051fac26c90d96f320
+95f9eeb1d2a52337167593a25983bb15
+95ff6ca0dfed9b7fdce343f18a7c7c51
+96081fc904881e9197c5fbefbed14d6b
+960b423bc75c01b30d877e98afa68486
+960cfcf08e3f707e06dc7c728dc44ace
+96114a6cc60f368aa63d79b41e6cb6b0
+9612a55bb3d270edb3ff48779f1b8dbe
+9615303944217bdff0df04413d485d8d
+961b60acd2709d82ab7d52915ba23659
+961edaae432aee6cf9e3c4a0f80304f6
+96250b25580981468376f5c7fe043dc1
+962edd266a94eb557041fbf8c5d30c0d
+9631f57788b210d50bd95278112e8fe6
+963359d4ba6890bc075dd8b5709dbe42
+963866bc2d0dfba40d0c5f8de251307b
+96399e179c628c4a0b871707ad42b550
+9639cadc98735d4484ebc753e1c70052
+963a32fbb93d2ce5da6eeaf87f17c881
+9640daa6500892fbd666dbb246317b39
+964329b46929f3630fa52d2a17faeabc
+965c9e390f0f05648efb5cb1d0549b1e
+965db93df2f1a54f9692fe1fb16ac075
+965e22b99ee6610e70d17fbd3192be9d
+9668abae0d9ea7282c7c41cae35cf973
+966bc855fb3c62d10dfae9134be8cf90
+96707493f2379580a8dce9b55fa92ab2
+96721de9a2ec101cbf50a79c1ef1dfc8
+9673aa33d6d2ca4e67ad77304ceeda4f
+9677b6ad6164e0a3a6dcad90ab9c7c94
+967832406b104cea8fdda445950980a0
+967b01a89ccaf0e7170c35d24980e158
+967e69b63c886d7634754cef39911513
+967f9bba25b593cc14faef9ec3ee083a
+96824a20e5fe8727d18b3df47fcf6e6e
+9687d8567e6c5e90f2395f001f9378ba
+968923ac315a91ff8bef4af03e87b2ba
+968b3f04bb9658d8e2ab1455d5440aa3
+968bcb427771195307da425582bfad0f
+96933e2083f795d973fbbc521445b003
+96947baffc7b44c437dc8ad1b204f239
+969614fac19521f70d44fecd4422f513
+969ff44228aca4326420b47ed1cd7b1b
+96a03a6fe10840ecc6765ab3f62bb825
+96a47ca681fe7f7748dfde0468496638
+96ab52aeae0cb530858a185c33c894fc
+96ad4c0f8e15adfc5615c9ac9fa418f1
+96b166310f26ad17a6aa7c106711feb1
+96b438bc0cf9c192b59da764d47658e9
+96bc7f1618f99e33f564dad29e2059c6
+96c1fdbbaddabcfcd7164faa9e096317
+96c5aca4068eb1ee05b0972f2476077d
+96d4ab835c5008dfd25d81ca2e6a02d2
+96d93bd9cbd444bf29847621aeba1fcf
+96d99ab9da6523be7c95a53b4f08a0ab
+96da0dfcf8a263fb94e0131a8278e16e
+96e900c5dd0de55d2bfc0b4c2522fa87
+96e9a3ba79c5d299629fd3464583e469
+96ea784158e4b550e51df6cb67b4d122
+96f584471dc2afc6c224096004d450a3
+971002557b2e18bd5c676dc01f8be2c7
+971041d9543367a1566950cd77d751e4
+971632af16ce958ae5c40226ce32e13d
+9719b6ce55b96a171d5f404c685bb70b
+971ae29d26ab6e6578f3358fdd99710b
+971d7326c79bd9292ee5f2861a9cf563
+9722c1c650f00c1abccac843e79b2f5b
+972475297dc24672d79d8814004cf9e3
+9727a7980ed239400129bef3a7b3f5dd
+9728bb415830634b9260fe1415c155ef
+972a63e62aca267cf49ec23e79e3c24e
+972c487a3f86e3084c77a8368b1cd842
+972daa442f9a0f386a39d1a22b490bcb
+972e575fa1b1b3b298f2807a657623f7
+973364adc55a1fbd6e08c10d4cb6e0a2
+973526a994fd3d8fbe1236849190e2e2
+973793441794e526e52258f53e467391
+973c4623a6e7da340eb60e5e320c97c5
+974489a7d051f11d102d94bf28b5419b
+974703fd7e0188c2cf42471c48a6c9a5
+9747b9b930e6563d6b070f720f6c48c0
+9749b4337dce690b897ad0b9a9e55a24
+974be5a085d18b5041456e4690ec3ae2
+9754524b5b3d8b43f833e896f579cb05
+9757670b24c3362103d8599467063074
+97597992f1517fac2a77f45e544e2748
+97598b07bde384ebd26e0c4162dc3079
+9766724a97167f4dbf39c6eb7ee3a5e2
+976de60823b0520daafe310d58079b8a
+97727acfe5566b28d759df940c8e5dc9
+9776357db5da42b16790d3f6acf04ed5
+977e1826b8e83dc15133d6957e51ac16
+9797abbbca5933094a0ebae59cc10f84
+97983cd65948f23f18fc7e2a04e466f7
+97a57d307b3dab3ff796277d89861d26
+97a5da8c04f3c82cdaeed5b57a4f483a
+97a5f2a87a2c8b0ad921e76997e5bc42
+97b1e4f8518fcbc1dcb257a1c317d6b2
+97b37f899ed7c1d3a4692f7b18543bfe
+97b80dfaa68568947dd40af8758e110f
+97ba3fb75b7f2f2a9cdc62e3841844dd
+97bc5f1a024dd9c014a36c5dc7277c41
+97be6be77626d8804c6535d02eb6b8da
+97c91858cecc18abab0e6cdd3a033a9f
+97ce03e2f456caf925024d1580a9562a
+97d4ff708a7016f0925f1e8702655a3b
+97db192a74c0d7713ffebd54a18ea4b0
+97db2f18d5ad1bd289d2339e6351c461
+97e5829301aa1c03739f8b576a39b09e
+97e8143397fffb51f5bb125828299e3c
+97f0afa684c351072d65474f39ac6979
+97f2870bc46a8d069ad0051f8370ee00
+97f321151d42bb74cde79f96d9861511
+97f3bb9c0880a5a4eb6cc531a636af7b
+97f5af9844f3bbf3b0f82c992a24c731
+97f640db7545e75336ca64b62c6f84f6
+9801051dfa98d753d3c59f4d9b93096a
+9801c89fcd7ede5d2e7561297b93afd7
+9804e0e3ebccd359ef91a18588182b3a
+9806b54e46b6b4291ea779bdec6d4e7e
+980c90ce1f01ff630410891f76bc68e0
+9810e8045e6a434dbf8add75e4959655
+981233072ae033a20cf158a288b858ce
+9816d5795f2123dc3400e522101a92e5
+9817274209c845b43537c8a3fc6f05f2
+981cb56ec7b7c2eafc9a4d61806d53c1
+981cdfbf0e06b39c06d517d3609f0622
+981e2924dcbbcf253b5afa514cd2ddb1
+9820b03da3e468e7e8749b7297854404
+98237bd28eac299607d400889f968e03
+9825b208635bd6387435d44af37977e2
+9825c8c811ff05d452e8176cb32fe578
+982a203b018574d758327b50a7c43fd8
+9830a39accad3c14e4d744e2ed35b9fe
+9836a2d691b71c2e2951fc75b1412fc0
+98389f8ca3d64c754ae66ce151bf5876
+984c342094eea7e1c8752637f39e4b28
+9850413262acc40d3e791b140258e55c
+985409c48103d5367714b9cbda8b9ac9
+9854e539d203750a1f54ebf2201e780c
+985a4cbeb150f9eb183c82e5b3219407
+985d2f619ae51b57162f30dc2118dfd8
+985ed3bd4c034ef0bbd42b5e36b30a51
+986af39f8bed3841397297561d5adaa3
+986cca8ab073fdfdaed55a013fd3d5e9
+987287a38325b00adde3116feb171455
+987393e0844691924f19354b41be030c
+98745fe9f4c53a2081be4fdfd317f150
+987d907787dcaad18d8c892f475c8021
+98825389e5572fc3ed5ccd9a826daca8
+9887c8112ac7108fe005d6d3459bea34
+988add19399a04fd2ed6c81cd0d91218
+988ce9b9eb36a9e7713b58ef98db37bf
+988ed8a8315531f344f7314f39b2c61b
+989279c6bba50c54a82d2419bf2ae212
+989677edfc59ba2af1cddc3b978e55ca
+98971604de800d47789f28c4c287f8e4
+989b4ffad1c1d992b16ce0573dd3adc3
+989d439f68307a8cc484dce3b20dcc73
+989ecc240324f997d5e1789747af9053
+98a9c5415c2f0f13cab2da05415e27f2
+98ae9241c41f7e4307c01c7e22c9dae1
+98b25f00b25fe75a9871840fd36a17f4
+98b4e6bd0bee591b85fcd083e4800311
+98b6eb643a27267ae252bfd1f003165d
+98b7ec1e19905d36d391b04c8c67a445
+98bb467efa0b403ed1b71887f74c945f
+98bbfbb71c020a8a9b3fc77fcce32b89
+98c59b5a2be1f6586e85cc73abd19b07
+98cb8907d50bb97c4955a4fc3b1828de
+98cd2d4a4c28d79d9f26d0c2bd84fb76
+98cfa274959e8e6cae7ee76ad5f9683a
+98d06d2f5c94ccfc9e0b513643e52000
+98d10f2f909e637648fcc9a402d3bf0e
+98d11258621a8311e5b8bf4282e6def3
+98d9819375d562e5aff3a28310ce203b
+98dc646fe50fa365d904b3da5ce9632e
+98e3130acca7b432d2f1dbbd6633dc61
+98ec6875c25d881ed5bbb6a879376da7
+98f43aaaffcbaf05d85bf8ed19f9316a
+98f7d2ddde6853188ce00e023b1d1359
+98f8449e4b0f2a0d416cced5745a97a9
+98fe0cb4b061c20d3d12956c2fe65512
+98fe618a3ef98d07d2bff144d1c53cfb
+9903b0218c7fb88cc023f6a066cfc1d5
+99199d68e7acf2945a2a23ee94a14dbf
+9928457b727a892ff83cbc826b966e00
+992a2acc09d0f0202b25370b8f135d48
+992a94b402335f58b9efe1c9c90a4f5e
+992df7fad95f19cfdbd0881ed1296a64
+9933e8ada843fe5cb2660a60a9ed07b9
+9935d15d6347b509020fc164337a5c5a
+993835a5762033e25c6d31d27d35af77
+99397a093960f75cada201535d8afbc7
+993b875b84f7b0afb2857acf87bb483e
+993ddcd4044305bed0cbec5983897f23
+993f03a49f08e60fb3c6eca9017cda8c
+9943f41a2ce7663d3554803aad3f3722
+99451dc3573da46aa887dc090b9822de
+994add08ab5945115bc225f2efd20cd6
+994ca46f045d336a9f0f83e65b432cf9
+994cc0029255e3f3c1790954c510c4b0
+9952a011ec7c057d42d4363088cfe566
+99537572a95b5c80d7e91a4efd17dd3f
+995c2ae2796dc65ba029f5f2d32dafa7
+9960fefdff8a58cc8160fb215f644bec
+99614e108361e58e7190464275c0bd5c
+99673019b873ffd447623d24638c7ea8
+996bc0c25724c0416e1f56d4e18d502f
+996c4ebfd1cb46ee46b204970c4a1a96
+997207b98a8db8be45fc9ecedec0344a
+99728f565f0314165a3972524647bce4
+997a1d008d5ef574bedfe17178fb6091
+997cc2a04813d5e7d7b2ce197a1f7b70
+997df4a45bff429898bf8a6c2825447b
+9980ab57721b93ad056468e060a07f4c
+9980bf2d6748b4f336a43d2430608d67
+9982948bf46b7bd3a2c433958ebacfa8
+998594acd134e1b53838898830d04ece
+999013cd579d6615d8392ea87db9e137
+9991d033cccfd2f89ff36d7a43112722
+99952e744dd77a7fd2e60b986294cf66
+999f586fd524f6933dd7239dc27ab264
+99a24f766ef5c61b6f6b3b3b9a12e1e6
+99a45058d5e66262ca657291c27e8c65
+99a4b2843242522a4f060f2c408b5e56
+99a654a338efbd6fc6a0e2d7e5f1e632
+99a6c68f58daca9a3bd411349cca4e05
+99a9b282ae165463844b3109dac3c1f2
+99b01b7026a89999d010d56ca65ba83e
+99b78b73e260b25e311cb1610fcb7149
+99bedf22341c75c5eca47d8d6d9b0d14
+99c65ce8b44c1de97d503bcb6bc96d40
+99c86f3bc07c963165ff5b76e4e40e42
+99d0afbb440990d4db1fbdfdd17c2bbe
+99d1501077821b4c90d628ef705b949b
+99d6019e97feabcdb49f68d3ed019364
+99d72f0eb6b8202ca80e29ad6ffe6868
+99d97926de2f6bafde9f598148a6ba5e
+99db12b4ddcbe31519eff9ab61a3ff3c
+99dc43a6beac54b53f1b79db129f14c5
+99e1b97286f64c7fd80615281774a51e
+99ed4d1e4de7783ddabcd227316308ca
+99f0f82ba5febb60af18640c9538842d
+99f69dbd30e3d9651f21f243a998bebc
+99f868eb6c6190075cbc47dda930ba74
+99f9a19a39d7619c591e309ad111ae08
+99fa550b6486ca2baf3d873480e91891
+99fc1f1099bafd39c166e48877826037
+99fef578fdbe2e00a934c0f33ee5b42e
+9a0042adb3bef413cbc61f510430d27f
+9a078806d0fad797d6dcf0603cbd4707
+9a084299cf87ae5d7388985b3bdd6231
+9a0b8cd434bcd328fc660906b6376796
+9a106f7a3e72a0ef1c29532e61922c48
+9a10b0390daff5ed34eb7c14d4b45e3b
+9a124b15d886618bef3eec663593a862
+9a1706060c181cd8a421d50141286fd4
+9a1d2ec74cbbbecab4f6c78a0a3ce330
+9a20995a6f80d37366770ba8ceeb72aa
+9a20cb9d7b4134e82cf09a6856c6671d
+9a21fefcaac971d304d9f89d0071524f
+9a250214586226a36b5839c6db140714
+9a28e554d42bb75ccc5a13df1c3a0dad
+9a2a9ff771e845bfb2377b07e6351ee6
+9a2c1b80e41024ba2251f780ba56615e
+9a2fae2409aa6c8227603cc8537da731
+9a2fb00189e84eab5b319134f18f61b0
+9a323025e305d89eb7f7c7f692bcc15d
+9a3299f800b6ebc2460e74a5ba53e491
+9a387d8cb566ee78a96193ef1a192850
+9a3e17fe7d84ca993efb7893f24262e5
+9a3f65d7fb3314f21a85806930c814d5
+9a4f5ae8d315e68a537b6f8d658c8990
+9a5eaa85758ac00242d40f98b791400b
+9a604110af202551f31755b60fbca1ff
+9a6322a2079fbeb6b5bb82a2c9c640cb
+9a640b5756abb61711666db8355cade7
+9a64f0135177a7b77398221842c7ffa8
+9a6a95701ad00fe7445025544ddd543e
+9a6ca5902386c4361a343c4c2f0a30a8
+9a6eb714517ab8e1044124bee52d4573
+9a71a1c8b2f2968785fc15b60a745594
+9a76ad439561cf5b22472bb3309ff997
+9a770b51ec2966537cb3d80614f0fbf3
+9a80162cddb4d24fb51a9ba812809954
+9a823353c6290390b281aa9fbdacbe30
+9a8738f9d45279fc6c0f06e15dd31116
+9a879591420bd3775dea24c85a2ac67f
+9a8add0b5945dcece09fec916eee6a91
+9a950a641179ff88fff59a4b6d91f048
+9a9598aae42ae47b7653d48d6f316de8
+9a970b363e806d01cb4a34c1ab72701c
+9a9c8ece56d0965a11cec168d13a103e
+9aa8295fdc5855782213084cf32f3599
+9aae1a6eeb6a87b24370bb0ab0540e31
+9abc0348f19e2a7332a452761bbda42c
+9abee557204f22f21125694601e862ed
+9ac1a3463a77339b55bc797c7f676b5e
+9ac395253c70f82527c8efb1ab5f5163
+9ac714e51c0004f08ccbc666a3b8aecf
+9ac856a06353f0661698308dd6a49a17
+9acae185c15b3a8e1378f6d407e45a67
+9acc1408eaf275d80955fb6d7c86475d
+9ace31b0e6600645fc369a137c512c16
+9ad24d9a4b634b1434d1a392a03fc670
+9ad2fde5ea54120a6f2f4fb5d2459725
+9ad3ea7addc4eb56904e9c75efc0c0b1
+9ad70cc24ee79a4f1d4890e061e8112a
+9addbe765b40096f3b88b72e81613cd1
+9adf444d801740d252a3e1ef34a03d0d
+9adfdf1a4cc22a5556d243b90d7c9d41
+9ae9591be382cfc45425b95e71309701
+9aea1f1cac816ab7ffe0baf7a0cc2e12
+9aecc3a565142f991dc8162bcfd7903d
+9af463c3fe323a8171a042fe761d1601
+9afebdd6ddad9e336c20ce436f2dbeeb
+9b050b29a51c821352328ad36b75f675
+9b0680dd24542c87887b28f6c69556f8
+9b06ac784f943e6965fbb312dd5c685b
+9b0bd19a572d45da058f1ab843d1e54f
+9b0e335d4f2a92586d3ac00841d542db
+9b0fa5111a4133758d56a2e0b60c66ff
+9b109829547e4352b3c882709640d896
+9b17a662f37c65be1dc0a2601be67d0a
+9b193accad73f3a8c533af098efb8669
+9b19956efa8bff480a5ec4228fc36999
+9b1ae07290d1cdf2a87e0505e142f141
+9b1d1f271805ec311012c57a612919ce
+9b26586e62fc26a34d78da1f4f29541e
+9b26fdef8e7e71e50d25975546d454bc
+9b27cfa7cd034ca572953d8d0536f8ce
+9b28c190fb8af1835f12e78527c7d7a9
+9b29631b084552d7bb89f9123426499d
+9b29999db3bf9e6520389bcc4e9641c5
+9b32bfda75a54110ec51526f63710b32
+9b32ed36c490edcbe22a895bb36f290e
+9b3bf44c4611ab5f04126c9d12918f0b
+9b3f2a04a21480621a49ab5ea27ee1d2
+9b4303b36a2a88f4a95ab0acf4c11026
+9b470327cb323229d8ec942b4cae9bb6
+9b581050e2ecf0b9f9d4c378a4b25463
+9b59989bbdc05148caa21fbd71495b52
+9b5a1dae532ef9bf9dd37ba88d3c8710
+9b5e31bddfaebbb14c5f91c0327b9e8d
+9b5eea025b77256b7e2daabd2b697a3f
+9b60df072c6f3027ee44a2100cb74996
+9b6ee4a9dbb1184c00391993aab48080
+9b6fe181665f80ccf11f4821917f059f
+9b72375f708b0a62cad42a72e4afffd9
+9b7486947ad365fdadcc773a75720c26
+9b796ae99a780f985c10c01d3642fe51
+9b7a257a3ffb10c392954df98e94f2bc
+9b7b944fc950bca5edce4c8229038ef3
+9b7d88067c11d22ccd9f86be4577c7f9
+9b7e3e613cd060cce8432971440c1a65
+9b83337aa3412932c25f40176b5ee1c4
+9b84ec457ce27bb961429561751b920b
+9b8554f6ae48eed99f4edf4d66524dfc
+9b85fc71907a78d1e28cc7d9c6195185
+9b8e5013ed0a3eb00ee34ffbc9d89395
+9b91c09cafe91467493be288ade8ed9a
+9b942445a0bd32aeeb86bd922cc0636d
+9b949bdf85ac91b8dc4eadec68fb7309
+9b9638e3cd3451ccdfdb8f069461df58
+9b97f24c07674e8f710a9446ec90cd3d
+9b9c096618636608ffbb0d893d7af5e3
+9b9f3d4702a291ff307d992164fec34c
+9ba35ea204c86c15353707ca77563e34
+9bab936a606915a42c18ae6b0b37a4b0
+9babdcca2fb7e9411de167206fa248c1
+9bb56af2d871fc38e91ca63daa6921c7
+9bb73ca867c339e40f589956a994bdac
+9bb76a2fd2a6133b9e671d30aa7f0b30
+9bc60241f70be80046243f842702c282
+9bcaf7a94a9db8a662eb4fd3c3d50e49
+9bda9800e66f4e3a9cb66973c769371e
+9bde563a514d60ea5ece05d7d628f770
+9be314a6af4bf72219be4aae60d3e692
+9be907d1333c349d642cc853ad841d71
+9bf1515d303c782486ca14ebc2eadfe9
+9bf77f6db4eb511cd2b8a1cb3af44708
+9bfc78c4290b03e71411ca6fd4b95479
+9bfe28fad5880b23d388dc9de3587263
+9c034476a870cb2b09618988d07c39e3
+9c03dfc873c31ae3108b94359e7278e0
+9c0e2403902ae525cfcf16c71b831a46
+9c0e56e5aa2d0613d3f636c9339cfd20
+9c14ab70d8ea2613b8a8db6b6d8ca889
+9c188c0402bf930dcc47982dac988900
+9c1a485bb8da2ed34e39457932623599
+9c1aa2667ddc3a4fc7865f65c4ae2a06
+9c23f54ea5b67ca34dcd3ed826835fa8
+9c2ac8d127341092c560f544d44870f2
+9c2b821b4b016fd977980d108636e9eb
+9c2bde90d2462140588a7bef6168861c
+9c2c5340021622a5d1f6b340ba259ff4
+9c36de49a8b789926d0a78db397c187a
+9c3c18e67a28c5a69f0f7c1b8bba2701
+9c3ee59feeac225fc1a6efcdf758102d
+9c3f8ba083740f9bf7badcd9967ff895
+9c40ce86b63f479ddd9b0f2968a142a0
+9c4514477b208a2202dfcbeb69d11c2c
+9c4706ce76b191d72a2eb421cd625e17
+9c497aecb96abc2a5cb5c360c7f8d156
+9c4e31171417d805ae339d110d65087b
+9c521b366b4068f855b2b59401857f4d
+9c68bfcd79c2031f41fcdb917c40f6c7
+9c6aacd3a127d07011c3c5b9663b4e6a
+9c6cd7cc2a9b0137f8f64fff58c97fa9
+9c70b3a149b3b009a890594933a6af18
+9c724db389ee002d4e04e7ae635474c8
+9c79f23c8d4fe9f146ab04285631d4e0
+9c79f44ffc67c70461f8c81c24e2e8db
+9c84ba7c5065f0ada916a58ae7714294
+9c881e9dcbefca8e2e896663a9f25d66
+9c8c3f99502a60fb004285c651b33046
+9c911d1e91da1dd09d0db7b49b8d6652
+9c921edcf290a38a9d0ac33445a46668
+9c9705a69dd2da51358aa9cd4f829231
+9ca8f5fb7bee23ee68d0b9b6d7ef81d4
+9caa2a0c02261e9b83b3b74ded77eb72
+9cabe7db618be23abb862faa2ae0043b
+9cb03083a669f675791a810c8efe2e5b
+9cb0625e1a0388287855c979cc3ccc1d
+9cb193e8fcb1a338b6a8353fd27c293b
+9cb8c52450f2908c8b5cda073bbd3caa
+9cc003b458a8b8e2818934a349fef105
+9cc2f1b9b7fcd1e26b6696859f972a78
+9cc513dcd5f39a4ac3d1b879ec4324fc
+9ccc10d9c9c4d05d31254480607d8f1e
+9cce3e1cb9b6d2d82d2054588c93d0e1
+9cd11c7473772e875dee00b6abc87e1b
+9cd55fd5c46a85f03293f972441d4742
+9cdaa71d475b8655e9304567c45fd2d8
+9cdb9987fa143095c4524eeeb12aefa8
+9cdd4f5dcc015846ab92db8e15373835
+9cdedd882054902d8e4b207080d26e3e
+9ce08e10c5cfe510e10979363b8f17a1
+9ce4443ce1a81cda5f8331d30226fd67
+9ce45c528bf0632bbec6265e7b8aa451
+9ce49f66d05a3698e9672ab71d93c022
+9ce5469ba4072b357e54e6f1987fb419
+9ce567387041f9761ad8de80bc0837fd
+9ced740d11d5d82573d11d779007cca3
+9cee4b8e63688c4e31a4014519887836
+9cefe9e9c3d0733821a75e70213942ec
+9cf34101a4f4ae8fcdf3b4958da6b76d
+9cf429e423d51ceab0b58d7ee16493f6
+9cfba90f300f65c50719f82578666bb2
+9d078ab0bee2e88cd5f7b2fff2784327
+9d0e284ce1c45a54b87eb0ed1ac45ee9
+9d0eaca84ba9a3576218da3e9f807a66
+9d124808d20e471bc123acf80ee75083
+9d13669a54a0641de3d5b7f46d6d10c3
+9d194d10cad48bd920fcee7703e07199
+9d1a3d8295436a7a9112023f6b789bfc
+9d1bac4e0bcbec10b9aafffdf7950e14
+9d204ae75b9614f0495be3932008ea95
+9d2eb770acc5c5faa3eee32e7c8da74a
+9d30ef61feebf6415e212501fd3b8051
+9d33a1b68323b68f950cb2b28223728d
+9d3614641bb94ebedc3ca44ff1708a6f
+9d3cfba4cfb1d0b1111620251f9d68e2
+9d45379eae41dfe215655a11a9860d24
+9d46e18e290d2a369f02de6bbf7658dd
+9d4a639cce13727cb814cbdd32805e0f
+9d4b0a3b18f24b672e6542049bf540fc
+9d4b6bbcd89cf1e406e1541c79ec1995
+9d4db32ab640fed0e13590b68e302204
+9d54d328a0b8ef4c18d65199f28381ab
+9d587a46370e6f4535e4328810b7f230
+9d593ffd35e14f83ca530c6ae366b618
+9d5be346a55ad49c86c87b306fb9dc92
+9d5eee56eea325dbba8ead8b3f34ec1c
+9d6600f52a7853f0c3ec34d6da5b4488
+9d68fc2311aa5231e1612b6d800795a0
+9d736e55c3cb558298331f65a04ca0e6
+9d76092362328ed92ee148ff35fa84da
+9d86e9caa97d78704d3d5d742dac748b
+9d89256bf4ddcac11d3f9fb9a8589a55
+9d8f554ba1751eb6f1d06e8e48d829ce
+9d946c9515cf0e4bd5af8ac30f7398be
+9d990be0a303be11b290bc443da71f4e
+9d9b38697f104cebf0913dc7aef7e4ec
+9d9dfced9f1a192e7a7fbfa5d3ba9ebd
+9da17bddc551171017b0f73f861ca136
+9da2547cb56337f074341fe1aeaa4a57
+9da30e68151a854380c520733b56b899
+9da47f91c2e3ca422a0879fda9cfbc4a
+9da4ecae0d130472c782bfae637e1d6c
+9da53f9523776c17a513b3b57c8e96ce
+9da82c2fdccb96ab140f80fea2a52c63
+9daafdd849dcd80e1c4dff3b18d72bbc
+9dacbb6867fa634529ba85b2368c9cbe
+9db607c1f5da6d9afb22b3dfce7eeea4
+9db61601f0efb4673c5be1b595441e25
+9dbcba23b3bfc76648d971b518507129
+9dc58faba8c34f18d3ce6e132814813b
+9dce91a19248d03352bf24ad50ae5bb3
+9dd00a094f41d53f106d9029b6059ba7
+9dd194dd70c454e38a2df74ab5b6a7f1
+9dd33bef2522dc45c17b1e314c23cd5c
+9dd3ff08414810f3989ccc381eedb4f2
+9dd4361a8e88929f992a0469f95b2594
+9dd8e5f3418bfe4257d7918b7c6975b4
+9ddef2982eb977497b7138ddf2b71ed2
+9de970cff69eed314339b65abf1d54f7
+9deb970d7b9121a768ed2c839d6d7957
+9dec6bc06c4e5abc29ab9b0499cf99c7
+9df17204912109ac06201eafb3f0a28b
+9df54218d3a9a22211314189d687dab3
+9df7a5e1a54055104f962f191ff470bd
+9df807fa61108e1e67b58e75f94419f7
+9dff57c66e1ad292389fedde3dd370a9
+9e013bb197bf50edb23b990950d7f442
+9e03879007d8053efca40934b49b5df4
+9e0ee38ea6f5674e37b42cf41548f81f
+9e109f9cbef1843c36b9dbe13d9016b2
+9e17dc72b2ededdb48b35abbc994e8c4
+9e1bfdc09b7ad24645a3793cdb0bf403
+9e1d97729a7385cb8676662e2141ba06
+9e2449ebd974f5596b00877e08f5cc43
+9e2606e32f73457d0d9a9b2ed5bb6f14
+9e2eda1c4f83929dab40f1a2939bbfa0
+9e31feda2692a26b35e84aaa3f5f2dc9
+9e36abe16a5a3cd99e656fe029ad38ee
+9e39bd820d236220ee60588ac21a7789
+9e3aad39819f760fa31779908c25d11e
+9e3c21f1f8986e8a2a025b797dd19a85
+9e43f9d05fb38177e10edb82c1bcad5b
+9e456866be7057383d137ec8d330a5c9
+9e48ee528f13794a4a9943d21f9b19f6
+9e49906ad75b1116e35e724fb8f73d74
+9e4dc2e769a7a61dc0e58c63e5272383
+9e513e4ace5f991460fa2b6046bbb688
+9e5515ccfe7d2507f6d70e88cf7417eb
+9e5712c955d89028108e52e13f5488db
+9e5fbe79cdebbf6325bea2f1a675dc2d
+9e60970247999d68e9a14d96d13ff2a1
+9e623424c081318359f63cc0eb3a8f71
+9e6f0cdd81a8005f60952c4d19089c57
+9e71b16c0d9caa9ea68e1b484220ee43
+9e78a0a3e4688b35241c2a8aed02657e
+9e8105e0a0aa5db3060f49843cf5486c
+9e8bc9f9733dff0c40731b53ab857325
+9e8d46cc05bbcf298ea169f4f8db485f
+9e938d92fd659cae26f2e70de70034f9
+9e945aedf671ec4ae1f1f82f2f19ed72
+9e980600faee964f0b809daeddb852ef
+9e99070827b1225519f3b9c4364e1857
+9e9ddd94861db26d2c5a64a2db96aad5
+9e9e1c249dd975a2c7b53fa451012924
+9e9e9b0cef9abef0f980fb2818306b9f
+9ea192468455dbc845e090ed3255bca8
+9ea4626a8010f6b583910cfc91b5a521
+9ea4a36bed9e163408222506300fb235
+9ea7829a5d5461f15b081eac68be11aa
+9ea93fd4b49046d774b32ee3a4e3dca9
+9eaaacf8776f959225944ed2777cf5a6
+9eaab062b5bb7d0df37c95221d6d8ce1
+9eac6f0bd10fe3d00ee70196bc8fb226
+9ead152a369d3e55e2f4d0a5cd22987a
+9eade967a04df82a064cd81a0795f1ac
+9eb2f0af835e54478407de50af1c5539
+9eb7acb72abe07970be8d104bdbff67d
+9eb9e791e0bd2efc7db603cda00d0ee0
+9ec1a7390e2abd75f4f103443f1c5f70
+9ec2c99c3239edd406401fd4183cd092
+9ec7e5483b022460569ed90706810f1d
+9ecded1a6ab550cde56df31d3764b40e
+9ed0692ef2393843f82b5c65fddf219e
+9ed6f754c45b90168d6345ea46410ae0
+9edb5becccf3197b52fcebbb0f94c787
+9ee6c0a166e295cce272eac2814fe4db
+9ee9a19588d35df27803e334dae77fc6
+9eee94438cf6a63ddd668c1651b23e94
+9ef3bc88f5fcb2ecf97f10cd2891b16b
+9ef4a9740938ea6973c84fef9680623d
+9ef756856aa4546570278f3bf775131e
+9f0007955e55a3c5e5d29bce15fbf1fa
+9f000b4173f83ec586f9aaa27fb689a7
+9f00d5ca8707ac39840aedad433acb30
+9f0b58de44b98ad75c0e6128a34d637e
+9f10fdd0ba7e9aac0c1233da980a98c7
+9f1741e24207ec85de99653036a9ce2e
+9f1beac7b6a2d9550cde5fc502f1050a
+9f1cc2b639554923084000cbeba67bc4
+9f1fbab35a344bd13e40b4267f935932
+9f200e257386f251c6a3bc58760c313b
+9f2c6b0d979daf69249139022c950a18
+9f2de3ec64dcda7364a5f67f79265a9f
+9f33ce84878221ace4c3e9cafc52fb68
+9f3504bb84b9fa5a36ae57934f2a3d3b
+9f359ddd800dc12d8fba1907aad2bcbf
+9f36886024be001896a00613c7c2f29a
+9f37932dfa37bfebb9fcaba9f99cb6c3
+9f39064c48dc286f614b2f7a5aa18536
+9f3b651213d6b9c0454807955dba40ff
+9f3c3d05d119f58e6921f097790852fd
+9f3f3f2efcdbd4bd71c58505803d7820
+9f413eac9608562ca5bf5599882f1abd
+9f4611657c4bbb7011eb63e7b76d426f
+9f488d2da29772f33246a3421c022a25
+9f49e9b5366b093494f2527d87b17da6
+9f4bb452c51568c326191e5eb0002d1a
+9f5804ba72dd3283889c7e0abac99b65
+9f5aa0b7618b5a20ea6666e47ac2d2d6
+9f5e6f5635c1d914ab65ec80dc136d58
+9f61a79bf942114640ffc67a925632d2
+9f6223459c7a03f268fa274f25e96ca2
+9f62bc6f1eae1ae3830ef830c995632b
+9f64bc1417b406aa7243ac89bae076d9
+9f6bea8ad9df9edf0145c77cf498142d
+9f703ad58fca11d8fe8a2415ccaee667
+9f715a1e507020983822b2e3dc21470b
+9f72f4558689fe93a5ec7986cf218f9e
+9f7cfac24ecca104f50303a0a80d25fb
+9f82341fb405a64c44ce46c4fa058ecd
+9f844fdad91d93a3fecabf616026b43b
+9f85175ce91cc463aaabc94a98b8045f
+9f891a768537ffe38023c48591684ff4
+9f891c569980f3a1ef2e162899273441
+9f8dcd074e90eddbbb61587e50005d83
+9f921c723edd536888f7a88c15836029
+9f952171b872ed2863f41427097dab9b
+9f953152db90da6cc41bb63e99aa3f6b
+9f966959344257f6499be26d10568d2e
+9f97d1b7b4256d0f1e399a7d25ac96a4
+9f97f83a929156a29d8dda7dff115541
+9f9ba3c30dc9317968e8ec8f29de488f
+9fa61a6b88f795b6f38bf453c533cae6
+9fac9dd7abea22815be7b6c71ff18f4f
+9fb630c9599530f5c27796fc588b0c6f
+9fbea916f47ca09326b00089b93dbfe4
+9fc19357977760581706234cc2c95d39
+9fcb4d2d86754c670ab97c73251fda03
+9fd3e4e469e7ca11b840bfa5cccfe15f
+9fd529ea0cf805e659059e1087535b95
+9fd557f9ca0c2e0c2d13b2639da8b34d
+9fdba845d5fc699d9e254a86e0d6bd08
+9fdbbc5721448d6912f168bdc396093e
+9fdc99297647c4e4caa87dddf9e82520
+9fddf6eecdc21984bc9cfb8d668eaf91
+9fdf1d41c0ab7d7819412f130430a882
+9fe0af324b2d2c1177a8e369a9f5cff5
+9fe2f4a9ef6e476ec69202dcd6a262e8
+9fe3a8aabb8e8b8664c7012d4ae97d88
+9fe70d38beeea21444ff97568dd1219e
+9ffcf18b72ae0de030d2c0ca0762cbb5
+a001aa53c992b8e1b44507178759bd8b
+a005d053267da46d0fbdf438ba2c50bc
+a00bd37972e644cb0f4930710c866691
+a00be5fdf5f1f983fdc2d2cf162e07c0
+a01013f15ee11b694450fb842590b930
+a01512a3055e7c01a51d4a6575e4c31b
+a0184f28213ff985ad7ceb0a55f67731
+a019661d3d4a64752d5fa024055b5a85
+a01b069bb752667d25574145e5fe2d1f
+a01cd71c166efebcc3fe549a26fd95ff
+a01eb567c6f10c7b300116baef769c95
+a02188409b5c324afc48250850db8bf1
+a021ae7c424b5a560d9da319c348ec4e
+a021ea56fce6aba6652c78c2a1f591dd
+a0225b4cbb6c419467e5a16e894e95fc
+a022874d1adf199f1caa1266cd9e8db0
+a0269216f1dfa879d11c92253dcd29ab
+a02a8dae004c46cc48d1357f5fee97e9
+a033c3f2565a7b5364d347c61ecb3388
+a034022394e00c130275f9eca73f86e4
+a03625c2def37c3c32fc7f4a23bfa79f
+a0399b4d8eaf3dcccc996c5c6004e62c
+a043756f898f1a40c15ed290eaa8a49f
+a045996ff25d6569362ef78e09e503cb
+a04a230e6289cac0fa9d66e22a80d5f3
+a04add201290aa5254a9219446bbb199
+a04bc8fab8e7951f6d3d98e527e3eb17
+a04e5434222f6b38984e2e2bd0344f8c
+a04feb568ccaf0dd30e49f25f89f16a1
+a05223d38ea206b5c86afa29be3243e5
+a054f6fe22cde40f4579b91c42607bb4
+a055349829c710c19585f23b850c46c0
+a057a4150f4dbdd91ccdb1c7a9e04ef8
+a05a303d9506f7adab59e6a8ed4991cf
+a05d34d6e0898e79bd3c282ab96a9309
+a05eaf38ada092177c2d6fdc001f6cd1
+a06ce69e36e8003de48dce635ff83935
+a06e6a008270f161a5787bd834cd074f
+a07c32d30456c644b471a81e864d05c1
+a07ea6c526940edfdd2a1c4157202ca3
+a0811b7e346af11a89e5688bd2b2f171
+a081f2fe0fd13dbe1f1c54787d503a93
+a08cc02354932fe88bf9c7a2c7a09e3b
+a094e410ec544f3e8e63ad7e2ec63901
+a09936d7c6fa4590cf2d7f4032023ce1
+a0adfed21f13453d2ea745d05993129a
+a0af6594eb34895029b017f1f973fdfc
+a0afc172c8c8af7fa3bfc0c4e93d2c35
+a0bf49b1014c4e41749ee6da9cc8f58b
+a0c45450b4bfc86da85a166c969e573b
+a0c5546ac5d1dc26284db9bbe62d286e
+a0c5aedbd48af78ac8d4cd50165f2930
+a0cb44fc35a9f0a5a8cd284cb88e29e0
+a0cb46fa016ff078256314ab5d1330ce
+a0d28d63266f4e88457545ee4e61be8f
+a0d3d4e1a1da0a93f39458becd8ef866
+a0d5d7485a6dabc9eac9e87b624c1bd9
+a0d609a8d35d9f3cdf7dfa6d097d9bd0
+a0d69d7b821efbba78ad204dc0887f47
+a0d728f55c8b9dadeea9d3d92938b24e
+a0d90c3ff08f0eb2ac242d8f257bf737
+a0decee73201290649f2a1ecf40f2696
+a0e0d745fb6047130de8deba180fb973
+a0e5d3291be6a0aecc64fa4d1740b9fa
+a0e710f5491a92cd9bdfac9e43799419
+a0ecf529454cda3171558468fee38f6f
+a0f3c060dae277b1e570931664bdbbfe
+a0f6d2af7082969e6552dbb65ef01acf
+a0f7f49f290e5f26872de6e971fdfe30
+a0ff1321c7c05de00879b7273e2e3ca8
+a1033a801e0f1ae4a7c3330a3fe4c8bf
+a10e41c9868ca874a31149dcbc66c9b9
+a111037291d55295435d9b569bef5988
+a11232ac6b0d850d9adf9553c4a4f37b
+a114c588fdd324b11a9b0cad73555f89
+a11558bd2148bbd471c6e43439483634
+a115f40a474c1bfbb5f9fe2366ac8e43
+a11e8309532499083a5443329a07d077
+a11f13cb0db16cd1ba1fe2208655b366
+a1232c2d54d60ba9ec2d768888b643ef
+a1271ac307f21e56a1aa1012dced68cc
+a1272007555bf5800838148e14c61987
+a12c81719b73dda0e5589bca45104a00
+a1386aadd6cf93519ebbf5957ff8d3a4
+a13922e37585a74a9174e8fda7fe796b
+a14251e1c1f33ef5489815856f592a7b
+a14e787b9d4caca45ac2ade19bbbc259
+a15397fc4949ffb6dc4781a74390976e
+a155422c453b0c4c371635ae33314481
+a1627bc656d53060e43503cf993d1808
+a16675e63d2e05b28bb88efd03cbfcfa
+a1689a2b819145db32d384c5f479cb03
+a16a6eda353a4e9f4053059fba8b24f3
+a16e2baa1e3c8c1cce0c932e9433e237
+a16f21ad17310b4b704ba9b51f422f06
+a16f3f16d0838c1ebd000eab07874f71
+a1772f4941ae5efb2cc25d43602f47be
+a177c332f5962047a15db842e8a26686
+a17da48a8abc29a54fcff471d6516fda
+a17ef5c7cf925ee6aa20b6c800f8705a
+a1857d0dadff90f4827a5395f5f8fae7
+a18b7b88db6b03ec2bb70f9d556ea3cc
+a18fc245b7269ea294a057dbf8abc8ee
+a19152a15598aad20488194474efae80
+a19b48a13812ab37bfcca445932f7c31
+a19c7b96ba4ea8eb13a7c41d3b7c14a5
+a19ed9e47f0bfd73c9ace792bd072852
+a1a3d35a6db788de0a19e05d0e8164cd
+a1a3d77cc43dd59743b8b511ecfcc5bc
+a1addcd7be30562f5c9050e63d787f63
+a1ae194ae74f175fd247617c7f8b89a7
+a1ae85f7cc770e0686b386c3a9d0c6db
+a1bf596cb6d003e3850be6d9efbdbda9
+a1c2561423aff7c1cd62f0bf2c0a8803
+a1c4c89851502becffd8b733f4f05f73
+a1c4e3588503477f6a712fe7bda7f849
+a1ccaef6851d55dac70ec6d373d3b5b0
+a1cda912ca1f9ca3a0d8bebdcffccc15
+a1d05df16f3434664311a483bafd5f25
+a1d2442c8ae623793e6658b8be0c9099
+a1d82a1500f8e5cb19feba2cebf35473
+a1d94e1fbe2a6bcea015c76564b10083
+a1e4b54303f52ab0e514447b418b27d7
+a1e8e5c5c175e3bff2dc157c88e9015b
+a1eb345e271b8da84a3d8c0af5077121
+a1f021a18f99a8ae182d5737653e59c1
+a1fefb1b98da3cff0b91394e515f6e3f
+a1ffdb301be7d4de21cbea53a4860a3c
+a201a390e40cb5e2db7dec9c22be376a
+a20b2186a2630b21be787ca1114dfef4
+a20c20ada4018428e9d8efe99963b0cf
+a21460302525000a1c9269abba4bf069
+a217a99922c988fde0abf094857a75d5
+a21a80f546079a9f57e921916be9e822
+a21e92cdcf6b57f2789ccd9e53ce038b
+a2237cb6f02e1b463f051e1a01af58be
+a224dc8fecd6d88c8e3d69a639b6d631
+a228db604527bea8d3b1ba6a8f101f7a
+a23a77e52e46b661603be079bd95ded3
+a23a9b4e9fbcc6cf725607a137eea17a
+a23fc9b47b0a18683f64c771a68e97d8
+a2458b7bff22a1a44a958f9e47772643
+a2466102fa7e26373c86dc6f67b95d56
+a2476549ba30b0fe4d84c360f8589f81
+a247d86a850ad860c666c5931653174e
+a2505f34dc1a893d79c863e37c81cf73
+a2511b84b2475410148f5b7b3e33bbbf
+a254bd2d62bd6958aad41a65ab339fa4
+a2556a587ff3b4d25a03886b87068516
+a25eb2a27f0834e100731e864264c95b
+a26077209086bd4ca3cecac772e7e9a8
+a263285ec661e3b4646ea00f219d9abb
+a26443dd10a593b2daafc3434b21f0c2
+a2650e05fa51fcd062b884a8746b5c1f
+a26c1490097730b94d0f4779854e5a95
+a26d24189a0212b3e9374f06400036d9
+a26eecdfa63527c3370ed96300dfc6bb
+a2735e239dc7bc7701a06bc91ec5b9a6
+a273aa9348b34e813ff403769040e515
+a27754fc5ac425838294cde5d6d364ca
+a2797ee7dcdff93e84c63f458a4be892
+a27d6a92723ef338be6e49779bd8c1ba
+a27f3bc78e1414b2b8ac13b04c62563b
+a27fa2770a8203be5849d3dd118bf5bb
+a2839e76b82faa7a3ca76c52040d3897
+a28602005f68660f2d13c621fd82bc5f
+a28c86f57a9df3c49b9a026de8c4694e
+a28e0b00285e12f1c01427fc1e34e3d7
+a29939b3ccf1d42781f652b8d9d41462
+a29db8790bfdd428f91d4a77f534ae52
+a29eb4501a17bdc156dbc525a9bfc13b
+a2a3cbdc810ecbc4404bb424d7dce422
+a2a429a38286b06742433903cdaf2bc5
+a2aac11b515b35dc50b8c9321580ce0f
+a2aeadc4c2496f6dbfe369cc5e75877f
+a2b5e5e3b99e918e5ed3b105b7eec3b9
+a2b91cfe8ac27f7bb6a631a3dd8c1b75
+a2b9fab6b4918b55c9a27cc4b9f36a8e
+a2bcea4932dbaa1bcab273d9bd8f2d8b
+a2bdd931e57708d5e7a048cec0c2aa1e
+a2c57bfdbc31410130920dc3f03284bd
+a2c9d97b621982bd0c889c8cdaa1c9a8
+a2cb37454cbabe283b060c260a16ef45
+a2ceae794cce3b67b4ff177c9d720cc0
+a2cf3bd2583aa9f3946f9606cf775af6
+a2d54e3fab0111b1ebd3ee3baf63ea95
+a2da59a042c28e21fe258df0e8dd471f
+a2dbc9cfb16e247906b2b097ae077ff4
+a2e2c1f31c91e6ac0eb791bb2f98ae3e
+a2e3e0d40b7d023a2ddd02534cc2dc61
+a2e5452725aa6e541d089bff0ef3a6a5
+a2ebbf0dc39eb59a4c9565df4b0d634d
+a2eea4a114bdd300b25ed3b7789df603
+a2ef972a833c7d3b21778c510fd14f45
+a2efc5bbda097bf697788c791df4ee5e
+a2f27ee9765a0c4e74d48dbe862ec81d
+a2f41b6b1a00f4d20866b74121e35552
+a2fca6c69294e7d7a3c84d4f80732d2e
+a3010ddfcfc489f548bbd7d7b2ec0d1e
+a3023a0fc7e6b17108840a4c9e1a6212
+a3028ba297f7cdf3ffe4efe56d666e3e
+a30522a6cb75765eb8eaf8124c418873
+a3076051255c9bff513d6db11c0e022c
+a311d7c2751094acd3fbedfb710ff99b
+a313c216fdfabe7d12ecb63644ff9576
+a31975017b4e2893e860736269151bc9
+a31e7c460ef44f0df12942171807fb3a
+a32877428a645ac790fa33ea24b12f2a
+a32878ae4d95c9a84c7ffe5f67dbaf0e
+a328f49725869fbd3e21f48ca9feb856
+a329ae26787e417768b9bade028ef239
+a333f72fd313ebe2855812fa2e36c5ae
+a337e5bdc1701c80b780062edcf18950
+a33c3fccc23510eeabc7503f1a3d8d30
+a33e52e5c5e1376369598c748ebb84a7
+a3486e3f4013a38d66cc9cb59672c0b6
+a3489db9cab7af00370767201a5f08c3
+a34b2472dadba391bc4879bfb596879f
+a3530b03fdc5b47955683bf9aa42b8c0
+a358dba532c4da0477c25f8444033d4d
+a3594a37cdd82d5f77c90e3071f6a475
+a35c15b07442c0393cee4a095842b9d8
+a36587b9d2ee5ac4f92fe39c26e6f75b
+a36ab9ae8f1901c82c597a90b84ee5cb
+a36b1275817af346d05ad3b0597bb964
+a36f112afaab87ee1bb28000c931113f
+a37482e503177b7a35ad575650d2f10a
+a3762cd7d5934a6f64415a90982be20b
+a37a784d2914eff602935ac0af278254
+a37dba8255da222dd4a2ac391da05495
+a37dbe82ffb8a8368e8aea409e6cce05
+a37edb9e1a4580b7b89d4262879e3065
+a380ac9c8583f48d77d5a690baad941f
+a381a0ccd5f95d58407c3ebdbd104ed9
+a389c17a58bb58b775fe153d4a589698
+a38c1b466f6c496e98343398d461b307
+a38e76d20d5e2ab5233cb1db7fad3847
+a38e9979814fc15fcfe707249925f203
+a394a2ccf170940dedaaa6fc1ba883ff
+a39fbf2bbc24e255ae157fec09c5a670
+a3a30104b76ba3a368525fdcc417fde0
+a3a56045629d866ef413cc12dd6eb5f9
+a3ab5a0b368b618b7a5c02ab276eab74
+a3b1e135f2b0865e2f6af6f9b2f91179
+a3b1f9ca8e61a751f2e458dde51c0de2
+a3c04b6f6195774140e757ae30d8a14b
+a3c41a40f82f32c5029bff42519e3d20
+a3c605865069949892a251b555131208
+a3c656adfd2544447d72890e9297fb3c
+a3cf9509f96879fc569ed21d73192360
+a3cfb706a4fe5642e1a3f760d4f29e77
+a3d00ec39b07064ab79f8299020d55b1
+a3d7b80491160294e495b767326f0c62
+a3d849627945901657c2029140450671
+a3e4daab6dbf18cc2d34de4311374d6f
+a3ea1f6ea91944dc5346d870016ea5b4
+a3ee94296aa34e69159b631fbbd3b7b8
+a3efb3ca3076e00ea4aa819a8e037ddf
+a3f04bee88df151c12c5b5dd627d752b
+a3f74fe7fe757467099d28748127c316
+a3f991d1fe812d9c077ce9acb2ad5df4
+a3fbbf92f1d1c2afadc66c3a949749ce
+a4004ae44d809b75163846255eb00fcb
+a405898093f1d9fa2c0ee0a01d768d94
+a407766bd82262267d666ebb2bcada85
+a407e3734437da008c56bc3d2cdea39f
+a40b37654839ae60aaae19c835e37aca
+a414508b05bdf630f0c93d78b51c0f5d
+a4170c1d89958d1c4dedd06ffac13573
+a41a1e8ead0191c73f00f839ef5894a8
+a4279a13a95e53879c65350d814ae0e4
+a42eab6930105da2e2807fe6f309b735
+a4302cc20eb59ac7caa2680f17d49ff1
+a430a1139530da49869220489a46f417
+a431a78b6eadf7ddca4e01544730e225
+a432dcff9af843b79132e80164852eb5
+a4350dbfe734a3b518df966b58914a2a
+a4353e9e55d717be29b9fc4b84e4f056
+a43966508c5c1285f89ec358d3b464dd
+a43bda7aee775b69b20ef5715007c78e
+a43c5de704b36e3b1e015a30b79a7dd7
+a43d81089ed3fe696688943bc0ad5d5a
+a43ecc1af75a31bccb870d31c0a9dd92
+a43eef9ee0e5bf1be241eedac39a5d9d
+a443879d36ac5ae023c485a084474557
+a444f4ab2204174dd687786541e3d780
+a4475a40e0bd7a180a62a35bc0f35b60
+a4481c3693d7e883ececa9c8390ab93b
+a4485441ab0b726d5a44c3ee7564b62a
+a44989b64b1450f255feebd379170ef0
+a44bf1e0aa4cf8acd949f5cfb8876a9d
+a45231051a73088c6e13ac18de75d0ee
+a455e330c26f5228c8cb94d7786b5fb2
+a4562d21cdeeae66edc965e7351525e4
+a4568cd497ef1ecc377c97a058a7c0a9
+a457503495682802834fe512a0f4615e
+a45c53a161bac48701b41af31aa0bc24
+a46698737cb4f089f78cb1a184773db8
+a46cb6c157cdf72cd384e5fe5cda5955
+a46d885929e971a7ce338df14ded0370
+a4705a855ed70f80823d30a66c544db0
+a4884dbf970f050baf117463dae3b799
+a48c2bc6799061dca6366b08fa965378
+a491935d5162ccfb22a63a75d5091075
+a492e8293a8983f0ff2f77834c2e713b
+a4958a034c4301a72739901b75766e74
+a49c02ce65fca446ce693c3d319b4f89
+a4a7b4e118c8f7040990c416c103be99
+a4abbfb8f16fcbd250c960ab9f657990
+a4b072d4978526c6e499d5f879705c64
+a4b2747d9b2857894034a3589aad575c
+a4b4fb8b0df5270e3cb907506f5219c9
+a4b71511a4c6ccda4f38e8f79f5d7342
+a4bbd1e3df889c556d02c229dfe9adef
+a4bcb34168a6426fde09fa3250c175ad
+a4bde247d19fbfab6f7b8071bd5815c9
+a4bedecd7acf6542974d0bb28b5967ed
+a4c39421c09a940f3ae9a9e83757e80c
+a4c4e60b53400717935bedf84ebd1f0d
+a4c57b8fe56ea7d87a2c27fc775ad52d
+a4c7a254426cb4487140ae17688930a3
+a4cb690cf10466f72098da9253c38495
+a4cdad07bb2d1969dc272338886148fe
+a4d26986beafe5d532dac54210501ced
+a4d2aeb539941ac2915ac7e2a1320d66
+a4d359adb840ad96398e7f39e823390f
+a4d73c41e13b0e61a232e31472d5f323
+a4de465248f984b1090b3e33e9260af1
+a4e22156336d9cbf25f440c994dce108
+a4e4503ac3cd7f5beaea4b281cc0c915
+a4e51d673fc3b10cbd0d29de73f46845
+a4ec383f72f56a5c152ac1d8e0993b68
+a4ef9cda7b55f7f220ffa4d7baa4606c
+a4f0a52ec9396ff20c6f67d5c3d3fe0d
+a4fb781aa749b6ca97ea02ca48a18283
+a4fef1f69a166e5d2e4deac9dd095f2d
+a4ffa5f0c7fffd24dc93017cdd9e7881
+a5041b1dce7b80ba16db3ff6c69754c5
+a504e96cb1ce1dd7d339e25c3d448e3a
+a50dcf5dbcc38258afcf7a19cad7ee1c
+a510bd092b2b0ea44c19c6092c55aa6b
+a51145d7b6fbcc43597785ccaa857598
+a518589bd1e8e71275d94f55c2335d4f
+a5192af6a0f00b168c6fbd640fa56e1f
+a51ca8c17f9487941945c9ff5fd4f61b
+a5216ce4c388a51c5ff5307861a189ad
+a52b48bf6084404cb834c3637c94ebd2
+a52ba0b7cb3567710a359bd1d313c1b1
+a52c4edc59cb9cb1d1d9bc1e7896efda
+a52f0aececbbeab17f505865b6d93c31
+a5328ca5eb5c464e8d9b94eb9747bef8
+a5383bb03c3461e6c973a9f60ade7116
+a54a8c8d8b2dd73b3faba5feaf4fd231
+a54f7deede6b53dedb7aef92f3e6c61d
+a551a96dcde83b4f80e6b6f1bdc08def
+a552555201886152855e204c5a4976c9
+a552e110caa5c5e8d196404ec08ca009
+a553024a3acf3da321acd23dc43f2c8e
+a5570a7e22addb8fc7b22662e67429a9
+a557361366d6c9b892812fe2c52e15d1
+a56963ed55086bd1c0e732c92623b557
+a571f2054b89e696e8d4e0da113a5f49
+a572695dab2c78225f4ac1b89a354d5c
+a5727929bfa0f2e6130ba6d1258405c5
+a57a0a351cdc9edf7efcbbc6d5198e5c
+a57c4431b4ca3bd3c8a63b8691bd6f9f
+a57d5414d6b45ce43c5f05de4a71f475
+a586ec469376dda5dcd4a4c1fe49e986
+a58f21d260a8a1b769479d2295600f61
+a59264fbb291ee4a7e6c14f7d9a04323
+a5945d4129214ff646db70d16d2ca368
+a5982b0dfe905bac0ec720cafdbd0ada
+a59e15dbd9e53b143423adc9906d127e
+a59f592df7482d92d9e8eb6a8680c887
+a5a552726577a65460e6ad950dcbfffd
+a5a689cb9d9012ec9da00f00a73f3115
+a5b0e845614d983a32dcfe5725eccbf9
+a5b1d1a32b2b41f184d9f8b57b456864
+a5b899c7020c66000f2aba2740a0b498
+a5ba1a2b2f6db09cba767ea1dfb2fd39
+a5bad6d753e622c1c112491bafdb26f4
+a5c0a24ec152c7b56e4e7ed0167dd224
+a5c65adee364c70ec860a9e058e4cdda
+a5c782086ad9692ce91c714af0951c0b
+a5cb98d92f6866b36e1ee8147df77f44
+a5cd8d4546ddb90bd8533631d8cc14da
+a5d1ef06e4dcd20237535ad389aaa232
+a5d602636c189438f48426d3b3db611b
+a5d751b835b2d241fde300fe690b463a
+a5d7de5dbd907476dcf3cbaad0638afe
+a5db22b1f6f1b0d031e2fb789226b5f0
+a5ea1a4e59d06e745772bddb404dca33
+a5eb6cd40310afdd796bfc8fb35c88a4
+a5ee1aeebceead355bbd62bbdee3f315
+a5ef453ae71997794093b8d9f62f7659
+a5f25d3e6cfaba8ad613303167cce778
+a5f2c990fedaa2747ce413422a8c59cf
+a5f48e4e0c0ef83220e634a711e1c7de
+a5f4ed3e58ad3b20ccb2dc01c99261cd
+a5fa999ac25f428335a669fe964379c4
+a5fbd4c850aee312360f2e892c3ab2ac
+a5fcfcc4071ba89ffd5c76fdf9964e93
+a5fe6cb745f5ce7f04dbcb1362d4d53e
+a6093f7d08b8c5b16c87271ec838afa0
+a60ced6916af7ae2b72f2e9788fc923e
+a60df7d7961650e90708574d75faaec4
+a612da4b93d33a4c1b4ce66afc454567
+a61b15e25f09460d642f41946129d0a4
+a61d2317ee4393fe16d84d7971f17e1d
+a61efa33aaf660873c26fb9438085fee
+a6299c78ffabe98f27498cc5398b2aec
+a62aa2d0aea162f405bfba7be7b6ac2c
+a62f20995b167153a2c61978ea5908aa
+a62f734ee98798e151ce468974207494
+a630d8aca0b846a64e0bb8a60da58df5
+a630e033562b2502f1f098ee858d0e73
+a63197b3c93ac9bb909cd308b3667a4a
+a631c1419e03f84d3d1ffc0ad3751163
+a6343515721108ddaab24ca02301cdfc
+a63597eed3eecb29917e646a8ace39c9
+a638889b0b8fc569b269903602095681
+a639cea41157ccc829d39be4cbfd51a1
+a64a29a174f936e7fd844376cd250197
+a64ed71f5d5d354be359cdc5f9172a35
+a6500ed28412329959407ab1fd189813
+a650f1be5235bba5e3cae340675fdd3f
+a652a870100eccc9d146aca3a2ef102d
+a656d451d4cbdd0389b431ff218406c4
+a65928090bb4434056617f44ff06bad3
+a65da9a19a867caa1c73368f36156cdb
+a65fb7a591532dc232d88fc8312ccff9
+a661ec652c02185bd50427539d92240d
+a6716da12d51b21652a316ec928404ce
+a672d722bf7d518ffc50ee4d5ad25681
+a6764b06e239d78f07c7fafcf0efac80
+a677d649f2aa9cc88b523b0393b1b29a
+a677da74bdb2887d910822fa6c56c874
+a67a972dc93f5d4360f27fc1b506da39
+a6862548fb3ee37a1eb192a00194c9c9
+a68df55bd0d5074934cec61e87d2aad9
+a68ed4b191e408e735fc65a2b6643a25
+a6932311c0212dadcb7b07aaa6d8ecd9
+a69de5c4a69414e9330d64e68fab7ec4
+a69ef562048276825c7df9d8f9ace3dd
+a69f7d65f6b6d1d4d212bcae15a679e9
+a6a59b14c4a0c0fa5c1b6208fcf2fac7
+a6a7f11a21fee5c42a9d408f90e124cc
+a6a9fcc573e6997bf21ccdcdb0f7ccdc
+a6b0cc8b01689f46130885eaf4d32f8c
+a6c7d0dbe9d7445a9ce19fde1c0a88e5
+a6caf8c60bda1a560e15bfa202702cd3
+a6d44604e86a19997282f5deacb3dd3f
+a6d5d2ca27de290fb13dd7d9ca10336c
+a6dbb0ca18539cd62021c1bbf9d134a7
+a6e6ea68bfd7ec7b987e13d7deb319b6
+a6eb384cb16aab840f8088b680c9468f
+a6edef1451200b6f23c90981dc6bb4de
+a6f56366959bf744901a75a3a575d9ae
+a6f69075484db186e7016ef55f9dbf22
+a6f995548851270343cde1ca53274771
+a6fd8d71223b138992c77e5e27be0ce7
+a6fe8e7c1f9f222a0480d5463d4ca5b2
+a6ff33b7de7cd82872befc1e9e54ef6d
+a704494f9faa2492f3366d989de41356
+a70be5b9486560802e177e75e3d7430f
+a70c1a4633c7d8d0092a3e4a2d31b5f9
+a70e9347c23fc3fe455ddfec4f0400e4
+a70fedf2ccd98d08230ac656de2078e5
+a71833011f93ee64074a33daf77f5538
+a719f420334dfd10890f0a75febffac9
+a721b5980fa2324587f512ed8e191653
+a722c6a97b555feba7921af166d40092
+a723d2e50507011effe89804bb02dfe7
+a7273b61d2d749d7078254a4abafbdf1
+a72760025cb756d8b3e9045dc03f03c9
+a727bbda31d7543dfef7eced5f46b76f
+a72a27b2bb8e2b4ff8c6263428a99e71
+a72aa5b78adc0fbd042c98602520a44b
+a72be6c9dd856f5ae05b927574179ac6
+a730061b86f005f7db82e3843a68c3fb
+a7317dedc7fd56b1b3db8ac32213ffd9
+a7355e48d98f1c7f6e05457c549a4c92
+a73bd906b3c5af56f46634a74b92661b
+a73c0821f6b0520de88512d77de003b9
+a7403c9bf31a8bf1f759f8c1b42c1657
+a74699e359f0d765168219a4d6239089
+a7469eeba20a1a2a83e29e85aec024f2
+a746ed980abcc7fd6ef265c4169d170b
+a7481c5afb0977324a19bc4ba123b78c
+a7483cbf7898a617a17cb1d997790680
+a74948873ca768881142d0bf8dc63982
+a74b1d299d1cc3be949104790d574522
+a75429a6aaeada52258abfebc90c62bf
+a7577cfae04ce78e64f3d6152da0d5e8
+a75c7555ea80465f5e13ccb686244f7b
+a75d2dd49dfabd6695483c96dac5c5a9
+a760a8860e41c4412c643c3e6c0be7dd
+a761ee2504cc0fdbcd90ea44121bb78b
+a767943204382fecc21056b63fe4fdb7
+a76f6802f3e4bbf5ae9d8fb6d3c39c7a
+a77af7c1e34d19ec3e9c080bba9dfb05
+a77f7d310fa589bf4e192fa26832e87c
+a789fdce26fd4f54234c8bbc93965c91
+a78a8f882fbbcca29addf5e5c1b21894
+a78c3df1755a65913e38773546b78537
+a78e408b05897458924dd1efbd01d0d8
+a7967cbe792110c24efc624f15a55c5d
+a79b6c73aaeb39826652e9a045452f49
+a7a35a3e5464c0ae3c535988f6630f16
+a7a3bbb1de7838e037ecf5109c05d669
+a7a71bfaa697ff117f264b4fdabbbe9a
+a7a8757ce72ab5b2e5fdab1345c8b4ae
+a7bc0595121b98ba6ee6e5abc4cc49d0
+a7bc439551bd2c0f4c5c9eb6c08b71ef
+a7bd4df68516424b6a6014a344628073
+a7be60ab3118667a751f6afa33087089
+a7be645680cfc6a6a78705489a12b697
+a7c5e8e68159f5e81d3854740def76a6
+a7c6992870485b434a142cef86f292ae
+a7c7f697212f846e21d8191784959217
+a7ca170e39ab05879f4ac8a449b69d7e
+a7dbf18feb9278bb41e7941ec16f8477
+a7dc404a9c96b0b73202212487003d5a
+a7e097eced828dc7b20946c7d21cce19
+a7e0aaa8995edc2d1a26c96479232536
+a7e47d018632e3033a3797c33bd3b10a
+a7e5216dac1a21eb81e7161bb1026ae9
+a7ea09dd1056187b020f522425202386
+a7ee06eeeb4edeac3a9f3c524cb9de8a
+a7fc44809aa8ad09b694d53b44a63c07
+a7fc889585628e86efa7e59d1ba41f0d
+a7fe63c4efc8c37fdc03fdb4e8060ded
+a801bde7b013adb54761ea8de91233b3
+a8127c4bb076387ee98257022f66c503
+a8157a7d0e3e260cb64a51cff47b5509
+a8158076acb1d0b0a296afca4c71acfa
+a8170abb2bae8b1288566b5fe754d3c8
+a81912d089d896cd4ee0675404b8cec7
+a81e625437e235d331ea942018ea0158
+a8203abf1e658a7ea30939118a5e0b40
+a8327e2938384254c5c52c9356319981
+a8338de28b7b0d08032fc6f46c423592
+a833b0e488c0df72e86a053416a5b5ec
+a837f4d396fe60211c6d0c9199d80931
+a83dcc35a788be3ed4ae0d33452162de
+a8418f118b480f3b4b1e4505429241eb
+a842297060bb977826d5d6458731eb83
+a8443ff9f2cc0af5c4ec1057035fa898
+a8476727289c3c96ebff9158d9f479e1
+a8497a29a88c27227f251de5a28b0afb
+a84aff98c850bc5ebd0555a9333ada5f
+a84d4b4f38fb136dd5cd8d0457c30232
+a858c1c6ee95e5954a6d9f596b5f168c
+a85e6e8f71660db42bb262c828d7072d
+a85f6a6b4e355b614fe72a6ef12a6fbc
+a8676ff679be268e84be90d9c3050fc7
+a86a4f49bef16f0e7d7004d0be4b3be2
+a86dc14b0553ff9303d948480370ec92
+a875d696d204220d40e159c97ad910ba
+a876f5234fe9808cecafefb0970c9661
+a877d6b474ee2f29819d5de32ff18a41
+a878e474925867e4119a21c6208e89c9
+a8871d48e1614532ba760477754392f4
+a889b2202a150e483e8a5dc1a313fe72
+a89fe66cbcf3435b64986c910af8dca1
+a8a3910c01303a363d7c750fa6455c6c
+a8a4896255ec1b9f571e5f04775080ff
+a8a63cb7a783a611e0eb21040fba040a
+a8aa4d7001ccf054fabc302e84efd32c
+a8aa6134938033a6abcbdcceb5530c83
+a8ac68600442239508f3564365eca842
+a8b3795ff4b72d0957678f4e5ca8de04
+a8ba540d9bd8109f0364d28533121079
+a8bff426604bef7d9b92ee2d6ef75675
+a8c19d3771220b69b4caf6e890dcd220
+a8c23e02cd31e0fb5b5ccb497931342a
+a8c59828cb92a9ec28fadff351b79f88
+a8c899b7aecb9ac02006f2270e1dff9e
+a8c9436e53fb1b8d07780f5049bb19e5
+a8c96be24390dc7884ae9f609efa496d
+a8ce9b503c4acc2b8987420941cc6979
+a8cf4f37d8ae1dc0f4f1479411db4c1d
+a8d28d6aa5a06ef2948812791fa3e1a9
+a8d465d6b03ed27165ca787351372c08
+a8d4ad54a4be944799ed44369357c632
+a8e03ca309a0c6679d8479e63ed002a6
+a8e6291e981f4ae2c4ae13cf21ba10d3
+a8ec39e07edf3439c208d912294797eb
+a8ec9963d57f2342a547aff422b4eee8
+a8ed3b9e2f10c8e21a659a2c212e8e03
+a8ee86824ec476fac701bac1b42a0fe0
+a8ef515aae9770df131e07eda4207f37
+a8f3099b51b7a7e0eabc4b1b46a7c69a
+a8f35bcd4d447d2761349856fc68b586
+a8f60f9f3db81585f291d9fa66fe1fa7
+a8f9acb5930ed8c99a3e3abd2651ee6a
+a8fd96e132a38af7969cf9319c4976c8
+a916496ba165f42c9f4cf9c2d34a6cfd
+a91c983170f6ba2b792070a2dc8472db
+a92601ea1172620dead87f68ccc31c8e
+a927c28dfcb8e126166e007660567493
+a92c86b2f88bf3e5bc78966ccca5124d
+a92f0e3889be852de30921305280ddce
+a93521740c5d6f1b8a73212bbe466892
+a9363d386dc3f1757d21fd1df75021ef
+a93964e91f6f0d45d7ac80af6c9e4c28
+a93d35765116314f01efc647bde9293b
+a940f4dc341a9b03ec8c2267fa59d68e
+a9431a62b7ebb044b489e3a6b1d0691c
+a94397f704e7d51ae3e62517f2f4d440
+a9512d54de43b1e1157a5de637db8e33
+a9516e7961aef0ab8e55f4fc1b2ea685
+a9547293af267606043dc73619a1d8bb
+a95aa1fc4fb9bf3f3cabeadfe16c8cca
+a95b9e4510e0084d70ed7b6afc496df8
+a9630ddd54b7ad136cd38b580b8a79a9
+a967f57688e95f0802189163f26d765d
+a968d706553240206c40567b517769f3
+a96903f1a3e3acf51924d1bf7709a6c6
+a96a1da56fbbbb3900737d6c8607eae8
+a96a256d2ae45b5ce69f5645d4344c24
+a96a4df93fe35f2601dd094ac2bac991
+a96b0d7225ea68bc857580cab75bf633
+a9703ded37523cb21a65e33901b6e6d6
+a974ef3756d642393d3694751842b936
+a9789d1c54f68cc87a734fa67e97ad23
+a97bfcb7debcf883acb3557079856942
+a980a3cf3d5c2815c799b487c336fa03
+a98383799472c1839c390291bd1ed0f9
+a9848d5aeee01bcbaf133012cdef83dd
+a9873fbc8581d66af8e8b15d07da1e57
+a98a7fe4f15d47c25db9cf857e266f86
+a99ab318f0efeb20c129c4f9b6368277
+a99f517d1cd2a623f096c0b34c1a5a13
+a99f6fb54acc674007f35f87040b852d
+a9a04fa1b877de43d03175e2347f3919
+a9a1091cbc057d2e578a86135221aca4
+a9ad2b4357b50f807aa85f970aa4c84a
+a9b43bdd60f328389455011d0f622982
+a9b47c9ef0e45f721ae405c9c88e42a0
+a9bb5fb6bfe48c23992ae091377fda23
+a9be1a5f5bd1897e65d513a39f1a0fff
+a9bf3b9ac11fc355efa9da970186f927
+a9c0a6bc0e3dbc9363cdc323b5d4e71b
+a9c15ca6aca2c390ab605509a6f32b24
+a9ced68ed00774ab8fb76fca3c8bb21a
+a9d57efd56642588b2681f19791391a0
+a9d77fdff295f39067bc806f3f440ec9
+a9da20325b224d7f1086969946ca6d29
+a9da21fa6b50de0c5cdd9a0c55f82537
+a9db85d9aba2591780d3809f8eadbec3
+a9e0d106b3bb15e48f5fafbf6cc262a6
+a9e13452ea060e3e1558f36931ffd4ca
+a9e2477224a79e6ffe3b4abb9a8eee3c
+a9e9439d16ec1408318610c28c80241c
+a9f69078785078fdcd7401b4d78335b2
+a9fc20eca9bfbed94b966f4d5b443760
+a9fe223319a97d9b04baeb1db2554deb
+aa07898bd32308b5eeecc1bb0c27571c
+aa13891d30cbdd13032e0dd9f4e495ea
+aa16444c37aba77d3f90b3d854a7dd37
+aa1a37dd2258643005515da16cf9ad8b
+aa1f717e77b530e8ba25b207d49e1b7b
+aa1fcc09399e5732fdafb11de3479676
+aa369f1823db1bc950463fbbe78aa4d6
+aa3f851f2ebe97c73274c2cca2f0c1dc
+aa42a33b3d4a98540b89387486ca3314
+aa4d1521b76ceaf6b62c505ebc2aa276
+aa4eb21df5b479c2414d8e36c3e73c5a
+aa51228a4a7efe52d0342783d81ded36
+aa5559c57eb83aa8afc7d751872d7e73
+aa576dc5b8175d47178909226f6c9ab3
+aa5abd33a2c35ea275715775044bbd94
+aa5d77c54b85b330ed95db2c41afd394
+aa698335b07402d9e912f52c5dcf17f0
+aa6ae4b33f89a70d8fceea52bfaeb94f
+aa6b2d060a58fe75f2be369081b7c060
+aa6e999fee6a2bad549133bd824f891d
+aa6eb13fadeb54560db07371f1478016
+aa7150cb03a0df1eee70734fd2a311e6
+aa7210422a34db2b1a8085e9a3d61254
+aa7309d837fa8c7188865c81ed4f4b18
+aa78a339e41f8a78be228ce62a6bd5e2
+aa78fef8a47c2e213c86f18111249462
+aa7c640fdcecb35c9e909b846720a3c9
+aa856116bfb065d4aef6426b70414c35
+aa88f995cdd6086b78e60c28d7599b78
+aa8953b9c0cfc171501c0887d557f53b
+aa8dbee4a607a46c169c4b65483f5095
+aa919bfda305ea4f8d7e6993e2c147da
+aa928c0b2cdc42615102e934386714ec
+aa9429843900cdbe80a3b2d2072b8c00
+aaa48e9a63a7029d48b0db26dcfc24ac
+aaa60a8c7bc7d4227e7c732626fc96fd
+aaa7d4535e6f28bfa38596f0b9c58979
+aaac993a6ad8325acb8c2ca7a4f3b4dc
+aaad20cca406dedb93c4a6c96937da91
+aaad80288dde8b48abd4d106fd0baa0b
+aaae39dcc8c14702ad3ac1252cd5af9b
+aaaec8af41400b5425aa88909a99ad34
+aabc0d1b10631c4ed24f2e2cd64e2d2c
+aac301604ebc388f17550eddd56a298b
+aac4e926a05f2746e20aaf34791f1710
+aac96958138ff9e4a9da07565986c7e3
+aacb63dd80bc889a4b66718bad1e5dcc
+aacfb786060e22687c7054f2131f659f
+aad22d001d4f4dea91a076cca09472c6
+aad7a29325659e62b1e040d858a50ad9
+aad8908cd15c7084935489e2904aa8a7
+aadc8a42f28346015200d9c2681aacd5
+aae3e0c0d866b2de371313c6cf6bd1f3
+aae88c4b4ecd8e448cc86b58215ac7a3
+aaea906a33b1ba2efc24ce348cd0b320
+aaf3eb10ee5ef36c60c7e07ec0c57bc0
+aafd84655b1d4a142649e081e628b54f
+aafd9088b32a3c5b0ffd75967d9cfd79
+ab11fef8b20d3c1cdb8e265505614a16
+ab13bf2ae39a5224001823fefc326e33
+ab1dcaa6907d46cc9ddbd359f6948b94
+ab207e8555d07bdb112e36542bc43d08
+ab23f37a476d5ece25036f9039532fde
+ab24b1b9397699dfea0ace179be3cbd4
+ab275ab49cc962bbdf78f2975c31d092
+ab28ba9015a6b8d92f592045e297afa9
+ab2b62dcb1789350bc663992e1466109
+ab2d8538b7317a357caa451049590266
+ab39f6032fc72c4d3b6808fd6656de74
+ab3c556300a80c0446da674ccbe1590f
+ab3d4774f46644206b473acb8663372e
+ab3d6050f237bc6b26c6e99799d34aa8
+ab3d92e13605b778a315969ed6d13f79
+ab4a1437954aea29ac6df34c2044b6dc
+ab4dbac9f96ae9f14aa35b792e438771
+ab4e511b3aaa31e853a17713aa8c1b62
+ab547502c6654a7341626f370c8c1bb2
+ab57fe3151f520a6335e863671737f74
+ab583191dbec06f188c09095cbd6cd62
+ab5b4a626337242e89b47c38eb930893
+ab5e91739495a4529085b93df631a1d0
+ab5f0a63b94cda6c90a0615c6c24782d
+ab62f8f380ecd91b11c588d7f58a1e5f
+ab6602f682faafb05ad3793808afb478
+ab6aa5c71870daa409f2c72777b9e11e
+ab6fccae0cb0ec5a63de70671c805cd8
+ab709e11382cea356ff1e508a7506805
+ab755079ac0b35b8ed4fde1ec5ade45b
+ab7637913bc3be415c79131ecac548e8
+ab781bdb74df08a595424c2991f10f43
+ab796c8922b118fc1b4805c911e4dfa2
+ab7ce75e17897292d8f1b63f56ed2160
+ab8019ebdf6d9b86a48a22e0c0694062
+ab842a5d3d3e59a0d4ae5ced387d1b28
+ab8d936d886d93a24b6a8f60aab7d30c
+ab8ffdb54e0492226702eddee8354e9b
+ab912910ff3465fd5fd042095715ac9b
+ab953aed3fc16cf00619a5b6c7ec5065
+ab9715859c554cdb0d4121239922e224
+ab98a06700af0658c86517888d67cbdf
+ab9dba2d9346915d8a2d8dec235ad6f3
+ab9e0a2b522d7e39458aab500a3ead16
+aba001bb2e74fa171e54a244c8f4237d
+aba8a6d3d4697dc00afc77f730dcd29d
+aba913bf8fecb68046821b21d32a753f
+aba947b0945cf24cff8fa86a03dfe139
+abb142234163d8b88cec2476bc4751cf
+abb75a46a7fb855f41f5f2b2ef1b13a2
+abb8e5b549fafb761720412b838b6e2b
+abc2b43737cdceab87ae36d7c700620b
+abca8bcfa8de4d13c74a46a2e8973d3c
+abcc7afeb67a0716942b7f24da60142c
+abd05cd2a40153675b96ed5053e0b68f
+abd307f26d776bed767633fb3c8b492f
+abd3e23ecf3610d7d5736632bcc9574e
+abd3e2d2803a4311f61bf37171bb75b2
+abdb8ced6946df56347667b94c7a19a3
+abe27c7f7dab0cbea056328712ad83c2
+abe366375a00485e5e5acb3075042e00
+abe4693da90c02553e4dccc6649a4505
+abe52768990a5249f7ded9aa22634f3c
+abed9985e50933fd0b14549ee819afc1
+abf255468eeb1d22b3388e8b0bbf6994
+ac02fe3164ed4066842e0dfd0984a7fe
+ac12c5a936da317bbe80a11a1712d8c6
+ac196f1b80eb226bb649e0ddb540c3a4
+ac1e077c3e4624f46d0faebb67ad7a65
+ac25a190bbde4df80f35972fd5131798
+ac25d8288f2f00ac28b6694540a092f1
+ac264e32fd9f555b3043dd58d7a59796
+ac298bd5036a9dfc9b5665322400915f
+ac3aa89b2785a4a8adb0f90bbe479291
+ac4046a312518289a6cbfbcc9bb005b1
+ac42f67d218bb47d22db32a79f0ca25d
+ac45894560292f5769f2f6f2b55c9478
+ac51cb3273de58d2578353bba4244568
+ac528d33203bfb9ec928745a90919c8c
+ac562754332572391995322b70b9b6b7
+ac579d7a970798a2069f686991de51da
+ac6076904e1b62ea0605d9d615d981b0
+ac60fd6dfcf0808d8a625dd4dd91f9d4
+ac6367ad90687659113bba6748bc54f5
+ac645970af153cb35b54890404cfe169
+ac64f17e5843ca400c4314e3d3903950
+ac68041cb82908286eb17a5b0ebf1614
+ac691685a848326a54db6f8f18686413
+ac6bfc2b1f35723980495cb51e6fd05e
+ac7631d6d4b1685f1dcf317fcb89d66e
+ac765dffbfe1681d0a5984f76a43a213
+ac771fd042e4c9798b3bb59ab12e3dd2
+ac77d68291b8eac9cc4d5425fc42b169
+ac7a5e6503eb2c117277af014acd04f2
+ac7b24cd138c55f9dfb7f7776eb55301
+ac7ca355ffb9428df93e6814f10996eb
+ac86e18e7078d5b4807b864ce2bfba84
+ac87941c0805cb16fd74cec864a93603
+ac87b4643a162d169619097738371bd8
+ac8a97792d87668ebc9eb08a3a3f9ee3
+ac8b8d53f8331417d6eec6e6f2dfad2a
+ac8eb3df595580580f25353eda07bcdc
+ac91b2ae9a20b5c3610c396a94355ec4
+ac9324243e6b465d8d694b25f263d737
+ac997754e918fae7733d6137ef519590
+ac9a755549431fe06844479fc0f34fd9
+aca1252aa52cdb29db67cc7e31056a34
+acaa80b1088bac61a21e9908dd970ebb
+acad05515ba97e152a05eee364f7f751
+acbe7f3439fa7f77b2008f8159458717
+acbf13e847ac2085eb510780dd7b4f33
+acc7b9362edd1dd2a856ceb2a5559d78
+acc7d6543a93c98d6d1787a7cc2c49ce
+acce4d5a212b261cbb7c26d61f45675b
+acd004085ea907d706c6bb1d1c00ce09
+acd9765b5228e5a68c82362e61df7961
+acd984510ecdf5461c112a3c0b2c875a
+acdb56f775256937ea3aee4b64b1956d
+acdb83b6bd1c98d6c8a1fcb19e271aa2
+acdc8615fad5f7937b4d9c96fe7da4d9
+acdd10d2c5003f10146e468aa03beb2f
+acdedbe878e59413ded26c0fd1599393
+ace19407f8860caa886d21086866a44a
+ace967816af932910830304d303cfecc
+aceb9cc5f25dee4a54201e6201636aee
+acee42817574e62951aaf741b5d85702
+acef487932486136bc86f0915f580718
+acf7438e262cecc4a212edc2b63785c6
+acf756e412497b0d23a686541a6d80bb
+acfee8ef9a37a7e626ebaadcea0cb097
+ad080a692a622b71e64d3a1ad135c90f
+ad0c6e9eeb25b982ca6cda00586d051d
+ad11cbbc91ec36ac61404971d9f0b3ac
+ad1553af989087080f628469b9ef3378
+ad20b0aadd7469ec05c462b027ff6323
+ad223922daaee509ab4b533bee252155
+ad2c33edca0d770621373ba0f58808bc
+ad2d9a801f1d5773661f217abfd10085
+ad2e68ba15e601f3aad2ea615008e49d
+ad307afc9013a76437b8149749e98a90
+ad348329ebb9a4fb63c48803a2a6869f
+ad368f9ba7b30e5d57339f85364ae72e
+ad3cde9d38ac8595b775c7c2c3a6cb19
+ad3ee435d3ffa3e6e308039d862ae6fe
+ad455b8784fa0ee9a396ff6b1bd74a31
+ad46879e929314a6b756cdafe0eca759
+ad4c8312d59329ab92a2ce9bc9a6ee5f
+ad4fa03740340c10a2321d1e6fc20b06
+ad4facb83019828863a8b9989e68ed6a
+ad52099399c6e6e10371ece7bba7838e
+ad583964da1b629961316a4158b302a1
+ad5872fb5f8cf9c3ab5e715500b49bc3
+ad5c80db3ecdcd0fd0ecb974734a8335
+ad5f27fdce108ac7e002f4be2d67bc05
+ad610cf84c8d83e7800d634209ff5eca
+ad64512d66b20e6dec2b522b19a865f5
+ad697ecb628335375d33d6514eb666e5
+ad6c8ee1006fc80b74200bd9879ab88c
+ad6feef7a7bc2853ecc2057c2f6fb720
+ad71cd75212a86ebae5f204ecaa3d22a
+ad794692bf7695dd01f79f375fb29fd8
+ad7f12aaebff16ed7f9a2a7a50a6aa6e
+ad7fd9361eafd5005a2e4b57b022b8bc
+ad82f82f770b441ca546e11b402d3b22
+ad8556798acc964026c7497b384984e4
+ad8bd21be0689ed471107992968a1ee8
+ad8db15378fdd0aaa2d19b98b88b6147
+ad8ef6f215d5dd273bfc639d0979e028
+ad95008005643421f80005021169c043
+ad959e15235351395edf7776412406bc
+ad96146886d0e3159f04ee0b10726857
+ad972903c257d964dd2cc8e9e6359726
+ad9980a90384e7e71b5ad14a4cfe5e5c
+ad99df8f1fbf5235cd42430798741305
+ad9b104b914b0c58ac9a53eeb1cc3327
+ada3f3765794d7a1dc9fa3932a2dfef6
+ada68b0af0803a4910bb27c5bee25c56
+adac8b89defa83c8ffb1c0cab96cdb6c
+adb6370ddf7a93a90a75a6d59dd9ccc7
+adc06a24ec0eeceb296fe9eb91421971
+adc1974be058cfdc05e71baf2015b211
+adc460f797783f5377c8d54d19d76170
+adc639271b164694a62408f965420367
+adc734f88e6c66fcc336fe5703c1776d
+adcb168a4f4920eb76fe72de68297bde
+adcbc5246ab68a58ad7fe679c8c298f3
+add2fa8e3624807f5bbdcc19fd36bcdf
+add49ac7c2bf5cf2062719ca1c5650b2
+add54d8a75cd7ad828927843caa3bd69
+add5ed27ebc3f22e0287f25607026b0d
+addceb8d02a96a1ebc5aed1f168cbf5a
+ade14a86707a2576c5e2cba801bf8ab2
+ade4efe4122631da2ee20778cbf8207c
+ade63187e6b3f20dfa42f2feae24c6f4
+ade664148ce481938bf38b23b588f8f6
+ade8643c6d2a18d71141dad6a0e4dc66
+ade960391db6bdad4752e9845a72ea28
+adedc7c241069557e3b6629f268fc244
+adee254ab06cfd81a7b98a9bb468c7b7
+adefb22fa12271199fc33bfa0fae693c
+adf3b65f9f539d0668c69edd6d33dfb5
+ae0068b6d0301f801cf34590e9520296
+ae023a3535192a8b2826918786cb8140
+ae0278fb2fadd69532bc5a35064a39fd
+ae02b08686deab4907156c787e6130a0
+ae04ccd6ef643f10b17146bf2de5217a
+ae0c84296748f1be1b184ebafdcac6a8
+ae0fb8ad3ea7745342cfc76e49951cfc
+ae131cd6ecc3cec04760aeacb769e991
+ae14d4909d2e423dd301b5a0c5b04803
+ae192bdf5fcb12deca3a87a7fd2de7cb
+ae1bb2ed630d0a4ecea9999d3af08afd
+ae21364ad937db64853f70be9384cf29
+ae2166cef4787d2e7700103ff0638f8e
+ae24df404469c8091734d00fafc813aa
+ae27604a14ea53783de69e5c9130a504
+ae2a3dcb26d8ce3e794a5a9b4677a2a3
+ae2d2137a094185486c580d280f3aedd
+ae3081918fd943bbdc453a7814dc7a79
+ae34bfa8c80b39adde7dfaf949958362
+ae3693f203c0be9a08bbeffc36de9281
+ae3879e0841d5358cbdb34a293c2f506
+ae3dacd844f7f360da2a74551def5c61
+ae414c54022163a3ab126f92449d1099
+ae431b939a3c331ef6da5b01e1b2e701
+ae4797d4311d01d45e095393fa215257
+ae4836d71786a0be2a97d6eca5e09bb1
+ae4867312f826c33e1fed2a8154d0f27
+ae4e4ca52249f236d4c5197a798d6427
+ae4fbb531c95dcdb3ea7aa70c0be6a59
+ae53ee7a67650c8e1812afa473fef168
+ae595434ea13223e3f4cc4f69b4af0e1
+ae65f351c83681f0d2ef9afd9386ac7f
+ae67a4420d79f4dc88f3fa0c5b543c83
+ae6bf215481b6fd2895c4362fbcc8fd1
+ae6d99c66fdac4e71677a318a4a193dd
+ae6f14aae96cc6817981032ab634663a
+ae71371b59ab1917b2afbd73d06818eb
+ae71dd72450506109babec4984448c09
+ae88acd7cdd5e5c441e14e916e345c89
+ae922a8c860e7bf2910b2f98b4a9b276
+ae95878a8a2703f78332ca217400a35c
+ae99d123b7f95f4d40613aa4d7f3ef58
+aea0d11e5cf469f7e15445d1dba0ec4f
+aea4c9010becd1b2dcbf04eb46bdaf1b
+aea51813be4710544d81841871fb69ce
+aead83e0a027aa8167440c8bf653027a
+aeadab88a5cca99f1ba7aa3cf9d29d60
+aeb0da2d6263773e3cdbd8d0bd65058c
+aeb1c952199e85aa1085e72ff78e33b1
+aeb4bc743a39e7be65d9c44c13ae6696
+aeb8a5e8a13f3dba28cf8552d97f0413
+aeb95a4940d14f5212b3bd08b39958de
+aeba152442d95b5eccf256b83e2849de
+aebe2648181f6de36855b0ef91d09c72
+aebfddb65449d2b8197e868386154c83
+aec1207b96bb604f422e25be1c260b32
+aec231aa631f46bf60f239fa34d520c4
+aec4b05f6daaad73b9805f9413693104
+aec5c9ac2f3518d52b513bced57692db
+aec67fd75a41f5d09cb4a6110200ca7c
+aecf4eee92e928506022bd29f4c7f8d4
+aed0f5ed42272f679e2964a3455e5606
+aed7511febd66ebd0c2b8c195f79a364
+aeda51ffc3100fe83b330226dc3d13d1
+aedd6ceb948630b608f91555da4033d4
+aee4c779d95b6123921f7e1fc8059426
+aee746816534167083de1cfb3b067fd4
+aeeed96207535fd783eef544abf3970a
+aefbb5bda80b82b5b8d7c4e7f2b2dad0
+aefce60666af56b305caf43be4f0eb58
+af0dfd62cd759715e9a7db665f6e9c52
+af0e8fa14e00075fff1b37bf5597785b
+af123aff193c9c3eedeb4992a19361ec
+af127b546be8bfc59b7a108857999b4b
+af151bc1f80cd923d04080c602cd1cb9
+af17ee6b2a7e8ed7ad54ca51b09a036a
+af18a720531c2f1a914dd963e47286ce
+af18df60b83225839a4ee33d89c94844
+af1b985f6ab0e4e302df88b20ab72bc8
+af1bc6c08b9876410aadaba0f4f74605
+af1d9b2030c56ce93c94a4453dab61f4
+af20a0bcf312ecafcb92d7d8a29600eb
+af2851144f41eaa76970f000fd5c018e
+af28b1255046e259b3f4416ebda9cdc2
+af29a7a9321c0941bf1200a2159f95b3
+af33c04b9f3d17e7bab61102634e3413
+af372365c89f4da8fcdcb987dd636319
+af40d37511714a65920e03ea6dc87591
+af4906392c40cfefe61c56cfc474bc32
+af4ca8db70e2b39f356221bdcaa07602
+af59039f7fd030221accf7065d289c8f
+af5fd4a0b138a7cb3d722648fe9f76e2
+af656357dc7ca3f568e0c6331495128d
+af67d598838637d4c2299843ee81236a
+af683e9bc3d22fcfb02bd187053d9cb8
+af7704910a12b691555ba2cb2bf45155
+af817c74a01837b7025f865389dfc203
+af8220f0b4c16293d034d4d72b3ad6fd
+af8d34f8092bf7e2814f29e7451699df
+af8e95b1b259cfba760c45921413f9d5
+af8f9af08f94ac82a8fbee8e4864be7b
+af9b75e9d5ddcc07ab528ecd4545a9a3
+af9d542362ef4db8540efb0b553eaec4
+afa32d64646cf4fd62b556316ae33e4b
+afa8433d258373b53252d7f3590155f5
+afaa34774aa0c4b0fe3efb999e1bc850
+afab22415a00b452f55ae5536b46a8ac
+afabc7d02b419669e3549cf0fcb8c57e
+afb0d0a02918af4371d90f3af6a4b223
+afb1833c1265f6106c39c3dfe63996a2
+afb3d65b40c59eeed5ddc0b4389a7db2
+afb403d8762ea0459c586a7624c89997
+afb618c4300402a6ce5f4bf84308881a
+afb731fc7719f91be6efc9db877b896b
+afb8a6e143b47e6113fff9acd55d10e7
+afc377db7b09267cff2aa001c1ba03cf
+afc45100957cd7234757c04ad453a8f5
+afc5200bc6c6f8540659cd10501229fa
+afc6533924aee63adb52d7a23869e26e
+afccdd1649487197fefeafff49276bc5
+afd0c3b118ffab2aed4d6075ff82afbf
+afd1c3f291da477ce8cb34ecaed18a4e
+afd1c74be55be88a9781b8f962879d2e
+afd354f01ecc1199b2fcb6edb1bbbfaa
+afdd5c2586eb706e9a01101a4be81a9d
+afde971233393044fb66d1ebefaa67fc
+afe5661f29269bae1e4fc100eb87bdbd
+afec409a1a09dc74f37abe9f24019130
+affa208224faffbaa43022423b1029c9
+affa47858fe22ca285e49d5e7f52b109
+affcbc60522cb62a40244e54e01272a6
+b0023ce545c557990da3292d3352ef75
+b00348062392a28fb6f64f55f8bef5d6
+b003ac024df6081d512dec7048711d50
+b0058d3dd23a8ecc32e4d6b42abc53b2
+b0072bf689bf5b08e0377fa084a65b76
+b0078c7b757653c9c0b7a2288920fa7f
+b00ceca7afb0bdd1a2b1893fc0a2982f
+b00e42a3bc94c064cc6d47ca904a7f8c
+b016968885805a2f4ec1a0e8ad0a7904
+b0182100b92e307f7ca956e565ea383b
+b0189a9cd14937e54239a22fe508f060
+b019c1605f8368e5bd89ed527a4d60a1
+b01afcae08babe504d65e3f59f19bdad
+b022a4e37a5002bcc96270a171460b17
+b0240f075ecf03141e99b871362b2915
+b02668a957b127a28767597757afe13c
+b029d5fff80b63b7d0d62b783b457668
+b029dd4ff5784be726458f57f3bae466
+b034ff0fbd084ba84446212d759f539e
+b035416c67fa432c05b66846195b9da8
+b03921f1d5675449db946cce11341463
+b03af17e55de781a31bd7e75e4d36d5d
+b03c110eb71bf61c60a052aac9cfbd06
+b03dd4051b0cbee245194248d69fbd7e
+b040c895327b8bf967a7ef83ca9a2fa3
+b048c3b0dbbf1c8eeddddad457fb0fae
+b04f262825dc79e7ee0285ad80ecee7e
+b05c7550a2c4cb538286278027e31b78
+b05d81b31ceca0cc8178f2440bec0bbe
+b05da5c12bec67f2967b577f9e61dbb3
+b061a36e84457ce83f7f8d2b398f9754
+b0636799569acae92f33b46faf3fa02a
+b068d4a6dfda7e6cf507078ca3748244
+b069ca76763079792490247f4433c61a
+b069e24f70c23dfdd1908b20d46a26b1
+b06bc21fceb9fe01427f93c14476371b
+b06f5b25100a9f2afa1cbada975ad0a8
+b077d1ff85932951f1032f8e5fe7d495
+b0780a49b7e5b04d3097689b3a5bb0b0
+b07a424b2a2c46de2e76984129e4c841
+b07c677b913c7ff2f6c65de4158bc66e
+b07d97574aeaf22c3601f39151bd98f4
+b08ea19a54932bad3b31c6293caa9ba7
+b0920fdd36227c21f04f84f0db7c869c
+b09724ccb17f368f6dcc7aaba31cfdb1
+b0993338620994c0837ecbb50fac12b4
+b099c5e1e0a96366b4b63fe6c5a6479b
+b09ae8be9397fd08c04b5442c2bc63f1
+b09cc3c319419161c2db3905da1071e1
+b0b190fb0f52ed04bbf8014537f43669
+b0b699fe21e88020f6a1c5a027be1edf
+b0ba0aaabd9b12161d4ad113987b83dc
+b0bca52f0058c1d955ebb636fab93bf9
+b0c297e12429822baff57b741fe5ffdd
+b0c79bb3e1c47ab4b308d8b50d3c7190
+b0cadc7b2cac2b8f2bf4fda135c23c5b
+b0cb5f3428d1aa11ca6bf92017fbc0f5
+b0ceb1dcb24bf679fce27c89318c9cb3
+b0d6090d6235adbf3ad65cfc621ca100
+b0dd7260658158dc6288aadf887f0b20
+b0de0a2550140b6708bfac7fc4d1311e
+b0e21c27cb43325f0d2e4b68774c9e29
+b0e580283d40bc2cddc96bdee652d456
+b0e62eadc8fff702de36db462f916158
+b0e847cdb66477587a793cae3a50849c
+b0ed5168ed64c5ea230e036ee49d17a4
+b0ed70bf96b459883d2562205e142db8
+b0ee816f433717323efdbe06bc385245
+b0f536a2d68e78327547df0aa7fff1f9
+b0f7475cdbe5ba7bde5d9d71d1c71cdc
+b0f7e6fee81aa9edd3b1d6da66741a58
+b0f9433ca106f6737d9f774b1a842286
+b0fe133cebb27f479cd849156143fd4b
+b1006e18bae5edc0640177167e8eddba
+b101e0fa1c94776e95b6bb370b927628
+b10f4a0102dde33b4e41f297074fb404
+b1146dfa8ffbfa6167afb0a0b9b605e0
+b11e01526ae9dfd2e509617e6a33864c
+b121205ed9e49767c22426d9e023fc5e
+b12378cc4e6cc89228ad7b722f7a1025
+b12b7b5f3619697297464b2931fc28c7
+b12c36d89f359589e4b24ebd2294de5a
+b12cfdaed7541d7557cc60af068ace97
+b131041da698d9df6eb243d147e25aaf
+b131c13318299709402bc08df954e568
+b13944daefefe8f1cb4e087700f17654
+b13ce15fe6174a07b39d2b14bf554965
+b1472d0aeb8839b61d94a10ab32d481e
+b14bf89192bc622c4d2cf83939e0b487
+b14c1f25953e74790bfb7979fec8c7ea
+b1507baead651d7e9e0c95eae3cd7063
+b157b93be085c79207c9422cb7e9e33d
+b160ac12c2ad53feab264b045bd64d53
+b164ab74eb5c3d6badcc075e0b95ca55
+b166d51fd6a36efcf180e30482c20793
+b16775eeb4430de4e9411fb6ff3ccead
+b16961ffa3a09580846e0412fc2eec95
+b17207c63ccf0bfdbd655ef3ec5dd384
+b17e33d2688e58b9b1b7f1426c4dc1aa
+b17e4eee58f92715f75b9befeb28a80a
+b1907f4a203ef7a3b1743931cd6e0ff0
+b193e2f5debab5c5c9ee7f313a7dee36
+b19996ab23c7493987fb14d8ac110be2
+b19f22462e4cb12bf3a78156b03f3404
+b19f31da27578b77e120124b7e91b8c7
+b19fb628ff498ad6da4faca70400dfcd
+b1b1f620b43bb68b2e2895f7c521129b
+b1bd0a9bf7ef833367f8ae66155d7c21
+b1c79036c2e37132df6beb4cc7ce22c2
+b1c8b8d0134270d983c63cf05f0681d6
+b1cd4ca15c3e4d2aa16723473f7575ff
+b1cdf4ae749fd3f4b2916f90c207db12
+b1d0e3b5dfe6e31dc1a3296bacdcd723
+b1d9bdc61f8dd3af82e23b610b6f7fe7
+b1dd462253a6860c6197ae6e5dfcc182
+b1dda31c9a8f0e4b43ea77a4417e423e
+b1e060cd82344e3247a9293d4b26a682
+b1e3ce89d84300594e6f13b39a4baeef
+b1e75ef9f125bdd179ed9c88f2c6f3bd
+b1f2fbc855a5aa07de3e63384b7defa1
+b1f346d4add415024bba3a5ccf00bbc8
+b1f59caa1b42ba87703b722c6567f4c1
+b1ff0d219255972e58380c0d1fec53b7
+b2019eb6c10d3df138c7a70b35efbce2
+b2042999ca8596ce5f25f2baba4b2df4
+b206f33679ea56623c70fffb7f6e7339
+b21e8cc81a67417ebd457ab61c912c4b
+b2295934af2a48ab0205ea8f6dab9517
+b22c63290111e73906a8f924d4fc7360
+b233e53c9cd06bfb6efb90f984faef0f
+b235e5b89454bfffda572e6c0b36067f
+b2362dfcf73a0313c923e3b2906ff194
+b2390dcb52d5faf0c620df796efe9269
+b23a6f450f8bd4e65de4f88510d8af29
+b23c91060a9172b162fde7923d1ab0fc
+b23d30dacd203346b063dfe141adf749
+b2403ebc657f8fa7660a798ba6d5f923
+b2407e2717defe784a20a33fa232fb41
+b2413940be04b774de28b69b11a97646
+b245a11852555054217f06148ae9ff7d
+b24c6362c93dfa570c2f7619816f946e
+b24c96a752dd665739f907a0007568b5
+b24d6dafad00052b6748f394dc93f4bd
+b24dc65c6f54f69810dcf5a1743c7e0c
+b24e94f047e5ad1d80333374ad1a36b6
+b253ea3aec6c3f496255b36414194760
+b25816af2c7e4750fc35823e691375b4
+b25f1cb7e7a14cd0cecfa39cc7d100d8
+b263eb9f0c9fe177143877a19c897af1
+b26505c6ad9b5432a9a9aed9f5fd27f3
+b269e042f29c053d8d8746da236c9720
+b26db0bf383246e625d8dcb2929fc2f8
+b26eadc04e5dc2cb71b0081c96a6b289
+b2794d1e3df2b53f09fed8f2dbc1dd18
+b27b74e34e5f9d55452d5c28f6998c74
+b27e4e1c5932fe4f90ec29f6da0752d8
+b28448e7e19e0a27766b400ac289b00d
+b2852e31126c1cb04f8d28269def1b06
+b286aa60904b4f09cf808d95c668b1c5
+b28b018c3de8a202a7a1e5ce6c88b6a0
+b28b9686c0f0154612975e8710e310a4
+b28eb38c4eca1c29e862110737b402ae
+b2906e1841b85dd22f01a303b167bd41
+b293ccd904eff216f617eceac55021c4
+b2957bb54ea6cda70766ee5c79069083
+b299e95512422fb4e9a117a62aa722ee
+b29b12e87e1b352ecc31e46cadb93e4f
+b29c5b8723ef7ba692d60c37b778dc54
+b2a27102e23abf83a48946d92f0d6471
+b2a5672d500b935223f5998d7abc73d1
+b2a9514a459d6608c9048312e0ca208b
+b2b0e347e56e1aaced5debed4deb944f
+b2b1be8dbf9bd3df77b314e58c3ec1de
+b2b7df3af217f92e5883f199ac962a7e
+b2bb59bdc79a692e5b6352f4af2b5ed6
+b2c2bf6c5ac22001c7535c6479baf0b4
+b2c45a006b42f143e8ba23977e89ee86
+b2cb495e14f04eba872f9c52dfc4935d
+b2d32450751a27dac911f847112faf6c
+b2db563db0c255cbd33e88744dbb2eb1
+b2e52b041f272d5f0d70492c2db7cb8f
+b2e59f8f8c979490dcd95de39dcdd5aa
+b2e8c7e8f8924bca673da771889b5326
+b2e8fa0582800341f74fdfd75aef2007
+b2f2949dc60f16d22a45f181b6fc6e66
+b2f32125c2b9ea6b03c035444adb7a40
+b2f9773b4b22d5d0142358a7f433cedb
+b2fafcab71ed8a7c5e5d56c14f03a716
+b30a14cb8792f2c7a54827d6cf7a0160
+b30a8ddb8e5a4bea22c4bd0700510151
+b30af080339e55e1531646746c429dcb
+b30ecdcef6d970087958cecb4d1e5e11
+b31102c192fc4329ad23706a654845a4
+b31cb5b539ab30dad854d8915cca6142
+b31da65a8024cd27f21df8062d05da9c
+b3201365c838a8944a49d11493edf7ff
+b320903d6ee56d8b25f0c5eaca4f3917
+b32380c8bc69d76d631cc7397118ca30
+b32f4cda774346878d27b030e002af0c
+b33a12d455a2b127b13f797c478e0959
+b343417d9448957e249e26fcbb28786a
+b34e7a09d00601cede220fcbc244822a
+b3513727d09c09179e40c4a383a0ee8c
+b35382fa8b5b16009d2a83a351a44bae
+b3576ef3f5c12757a91e324cf3abf627
+b357fbb4df69383b91a6b815af87dc2c
+b35aec3cb72a2e04283007f6f6e56c5c
+b35be7a4c8f7c757d74608be9995e9f3
+b35ec4d713062489be967eb54122a436
+b35fd122927103cd9f100c903e7b4f1e
+b368c6a80d83570d679da36d388efe66
+b36d96665f578ca728f63710668f6b11
+b3722224819f809b0a1c8d1f4a553b4c
+b372599e9cfa3a43e4bed96a75182f03
+b372ba10255f53a089a04f1faa7183f6
+b3731b1f430de79ee8c5c693f42af1b2
+b37455e8605029af34b292bc5791793b
+b376fb1036220f96e52e3f07b8c0f0cd
+b379b06c7131405870ac98db03c9da1b
+b37a2af17bcbc7bbd869c156dd1fd7ba
+b37bf8e513438ec83ab68853c9d8f279
+b381533872948313ef7e22340849b98e
+b3851ba4825844148b27f8c3a9acfbae
+b38b66a31066c8942c0c2b63e1d79fef
+b38bd2666e54749f9174c96e74feb7a3
+b38e86f5351228e3a1e791d0839ec254
+b38f30f933742b76919c55b687096c94
+b392d9c9463ae8c581dfd8d6f2c35730
+b395b879d2dea9e3a52eb2750c37ce47
+b396a416394e7b2a78cb2ac2f542501d
+b397862b0eacb677b0d0bb1f7c8730b6
+b399ec7d1c2af23ed6d671927a346902
+b39a925e242c3a722784c58cc18c355a
+b39ba9182271b0ad6bce9c68687f34cb
+b39c51c6ebfe70f33ab91ef5f5b3ba2e
+b39d91eb144ea2657b90cbdde4055ded
+b39f6909538e91191905245aabc3ee55
+b3a353aea9aec2c321dd31a0686d375b
+b3a437d6b6c8604c2fb733758cfe63c0
+b3a65f8660a7fd2a35d4b30ad17cdc3e
+b3a7dbc4df2ec4f21eca8df202d73ad7
+b3b3dcca29282bd30b4d4e43f62ea505
+b3c0bcb764bc8dd61fee703642206373
+b3c0f70df9d89a6cca003e4e4425c544
+b3c8104287bdd9d55cf13c3cf43e9d95
+b3c9538e0db046f93bf35974ba508732
+b3ca9d6645b8492028eecae144bed957
+b3e4daa9dc1e1e01a687052989c09d42
+b3e86deed6244e60d35e3cb7368fb06c
+b3e915831054ed3db24c914854548f25
+b3f9fece9967896f7e7965035d059b2d
+b4057835bdd097e6a275ff066b747468
+b4059286e09974abc18a56ba7fcc9eee
+b408fc99792547be484d15a1489c4a0c
+b40959f08d54bfadfcd2d1d0cf5f5d2d
+b40dce3711877f0e7854135510f3f8a9
+b41336ac875f4b1ab44d9a3ab61288c5
+b413c3b17aa56ec1183a2580b8f75929
+b417c733f1584d7ad4157a533433b29e
+b41b53695d9294e78ad1db2c484b6110
+b41c82d9583d00cfbd280a47273c9b32
+b427a23d2c25ddd3bca012260e1e3912
+b4290d70b61e0d597332ae1f50633eb6
+b42c057630f7f4f1ad80977ca24c0121
+b42d5b1938638f38ae1f97c45737c314
+b42ee55d0036530e7626cd6e88937c16
+b432216db666cf4c5e7d265d189b9c04
+b4350c822e414a85f403129d630e5274
+b43563040b3669c1a707bb791c265f4e
+b43af6a09b032079b597b1caea126dcd
+b44760993d5e68c1dddd5d4e1202f5bc
+b450f778ab866ee81f2bcd880f9df1ca
+b45637bc8be31c80c3972a69f65d035a
+b4579508a77a30a6c18b309b49203d9e
+b457beb9e98059249b5cbf39c4806fe9
+b4649b456b52a4eec121775323d3c7d7
+b4681ce6f72143bbd086dff973176654
+b46c3b7e1bb9be9a90fb6dede1f5aa86
+b47217003f968a3818468548b7977a5c
+b47bb9810c7a8d91c947651507e9af57
+b47bc6c98fc5934dcef4154de7f45d67
+b481f6b418c637e60f56d40a708452ab
+b4868958d11a557981e978b758e14320
+b4915eb38286404f2671908745165223
+b49a81d18c2a7d0bd3d0e7b5bf89fab4
+b4a3f88cdf326388120d85e075101fcc
+b4a4465ce878e1a27c980c5ea4399e26
+b4a4cf809e635eb019cecfcfd330de46
+b4ab0c96048fd7a61c96ad13abcd2015
+b4b04035a24c51d7943bffec4814ec64
+b4b180e0dad7c69d859ac96af46972ab
+b4b499b76b1cf8375e0f57fd82d86ba4
+b4b6a22183963af9580282dd6c4864cd
+b4b72fb46b8e1a492c76f50a4037eaa0
+b4bbc9f090fa57b28c0207123c5ba2f5
+b4bcc934658663804589e613674f52b3
+b4bddad7772aaa0673b347674cd13396
+b4c038e3cbce873c5ce8937f1708dfef
+b4c07fcbfb5d101cb311a1e4aaac37e0
+b4c3f55c8f7611b27925baf355e8918b
+b4c9645dce46dfd073176194acbd8f3b
+b4d16fc6080150cb7ffeebd2985ad760
+b4d3724f9606189aec0cb6aa31f756d0
+b4d5081d91c9491c6e6a7e07619fe876
+b4d648285c33f8020ed81887dbd150ab
+b4d8525cad03567f8a9fda86c5f2dd5b
+b4dcccb741ee42b8c7b285526884337a
+b4de5daeed519e12b83f30c57df33769
+b4e796e848e3b6231cd756bf8b94710e
+b4e92b72f6a5cde9e5d49636137f584e
+b4e977a45b0e995e4d9b70a0c0d2fa2e
+b4ea68e6a3fe7b3af88ac33e55560e54
+b4eb35b03c731ede85afd662bc157894
+b4ec539c02af8d49a1d0bcc466b14a3d
+b4eeb6bd5d7e3275c6bc0736dc027bdd
+b4f7056302cd9550f895707cd9049578
+b4fb636dfaac80c44c37b30fdffa0282
+b4fd3bc9366a91a4607c09c6e4014bf5
+b4fee6a2458413360c42248ec60ef61d
+b4fffc5075cc9e8009099a3fa36acd70
+b5017363161e802674ba90177b9ee4a9
+b50aecc2dd0b7f8b71413fb9c64c24c6
+b511d597e8c4b7d91ec8269bdc52d9a3
+b5121b742dabdaed7710b3e4181a7236
+b515483dc3b15a8b797e0fb363798792
+b51c5a8b0d46e6992c634197be959060
+b51cee3f88e6b43cdddc469163ce9b26
+b51e41905f088714d3d0bc3cb2cf5755
+b526d99997de432004a6891553ccfec2
+b52d8f2c079035bb0cff087c79c7628d
+b531e9d2e1fb9f16206d24913cd147d2
+b531f8a6127c1e2334669aad2702c422
+b536d62d60865212b07252b613fb66f7
+b53a82529c6235151c720adf9a84639f
+b53acdd4547140209f6f9bc0d78c1362
+b53e512da982d82228fce6750accd1a5
+b5475faeac6ae602fbe1a7f7cf3d734b
+b54858eddfc85c5062756029b5b07905
+b54a13d2e6ab83c2ec5d360e6a30e9a3
+b54c80f2b9f28ed1268c9aa58675ec16
+b54ef082c6949787f56e3f45a5c3efb9
+b552bf5e6737864508ca08a1d3bd3e10
+b5542c2003efc970af3a5f55ba0b8c1e
+b557d5baa473a0f01a5b3b898c38aeaf
+b5592119c2428a65546dee0cc6f7e022
+b55a33b4a109b7e6aa49549fed4120d1
+b55b1469818d69489edbca29ac54a2d2
+b561a3f62045870c2b85853036b59aa3
+b562459e2cfa4f293db33d49bbe267a5
+b562d87d375ce33ad57dfc3d72ae55c9
+b563f09efc2ad25628454b916a08910f
+b5687bdb75fff9332a746932a5d0c07d
+b5697fd50a12bfce80322574b250102a
+b56b262fadbbbbb6a1608e818fa1c1aa
+b56d38c75346d0f941e8aa58a129db31
+b56e2205c2769cb26e89605536a16c5b
+b575f5ff3d60b580b9363a0e2a41d2e1
+b575f6deaed55c35e4785cc6d31f1049
+b5764f8f5f0ceb5842a2525c09a5efe8
+b5775372139709d1e7f1fa20940a2b8f
+b57b40e3183ec68484eb9d9f9fb5e96f
+b57db92095e48f2ab4aca9267e304db6
+b585162e73efab205530a6dd32f3f7fd
+b58ac64489bb38be1efff7a320b48fe3
+b5a0fc784279541f81d64b28ae984dc4
+b5a301d559d88ab3e9d99635df8254aa
+b5a32260676a51bb1b1ea7afa30c8c51
+b5aa91ea815222b8adc599056f83ea49
+b5ac66b401763588f5f07dc51a4df7ef
+b5bbcef3b3509ee2ee88a356aab69722
+b5bdc9e9dba3fb9859c22362d0fccb10
+b5c11f5df3b752249fa4b360c7a20995
+b5c1fe4afdeb13ea6508f7da9fb53cc9
+b5c3e55567e93d10270fb29884697ff8
+b5c99d08c545abaffa7ad813fabde1b5
+b5ca00101275b22e7f52520051127417
+b5cb1333371793b699ccec828b08f773
+b5cfa56fa65818c45f1ff5176065b1bc
+b5d09f7f4b2d6c05c44b164a844325d7
+b5d1cd5a8b5f1fcda7ca245845ddd697
+b5d2659f1e36d48599f4a90685818f49
+b5d279062b0ba10001fe801e40ff90ac
+b5d2f91a7dad51442603ac08c3e28f67
+b5d8bd3c48ec3e0ff9754c4c37937444
+b5db7c99eab404f1dae2508b76161116
+b5dbdfc83c991dfb6717609cd276534e
+b5dd9625f2f49471d2b272869d97fb7f
+b5e47b5b5c65c026bb10488d57c2cb67
+b5e5a37c52fb349213fbc2c6e7a367a3
+b5e6c961a353faefa2a630a7a0b91b4b
+b5ed6b5965eb31765665f5539a6fcd59
+b5fed6bafdd943b37f5ba3140bcd0ff8
+b604d50e77d8dd3fcf925a55fa43e407
+b605670516214e4fdb4ede76ee486c22
+b6065bf5901d6636ba0f3cb1c5e75aa1
+b6120cab2d46fcb726feeea96ef18071
+b6149cfb1c5e2b75869b52035a3b3225
+b61bdc4533e5eb937939114e375fed77
+b61df124faf5f1bc2a39ab1b978db6eb
+b61fd109e41fcd2e0213a44e6d6509cd
+b6331bba73672af033f050618b935291
+b634c547b95b9dc28e41ae0ebe6943bd
+b639495358d62618ef62404e0840a60b
+b63bce1c9631f2e187211de76797daa2
+b640de0c79fd8029d34583137c6c65d0
+b642849fe4b52121fa2786c10f4ba356
+b6434086459942467e936baf3710fc99
+b644dcbc7cd56912173df423e946aa07
+b6495a62eb76e9b0fa16fdded0078bd7
+b64a0e4b07a4659f46eef2c47c2a16fd
+b64c1c474323919a08a986574f187444
+b64cb569fce7eaf525798fed49851a7d
+b64fee61df0c32b70707d22ef70a6885
+b6562cf7ccf3975fd25218fbdf96f60f
+b6574d97eed06ca8eecea1b22ae82541
+b65843aa523573400f4077101624d952
+b6585888bb6f94c91f8a88ae5e1bd6b9
+b65cff8f8f46e4ee0e2889d92be4ae13
+b6667a90211d22ba59f85f81b6005d26
+b66770c6802907ae75c211a8bcdc561f
+b669a4ba8298df432a3448f084d90946
+b66cd0a70fb348fdaac3f4a7dc1c921f
+b67994acd01b4fab48630a1a176219f3
+b67a0d4b1cd27f7a1c9cc187a4c85d29
+b67ca69830c2a0364a3da2eb6314be90
+b67f6231787dbd5a41ae6c77d388fa3c
+b6818eb5f2069ea51198cbf329feff46
+b681bc77e93ff8e79835a16b8255bfd4
+b6824c9940bcdb0b0569a13114b579a0
+b68717367c0e301b4219cb6490555ae5
+b695a5fbf1bfb5a12183910ff74d3d4c
+b6994b323e0c476b6cf0256df81a885c
+b69a57ead54caa03d7a7eec71d0616f2
+b6a24066052492135599082429156ae8
+b6a6ca5da9a2e81772ea87d03b604d31
+b6aa395bccfb94cd8e401989eb14f811
+b6afda3dfd18e00aadc1f9919f268538
+b6b4546a45481a4e896745d3b51ff359
+b6bdbc9e7c602e03c0e9fc40052a51d2
+b6c11c05b2484649bedf0fab599eda94
+b6c52e58ecb6fa892b4e8f0e1309b9bc
+b6c5662b094b37b3183184f299c461a8
+b6cf5a7cd3dfe7a13625bdfaca18eb0a
+b6d022d19e9b137450717bebbf0feca4
+b6d18afe1152647442d4e6c28d431d37
+b6d33ac8e3eb527d04166de681c3aa56
+b6d6b54adfc3022c19aa84388c04d901
+b6dedc92d9e4337ccf4eefe514997861
+b6e408057cac1f6beb7397983fe43807
+b6e7a75cbccf4a48dcb0ade6a0018bab
+b6eb8a5962ff3a198f3d22fb4575be40
+b6ed6ac189fb8c48378e3ce6ccaba302
+b6eece823e50bf6b073f3bd26541e70a
+b6f2e9f00fc3f2d542d224239f2ca13c
+b6f644509d00570fb134bc157080ac71
+b6fb4ae57dec5f638c2a0b725ae1dda9
+b6fc246834effe0116ce5c9ea7cd9962
+b6fde3c37381cd2b75e1d0e1d5fb6b2f
+b6ff2b3add111601d019466269125112
+b7018c6bd8c836d3da7ab1c4434810aa
+b70bc84fd3b06cfc3d2d3d89233ef1e0
+b71378a4027fbdc76646a35d7fee0738
+b71442f6563ad3f90b619385f594b3f8
+b714fc05bf961ce2cf939bb773ceb9f1
+b7174d895b21ff5d0643636456e9a6d4
+b71b6e788ebfbf88b29a62cff3945a14
+b722d3b5f62f8846308f78554da688e4
+b722da0f598dca4e7b5d976a29a5cc99
+b724857f6afd01fe91951044b431ce16
+b725d67e99d644f465f251817abe4e4c
+b72767739ce4b19826c27e6ad40d01c1
+b72a93169db476878d45bdde9b1c0333
+b72ffba4cf385093b327c192f77ebe9d
+b74473f6d717c7f20ea20dda5500e50d
+b7461112f87c3c1676ac9ca6ed239234
+b7464c284be72047e773e8bb5ddf7366
+b7482be8e3b0fbee0a2cbdc51f635503
+b74a0cdc89325f8ad6ba5c4fdeb160eb
+b74d61822330e9b15dd1a3cebbf0bd42
+b74fd017ccfafc319ae5833dda070df5
+b7590b83b54c4963ae2d3ff8f74e9bbc
+b765ea251f92805a6487dd226e6b9453
+b76617223a4efbde6e2f590df7e87b26
+b768001e49b90a090d81851045a96aa6
+b76b009efb46fe20bad875661ae3bbf5
+b76d48e9561cd5eab8178753414326cc
+b774b773b4eb127015b1ced0edf87dd3
+b77529ba410e1efcad163f1e4be78c2f
+b77daf32c1c93efa0ddb11fc97ad0b6d
+b77ebf6a874332ff6a45c9b87f99e510
+b78490001873decd7006ffcee8b9a099
+b78732d8c96532ba15bda3c40f9765f0
+b78ac07dcd59aaf04471de85b050ed5a
+b78ed584b092cc383e74d49ec6a842df
+b78f253bf4339a700e9f0585399279e2
+b7937c5fb23ba8da8eff406f0c4c14dd
+b7939fd331d332e4b8985cd9aafde654
+b7981e743d4a87d5b74b6244cca2f609
+b79b3cc34ecc8c93b61b54a519d790fb
+b79f599dbcb864f64417934021e0a900
+b7a1261cf4722136a80f462ff5d003de
+b7a1bfc7e42afe289d975e8bbe62dbaf
+b7a6614063c540601a8e31b8240bc739
+b7a904a481df8e33e338a42fae183b1a
+b7ab219558d2f13ea4a014a71049e2cc
+b7aed85ef3092ed610d259ea379695dd
+b7b65426c6b2143d52954c2a80ae17a9
+b7b91b1aa361d80fda267649a213a4e8
+b7bb61ef335462344dcd7b228f2c2b06
+b7bb87e8d3d782f0fe0ec0205397297f
+b7c043510b9865764dd8463d099366b2
+b7c6bd332f9652defb6f742121575cac
+b7c9825387c611a832a145c8435b18a6
+b7cddcfdb12d5a2cc6c718dbb19f9d3d
+b7cefef41b6f07008e8125982e21c761
+b7d035b0744aba89d210b76876f5cc76
+b7d5e369473a9f9c66e24e9cc6e82239
+b7dc560c16120eab64dc69d95f184c34
+b7dc9e9525125121db81a1ad0516cebf
+b7dd968ccf0ebcc6506359c237d91789
+b7e097fea412d0ffaeffe7482d3bafc9
+b7e4439c8508f51d511b0f22c2e4fdf4
+b7e6d180209de4ef34778e9831ea5ada
+b7e84922a0a2e466234e7c064401c042
+b7e88b18fde4eb706f25e6de018e6daf
+b7f1d443b6e30649451ac82f314f9ec0
+b7f48614c183cf1c2d1f1c6fccee2159
+b7f5579be26a71146689dc45447d6109
+b7f5d16c4f260c102572fa095c0e014b
+b7f7b1c42128ee5330da892579a91e26
+b7fef3da71d6f0bc314a1fb4c42bf0f3
+b8123a62c559b51814f47e46f0a2d1db
+b8176443e18c8e61d3f1f442e9e51c78
+b817e3f6beed7dbbd71ee6bb32e9f5be
+b817fc56de55e6f02ebcf9a9f5f7b146
+b818ad64e1776b4d71dccd187896464b
+b8197c38d7cb8f2846bf61e313d91855
+b81dcba0273509e87c11dd7c4eadce53
+b82095a70c1e02f465d205ce5840c424
+b82749ab5ccc4657e6fc1d4497a24d84
+b82ea73e39ec97b1ef3668f4c7c30b07
+b83cb322f39e66fc960d2ae0cb8321ed
+b83e7ad7f316fed7f0bc9b67fd1f342f
+b84e663dfaa78f3787aba3cfabcf1fbf
+b85bcb365e48aa1116f4312af3ef7215
+b85c6178d82ae22952c39d44d6efdcb9
+b86346cfd904ac9964df0493a0a8c610
+b864094d19d5986cc21cdcea390dbf0f
+b8644704f00d5bc1b9536ed91848a5f1
+b86b8ab06d3460afd3f600fd06384254
+b86c5336c805d24b7b4dc2a36ddeec22
+b8741f9ab210fc4d3f231b690bf30094
+b875bfedc6f2b2ee4dfcb5d907a97d97
+b87cb56ab4945acdceeae33e5361732e
+b87d3d42efa93861f70a8a1e9c19f788
+b88081f08f8389616b708592637fbb13
+b886776d1670cedba8056ebb074ef68d
+b88832f6ef3fd387becc48e0dfa98935
+b88cc8a53b0c3fdc8ae7f4ae4428a3f8
+b88f94b40c10e1c449b5584d1b660351
+b89463fdb9deaa333c35313a31c97ebd
+b894b3668b85d402c86874a2584ed469
+b895d197391ad65e2659b1bb088f3422
+b898a6b282c5177934cc8a1a37214bef
+b89ce451c6f6762a47b6cd5de32b098e
+b8a317445bce2000993db6a7eb92ea8c
+b8a591a48b48be2e5a9335846ea02130
+b8a7d094b15c03f7896c96a6f40cb710
+b8abb2138a471eeb20215aa7ba7948fd
+b8b6396c5e12dc79c3b36b7c46bf8751
+b8b886a881c069430c3595ff35b4cee5
+b8bcc42578b54f5b4cacb02e837647d9
+b8bf3c2dedce91e8d81e0a7f581a207b
+b8bf6b72acd57f38155d79446fff6e4d
+b8c5b9de601c5b03286fa26dc523549f
+b8c8f7f77b5e103a4ba2f3397c0967d8
+b8ca52cf07eccd108bda5e79368dc750
+b8cb7a9fdc7eaddaf43112f5840705f5
+b8cd7f57f9b52fe90ac4be0c8fe3cc64
+b8d0dee04decc668a24163aee079ef51
+b8d5cda5d50bd4126ef23e73f7df4d1e
+b8d6e93cb3570bbc338a442c5579fa73
+b8d73e600d38a8f3f1cb664d949277ab
+b8dd05c9a7d8c6c7657c5b1d14b203c3
+b8dd35f14f4621552021f93307423480
+b8e4bc22d65b021f1ac9c0e711c4dbe7
+b8e71fbcb37b073babb20a07cc9f95bb
+b8e7786919f4ccba6b9da7cec25291e4
+b8e7848363de2ce8cf64e9ed360fa936
+b8ecfb5f5aed2d30aa21a7a81b06b05d
+b8f14946a441b73586834bf6aebae770
+b8f81b29e3eaca0da5fe9179c870911f
+b8f915cf383c5c570e3fc338badd83bd
+b8fb2c91e26da0bcace87df327968846
+b90518e80ced0ea79e72b6ea53ddfe75
+b90623c2af7e48cb3664446d89321244
+b90d8b47933f866ef2d76f7e73b3af24
+b90e2eca6e5e1b5595be4aa3dc0c4c7e
+b90f7c8343b735dc976bf736eae329d5
+b9199cc12acaf8e032054ff607c83fd8
+b919a7b575c43451b2e92732eca6ded9
+b91b0eb468c2b82913ed45e02fff8bc8
+b91e48e6aa5af6728d3ab2ef15c27e35
+b926e88193c5beb17b1d1520f43b889a
+b9273bb950f7fa0fcbe7f31aeb546d2e
+b92edf765275522e327083f34847700e
+b945e57413a7906380fdec6241ef8f76
+b945eddccd4531a49a75e60f82739af3
+b947ce49975fedacd13e001d1cd657c2
+b94f8e08d217a38d5b6e1540b0536569
+b95d0d06f59a47cb634aa42a9d808ef9
+b9634b249258f434501a78c34dc8b20c
+b96b6b5bf2f170560895d232279a6ead
+b96e3d0d231d0d1091ea3ef7e746dd89
+b9785e6b87f36e1e5527ea8d7af8c709
+b983c7fdc34b28c1ca2ea8dbf8f1063a
+b98534c22fbb64644b0243ea6591b2b9
+b98778e7f2390f3c8a7b36df23fcfa84
+b98a92f98794673a9828ae0e2b7abb85
+b98c36a5150b75e59f5ea6b1ee2ab410
+b993e3fc2ae12b3f3e77b65c7784b726
+b99ebb5979f1900163945c5b7db09e45
+b99fa57d7e1f71529ea6750ff3b76840
+b99fc4b24b67034ef02b1f4bc7218319
+b9a07c087a91ceb2f6b5d889421fbc51
+b9a0b4720451d3f5ad194ca79cd4ad67
+b9a25bf709c9ab1938d644cf9f487b5f
+b9a52d9fd02f40ef4fe41a4335a6c762
+b9aad97e50c4bd33094ea141c872b3a6
+b9b56f8b413caa5a0154f0a7447ccfb6
+b9c0653f025eb7bf4a47d77b7eae6fae
+b9cc3ac275011aa259b067fcdf315fbf
+b9ce4aa2ac8ee309c69eb5b841dd2ee8
+b9d08daf77b8bdcf5c9fa32fa5a36e73
+b9d14dfc1b9cbed103d27cc73c4e21dc
+b9d2eed1eae3e8ee88c4f68a5219967b
+b9da18a697602025d167a83aa8648025
+b9dba162b0c766d9a0fba5f4e832c598
+b9e8f95c87319cb059d7abd7d4f2f6c4
+b9eff3df0c04dc428572f21a8ada9900
+b9f456201cf46155a5a92d96dd2690a9
+b9fd827d79d5478bcd69c4c417a695a9
+b9fea3b009496d1e8609ca86269d1c84
+b9ff6842cda7c92286c06c2ecde8c3ed
+ba00eefa71ba4cb3ebe4e7c066b88444
+ba0273f3a01c74387eef4191ead1fa8f
+ba0c06f62b5d9b545d64e5e98bbb2ca2
+ba119723b31fb8467d98c87652560040
+ba12edb220cc509ecd4b8721c3cf32d1
+ba1987ebfcf643da479cf344c9c2f624
+ba1c516fa3b470acea0646c4a6470f8c
+ba219ca9fc072219b42151075d1f3f1b
+ba3c20f6889c601273b3101114ba61a1
+ba43778f711b1b922b630c3954f432ab
+ba47d9872c4d31f336b795d2434dc614
+ba49637f5c87b169be14a1a3b26bcbfc
+ba4eec446234aaecb82e2dae10bc7325
+ba54ae9701a227376d72dd1560268b0e
+ba5c2279911a0418e970059a88414b08
+ba5cd9c8c6d317459f53456ce51d63b3
+ba5e6da597b8fdf217eb3dd87d997732
+ba64af3bb24b42b0a072f1bcd3bdd262
+ba6515873a161e3988d071a6295d9992
+ba660b30030bb5687762229606c2e69e
+ba692b72d5125d29e07adf9c989de801
+ba72a15bccfe4cbac687b82dcfa49d2e
+ba78b4f758112e2defae1a3475586a83
+ba7d8efe795c88bd955de995665044ce
+ba830176431acd854dfffe086756f04f
+ba8d0b8ca6a227b5cc6dbfb749628917
+ba8f69c0348e29ed99f538c1a26280e8
+ba90c94a738e87035cb6883d10d1f188
+ba941fdd11daa2f0adf55ea7ebe41daf
+ba94eb4b3cddd0c5babc30462c30ae09
+ba9832331311e6da4c795935deb9f235
+ba994c9097fc8a993d9e60f0e3ee7f6c
+ba9c8172244fa5be78346fb8f1d327d2
+baa004b3f1572b62c5b1b5dfc37fbde3
+baa1dda5d74a93f08b5bbfc3b4aef135
+baa74e4490c56d1ca455432e01edd775
+baaa70a3f38d5d6198f87ec3760ce61e
+baae2c61273ba06a179d8a029133ffc5
+bab16ea54cf34e6429dd2daa0a944e04
+babeded7e56bcf094f399459ed1a4efe
+bac108fbaca1ed7220117feaac61a8e4
+bac134ffe9ed37a35eae941cd969bd92
+bac9d89279954004a8cd76676d4883e4
+bad16a6f3b694fcdeeeb6698f4c8eaa5
+bad37e9555a12869ba9648751569dc71
+bad37fc4e2ff156c8fe4e64cd6fb1f3b
+bad643cdc23d2244413db278e8214490
+badb89863438fb6dc644b66cacd12cdb
+badef9b2092f502429e9423e7301dbc5
+bae1b23e2019f4c9b2ba0594d9ab8624
+bae51d3e250294e50fc8be12acf58a00
+bae97cc36cdda7b3df47abbdf86d8de5
+baee6236ef998c27d8039e2bc6adad42
+baef8f12be7881f197a66e7922b98851
+baf008e64f03c22659f8cab5ea95e211
+baf1d325e575f0f6ee0fc80da89ddd09
+baf4253288ad73752bbeb6d62c64739c
+bafa0318438d10d3caaac95bb4038204
+bafb6176ef4c8d05f9d509d8076af046
+bafd4e2bd4286a0adc20497116f58e7d
+bafea387751f8014e08359da50d33028
+baff5dbe83c2c90feb0db4e680cd429c
+bb001c4678fd8180355cd9e83e21ebd7
+bb0ae8c5760153518a3e4afa05da9a5b
+bb0d5fd4d3641a1d664e1aafde8a2d00
+bb1073e32af7e4d9e28938651403a04a
+bb1a2b161b532297cc9d7aac88af8f06
+bb1d4a675756e697202e5f11946964ac
+bb2810b92b3460c41f279223bf8221c0
+bb2c9db5f03126c9b830d54e77114b48
+bb31565ce1a1738395823354cf690251
+bb33bdf5b80f9598663bf544288b60d3
+bb37431c861823d8c4db0f348d1961c2
+bb3757250f97e77d3dad4af77f54043c
+bb3a2b318c1ee70b44aa28e485bb8e93
+bb3ab829942c5386bac7f43e6952ab5d
+bb3c0d25305b3cc6bee690f233bd1744
+bb3e5a483b7252af136a9ba792761318
+bb405ea068510105b81ab865ef2ed1ac
+bb4081d803a2bb97e2ba95af46ec18d8
+bb4b5973caa6a9b82138424f0221b055
+bb4bff5cab67095d662588535ae119c6
+bb501aff29bc405007d5701863506a10
+bb53b417f2bbfabfacf708b36a5d742d
+bb57a43a5789bf0a1149c552cb65eb9c
+bb5a3c15731d68df3a415c1f4fa8944d
+bb5c11b791f795a1a394d92abbd8340b
+bb5f9c0597f8b32bd81a1e4a6b684cbd
+bb6b96f290a43a7ef5155560c3e79d69
+bb6bafed1c9be8a0d6a9b5c6ec1a0f93
+bb6e36681866c8acee06607f54dcec47
+bb75c2b85d9fbb5e810bb001f6db781c
+bb7761bbd57ce4142d6070be3f16d413
+bb784f6a1bfc5af498231079eafd1fca
+bb7a82148c0b6a58adb5638a50bca3bc
+bb859bebca8033774638c670c9f269a7
+bb8874d779c82518341fc279c2c0f3c3
+bb88afae3c77daffe8befbee730b42b4
+bb9000bbdecf9dba1eae618c71d5e905
+bb9716edf6cecbdfa7fd8213274259ce
+bb9bbce7bc8e498387649a5a367e0077
+bba3273dfd073da47f7473651c5df51d
+bba5cf2e249312ef9bb28803f387efe5
+bba7a5ded36653bcabf8f0d6c0dc1e25
+bbb08222ae7b53257c40b4f543521f29
+bbb705fb0025f18dfd7142816b5ef639
+bbb7de5497845d00a68947c4f759fb66
+bbb96cbf838a2aafc7a5cac94ef08568
+bbbaa1a974f14598dc6a28415e97a984
+bbc6fb96b7a883aa73ddf4abfa08d617
+bbca16c458d67283b30e7341b8c6a29e
+bbceb443078694c4d171ee5939545662
+bbcf08fd98935328c7ad792cce85534d
+bbd3e91cb991018db086e2a90985d642
+bbd4a4560f6c6b1a9127df10936ecc48
+bbda51cf8c13a8a58825f4178d0b97ed
+bbe0c7398a803171cabbcc3e428ed1b7
+bbe183677fb87f3b830a0124d9d6cd19
+bbe7c1d3334a0256893702be5d97646f
+bbea1a270dea8439929aa0bfdca6a48f
+bbeaa2c9ee8ab2b55c8ff053bf7b6767
+bbee19ca2913c8be31f49b685b3caba5
+bbeeb017392bf0d36a30d75eb024cd5b
+bbeeee07e9609be79ee564dee1c50377
+bbefa74ab2d857b0f5709e3788eaafe9
+bc0051b6d81246631aa693d89261bb00
+bc0169cd2cca2de2d4c0d6ca5ce6586e
+bc172569bcc96ef42ab2a54e8d1971ef
+bc19c25288b3ed414759533d6d11ac32
+bc1a73afbd65e3ba6119b9f36123596e
+bc1b00dedf235c8c3c72d5ec97a40a02
+bc22a54ac80220c55e554b88f2163e96
+bc23e222cbdaec8983526b7b49d51743
+bc274898bb463d176752b204195f4841
+bc29306185c9f61ee1869affc9c8cb7c
+bc29db5b95e4ecc77863a129eb6e6afb
+bc30525c7107e0904cb32483771117df
+bc3087608aa67e29dcf5fa4396567ea0
+bc3497b0dee58f7462426379e8d62a0c
+bc38ad7396bc25e7f7a99b6a019cda2a
+bc39d33fb044c4266faa1593f505c945
+bc3fb11e5e5b8034e917587b28ddf8fe
+bc43395166bd73040a6fca3b8db0b81b
+bc4b2039c2cad8ed563df871b11abfa1
+bc4b9f25bcfe13b7c5fa5b2d1125fa41
+bc4d8c4544177021e6ccf1896c43ccd5
+bc51fc72a9134f55ca49415bc1ccf9c3
+bc52eafe24b19fbbd79ffb1e1d9a23b3
+bc55dcfe5dbded40eca4674d8442fc4c
+bc5854fa2b4ca600d083dab14b9fc704
+bc5b62b04170f7c207e6c753fa2c776d
+bc5fe81066c6e004967903b4cc84098c
+bc625d9a3d5bb4595699a541949246bb
+bc63da34d4f8c2b59d1c941083e8e0cf
+bc64df93b22f21ca27ea892194f1f081
+bc6690341c3f31633f2867b63650d3e5
+bc6a611a775217d8af8adb1829e9a4bc
+bc6b3662788abaad227e9fe887e8be02
+bc6d1decf7b0cfb40a92612e11c2a419
+bc6da75bf532a7b985f7ce6c05e8ec9c
+bc6e49690876359a2e9e034b4289bbe6
+bc7251ebb5a208b4834c2e5cc68dd173
+bc73d19e5d98d2421fc2eaaa7c9b5f04
+bc764f67f09708a897e15cea8c5a1036
+bc7b09c1d08993d0b178248a42e90d8a
+bc7de8289d0c441f8512059c671a2d20
+bc86ed66bc30df225b248e040881c26c
+bc89a835e2e9d17e74862862bfaebac2
+bc8dcc3a0b3c356b62272aa5be1b7350
+bc8f78ad91b161b39c86e7f60ec1ce70
+bc925aec35475c1ccb1618f5740d5050
+bc9500551e8b9bb28f082db5df179777
+bc969fcabd8efa5607d0a9f2c47b6c04
+bc98fb9045921d5bc386d5decbb32e4e
+bc9c5594b18de4f32ec8a34fea01d7f5
+bca14e10c3ec8953d50795b1b648977f
+bca64765d9c5f2c085daf06745b30a9a
+bca6ac3a16ac6e47ba54d09355147d48
+bca6be4661a0d63e11bb04f6c8514229
+bcaf015da5dd0b7eb4a79be754314a51
+bcb082888afdfe9dac284ccd364a75a4
+bcbfa250f1562cf9ecd0b8696f480af7
+bcc03034ca94a163925f725de8e377c4
+bccb0a8d7b6a9ef904d9a9661602b77e
+bccfdff9365853328320b0e7a480b453
+bcd729a6732c842bc9e784198b5237ee
+bcd747730dc6b2dabfbb1b43d9508a01
+bcda9ec8010c53c3800663a8d2c6fc3b
+bcdce0dc757c8d57ebf893ecc21204ae
+bce09bcfe85b51f45ae667831cdc1491
+bce304b263f944ab86b0902c45494fee
+bce8fcfcc12af0c1b2a30a42e95c8fa6
+bcebba46754e0dbf2204e304d0fa51f3
+bcefd169b74bc275b69569e422eb8662
+bcf78c99583165301f2129ff4475c890
+bcf7de38d5053f0be7a8ccab395e5e0e
+bcf801558e1d56a1f5adaee1f8e874af
+bd02dcce2334ea6b237944c4fc8f5b1c
+bd106277a17b68339711b18d6cf02a21
+bd190ede9175ee6d5c335f52fec2ae54
+bd225f3367d5f4ba42490bfb7fabc2ac
+bd2c67357f39d770faaf7ec249a17bd2
+bd36196ec9a9871bb30291ae60247ea2
+bd38730f29418b36df49065a9217b2ef
+bd3d246b9b6de2a50d394ada65be8283
+bd41d920a4c02e1d35c1e7235162f21d
+bd44db4e0121f2bd9315b94b82da4ea3
+bd4d605a7893ae28a900d0739f73ae99
+bd4f7c2003995dd2cd1312be72043cce
+bd551c12756021127a407aee4bd3cd29
+bd6579e86fd01aa8a2afe0bb51532bdd
+bd69cd548744290fcc7640f23d4f65bd
+bd77107c575b25a8cd1ce223a9696b81
+bd791e179bf92c897d127d8e6a34df8f
+bd7e5eb7babd048aeff454a0abec82ac
+bd8b0655ce0116eeceed0d36a550bc66
+bd9233b3d5de76751a8d54d6bccf7031
+bd94b32f8475a23ca5d080aacc7545ac
+bd96cd1b00a05c61b1e89fffff02f929
+bd98a1946fc6a3d1bdc7bd7cd3a69a8b
+bda3ae6ea7c56b9a2fd986b70a6765eb
+bda9c170ed50bc53f3ffa6b26433987d
+bdb3a4c617b1b6243b800ff7c2731cea
+bdb5ca7d0342f613998748525f7763cf
+bdb900ee9d259d279001ec87477d5c39
+bdbd01278f40e3c439c4101bdbff389c
+bdbd0624ff98e3de531b411bb75e523b
+bdc38e6cb79e1d37a3b2f83e1363370e
+bdca7eaf53a4233474166a4bbf77bb72
+bdcc58f9d18e4688ee255bdbfe8a6c5d
+bdd51699a6e0f8e8809808498126d890
+bdd5366444bdece307b0b03c7df44633
+bdeac028193908ad7d991d264f436f70
+bdec385e84fc77a8740f679cf97d3e8a
+bdef2d965344ddc7b1e51694f44e139b
+bdefb5d19dac655603d2fed72d6caefa
+bdf56cf0bfdcfcf82dc5965c360912db
+bdff461f2217ffa9c894407cde8fa8ce
+be00e0a046819500914a66ed247bbceb
+be055a378ba92bf4a0c0f7a81254ca0d
+be07618beb3dc5e45f17d851fe794c4a
+be09ae91184e890cf5d626191b999863
+be0f1c1b0c309a3009d5ae0d61929ed8
+be1bccd491d83f135cfe6f0cedd9e530
+be1d0e5128788570873924c3bbe26753
+be22696385df848cef30e5794f0fb10d
+be297985c9ae89a785719c214cd02e05
+be2f65c58fe5f8fb438e42569b39022d
+be39e64b7d1b5e0bc03514f271809b2e
+be434b93330a3ced391bddda0cd432e6
+be47b7970e72eece304a67509d16e0b9
+be48ec1485d5045ecf80d3a28fc8ac33
+be50220c4bfcaa522429989f4a727f30
+be6318988bac8951da24553cc1899531
+be6517acc353df9960e7d8ee1478d940
+be69096da808231e839afd6bc827a047
+be6f266070d74edddf27dd2b20248c93
+be6f8ce1da8ca8a2c0e80fd190eacd2f
+be722e26a11388df55372155042f0ba1
+be73be7406d3b6d30de4360ec6111215
+be7859fb476af5eb05a495dcc4a5fd62
+be78c70ea4cdabc8ae2053e03c2c7fac
+be7a0f3a88db1893bae712f540f52582
+be7cba3a10094c351264d6a941c5546f
+be86fd614ced2fef635e870c06ceb22f
+be8e83ca4d1c2bcef8955afb6e88d375
+be9028c17d382dd28a49563892a5f84b
+be90a687591cd8ef5cd66be0538390c1
+be93f40f7574e8245fb5f9b2bdc8c81b
+be95988b30e1af7749aefb285355f6f7
+be96bcd53dd56deef7e2f135751a8f23
+be972fd73b8f9e1576e8cf0aecc6e1d7
+be996b52f43f196670283792a187aa7f
+be9b193ce9e1ce4144f2a43ddca30583
+be9ec304369856228884bad07099b2d0
+bea4e465996e71d46ae511e7d1e92cdd
+bea7b9312c61438d2e428fd5fd89a8c8
+beacd19be8a4204b1f3f00dcbdebdb4c
+beacfa933aec442e6ca101ff121e9b11
+beb3f44ceb81ba65614c2da119fc52db
+beb84f37ba70ca85750edbc44f0e26ac
+beb90e272a4f60c64672fe320593a609
+beb9b5a60f61734a4b7d4fb05d989766
+bebb423830d2538d48effb7526337871
+bec1daa91de3f050425a312621c104e1
+bec1f818840cf064122ef2bcff08fefa
+bec6bcc65b035f987fa34d0dc9db18cb
+bec83f404460602a251abc57459d7e75
+beca63adc4bdc9ced6b649e26365974d
+bed2789000436aa2ba9fa18b3fd9eb05
+bed4c8595526efa3c4e97d2f12db02e0
+bed5962b6e5bc6cc5800ddb58c3f8976
+bedb5b68f14c87de2ebb1431e262ad39
+bedc132473ad752234713ba7832413a5
+bedea6fd3003e973ccebb4c97d1d41a2
+bee3e2ff08e342fa882ed8bb53e7f62c
+bee5a1cbda3e995890e7892259ea5d16
+beedfc57140240aa8cf10d6487e71c1c
+bef0f2841394b37b039cd033e24e8b4a
+bef82295587a00e8cbc9d24b35cb41e1
+bef8556e56d748cda2795c9099074d23
+befa7c4f984a96250a7f292a6b40dece
+befbcd5af790a3534e014684b310c324
+befcc6ddb14c34fd92a04361ca947574
+befcd874971e674cab8caff787226378
+bf00d5a8e22a4918845cae91b4c54af5
+bf037bd468caf91fd03094a778285773
+bf05d961fd7b1483ec69bc8705a3b470
+bf0c38f9eef0ff230af19be771b0a83f
+bf0cc30cc12cddc4ee90ff671bc2d817
+bf18021a3cbbaee34250a8996ce5c82b
+bf1a36587bd35ffa2dfeec52877ac33b
+bf1fe7fa36f1f90dd9af1a08587ccf21
+bf233ce1a481581d687bb62331d0c643
+bf236f619886d1030e9c3e147aebefc2
+bf2452793f3c6cd940f4b079e9da0cd2
+bf308633197ae0d5e3785d5eef1cc598
+bf3134020de007cb427da00e40c44227
+bf327e13d9ace8decb023fcc1d956114
+bf37856897a4b304f24ec175e886b353
+bf37d41cee19dc03a51565d81de620e7
+bf3d06dd2467fac353d4543864e362fc
+bf42d9affd3357ef148d89405ea8acdb
+bf489ffbe8b40ed4c9c2235e2a84d4cf
+bf4a139d336553b84f70049609c17ae9
+bf4b8ccdc42d77b2c7007c5063f73aed
+bf4b94bf10627cafb580b083353b0e38
+bf5404909ffabda7527f1667e6f98bd4
+bf574d2d97f49d7d5b6e7d92d2494d60
+bf59328e9df87531370c449e686eaa54
+bf59b080df02f491cbe7a5fc6ca6c909
+bf5ab540efa0c8a475f89d88e223725d
+bf5e82ad937d584f7270c5288448ecc0
+bf5fb6cf2eb081f5f892839c96831695
+bf6e47b4799db25a3e0d266664483b87
+bf6e79fba544c05b2e82e938c1a2a8c2
+bf750d52efb07c09febae3a3efe035eb
+bf75e7d8271e2c4e4ceada220f04b538
+bf77b952b9348c04c9e0140069028c34
+bf8040f6b358ca6d6133c520dc265983
+bf83d7792c97afeff2bfb0b623a5d352
+bf90cdadf4ef764ccaf46eb84d68b497
+bf9b7491c76d79c02dba8abb3a2dd3a0
+bfa649b59e78a2b9c47749d0531d9321
+bfa7726ba63fbab0d7e4f7105313391e
+bfad2d4b754730ac5aff41b91f82974b
+bfae94de111f72a39ca2171094352c2b
+bfb8763e2be116faeb79b6e9212677cc
+bfbb09c292d383fa9d8511f439aa0079
+bfc09567cbdb82900d45b230162d40f6
+bfc81b189e3bba28810f6e3e77b8617a
+bfce317ac0581d2231858920212ce3bf
+bfd1ff4e0ca22743a54068e55e150e64
+bfda1207f4578cb7223755992c5c8372
+bfdacb9bcb08638699bee8a6456e5f71
+bfde67c959d53992d4cc6280d9bafa87
+bfedc8a2b57e682d807222a622fcf437
+bfedec10da0807975893f485381fa13a
+bfeec72c93bf2626d86dcca4b3cdbf1d
+bff1aef3d5bda9f9aae3cc69ee7cf08c
+bff2e1d16108df81b2162419c362ecf6
+bff62adcc58d0b45a59bf029a0b72e7d
+c00644fde02c45288df875c279269879
+c006885811fca93c23507daed13915a7
+c00e6cbc4440278e95539d280b678419
+c01566650e97e7e78cba94ee7eccd8f5
+c0174a7029f8cc629eb175d0ddfb655e
+c01e8051079c93dfd67bff0b86e240bf
+c0214488215b553d3c93cead9bcb10d9
+c02a8835fc8445e4926e88a07fee402a
+c03a4b32462f82f98a42c03b9a31b7b2
+c03d1d0a8a726af56c9bc8d49d4cc7be
+c048198a8966486be8720352fb7391fb
+c04921bbdf30537beb14ae4445a63dae
+c049aed19ab4e0b848b518bb7ba904f2
+c050df4472a32b17307a0883c517420a
+c0559e025d808d5e79e496af6222910e
+c05ada9089c68cd72957560fcb28b8a4
+c0628c034864261daa74e996e6911f0c
+c06567ee263eb08f7ab4d465dc2e80e5
+c069a2c8c07e5bd64632ac05f51cc837
+c06e61a6a1d2bda60226e14453e32694
+c0740f4f92671c26eb2f30043e9875ad
+c0748908318df7c066de172f934cfb20
+c074969ee21802ac649a0901be836776
+c076df1d91da2ef27732639303c24366
+c0778b27dbb1731ea7e853a1ebcce742
+c07ad06666871da3eee7ccc8b55a55fb
+c08022bd533b48f4e348251629f04c28
+c08547d425be4f6e8eeb2109ac8908ca
+c08a727855754e46a14c5e70a7e7707d
+c08c9ce623c9fc7992a21cf90f5ed0c1
+c091423b7108f7b7af918b4e7d7af6f3
+c092ddf9182ae6fe5f0339219bd265f9
+c0996ab78eac0cd40e335b1bfc232ff9
+c0998607f7b96a66c66f4a589870e4e7
+c09daf097a92e08dca449447330f8640
+c09fb046702fa1a796c9a1582a5daba4
+c0a50b4c8616514ff9db36511516a1ed
+c0a9ca8cd78f4133e98e9ff9c7e968a5
+c0afa2736713bd60f84387fc2b594212
+c0b362e9571ecc43ee4d5228d3641de7
+c0b87163e3faf1ddf623ec258261dd1d
+c0b9a3c49c98c76f83a5c3554458b2e9
+c0bc9f5044c19090e7251d262f25d49a
+c0c7e59b0e8b45de7aa5e074910890f5
+c0d0e54978e27a44fb420e83307cd921
+c0dad5ef711a42ba6e845d7756f35a7a
+c0daf22052e1791076b80a70f197c981
+c0e7089d941e9b6164cff1480852fcc2
+c0ed71a7eb6defa7b7dd97600ab41c1a
+c0eeee7e5aa7fe3fc5822c8f10ac6e04
+c0f0918f7c920074ccdba7bc9285fef5
+c0f50abadaf3c34b5fee45ec878edf04
+c0f8034bf44972cf649b13332c6a3587
+c0f8342cd38765d20c462abfbd809d39
+c0f9354fabe0f78eb2dd5b39572ad4de
+c0fb096baaf2f825c94b569a27b3fe19
+c0fc4d10a8d3162088d5ee794ef11601
+c0ff3c587920fa9d75ad8983705b7701
+c0ffea3a4150d35044a899aea160bf3a
+c100ac72c110cf0d003783d750d216fc
+c1066ffbc53e03550a26d6a37ca2ec17
+c1077a688e25b2b9a3ea8ff09945eab1
+c107bae2b141263f902c688026bd2b1d
+c108d809e8b27d3513f791bb92f2f4a5
+c10a5311bf0fa8ea7f62b2ac271ee36c
+c10ec2d59f876d3d1219f5079267b8f4
+c111e16c61532ff76c48da6d02e0d831
+c119a6f7872019d11011edcedd154c41
+c11aded8b6f784f801e4d784a8345cb2
+c11beef2daece4fb84d5177e3092e309
+c1229e9197d1ecd57b3c1f4d295fa92b
+c123c5bc4281a277e85f64831b51f710
+c123ee95e5584c0b0f2fd44928b35302
+c12aa0f7ca1a45d7351651fab9986222
+c12ba02973b898a30e78e5399adac5c4
+c12d0af94ffff16e65769fc9483025af
+c13c1185a16a43c48750e2d9171c2eee
+c13ce887dbc851ce67020a69d4de82d6
+c14208aa93208fd3f305a9494f05ad40
+c1430ce579fbf59278158a7f1feda13f
+c150999703c98586f7afdc45a5bb9f15
+c1518f7a0b95956f72995b4b748a86f3
+c153864c98b95caa0147d97d1dc1a08e
+c1545f39142cd657988e318c262564b8
+c1571544816c43aa65cf91e67a4bc664
+c15768e4ee823987589974029531adaf
+c15b1386801e7c77546f4544c8b577e2
+c1664ec573c995c2b0c90affd47ea1a2
+c170211abc89b51ee24487e58d228f31
+c1717ccb8b6140ea3da586ccd8bd4f6c
+c1733d993176bcc9678a278cd175281f
+c175afa1ca0c04e578157a21eb546d35
+c179babd30637d465b5fc26216958a49
+c17f3bfad18b0d818e283bcf0461f746
+c183b7a982c69a6a167dcdf70a420e65
+c18506a35f2faebeed0e47045340f1c2
+c1870365534632dffb1b39b5bdf4ba16
+c18a2dbdac98b4377105377c38db75ae
+c18bae9ae7adc0866ab6d1e04c4bd597
+c197845f0983a57f053e82adefa92c3f
+c197cdda7b70347466dd6851dabe94e5
+c199692481f7e5fa335c82009d0c4996
+c19deff62aa073fd829f74ec8fb4e09c
+c1a10a2a11a81e5ce88910e6718990a0
+c1a44dd6741441105765b774baa14a7e
+c1a69f99b44ac974b5981ffe10f8ef24
+c1a7b954ea20d05743edb979508e3e4c
+c1aac2fc27c2803ae5096fb06b1e3fc2
+c1b6fd8f8feb6261de93a914f232cf13
+c1b7bde2b5732146e878f62a28356a99
+c1cc5c9ebfcd48726847640faaed2707
+c1cd800a506a48509920fddda38d07b2
+c1d1c5a65036e6f22e00d1ac4dfea4c1
+c1d36fc1ebc0464ed8ab3184af0f226b
+c1d54d847dc2e90b03cc0f6bf2e5c36f
+c1d72467d2bdd83dc35fee40788d04e6
+c1d7708b609e17e52306a1f20848e9ab
+c1e0a6a97b3288bac6cea66055b7abb1
+c1e16d8e55a68c8b518a3d03d2ccdd0c
+c1e2b443734d99ec7eb7178847395663
+c1e4c72f04221acb6b14030ef8efca79
+c1e76ea8839b654fbd04621cb7cf355c
+c1e8749bc810648e8295d6fc68c888d3
+c1e8b8bdede711b8ac62cd5368486d47
+c1f36e57f5a282814b36b7469ec66736
+c1f6f033fae021fb5595619ad3f2d3ec
+c1fbe9d5a70c68de45ed11d67f7ae92c
+c1fde5bff477c7667250e8aa1e938bf1
+c1ff557c21bf14efb3fd2d9bf727329c
+c1ffeeb374312f4dcdc3ac211d017805
+c201021b9ba276fdf4a5f4ab4db50720
+c20b90b283a9917d0a192d00f47c32d9
+c21ee42a4157974ae225a36d4bdfa701
+c220c8a990d59180348eed7b10f1edc3
+c222b9bdd7e928babfc041e1a9fd54dd
+c2267ee56197db3b74f2bb4df652db9d
+c22737b4f8ca1bbe7b0d3c6b9ac2e797
+c22ca079ab884f4e3eff4309c1174ba1
+c22d3da08a632bef198df6fa216ff222
+c23279dc7e02c5f81073173bda444b17
+c233fc8edbff61860f35c7bd456bb37d
+c23530c136929b12eaf175576cda9639
+c23cf0bc312d621071fe365d3a072c80
+c23f5e292cc29251fbfb8d4921d48c76
+c244ff7816101126e10c9567aeded9ae
+c246bc48223311d06aa33a23f9576112
+c2495604376bf4b0d4c0096dff641f54
+c24abc9659d1c738c84fea437e4c6e0b
+c24ade6ec39aba913215590dd401df23
+c259b8fd04daff7b1d4d328305870332
+c25bf542e639dd5621af19000a4697d9
+c25c9d1d1e50d690d3b2e7e7136f13c9
+c2661e983ba907b40e7ecb57f3a8a35a
+c26ea6fe6912e2fa7625ae97a41e1689
+c2703bebb985b8bf9a61b4f66ed0b7f2
+c272e74a374d24e77a1fc8477e085fe7
+c2730ddd6f1c0bddda0932bda4d47812
+c277cc896e428f65bc43269fefaa43e0
+c278278cf777a1b6c9167546c0ea19c2
+c27aa02f16e3a50963a291eb66894aa5
+c27b7c9a813cfa190fb3578caaabd381
+c288e39d9344691d96127ba4bc31f720
+c293e74c6bfaf1248526be6e16bcd846
+c29668b210fbcf31ee5fa9346af6be65
+c299ffe4436663034bd9f7f303f62b7b
+c29cc9154292abb5f803939aae7a4ccb
+c29ce00fca5e03be4dd7bf2307f3f56f
+c2a0104e63b0576b885a67c71ebde29b
+c2a30d74b4b974f08f29d6e16b292b5f
+c2a96581cb8ef2fbb8fdc32a79a588a4
+c2af3620dee4568e1338c7c2d89ab5bb
+c2aff9dfe1fe6af0e5ce838c916f6ca8
+c2b1005454c72142fa5b832020e121ea
+c2b249f99a92bea61d210c252e597b54
+c2b639152295c208c0a1fd945862330d
+c2b9131490faf2c9bf8680c768d60be8
+c2bb29565f00807271630c3650b75152
+c2c14751575821ac28eb2135d848601e
+c2c546a4b55d1bb6e68aacb0b809945e
+c2ce03c156ff68513893a46912d865a9
+c2db13d0dadfacfbe911e0c9dc3aee8d
+c2e057462f4fec0afbf750715cd68bf1
+c2ed45fc1704e7a5e1d8b19334133306
+c2ed49fd4c15d33849485a9b4054d7f8
+c2f0c87efe1c7f4c1ce642f36c810d68
+c2f23803dff72555bf1ca01923517685
+c2f5d0b96f8da04c256d5841e326e056
+c2f6c6b4aa1152a5fbd0107ce9e7572b
+c2f81ddfdfa2b32e60499cee2adea05a
+c2fa2cb00ba0612c1c6d88649568a810
+c2fc61e30db338089e9f7759efd6d997
+c2fdd3da3760429edad9493948504773
+c2fde8579fe12b1f7c5f45fc9e1a1311
+c3066997e078296a50f39e5b4480927a
+c3088df5b0329802554b01b1f3afdaa7
+c30af07c53ebeb5cee10d3686d19afbd
+c30b62b54ebba29c4a73280dea700fc4
+c30ecf6950a0087dd7acf7400186af65
+c30f2dd44c23502cf3d5d1b3e0f05ac2
+c31696f5c54f9953738e8ba5c21c3840
+c318111f0e8b3a22e39f7e48d34fe783
+c31ab7590b7a627b74e3c20f718f912e
+c31c092d0ab0c98e985913f36d651c71
+c32ad66be4f1bf38fcc8aed5a5465bfb
+c32d56f627a76fb2c55c4d4c8f153f34
+c32fa227b25247ac2230376deba4726a
+c336ecfa407d79f8073dea458383b5e7
+c339f857aa0e6f6ea6a814a07d5dc7c8
+c33ebc107477a6374adf89c5c1552693
+c34170bcabf461e7a44784c8eb48c710
+c34212c1411652919a0e7b8309155f00
+c34cc04d088d32608db06c9adcca36c6
+c34e3b37928dd9aa6983417b49c87621
+c35209acfb3697a103b11221e338a88e
+c355afef105d21178db3a66f35163fd8
+c359755e89002d8bb3f14da9a8d8639d
+c35ab5ae0a6f9d64176b5b97ec2d54a8
+c35e69238ff278f304521307fc140d94
+c362a5f720be9a5eff0dc6783a41a81f
+c372f1e1872f9aba48b7e485316807ad
+c37a30a5e07d62afcb8b142de43b9f80
+c37a49ae06cb6d9d9648b35632518215
+c37c3a1dd81faf0db76049e54c0f11ca
+c3849d8078fd4ea89d99baac28a8d9c5
+c38798aa96489f21c4f72cb0526ae018
+c38da9350ecc780cdac09ed9d673da67
+c38e6452e05b4502036a0d2d7a6cd2de
+c391162f1062b1884bda41814bc6883c
+c391e22b6d09f4f52cfd8e9ff1192ad7
+c3948f8251c4fa9c4ddf65ea2dc2e252
+c397503888b098dfd65558dcabbe8d49
+c39991060fc69964338ccbd445e7a167
+c39a4e717f8c990b35709d5a393d378e
+c39dcca688a1b04556fa8e9205bb5512
+c39eddb90dbe2d3115da7bcc01262b05
+c39f911754be809ba20f47f6f9bd93b3
+c3a4cec00324f18bc9f96c7d31825cf9
+c3b018bf85e7a771bb8f1abcb7f88571
+c3b137f11dca18a44afb514833f0c1b5
+c3bc189d0d3f41bcd20964409491e591
+c3be642d7059ae6a597f4a5fa21a8389
+c3c46e75dc0a979fb547ad4672c79ff2
+c3c7b2934adc9caa3ea006923f599dcb
+c3ca250a07cede92b392d6444ae76861
+c3ca7c2e7c5e7193824ffa396be2e88d
+c3cc24b00ffc603b7c9dc221b096c161
+c3ccf8dd37918d824c00e69dc682af4b
+c3cd1c95d69859ddb4da04b14ce770f0
+c3d038a3b1ae5e02365922a81a585e39
+c3d2617e1adfcf772a0cd43a86e9df9e
+c3d57c30038a88251948419eff73f642
+c3d7bbd2b54c47789bf465106efe880c
+c3ed54b69e85e17aac7e5d8a5debc7a6
+c3f87f0626a0f8c2bbc7f159d982ca10
+c402703b89badac9661b1ac809ec6e6b
+c411bc157437c6a7a1d6a648848de3b9
+c4156f42875f915253ea7e9902de1229
+c416d791a255c0d285b21dcc7cde1e09
+c4199c0de57911950812db778fc996e9
+c41dde305e2ed7b57358bb2432b93fd5
+c42013d775ae7a99f750ccaa44674a44
+c42087c9d335970d66f45f903b1fcaf4
+c421338b7e3af83d4f02bc5bc77ae7b4
+c4252bf3d70b3840e6bb251881e9bb54
+c43151cee513d1afbec884210a119864
+c4320976e5438bcd1cbc0738e68f8653
+c436056ef9aa202808f15b0a3ff5ef86
+c4385ed5e69f2cf5ea4a4d537114d857
+c43ae0db82d0f680f78ae66cbfcc813f
+c43dd5845458724dd27d46dc6136de5d
+c43edf243d77cfc1fc24510090ef860a
+c4425106bcb2d555761ece9557931fdc
+c449421e9f8f31ab93cf296d44e83e33
+c44999712d2e30964d2a73e5c596c448
+c44d30d47604429bf4fafb822eb24b90
+c452fa86fec73fd4e44106778e035ac1
+c4539a6a0c27f56e705b7966fbcc886f
+c455118cbd5e8901653fccffd52672dc
+c463b11d677b31b1e180961bc12707d4
+c46960b6d21454c819221f47d7c63aac
+c46b1092d2a7e6aa68e644e4ad30d321
+c46e1377b8cea2a5fad3cca83d877d6c
+c470bf5d8626ee62c03283f46f7d0d3b
+c4717d04ec723e5817fc900bab996942
+c478cf000e7b3faf85cba57e71d12ffc
+c47c47e100cbf61018e9a860d4e01221
+c47f77d6ee076b723870026b1532567f
+c4857f3ad2128bd3f390b55faacca421
+c4886da36b252a1c39b6ac4ee68c6d3c
+c48873567a93654559d9434b6bf4d272
+c48b34880880261540f9be9fc0ebb031
+c490c814df083e9a8eb35a298104f10d
+c4933f2f3c1776f96b9f60dc33718d0c
+c4939a757c3d0c20a74116560e5af9e1
+c49a1a58b3fc3f4f72639e992df51f98
+c4a9384e620addc23e7f38853459afc3
+c4ab2092d880c46725a109c729ee87f4
+c4b34d21a50eae2ac399191f5fcba12c
+c4b42ce50eef0ef45c07ad31b60397a8
+c4b977e61d0a817a83007dad5551e186
+c4bc66e63b16e3df3bfd270c50bdb488
+c4bdba7c92f8b7c7b3c50f654a3b7d26
+c4bf11d1d39563da815eb1879447421b
+c4c2dc6d86bf1a729339ef3bbfaa16ae
+c4c3b5f4743036d6de3f4d5323ed9004
+c4c8a4ebb01703e9c3a8ad4de1e9df67
+c4c9a0cfc70f524f7c30a0ab2515641e
+c4d499f98d37985b97da5e6dd8404c90
+c4e3cb852eab970a38ac062221fd7158
+c4e51065da7e99ced4d64a059da59150
+c4e53172ea6b222e9e2179ebb258cf51
+c4e7310486e9c6974b11520478188ba8
+c4ee5f6da2d3e058a1847599855e7b59
+c4f3e1be0bd14fc74c245840ae343065
+c4faf0716737705e07d5f1031ae8f251
+c4fe6722603e041578a8b72564f252b8
+c50ebfb88b39645a7570f98d9089822c
+c50f5009215d72770f5233cc6b7183c0
+c525c74dc5878107488bdefad5b9407c
+c52fe07c54359a421c3ffe85d59a5fd3
+c530e658d0ffb6f9a0202e87a05706c0
+c5386e8397753be181e1031b9ad161fe
+c53a012ef91ee82ec8182bc225331e73
+c53adacaa1fee7dc7e3b4cc08af30ad2
+c53b0b704d137c640b7a56980b4eb39e
+c5447887e7fb9a484224f268bf5996d1
+c547a15e3fd649743f5fb7b4f6b81a1f
+c547c67fd5ac3e4e141fd440bd4774ba
+c549ae7cd02c706dc79c3e670efdcd05
+c54de6790c619d3c58f1420d59dd2bc5
+c54ec9a34c9d61c7348930803d854635
+c55167f1db19a8271e829d96265d150a
+c555e0140e1c2ff70b78edcdc6714c02
+c568cd2cb065319f1bece6a6db3fbe21
+c56cfbc2d4614222615aa41c8e059c2a
+c571adcac4f87f9749ab6373f086c982
+c577a6fab0f0307c520f93f60b6dc9d5
+c57a71876f425e95b5a7d1e527609f20
+c57cf893b9980f28e06a24602526e3ad
+c57de47c4d8a1cedf631ab2af8e0959f
+c57ecfe583482b138d34d8bea92e58ed
+c582e6886fc7f35f689218a9dc01f3f6
+c5837ba6b086e93a193c582a8de32e5b
+c586a56b0cf889ce869a197c3f406653
+c58d3bdf1f9173fcd3a4fca1d5c69679
+c58ff3a71814fa00becee9115024d6dd
+c5913891a163b9944264997f6bcdafe7
+c59e524a61b1efaa09ea2f7498517b17
+c59e92f4f3ba8284c18e0e3439562318
+c5ab653a92cb740488a85cce307e3fb3
+c5ae2315bd9876c4f5a4744915e34406
+c5b3e3d971c034e5a82a93a4027ad0e9
+c5bc9e39a7c421affa6b5146079a451f
+c5c008e092336f442cd651a52a3f82aa
+c5c0c7a31049d18114c8df41f699963d
+c5c192782edd08706660a2772d7a091d
+c5c47722b9b06104afb404584e46f4fb
+c5c61059b70f6a98284656b7c31a6e17
+c5ca8e6932ac15a78853f2dc836bb7f6
+c5ca9127c8c727bd36699e168f2e9f7f
+c5cb161f5d934899ecf8fa5c891d3b96
+c5cb20c1dd2d4d5ed1230d86bc281dfa
+c5cbc904c7d25ebf062a9b039d3b6ef9
+c5d563d08a2ce09e2001d99a21c29fc9
+c5d5f3f986892ac5acb27cc2a4e673aa
+c5d938eadc54a5c3d72e25d3a66674c8
+c5daed7ee246bd766317aa9f0bc943b0
+c5e039c9e20862b8345dc7fdebb7febf
+c5e11e5a46c84c0dec6bf8f5cef3c2c6
+c5e3c27f4e673aeb6e688fb0d9887950
+c5e94b735b177c02f5bbc87083d21501
+c5ebcc2395eb661ff434c266ac8e7b08
+c5ed0e8faf4501488fd4db7782a444dc
+c5edac9e6c51ff0a49c007b3624234db
+c5ee0e951ce5c40b4cfb194626fec6bd
+c5f1ee5012fd9c669184abf35a2f6291
+c5ffb5e202698c909877dc749596107f
+c5fff2fc0e902395c50dee991639ded7
+c6005b6496f67e1f8c11e4b495c06a78
+c607232ce5757e87e00ded8014cfbdde
+c608fecd5c00bef5ad0d1dcaa549fcc9
+c60a7559ad4e1f4ec715a972902df8ac
+c60cf58c546bb5d7ea53e335ed99b1ed
+c60d5b54894272925e013177814aa48e
+c613cc8792d23370fe8a78dad8fc4cb4
+c6178eaf4b21bd773ee8b6218c27b7c6
+c618597b4bb58d56693889c2101c2dc9
+c618b8d973cda2b5f42944f4aa0581e7
+c61f477641ac977a949139b5edb22e6d
+c6282bec2477c342af3f8e6032e57b87
+c62a15086143d5df014198423ee4ebda
+c635e7b116e9a604f3027d487d635702
+c63d18482f9403274246751e1d5b6119
+c63fb774d67ceda3482ba7da8f20a1db
+c643279cfded35d12c542c7e8150fc12
+c6447bfa13f859288c154ffce53dd7fe
+c64577b9db3f2006b9dd80a887ca31d9
+c6519fbc9b68223f62e85caad4fb05ce
+c65ce6a4cb0a227f1b1b59f8854c4462
+c65e4248e74664ebf9bee70505d4e6a0
+c65ed1a8e8452f99857e6aa738634855
+c65f55a2661f61cdad217d04f03d159b
+c66f73449f8215d2fce2b3ed931a341f
+c66fad6c7df648d5969fba0c4f02f105
+c6700b0525f6c2ee426b1d8974107705
+c67011898b7c4267b082dd4a8d85238f
+c67259bb9274fa237b8136f7c66673ef
+c67314f9b73a7f20646ec829f9e84792
+c6780e75adb1864e5bc2e3452fb982ba
+c67bd9fea40729a11f31c91ae49fa156
+c68c436a8a26dae11f8c67df7b4dbda6
+c68d1254eb4a2180788975f1bd39a281
+c68da41d74d521055b7afd50d87ff83f
+c6961b3a24b3f5216ece4370978cff07
+c699da7c803f61398439ddde77a4461d
+c69dd3c6a39beab559c172dacad7448b
+c69ed5e1adb7973404d431f4b4a5bb37
+c6a09c694b9d095e7aa01a4fcf172e9b
+c6a399490f33775c8cc6635a8540dfb1
+c6a3c6d4c945d1dc9ec6b5d28c57c109
+c6ab0340832b0a4bc07704616c2ba3b8
+c6af7ee85a28cc2f91747411c0126fbe
+c6b1001b750a6b10825f4494d3c4678a
+c6b2806de12a5a66cc5376e988ca0dab
+c6b805984bfdeafb23cfbeade9221aef
+c6b80c408f5bc8ee061e7736d44324cb
+c6b931563a7dc6131428970870d38da7
+c6bc426932f5e0cf2b7ed0393445f965
+c6bf404bf3479edffd886bccb71d26ec
+c6c25242985cb35843d8ade137334c07
+c6c427426c299205f09d9747ec190332
+c6c4a50375301f62b1af2f331d5875f3
+c6c672c6a78e6d751923c4f178ce14e6
+c6cb0fa1a72ba56a5a4c0efe27f989ec
+c6cb6b20ce632430ae30abf79ea21e9f
+c6cc90aff41bb2a594381be913878249
+c6ce252b2be297db0bdb6b1d9ae9627d
+c6cf0be571ef4de4a55b0ec4b01cea23
+c6cfe9be6835d5ebcc788bf4862b7a9d
+c6d454a489e61d8c3b480696cc770728
+c6d4924cb82d81482e951ff092faf570
+c6da0de9ef3ecd42437b0e0362e51a1e
+c6dbc40140a5c96ff6d985a39e2db80c
+c6e4b1eb0fbd72679fb91aa903ec0c9d
+c6e5a88467e02a2e741728ebe16552fb
+c6e64050119f1194ca921cb472d4470e
+c6e66b37db918ba3c37ed09d37018d8d
+c6e7622ed684d877142be34dc71bb4d1
+c6ec18e06c40d8443c1dc5c713fbe2b9
+c6ecf28956e3124002b4e6a9a81344aa
+c6ed02e7e14293bf59b0bcff341955d6
+c6f0fe7a4d2f6d4b8c74eea5a46d9789
+c6f3bfc245ba29dcf7baf2a59cbb63cc
+c6fb552e975e5daa35d990d47bd20c8e
+c6fcea0b382e244005f8cfbc10800be7
+c6fcee28a929228ece28aa713a941f50
+c6fd5a8ccae7ec96429b3e86585d245c
+c6fe0da6442ca3160f1ddb3af3d0e1c0
+c6fecf38b2f561d33cf52b15fdc48042
+c6ff65e29f53716e8ea5df86649562e5
+c702a340b413e9eed175ed2245642cc7
+c70535372cf63f08f54b5044fc20db14
+c7062774b23a52752e51fa5df78cdf8d
+c70dbe1f7c68539607ea9f81d3206ce7
+c70edf444f9e92d215e4f7964994a1ac
+c71114f65bc1f06b718bfebdc778ed60
+c715d458ee41b8f8938e139441dbdf09
+c715eb673545fc4044bf9411ab43a0ba
+c71f6d315cf35f16ff1cdf16cf0405c3
+c722d71c2bc0447ad5221267938c0c82
+c7284355a3d4519cbb46679fb332817e
+c72ac3d0771281a11b3c12540f35ce48
+c72f177a46a275922a451e3fc21d3c85
+c7322ad004135c3a9121873e6b6a1c45
+c73ad8fd2b7799542ee21fddf1e897d9
+c73dccd08a572489bdc10819f5bb5dc7
+c7436143e7fed0edf980f645319e2010
+c74fb91607a7efd2bd77f2d8f209be23
+c751ca2c54aae9a01f5dfcc338691cb5
+c7539595afcd8da6c86b1297f5457c9d
+c753bee58a25656ec257e8eca5fd9b86
+c75687951ace005462de49fa4c2609ff
+c7584430278bcbddec0f086fb0bb7443
+c75b710431f2ac27a805b99e1c9412e5
+c75ceb97bc08bcbb71f1f028d873fee1
+c75d479638dace5bebd675a76cdc5ce4
+c7642ade620357d1933d84f25ca2c3b0
+c767e6095c17dabcdc0e5efb7ad9a750
+c76d2d4b4d719a6a21a923a2ab8c535c
+c7735f072f8f835c3f2b2626bb830ed1
+c785a2042b83757f917d7cdc3a4f472d
+c78c9221587fe71c1ea20474e0978c75
+c7921ea53e58b7944ca527a32712b529
+c7a027285c1be04cb67b9da83c3c495f
+c7a77340680547b3f9f3b3b466f56a1d
+c7ac03cce0e1436dc6700c13fbaeb1e8
+c7b0b1f2c4b23a0216340ab3fd9af285
+c7b104fd4659def30399dbcb210af942
+c7b4de1a6f8711ad30c694dd70fc2c8d
+c7b63d32d804a071af1b0a836f590232
+c7b6bb2110ec7534530b252440894e8f
+c7bc2bd51ef03d1b1044447d54275a40
+c7c19c54b109d1a13087318dcf0051f4
+c7c4735459531a21f4d8b1f6cd6de919
+c7c8f4c391aa75635f4992751ac13af8
+c7d34d606050d97d251efeb67ced32af
+c7d3c4c00dcf88ca9b1e47e50ddd9010
+c7d568f4e87e2e0b71381c24d47ba0a4
+c7dce23b322623c9221c9f66c43db118
+c7deafd4c683fdd9ab87e061cb4dd08b
+c7e0231e3ff6a3f925fd519dcf73774f
+c7e45738d36157795b31019fa962e7fa
+c7e4668a49a72f16fd2b8863d3fd5a82
+c7e7cdb1ba82eda7e4384d916c571bed
+c7e89f7a3efc8af530845ce85261b51d
+c7ebc1e79a02326a1d60dd1e7ee636ac
+c7ee2c85840800790d7e500c4e2c5373
+c7fdc0a95c04d600accba09aae2e3a9d
+c8010f1f6d8912fecba617d37e6cb05d
+c804baeb5bc541ba5d328ae35f0a8125
+c8086046016f5225055a338281842d7b
+c809ac84e66228c260f360b5c3f42254
+c80ce3bc1c73bdcddf3706a468a7857e
+c8123d7fb18c8eaa9ed80ee37b20c238
+c815808fbb580466b395ba0cc11c78e8
+c820d91c8581f1902523160dd93e3a85
+c826140a3f04aee9a2178d5b669b6605
+c82702d9d59fffa1948d946280fb505c
+c82a2d189f943836c27ca9c5fe29e715
+c82dd07b5259a426e7296e7e9c63021a
+c8308e3876c92a5f112d5392bc35c81a
+c8328cce4f6cb7a5ab35d7aa71cab7b3
+c83293c7d6e3349799309d06a2d41c79
+c834ccee463cc2db98ee91a8e17e33f5
+c835248adb6b18e34a45770d864713f8
+c83649761cbf1c7f1bb1fabf7b5820b6
+c837bc91c77865c507e0a2c04bb4daf9
+c83904ba3e1b991043c3a49a6a75c478
+c8396930f6930c06594ae6ea006f7910
+c83a426d1ef4b068c61a1c07f71b56d7
+c83efd37c2b08d44e2134110ba3f00ec
+c83f9e1923c2d1c0d02108fe99889fa4
+c849a962f01fc1a3be1b81d30c2060b5
+c84b6c14ddd87407aff3de3a1885d89e
+c84c8adddaad155b3ddcbe311a6220c3
+c8501eef9bfef5698f0fe95054a83856
+c8521dfb6ee85de25044c97a0fdcfafd
+c852301e9b2483596139cb808929f0a4
+c85244138d9cb1f20231315c55759eea
+c85403125c4b4cbfa64d97eec70328b6
+c85a70c1840dcd26833090419bdf1490
+c85c5273c96bde994f5e70aaf20f1882
+c85e133534dd9a9d56d14df585cbfbcf
+c85ebd3a1e41bc969f47a0d13334da0f
+c8602ba7337d3ad5c0407e2b41ccd606
+c86155cbd365aa21d5877f81fb802fd4
+c86545926bbe3bc86eda43a3e0400bac
+c8654abd70d5e015e4f74cc26ac063b1
+c86b1f9ce91b56cc3501fa5312a2c91e
+c872988e0ce721e87fe5c8cd8309e4b3
+c87976a05e613d8682059b7d09b8a5f2
+c87b35351acb00b81d44cd2fd8212bda
+c87e04d4198aa2fee677f8d01f5b919c
+c8826f70c0786fa77eafc12a10d76a03
+c88301c7056f1754d84503292a6b8ed6
+c884da28f491ca078e976901f9b7a327
+c888330662eb5f009394c1ecfdc05e98
+c88ade9a2ecc943bde56d61abe1cc673
+c88b09976ba23fd3a5bcbb29280f6a12
+c88bb0264adb0de47044205e155fec1d
+c8904b09657cb77927e72a8429eb110d
+c89147644e10d1e58bd4b476b01c8b8d
+c892b8dae0a858465fa2b1ebe101647c
+c8934796dfe1ddc735a5ff2a56477833
+c8948640f17a05d1d31dc2650dab72d3
+c895b7e2f6c0bb9111c1dee0218ccc79
+c8ab6b2eb580ad63595d8962a01b1da3
+c8ac24963996be2f6ac30c4ff031a543
+c8b0f12e343b3b0ae763153527a0220d
+c8b4b8e5b7dffba06ea08095a51e4044
+c8b6542d2ce75d2488b777580d348bb9
+c8bbc8bdb61a90405210da982bb41b8e
+c8bc96eb5c25170768b0c5036201c1c7
+c8bdfae6b3d263f59c2838bd1e776dc2
+c8bea55512fe02a005793abfe125ba21
+c8beea9df289fa1774975ebf397bdce7
+c8c1d895ae828bb4dbc90b8eec29850a
+c8c68d6211430475a7212e24ad75edc5
+c8c97bea3475b2eb9988ce45c427ff8d
+c8c9f12a7bc1fc700a14ea5e63980373
+c8ce94cf567ebb2767654345c6f0b68e
+c8cf23642bb68acdebf69f7b7818c416
+c8d42e1f22597bb05ef3390f89c94680
+c8d520d44a57c74c3dd2ee4d6769c6ab
+c8dd528c1e2994c710f69c6741b76df3
+c8dfaee82caf34bc38f0f4f6ff3df921
+c8e11d85d4fdb2fceb7c9ffc153800ad
+c8e31531598feed925b6355bad681cbb
+c8e523305bccc2da581d7f17798fd55a
+c8e7420c6a217fe0afa11009174a0aaf
+c8f812e1700a1e978943848b3ded3990
+c8fb69f613e8708c68d3304afec8c028
+c901fc07f7b1036de6bc7103c29f2aa2
+c903d4418bb97cd067d64b47f41d2b3e
+c90638c4bfd289ed524b20d2f0e05185
+c90b28604e8d580529dff0cd7032df98
+c90d8c4554d24db29d7d4374832008e9
+c90f62a8ed4240bcf1db3c900f1a59a2
+c9137cecef25a7bc66c2684d52839389
+c915acf60cdc64e894f1b7de044f1364
+c918c017282b70c1a95fe78f91e3f05b
+c91b5ac998b8cabd048a9e36afde00d1
+c91de6d658d6d36391c00275d8ccbca4
+c91e040bf3306204bcdd84cdf62f5c9d
+c920c149b18d940b09fe26805bf56180
+c92a5a113cc9729a620ab84a375a8a4a
+c92aa641c2942b967523b2699159fc2d
+c930a267e99e4c905a7eac9d45202d7b
+c93254fe2f05f0c7e90471a48b447b81
+c9371a60155a352ce4931fd252f8249a
+c938d8c56b4b4bb80c3ff6209d1d3cf6
+c93d6e4b1a2814434ec1dbe893cb4361
+c9409d7e3053ae782b65bf2d83d44e52
+c940fd9294e4d36243cc992e169d6cab
+c943aaa999a395a962ddb811e9fac405
+c944817c9eec77ab2dc24d68d22f06cf
+c9471c7e47c80b13f71cc3966a6f884c
+c94af86bb168828cd2dcc4f93a606461
+c94b5aa89573d2ad23de547423c5531f
+c94d830daad392e66aec2c82542a3152
+c94e92c2392e59e738dd4ed37d93cec9
+c955c8c4f93f27bb8433ae7350084674
+c958039f4ee6c329482ad42045105401
+c9585d1d5c7a5c87747fc8f33adc06b9
+c95b6d1dce3fef06c8322ca27f3e841b
+c96092c99bbf7c813321e5411b31dbd4
+c966291389117ab8a86117cec9871bce
+c966f607d9d9be581e6ab938956f4c36
+c96a727124d1ee4aba5f76934b655cac
+c9706ae819a2c6728c4ea4343c0c4dbb
+c97118cf064e3fe71c491f7936f098c3
+c9789314bd1bd6a0edd39f9155ea881c
+c97c0606aeb848aca9d2063ee702c6c0
+c97eb85a03d93ce1d4a1493d6cc4c73e
+c97ee1594524cafcb26347f9e7dd4912
+c980388e23b789d7776a94b93e42f472
+c9848145f2d1b74ed7fc25535dccdcca
+c9862da6dae93b5ec0e6343d7a7f9ca0
+c98c8898944d0af968f7ee15114567cd
+c9954314c0a4af38dd26a0d3c4d30543
+c99d64fcc7729d96d1d989f1eff9e437
+c99fec6b22c7f6e8c35e14138cba7694
+c9a65923983f38dea3aed96f15da702e
+c9a83cc7ef35fa9dc69d4d7bdee57eb9
+c9a9e7353d2eb74dd657402946cb62f0
+c9ae773056f7d370502fddfa70488977
+c9bd62feed525fd2cad60dfcd5bb934b
+c9c4575da1d1db0c8e5e38a3bde2a3e0
+c9c750a36f45e640eb05b2e1d65c01ba
+c9cb06caf8ee9cb407b9db57679b2703
+c9d3892d859243b65217fe5924ee3c0c
+c9decaa94f49b65efde0bfabec4ef032
+c9e0c78bf82650a462055f7494e70950
+c9e479668f5783a53e0de5b36a0484e4
+c9eeeed8b519da2b96f6f7674af9a9e8
+c9f5db8bc29714905358df69fae7969d
+c9f601ac68ec6b740f0480587b1acb6d
+ca015d4162dd74eb4f7970a421dedaff
+ca0778635184bea008ed22b32a37e9dd
+ca09e4dad6e596254546de26f20e1fca
+ca0bf022fae68e60549b97a4943051a3
+ca1495863fd5c4483090e4ff8dabaa65
+ca156c46c2babdb3bb0dc5463f62e4ac
+ca190238d2069686066b55b8323b3a08
+ca19ce33742928f9a98decb275efc862
+ca1af0bac10f552724a0ffbd8fdb583c
+ca1e4be1c0117fe91d1e7b4cbd165ec5
+ca2094810ade8065e8ff3a5ed7aabdee
+ca2154575473b239d5762a9dd8bca93b
+ca2b9e4641b24e259ec28c22192cedb3
+ca2c97c052eb63b302d60c4cdbe1b771
+ca2d4315447ad01d7af21e6e77dbebb7
+ca2e6dd2fce8198e7f542fe34d6a64af
+ca30e970eb6d9b8cf4e0df36f7d98f60
+ca31ced64e07d45538084f78593675ed
+ca3287314dc2e6b2ab20af62dd24cce7
+ca360e16b9a34d4e67cf5c15cfa019c8
+ca368c4d5955fc068698f5ce8a1b65e1
+ca4bb2df5b40a894a21e81526ac147f1
+ca517eb11e51ed4f1a3987785673f153
+ca5477e421ce1bdca10c7c533effb796
+ca56725304d72128609e730ad4ba579f
+ca56ae7990fb049e3439ec432596f49d
+ca5afc076122c1c5226dba9f3abb5757
+ca5ce677031a6c8941677dd0329a6f72
+ca5eda939ba4ff11afee9348bd8a4fe1
+ca63bd4a860d4341e0a0fc01093701b1
+ca69ac52f916abca680c5ed1157188bd
+ca6c432527d0e08a09d2486212be6be5
+ca6c7018721faf339e39f064d5f153a5
+ca6d62ea11f510fe8ba7bf4a918ee2b8
+ca72e3a911b80c1293e33153b3e1d9d2
+ca7352bc912e43ab83080131dad9fee8
+ca73a7a2b21cfd0acf0226ca3543a942
+ca74e273fac6008b049087184be71692
+ca74f3dc84e82d3a075a076e4eafda42
+ca77ac1976311f268779d82bc631a748
+ca77d685e42cd5c39f3fd63a42cd996d
+ca7e04dbc311f40706e190a9dd38b9d4
+ca7f90e6fea01789c9236dafb0bf70aa
+ca8bf5ed05247d969c89fdc295664f9d
+ca8d56bcc7e34c01ab47adbdae692195
+ca8e542b92488d1bf0e7f61bf6e6de26
+ca91188bb014900da3c8910a8832beff
+ca94cc6d453ed0b2d072fee031868d39
+caa1f4818591218fca6ee290a2117eb6
+caa26e651942dbae56bc1cb25fb64826
+caa3d85513f5f23f32e4b049dc9753fa
+caa5eb83c86fc7d77e4d6cdd64333c0e
+caa72009577e8f46133720b89daf817b
+caac5af1e2125dec85e3f481a4a50ecc
+caaeafecb563ee0e7847bc52537fbe86
+caaefe8714062df108172a8e16531053
+cab369d3667ccd70b1269f42a4f2bfba
+cab4684f3297f516f5858f0cb2f1a94d
+cab95d9f2b4f3dfa740ef9bd4ef35f9a
+cac11864024754fd487eab172bfd1be7
+cac7bcb09a2f531e71db07f658fcc220
+caca356983925c20a7f1182d8c5bbb56
+cacb31845dc328fcdc12aedaed98ee57
+cacbfa9861bc169c12100837b60e4a22
+cad76650641ef43923d50e791f696de3
+cada2934366802dda0bb05f45ac31a2f
+cadfaf3f77990b6f998930a728ebf1d7
+cae328296e8450f8a2b621b212bb24e7
+caeb9e84ee355bf3254903b332df6413
+caf162834c040c0ce4462b28407bf55d
+caf1ad6b4f75ea69be1f8ec48da57d5a
+caf3dacb3722737b50dd0a3a6aca01e9
+caf45317a4ea42221441746ede18b4a6
+cafe15d7cfa5514fd6e2e11200a083a0
+cb04359b6168da8562ab2008cee999f8
+cb078facace9cf193f2232b47023261c
+cb0c3bf0d4eb67a382f509b65bdf985d
+cb1085b0dde7cdb08d62f2c96257a0e2
+cb1808d59b2dfcac84b69e8fb41f2768
+cb19dc4cecedcc8292a558aa1e267ca6
+cb1a32bd293141d04e7d146406d3ee2e
+cb1fb0701bd0d034f56d3aa3e960f8fa
+cb258ff01589a93c190a66f537592c07
+cb27b6ea49ce86a9a62e631632a5b983
+cb27d80af4943092d63e0ac0175b3129
+cb29ba95e7bbf8d010511beb91b3212c
+cb2edf61ee2ec82c9588a77574b167a0
+cb2f7c3653cfd92f75cb72fccfd25a24
+cb318531b18d23e5d5627eb841ad5552
+cb332a11f7fed43f06b3eb006580f5ae
+cb3f91408bcf36b69fb91cffae517997
+cb454eed48315bf4051d2043f5308d78
+cb4ca49d868e4df000c65290588c9363
+cb4d553068de3a4fcbb4eca6ec4f2ccc
+cb4d85a00552c10686c6a333502cee25
+cb55ef81f8c685a6f50f821f3e7462e7
+cb560091ac67ae3374038e98293d8bf4
+cb5a59ddf499e30ecf8ef398696fa4f4
+cb5a64fb3fefccaf0440bcad851a1790
+cb5bff56c5afacb033644fd2dfc1d935
+cb5d8079b6547c51b68f1d70453933e3
+cb5e0d49e41601fd0db7027ee8fb60a5
+cb6621e2284ea6c6d2fb783248d43d66
+cb6a0046837e7eac42f5c085382c0b8c
+cb71cce2c6007925111bcd1d97630520
+cb7314cf34bc73e19f52a34c06997059
+cb7475a883d17e1d52e39769fc8897b3
+cb7cb819b971c81380255caa55a3e3d4
+cb832efc2f35045f8291539cac901cfe
+cb8b0ba75036eb81ea91fbd518c29ba9
+cb8b174fd84b0bba429d6ea876546a10
+cb8f4c85ad8071e5b74062776d57819c
+cb9269959a6eb3fa6aa9844a886e5c74
+cb93c26e070d7bb72cb6393e56821019
+cb966a10377cb4deac765ad75279f90c
+cb97c1d2e3072898bcbd2360249a5b04
+cb98eb36507fb5b76382a132466b3c78
+cb993f1439dac25119906217071d9d6f
+cb9d26750a35b47639d6aa2f2df27cc8
+cba35b11ed5c9052076f4d5f2d1e3806
+cbbd2b6ffaa57dd6b2dbe5b364ec3ebf
+cbc20591c0e6a3ab97b8921821a8d0c7
+cbc4071a1461a6075638ad0aa8a16b47
+cbc7a15bdac22c8bc2e5f2544c7a33eb
+cbc8d06939bd0dba702d2103fcd255aa
+cbcd93d86aed18c394771e5805278da5
+cbd2cf93b33afb7d6c374c6fcae20fce
+cbd4493806d133055d74b4bc23f163df
+cbd682859b400a2fb46ee83d41538f82
+cbde8a8677860e0f920198d593a59917
+cbdff875ffbbc2214ae6cd9b254b55ff
+cbe0b69393d696c20de52c91f2335653
+cbe3c1175b0f224e2cf8ff17fc97dc50
+cbe4bb839d7abeee70144c43c7190234
+cbe5c84b6b811a8ef4c6b2bb385037e1
+cbe65628977654514b8b0f09c60b96a0
+cbe99bae8dc31db33e874d18e9484bbf
+cbeaaf07be368a0b236eecfea5ce12b9
+cbf2154d7c257871739133a33178b564
+cbf2e72432a816d26c8d0999f20f2930
+cbf6a0c5c41223852213036416632dcb
+cbf90f72b032a6d680f844ecd6df5274
+cbf93c2a7bfcd430c22bb93010b23fe1
+cbfa37241495279b52fe64fb6d8aa8d8
+cbfca1587ba1571bde42c843a7b8957a
+cc02b0100f7a63dfbcce6c09b2e11742
+cc0c600be175b105a15fb741c3b0926a
+cc191afd5ede7ca8b491c13fc96729fb
+cc198d528f67b5b006e4728fdd9ca0fc
+cc23f86d37cb41531d636dcc5f304d4b
+cc244bbb63ed84bd484425f23bf791d2
+cc283ba548942bb55af3f19157d84065
+cc287ebc8a179bdb429a24c12a1accb3
+cc2a6a4e475587fe0db859bd774d55a7
+cc3470a972e67e8dc382259a3d05fd53
+cc369366e2adbc41de87d4d59f11208d
+cc37c13b0d984602f2699d3f16e864ae
+cc37d0d168eab7c032c1ca76e36c77c6
+cc42319c0d2b8c2794e9068f3aea9e6b
+cc440895dc3762cd41792886632a246d
+cc4abb0a32f1d054a122d5c7605b653b
+cc4cdbd542e9aa43fe23c4586615deac
+cc524a87c0a3bb64786346972dbcedc2
+cc52c3e0fa40bf9902fbac333b5d960e
+cc57a3170659d54bd21077294675baf3
+cc5aab7442f5478b548e5165e0d0480b
+cc641cd4a773ad9f4cffb5228f1a85f5
+cc6584f54f0d2ba99cee06f4ccd26211
+cc6be062768e334c846e051b4ebf5776
+cc6e76b559fb864675993b7cd1f2a1d4
+cc780461ea336cefaebb576c3d8c0c78
+cc7909eea2689ad5d2f6f8fa446bcca5
+cc7bfa70c766782f3880da9f99e84aba
+cc7e647f85abb9fb854ed7001637bb6a
+cc809167f76c6d3409d508d7714010b7
+cc882ab91d7f1f86a17fe214bff8943f
+cc89cfec63dfabf2d030da7572ea1dc7
+cc8b808b7a4c0d48fc236d5ee23aeb86
+cc96e4ddbd096a4af52480ea620505af
+cc9914560f6197b696a08c827fd84edd
+cca02436f1954b4097709db575b7606d
+cca798ad16b61787167eb9d365d797eb
+cca79cc5ea29814e98e55837b315d788
+ccaca57bc58df4fec1400e5b9eb43c47
+ccad02fbbf4def4dff2a2c3c612891f4
+ccbb3de62bfccfe4c57e12abbc9bb786
+ccd20e7eb53b92615139c3f94da5430f
+ccd49a5901eafec768b8c12634011b11
+ccd6832b08b8812229715f68dc4e0437
+ccda38420a76c7fad49da5bfffb9f98c
+ccde7328a7d300d0347a6cfc96319428
+cce089abba6eca589534deb1e630ee0b
+cce76f140aa971aa67257d83b24579bd
+cce857265ca25c8c514302eae85cfd3b
+ccee74bd72f7d75c3b0f9d339a4be584
+ccf43be15ae460a5e981c6cc24b568d5
+cd01965c341c41aac6b697c32b7d312d
+cd0d3609f5f761f7dec3d4a0750659bb
+cd15b2614ce031e03c8e4e709b7490e1
+cd16edd9dbe49cbc57fc1b1fe8b8c19a
+cd29c2ef5f2d76f7bd91ef9865cf7f56
+cd2c36e816e8bc64a312c2e5e26ff9a3
+cd36ef0388c59bbef1cb3cfe196d48d7
+cd39800d7d2eef52fbc4fc6b8721a8ef
+cd3c6e9549e14e55807e34dba2d64583
+cd3d636d3a5dba56eb8be46ab8f3aeec
+cd41c9c98015c51091aa1c47e5e008dc
+cd43e0c0212972d5a5533e98d68c1acb
+cd56d1d950dad8ec04a5dcba9d761ac4
+cd586e2dc3fc671f8908e90b9e4728b4
+cd5c7315eb3e4367a943e782b958fd2d
+cd614bad987d92ea4dbaf2f66e11af62
+cd628edf9b1271b1f4de15554ce540a2
+cd65ce1dd745932c97c48fa429698302
+cd65ec9a85993d154696467b2a166f48
+cd6bccdef4046defc710486d329aab96
+cd6d7e155397db5263932aa4f597706a
+cd6f87639cc14c6abd00f307792fa0b9
+cd71f10f69022ecde8f1cdf631e93d66
+cd74991d6af462004ae65a91447b2f6a
+cd7c5a12fc6819693e17f5b662abf4b0
+cd7d24dddae3ba076e5de7527b948f9c
+cd92657c95b7ca8e1d27e627a663f4e5
+cd93d1b0c245b62a9cf7a765cc04934c
+cd965f10e5bf7bd069d3130a98db14c1
+cd98f0ae17e5018b0dccb6ed529836c1
+cda25f28df36e733bcdf6c88bfce3b1a
+cda3f165fc624dc19c6aa8c518e03ed8
+cda8b541f1afe3efc76d3c2ef7323d65
+cda93bb3065213b87d60ad065c5e42a1
+cdae9a5d536184d6346a79fc753efa1e
+cdb3d87a29ca9f284ff3972eda189d21
+cdbb3c222e051f6b00bcfa7fc64eb155
+cdc25c01cfd5d362dfb2791a8d156503
+cdd4103e1ca488bed5a59f4ab18da23a
+cde24efb7826c804b730f82c12770d89
+cde5767c83b73242c1292d5cc2d97096
+cde8dbf31332b79760d17cfe15107863
+cdef951b269e652cb71406c5aa33e939
+cdefa6124dfcf90ecbe9a2be746d4f7c
+cdf80266bece467aba3c378a06a9fc7f
+cdfaa3cb36f58651c81e44c87271271d
+ce155517510f43d7904b75d1a99dbb43
+ce185abb8d4211a4f6098596d3593a68
+ce1d8d31c94aa37dabe8e15236716f5b
+ce1f16a8c364f5e6ddb58290e4b30ac6
+ce2e668aeaf03ed4caf0662595d41eed
+ce307ea56edebd754e1c00b9f4d2c175
+ce339cf109d2408eb074267329d4e336
+ce34e579c37e7afedd17d326b8fe5ac6
+ce361e3fd4d2c04530e39d5a44f9d823
+ce3c0f1c135a81faf17b6a3a6a0b4ee2
+ce49cee67d3fa5050b7439242e0c39c0
+ce4ca8bd41d50c4db6cad8c7c75a51f8
+ce4cc12d319e7b3675495eb63208df31
+ce5354ff079a64b85076d6de263a5a92
+ce53f62ba78fab4005780cb29b85d5c8
+ce55116425d6a5e7946b9c62421ad49e
+ce59b2f21985eba4ca4135ebfa5d3da9
+ce5c929460b066e849651e9365781225
+ce65d6605c1171d2e66cdec017b18226
+ce667431c4d8d69cfb8a6a9fe806af75
+ce66b7939459a29edcedbd547ae32471
+ce6994bed569cba6e1a15acae4b10e97
+ce753a955aa8902276da9b5563ce57fb
+ce7770801757389f8049ce2e42ba8c39
+ce7944898cb8191507a6f5563373abc2
+ce7ff5160ef01648e82988d78b2d815d
+ce803b30961ff2b8b96651918bb2241b
+ce840ee90f1ce760b801ca3d99a86794
+ce85638abe130967da0d3fbe12754715
+ce860c2356a2c9215f456aaf6a43811d
+ce86acbe833ca40a28b4db58eb8ad1b2
+ce8f51ed1a082d3428760f14379d179d
+ce8f71463b78742d0bc854e130acedb4
+ce96e53e72d4f5aa98517a57c042d9a9
+ce9f1edd56b89d15dfb1a826e7bea11d
+ceb97b3b651567d2eaabcc9a28f45caf
+cec141212789f7c449a84a82fe7402e8
+cec7280bc9c0c76b2793b0752b308552
+ceca246651679761c6a631fffca56a7a
+ced0692e69f651b7eda7240fb703b965
+ced1f19c1e9aa471e60eb2757bad7db2
+ced37f9c5bb9ee20dca2cce1cb83e52d
+cedb093b2b4c3757d3994d541fb7f0b8
+ceddcdf9245fd235d2887ca1d54a77e5
+ceddf9bf53971397c64a29553933c256
+cee40efc9451f3104bb894b683b9112c
+cee54c6989ce27445dfb410d4aff7e52
+cee5649c61e6a3b384a6adc91a6a0a0d
+ceeca37380c88670154458b12b138f40
+ceef58856688e93ceff24ce81e9107d4
+cef2888c9177d60cecfd607ac2273265
+cef58ff59038992cf3ee95903466dcf4
+cef9d360cf5eee09944305c0057af288
+cefd7cbc7938a390747baab664014c17
+ceff39b070918fdf7f5cfdda2fc8ac75
+ceff55fecbf926bedb8b639e301eb27e
+ceff96a33262daa063585524b60c3b55
+cf00acfecbee8794d3db0759eb9e16e7
+cf0f728d6dc8412c314567e9b783822c
+cf11c18cc7f4c7559806afe4adcbb065
+cf12d0d807080a99c9bff90075ff02e2
+cf197d4efbaec721a79718b77e0892e3
+cf1b5e4788946255298f0d63007c1788
+cf1fd8a636ebb34e0bb2c39273b2264d
+cf2dfff9499b79ef1ca832635e1948b5
+cf30628ff8390b998561dbd3e7b42e97
+cf3d889e493e2339a08b0300acf93ff1
+cf448487423d7148fdf2355b08698e14
+cf4eafe187784b07782839b1c7b39a92
+cf51fe98f5d26cb01248a32cca41d747
+cf5b212c2891aab3bfc6f66047cf68e2
+cf5f157d38139708ee6034e3a9f24677
+cf607dda9f8ef33c99ac204a08cf47b1
+cf62be85cc30ef3a7f94e53d6a4764c7
+cf6b5f769ae6cf06dda78e1ec78cef1a
+cf6d6fc53b346753928d429c752c783b
+cf72667687674ddf429292d7a50b5e6a
+cf7352653b38b8893b3d3eed48543d49
+cf7416ef3d3702ab508d4d1e5321c91b
+cf7833ef2c25b790b9e3eca4e0d1ea96
+cf78d5a2927ca22ad3004c16f6b7174b
+cf824c1ac3317e3ae17f74634f94e17d
+cf90371b86d295a773a7253dfb73bc18
+cf96a5133a5baed24b47d9db5d0afae0
+cf9c2d6f360a8c2523a594f201642e71
+cfa6d043c7d090aedef9ced2e18c4999
+cfa84e9c1e12a4ec6f16b41ba05eee96
+cfaa95c985adeb14e83d298d513d7068
+cfad42504b8193ec2de85c1fa51e5be8
+cfb02f2f466af7f6c5b8cd2c7ca26f76
+cfb508d42949f56c1c2994e133977711
+cfbb8f24c5e339f0162690b83e614199
+cfc791a55049cf5b81450700092d2718
+cfc79fff40a21401db702a00c177d95f
+cfc8fe38e6774584886ac3e48f47768c
+cfccda6d4c42b6b90356c503d2139bf4
+cfd49db5f77b2a8c9661af173d371e69
+cfd6c34498a1f64cce5fa82dead2309b
+cfd706ae9092c045dcf46d88ad98c3bf
+cfde934bab75cfc713554212aaac2fa3
+cfdf67c396f50b8c59a10a86f69bf94a
+cfe2bb8060082b0011aad76d705c92e7
+cfe8483dc66457b4bc87a19802a1bd80
+cfecc31e35d34e0d4ead71d94f554be7
+cfece79120c6ec56c7cd7d5778adf5bf
+cfecf7d9c8d20283a73cdc351659b5c6
+d00137aba9c23f66cec0fc38ec014da5
+d003d1cbf255e1aa7bf48e2412eedfc0
+d00785fb08b7c5d94fcc27b062a09357
+d00a939b9f028f67b111dca6ba80ae13
+d01dd26a60e85260c2ddfb2e8605c3b7
+d01e5c6eac0184d1dfc76e3010203436
+d01f867df34510993478a44fa3176f52
+d0283da776fe5aa2739f5018ce9b3c89
+d030ea5e6d0951e99bf4ece9b955891f
+d032384af848ca4e9f394b7d7c857ad1
+d037e549bb8a062570c6e923a32d929e
+d03ae6100ff3e2a39c71748b1ace1b54
+d04e6ca02c9886f3d689e380ffeec1d2
+d058343eb61f8d449c30e50df70284ab
+d059fbd290ae160f185eb264d85164a8
+d05be6a6a40f0f0c2f42a0e85dcdaf16
+d067c266e331ec701ade4448516164e5
+d06c78eeb37c097e2ff550d37cdc25b8
+d06f69b8eb4b60fe9e63ef0ecf0f664b
+d0740a9f91d4892d13b00b8bca0b34c1
+d074ae709e0260bcbe9c44a3b57c9bee
+d08160abc8441d1e373215cbb51bb53d
+d09015f441acf7abc2c17b695376bfa6
+d092abf1a8d58e4bf5802dacd1873f6c
+d0931015acf8bf7879ba1041d89331e8
+d09579bd2cf696ef6b9fe17498a82d60
+d0957c1b0a4dc8d04ee50e4aeb89c51d
+d0960af6f1e13de9d633754b07b46b22
+d0b0874ccc0a89b85cfdd584095e8eb8
+d0be17aba6949ab7adf2cecfcc8e3ee4
+d0c24ce95ca2162a9758ef3fd035a036
+d0c5ac6a9b17767009ce2c032a5c2820
+d0c5c7e979cb8060d8c6eda47d8b8dad
+d0cb499a383d22090f7396ad1e911fd3
+d0cfe94a0f0af304be6f7b39439d5405
+d0d3552f13005fd7b8ba2238d2b322b3
+d0d71c7a84b01cad15c5be93cc200121
+d0da18badfe6bc8c13848bdb12467966
+d0da8eaf000cf7e1438f6b2f9df76015
+d0daa8e3ee3933f6d43b5fbef0611973
+d0dd3580e3ce09fad7e60e6acd156946
+d0decccfa57f61f3037d5b728ff8f335
+d0df72d9d60d3aecd6fe512e0a6fd5c2
+d0e2f6fa5f841c61206ca787c9e9bd16
+d0e50a2a945501d9f29d5e0b272f928c
+d0e7beab8ccdabbed3ec06f6fdef323a
+d0e8b80665ea8304b6b590100a6e594f
+d0e93348dc58560d895de517748d1611
+d0ebc795a9c2069f12b2ecfb8ac34e63
+d0f14ffa96c660732862fe607cb63aa5
+d0f7534c660655100294bc92f2dc7956
+d0fbe2e4af8bfd380529acb634874ec7
+d0fcc29f06d2f38639683aa0cdf47bc9
+d0fd3fa096ef037c4ba5fca9ad4abd2b
+d100b1ec9aaedf7de3f7378a0e909cb3
+d10219895df02a6d68229d447c553fa3
+d107e0056dc6919be184b595f3a94a8f
+d107f52f252e930e09826230dad6bc06
+d10a1e889baa17e210438d13b92a5141
+d10ade6eb79842f4e0210e1b793cb0c3
+d11148facada0a3bcad62394a3e332b6
+d11b5d60f0a871a90972f55f9e3bb1c1
+d11bbe2f51182a0d1b09e1e8c5aa91af
+d11d60596ccd2ee0273e9fe36fcc8fa6
+d11dd96714ed457d5158ae5d5028c999
+d11e802406367bed53a2bb020454981c
+d123a67dd337ec696e7d8d83675ed242
+d12445c0d56ae133787ee34300c90a27
+d1250b3df7085d771b2f011bfdb32b69
+d12733b3bc742549205da818a931f7c6
+d1296c1283cff880f35fb0b7af6528dc
+d1297dd1666cd79b001d00b4841ec3d3
+d12d74758844d42072951ff5476732aa
+d12fcaeccdc513f263e3cce81da97301
+d13be8c7fdc35c105075451e33d50bfc
+d14152f666bf2312e2ecc84bbe31e5bc
+d142e8aafe486b18cc447d7b4b893860
+d14317e2550cb009782939a00e5a5bb9
+d1436af2af979e7c8a54e306813cd030
+d143ac8411004532c0ef59981dcb8fd4
+d14a9f8cee2598cba68b50f92b8b3800
+d14d7b5fcd4c17d4142732f3abc074f9
+d15365e5e73390c6bf5ee7c11df8eb8b
+d158271ed488573fb8f8981c7443fdaf
+d161e93adfa6849cb9f7eb8f9cc8406c
+d16e76862fa4a27fa3dc8eb027596230
+d16f092af17c82dcb7336eea51e77b45
+d16f108ea6ff919f006086890ae311cd
+d17123b9af8c5bcbce761298405c239c
+d1718c9b6d02f9993f975a3e83dbe6fe
+d17472ef993241b391921b570daaf9ed
+d17be78f918542eead17ec230bafa20d
+d17df0f17a8b336a1a89c5a5e42abe80
+d181545ea04bbe68c6607f4b3392027c
+d186e4cb8802072434144577431f928b
+d187263fec0a79f32bb6d6781d01fa18
+d187ab22dbb23b5b2f02314926e7bea9
+d18b57cab9575869f11edcefb7a79c9c
+d18b7884ebf5f2e8d6b613810ac63c78
+d191b5666562f34ca0426227232ab809
+d1938041d3d67e1b0a83828f97ce125d
+d194b7ae743807caf452942c064bea18
+d19bbef3095df639d1ae8cd6fd7707d2
+d1a55fcb25e6ec1ef740a54357ecbdc1
+d1a6899af4a02591c2188ddc563a370d
+d1b40abd6bcd116f3c602325e5bf20b3
+d1b71bc1d9aa9721f493956beaa071b8
+d1ba9d738606caf4e8295b76ce162da8
+d1bae303bb06a6ba80b23464ca6634f9
+d1bae669be1fd867c025fd82b00f55a7
+d1bb8cc9908a4fd36b030d3e3a489a52
+d1bbff7fd94587d5a9e09e7eb7a69af1
+d1bdf33d619d6d46e81d1b01c721283b
+d1c354463ff151cee3d4059fcc3d1e29
+d1c798ab86b03849420f15fd23632d85
+d1c980c24af9e918585c91f6d494cee4
+d1cdfed97e4fbe8be001c04bc328f558
+d1d1b1dadcfd8844b4fe38126bf313cc
+d1d6017c330f806ee81e9201e0b2cc00
+d1d8e466abf5f3beafa196383fac806e
+d1d9597ffb45939261fc774c9c28e023
+d1da00a0a652dab36c7fb6d8ca17d01c
+d1da353f9c987d56279619566d7a69da
+d1da457ad304376a2fb761340a8b47b4
+d1de216b19ea7179911a5898b48b3fac
+d1df1a1c66b60b88cf26d46da9cf8a32
+d1e09a4f4d0e7812a0c50ed15a833eb7
+d1e3432da751bcb6fc193fba72880074
+d1e526b2246d9319b10ce77950ec670b
+d1e75f551773176efb13431560c9bfbd
+d1e76a1725aead00aded3a90539dd293
+d1e7bd7fe23703ab5337ab80902796c7
+d1e7d93a7a88a400b6655de738fe19c3
+d1e98a5e78171f2fff41cd0fdf1a0ee1
+d1eec1b06a0912e13ff47410152b81eb
+d1f5f71e0822df2acc4965a2a81dd13b
+d206324608f9280d0d9652869a3980d6
+d212d7302fea1dd56677b12afb7e7ed1
+d212f1d9d066ad96acef091339164b84
+d2197b07d5cac2cafe8e3556658c657c
+d225ac9a781e1a57bcc7412190dac791
+d22bad17b29704a938353c42591778e0
+d233735b89b2bf5687a3dadd74e221ba
+d243385c9faca72dac6593e0520d26bf
+d246c8d2d6ab81d8e51ae1b5e21846f8
+d24a81e874a01bea21e8ff3723aca967
+d2512f1c67f4598fe3409d8108c56973
+d2534104a8b7ce69e3a950295dacc437
+d2558e8a307dc01fe6a8007f9b608de2
+d25d4f0d8c175f0912f8c6916e201995
+d26ac869b328a2a27221f6d1aeb7ce7c
+d26dbd1afb71bd419c89418960c38f84
+d27502e9e81852f0f329c1273f90ba41
+d275fe8fc18869f4cb961b3d13cca288
+d277c198d087d8d48a2b6b6118e68a18
+d27b3ad4a0510f176b0d407f71f78e8a
+d27bb3b15382b8f12be448744ba38605
+d284ea21f94a9a7a06e49e4deaaffcbb
+d2883b6ccb3841ba3c242b65a6a8a1cc
+d2894147bdc91d2afd029a5960a22fde
+d28b9cc11848a758fee0f05b08e28d90
+d28ce9ea4e9d01e802570017090c7188
+d28f90f6cabceb95eb28f1ad1ddf339b
+d294d2fdfb00c88e09ae60c67a1addc4
+d2974e2e2bf8a5802a09f778170d3f4d
+d299aa1cea1ee15a3ec4b755d4d90163
+d29c8e692e7f8c266ef53205af88403e
+d2a439d19e64afed27b7ec41cadd8925
+d2a4a8ea3a41883dada0d7eab1c267cf
+d2a7c76b170e5c1f886336e450bff02c
+d2a922e1180383982eb208a2903d1ec9
+d2afbafd767971a35b33dbce65e88ca3
+d2b0d2c15798501a8302b47d058b4efc
+d2b2412de314097c62b62e819f14f176
+d2b2e98794f24076da675ca965f0b8e1
+d2b5326be56115402151ad0d259d63fb
+d2b959920ccb9e0c8529eca8e9c89acc
+d2bd9d6e195c31b8502bb090cd736d05
+d2bec79bfd9bbc3c3e9e6ea4a19493f3
+d2c46fa6321a948aab9f7098cd0bb8db
+d2c535d6a5a1ca30e1b6edc0998276a3
+d2c8b907a1c7395149aee3f2529819b9
+d2cc42cf231abc805ad16be2d8f3655e
+d2cf0c6535f15b1a05605bacfa7cb734
+d2d27886c386155898cf7aacebbd8713
+d2d5db7a88832721bc1c9a132ec7452b
+d2d91261cbdaadcfe9f5f4a117f7af34
+d2e33b7fbc1a52ba67cfbccb5f8e389a
+d2e946f5a868eb9d91643d964d5573ec
+d2ec0f20643a8bf8e1ddac20f0980c73
+d2ecef2d13f876e00d794d587eb04150
+d2ed6078db599f41408aac35c6d3a863
+d2edd2093407d0949828cf420231ba44
+d2ee2cfbce277e9401b28257497f5ae9
+d2f2a789972cc1f0f8820e1bb54223d2
+d2f9f5d7f6b0517b6851791b071a3d6a
+d2faf3297051bd0a34f9b08b1415a2a4
+d3009a981c26a43a7d9c9527d980de0d
+d300f0c184edf18b392f0687bad2cb9b
+d301ee94294448a36397926176ecfff5
+d30db9738bee61da462205f612b10489
+d31004b1702091998a9369f192cfbad7
+d31420ed27ff25aad1a8f24b697edd68
+d315f2f210aece2af3c5ddd9092c7e92
+d31bfc8e4b7dd99bb0c1b4064c07c697
+d31c91ae1042c1e22fa7972991686b8c
+d32067006c4083d92c9a3e9ed690d41c
+d32905aa7aa6547f37ff909f12e00d4e
+d32b9d6aface685b2ceadc2d740f5362
+d32e20c60cadff4838dbe1e383b55477
+d331d2193f392a9ade297a2350f4eb6e
+d3355d9f7b57dec4667b328f31938813
+d33cfa004fee22d6587c7271f19d05c8
+d353335b6f55255700361872d3afe09c
+d35710c796fddbbf29a3d73c3da796a2
+d35b2d239dd22ab5be6420910a3e848f
+d35ce58b693c2e495cf74e016f8e44f6
+d3615e708d1d533ef36d0f44e2037561
+d362987a326f020536a4786fff89d3b4
+d36a16cbd4cfaf8da2006e4ea089641a
+d36b08d99464df020718916e6b537143
+d373f99a2ed653c9bad9c685a648d2eb
+d3743ece113244b68460337023cfb56a
+d3787c923bd35e1d48327c3a51ff0681
+d3805e84b8eb97023e2c5fd8cc08ee5d
+d3883a59acf382cd79ec50cbbdf65a81
+d388ab8c33699ec8fc24395e293b9869
+d38af91c73c93bb5f3817aa8bdd8e91a
+d3907461da7d7adbb2186c1c3d5550a2
+d39233adf938cf839635432b1018101f
+d3970d5948a53e0033ae68f7fb06e5a6
+d3989dab019a20a832d2327cfa1a00ab
+d3991dad2de59297d48ba0a85a8a8dab
+d39b58b8f761d50aef9150cc32c7788c
+d39d8b21778e3784f27fe0bcd6b14f4e
+d39e3126d6c99ff6e5b15f597127b711
+d3a364009e4faaea823e52da869b155b
+d3ad6cf6bb5910e8ca960baaf630a6ae
+d3b0868e1fe61103f452712ec3cff58b
+d3ba0e5dcadfe43abd606dbd9e9f83f5
+d3bf038e57ee5352136676586e0243cd
+d3c22de93616e9c28b7a85b676e128f8
+d3c2d6328418890b7c490a51af448371
+d3c5110f78b3ceb8505ce48449edecca
+d3c6df1c29fe43edc84f78c68974eb07
+d3c7e2205802a9ccc2d19ebd97d7d9ab
+d3ca11a445914c5cbd886ac1aa71a10f
+d3ca5c4e7c7377ec997ced0c4764179c
+d3d3abc0b6fa3a653be6188677555237
+d3d4b7031fc91b6976174eea2a05082d
+d3d6b5a1b75e1739fbcac0b25940b6e9
+d3d8adb788aeb43231d60945e43809fe
+d3d92e0cc3f03950ce7b78f02b71722b
+d3dc2590c728a42d6fdf7ce0871d9496
+d3de57bf2b452efee5a167ab93039976
+d3dfb0b7a0f49b9e2276c8847bebd9cf
+d3e597fe4c1ed61b252e4d7cf46b78c9
+d3e5a8fc06d3ad09a0432976ab11571d
+d3e78b5c0f8dcf92b296c1b6163807fe
+d3eab3ef95bd64ac8ca3c48451a37401
+d3eabb691b04398f659cfb94b8775142
+d3efcc7cfa9ee37631b6febdf2154935
+d3f1348cf27706f1d77ddae286344e52
+d3f63bb266aa4ee329383eb9c0c32826
+d3f7902e0995ad2550a35453aa1d65bc
+d3fd585d61f73877dbbd3896c0780c61
+d3fe14f9bae32f134eb70dce358f8bc2
+d4022d68bb61cc9fd11ce27a8f7fdfec
+d40d8de53a55770855bb6f158681ae14
+d410a57c21658181e0575dd13a74f37b
+d4154c065d995abde27cf9d767044ddf
+d416476dab13291297bc5396d426ff1c
+d41918de88385de56d30fe53004ddfcb
+d429208466e0656ffc0664d8008a54bc
+d42de439ded5724355f737c3da6924b4
+d4322e6e3a81aad0fc41c49e4c4477ee
+d4362ffb3c323fef9c1abc3a56d15bda
+d4370e5f55acabcab3368a6a0313e300
+d4383a6331038dabd8b3d8388af18de0
+d438b88f6531dc5634585e482eb4a5d9
+d43b3e47534276b4e787c8895b1f17d3
+d43d800d419b161a32bed57ea07ab2e2
+d43ed56cac64d0644508fa4c1f382e5c
+d441e8e856839f6b5bfab0aaf566fb67
+d4449e01ad1007c964cdd52811907d8b
+d44bbf7e3378a17428e2359803b831c3
+d44f88d358ce94a1053d275f69953c20
+d450aee266587b5389478340bd5b3af3
+d454f0e451c0e06ec8e41fd415075039
+d4584039e91246f97a375c31e1928490
+d45cf10e958a224bf3ee492635c45abd
+d45efa03214aa319bb65114b1b5f3429
+d4647071071c6ca0a55fa12ca8cc6c21
+d4669e9b2f115a4836c9bee661905303
+d4669f4f1d63eb7d1a17340bf8f415b7
+d47146a3ed42568e5ec16cd4e30eee69
+d47750afe02dcf23f169c36e3c3cc504
+d477dc94adb88c66844c36bc7a769d8e
+d4792c82a0f4ab3c7d97f41f2cff15e3
+d479d12afad1ac59fd4e4f0867be3fd7
+d47d99a82dcaf4733c2b9820a242a0d5
+d47e409972875598e6cffa60980cf368
+d47ebb01b3560eba62ab339e3f86cdaf
+d48645332ec053ae431a15096d49b875
+d48948e714cebbcb60b38f5e96c14982
+d48bb09e30ac5a767a612595691ce486
+d48c52a14cb52948a5ef9b434fb56cd3
+d49a934efcd8f0fc5d70353fd645dca9
+d4a86deac504fe1bf806a2c10d2bdd96
+d4aa173ddcba0e9c5813d09056bc3b56
+d4ad399f3b5e1f7e7b9f533b27624ec0
+d4be707553f579c5571e4bc573185cf9
+d4c215a5aca74771dff2ea27051ddaca
+d4c431da3f187f3d469ab1afc274510c
+d4c48debc6c4a3723841c978afc4837c
+d4c4f6e41f5a236e2130b0d5bfd97620
+d4c565b0f62c162ad740aa61d1fca3a9
+d4c6166ea4fdcb979de707bb94dadeb3
+d4ca13fe9a6702282c613cc059bc76cf
+d4cd858a1a00f0408dc78e1df88c086a
+d4ce9d7105a0ae217b0c73ebcb106557
+d4cfafeb137c4f808c6cda0d5fb16301
+d4d09b2941e39fd39988dfc4134c5ef7
+d4d590d33dacceeca2aa79e01026050a
+d4d9de96c3d0ab9e375ad329b0446d07
+d4daddabec903440a97e59456a971868
+d4e2a074856db201a05efb5d2ec2a749
+d4e53816c9bf2a03972757e8ef102691
+d4efb53332d116e7e6c971cfae6ff89d
+d4f8885fc4fff9efaa90c5e28152df4b
+d4f8afd033d4caeb406837b15d6591d4
+d4fcf3a70707ec884527936bfccfbe60
+d501132d2c8c72e17965b5c1015a2087
+d5025f065590648dde547c21aac60b1e
+d502e060a4211cb74af463f277d4fbec
+d505cba74304758bc5b4a20f1dcc44f0
+d507a3bfc9662ff2eff3ccac3ad6a161
+d509bab3b75c0420b93d20ee78650c90
+d50b371bca837aef59f78ca7e0cf9a48
+d50c3faa5183e592322aa0404ba95fb3
+d50e6cf7eb88deae981454363525a7a7
+d51bf75d22924f6536ff34f965d212fa
+d523260923041f8cd140692d0c869821
+d523fc31955ad270ded62e5606e1b72e
+d52531125814e61d5bb9a01f0f1ed4fd
+d527f8105e760c52c137a59d58a4f72c
+d52940214ce09f99d623cb6f0c0921bb
+d52d7eb47907f5fa493e1325b1d205cf
+d5311c379baed55cc78f3429ab4500ca
+d5345ac1ee7c082627c9fbd740727fab
+d53950b8a7bbbb778318059d2bc1baa0
+d53aca0e386d2fa37f69cd9f3aea8921
+d53be08e832b9546cd94159c311db613
+d53bff6cb1decf2a90ee551a7b35e86d
+d54b32ebce9601acb4ed14af17e2a9eb
+d54c546baa36e4fdd91dad20569d5a77
+d55afb5badf230d6c800cd810fc621a9
+d562594124eb91f3c3fd7d3ea114f800
+d56f098db7af5ea8dd2955f777da40c1
+d571252a060d5983e2a8615344a5de37
+d577937172efc8f39b0503ed97f7bc3b
+d57babed438b9effda531857073cf792
+d57e98538eb1e5af75cf8e365e1eed5e
+d5843c51020444d959291ea1ce715876
+d58a5cc0f1be66a2d8aacc446604d70f
+d58e02cc49ebdced9a6e376e754c0563
+d58fca799048238ed2bb343bc5401dd2
+d59512c6fa06fc3b5c0ff9005bcca9f6
+d59815397e825d61b879351f4d52d974
+d598f3781fbf961c67e76824663afbdd
+d5a9c9be5b6e7fa79f9ebabbca94c5a6
+d5ac67ea0f81c96ade5d1bc19c34a22b
+d5b26b8921f8748dbc2dcf9a1181f308
+d5bc3d269b625c373d9268a2dc088e33
+d5bef5f537bbe91412d6b18c6f69d8e5
+d5c04b11d84840984fb9f1e946f33fd8
+d5c8f4f97ddbdd7e15fdf2f9d905a266
+d5ceec8a30fade99c315d2af3a3dfc00
+d5d143677e330148c56e760934b854d4
+d5d237ccf5758877b612526f1f87464e
+d5d3267c18eaffafb5c65da526abfef5
+d5df68b62365afab9cbf6e7669ac80ab
+d5e0bc6affd96532f4c0c28cddde3bcc
+d5e555b7fbe17def9d74b353cc9bfbd5
+d5e686307096d16041ece80b05de0e20
+d5eee44130f4ee9e5c65a68998642729
+d5f01433a982ae41ab75e40fe3c52742
+d6038df4019f454aae7a4e43253927ae
+d603ad23629db20930cc2d30903eb0b5
+d6071486bdaeb3fd1ef8acbb1a4dd980
+d609b3847a0176320ae9652547e44c04
+d60fa929e69f4fdb78f06673eb36fad3
+d623ba3f2d4aae81be37c590e250d488
+d6257fc3202e5ee80bd8cd2fe7f5a41f
+d6322e32ec2fab492e03b6d17d0e163a
+d638a7ce0b866057b0cec3f93852fc9d
+d63908bfb2b96e191f50e25b4306e5bf
+d63b33edc1932756c87eefa4c4bfb5c3
+d63c7b5fdb539ea62331a1030f57022a
+d63d6748cc359a441d9dc14c386adeff
+d63d80278927f3016c925f3fb7c47657
+d6494c2b4775427fef7d418ca5b5ae62
+d64a85875bbca160b1baa7fec6dba421
+d64bbab35046015ceca0cb380bfc0d0f
+d64bd8ea7c969476074fcdacafaaa42a
+d64d71dea4c77ddb8834d5173d01dc39
+d65ad89c23565df47c2e16f8ec34f377
+d65d19bafa797d0e282140095ec916d0
+d65df5bdf15392d25db24381ace273b5
+d66001b231369bbb0d6b951d121e6a67
+d6706a27c8f99bdf0be7da8c5d95eaf0
+d6807a82170184780ade053616779426
+d6818144ec5782361f5b63e5d6eca8c7
+d684f52bda20b17b676170d1571c9f3b
+d687048642b5f04ed4d516e8e63dc2fd
+d68a34e1efecac1d66ffe7d06b247d7a
+d68ed923bf96dbac7e721c61bb96f6a7
+d691ffbc2841a00bb9a481b2e94d123e
+d694ece2a4b12697c5d0bf44d5d583f3
+d69a74d67d8be7e4236f1c4ed20d588e
+d69cb7500eb9d4237a7f5e968b652e18
+d69cf7192452e63cda4f51a4c3a56f6e
+d6a20c6b848c9065b10a19d9003b2410
+d6a5be584ec5ff92f823fe925f00c56c
+d6a646d1a4edb48050f7ca52e62a1e28
+d6a925ab949bc4dfb253eacd7103723d
+d6ab9049ab4de843dae0ea5985d73603
+d6ad6d06ae0e601fb75fa5d835073c0a
+d6b4eae42159b9a3816cb68d9ff5a9e0
+d6b6690c7068239b700948b048db29be
+d6b8e543007305bf8ce05e3bbd9fef60
+d6bc0798776e5ba06807b5ab2ca229b1
+d6bd9d091685636970d75657e609eadf
+d6be85a42697fb96f84a760add1030a7
+d6bf5411bfbe493c530156ab3aad4e2e
+d6c0ed8483aa7ff51743da3fdbc812aa
+d6c1782fa0159c7d674b7e1aeeadb105
+d6cb5b72b2bff6038a179a544533fb11
+d6cec3739f24ba0488efcb0bce4181d2
+d6cecf69ff57aa0177aa795e95bb2d71
+d6d2297eb9c8f51b5ad732deafae32b5
+d6d40175fd9c2b152391a5a43cc138b2
+d6d80d01d0306a41d484201bfba86e2f
+d6d9f2cfa27c0360a7561b0b837d3a15
+d6de79026784b77457a3e27dddab2e89
+d6df2ca9f414f62a854f621b35d00077
+d6e378d551ae117c4fafdad94ea05e65
+d6e3ba5bb1646dc66c9407386a203690
+d6e6cb97ffd2bceb882428a1ec51c4a9
+d6eb30066a7d1639145c30ceb781d45d
+d6eb9487917032b1e2b6e079044229b7
+d6ed5952f8c69bdbd0c793b530df01a5
+d6ef367abbec57155195efab72fbc607
+d6ef47f65be251156155fbed7dee8d68
+d6f2b48d61dfa99595b8dcc0abf9fa10
+d6f54bd7fcda27146adaa61d94fef23b
+d6f74404081ed88c09af09e44dd061ed
+d6f98b01f17c23554821843c800af69b
+d6fb382cdffc9d7aef3ae9d41c4709de
+d6fd4da7e8b1dad6452ff5277d5dadba
+d6fdff53dd0d63caf0943ab64ebb7959
+d709e40dafc19739190f714f2a98a6c4
+d70d38e00a87a03ede4b40fc90a6efc5
+d70e20d0bb71e9d036acd83ae9fc0d78
+d70f54c0abac7c36908520b1a6bbf3fa
+d715a25052ebab71a19e2a10e60923a5
+d71a550b66884ee8c88ad6343216ec5b
+d71e3418d44e2363778d5d1fde340179
+d723a7d284b0988cbf83165bd213aa0e
+d72bbbb9fba0c1f3f7a81c45553a9285
+d735cba164bc1db1f5388e7bd9e8884e
+d7360e95d09847c0ce25e188c971ba46
+d736c131076b3cd535ae18142c77b639
+d73e8e1d86c88b398c26a53891892f40
+d74049a46d0ca4a6e131875611764715
+d74841ba3b385c489fa495accefbe968
+d748ca44367de33ee1c818caf3c8a1ef
+d74dfc6ba8790442395f3f86e1a9c225
+d74e2f1413125eb5b13221a2ae3a10c7
+d7504843db26582021b69fe198fbc597
+d751c9cc89171e777148c215e79b03f5
+d751f4c079cc76eb51a0814cb8da67ed
+d75eaa22e2908fd05acf9d51d0da9d2c
+d7673052b09f7446a035d63bb94e622d
+d7700208e7d79e46389d61dad341dae7
+d770c5e88d1239c6dd3b16c5cbf85beb
+d775b40be79c696ea0eb81aba936dfbb
+d776016be41e922ead34846aaee0c9ee
+d77fa03353ce2332020b9d89906512dc
+d78289056b5f89e4d8e8c6f52124daa3
+d788ff47fe1173c74a7d292e0365d3ae
+d78c542bfec5f8862e63e5bbe9ca0816
+d79011dd7b69483541eea81646990626
+d7902f64fc5384ac249e59946515f619
+d7911ea2c7231f38bdd6b997b958b5f0
+d793746231867fe1dedca07d2bbca15e
+d79380fdd94701e621e4569692a79a5e
+d79857c356a1a04775fe99c3ee508469
+d79a400dc305cb6dce92484bf731b640
+d79cbc8e907c83df7b0d5cc99c689a4a
+d79f80250d2f9503ce7e87f6ba60782c
+d7a02239f37371daab0f81b6d26092a3
+d7a5f1267f73bd191e0ce20559a98b55
+d7a803fc6f11639ee9c64f2839de7b36
+d7ab28b79da0a8ec76b9cce393eba4fd
+d7b541d081a66933adcea9cf2235ecf6
+d7b5cec664694e992deb46abcba543d9
+d7b6d8073aae0e5f62a7bd327366d70a
+d7c0b9a6ed7e6aa9ad232df7e9553b6b
+d7c3ec461e5e4264a999ec6ae9cca6bb
+d7ca4fcec335aeba194da2edd275b418
+d7cb672c573fa3f7a9f9d01e20903128
+d7d22247bdd131503288c4b31b83e0a9
+d7d25241d5248f6db834d30f852506c5
+d7d67896c3180dc66c141aa064b78395
+d7dab2b218d444af58fb9f190a836ab0
+d7dedad771fc082261a072697dde7cb5
+d7deedb5887acb67e66ddf4a4ce81aa8
+d7e975d29d859d9fff6972adde94c16f
+d7e97bfb093664d3ef17fc5bffc5806b
+d7eb12b493dd980d6dfa0963336b3d9b
+d7f2edfa823c4c93fd266721c239f824
+d7f8d1e82eb2d02afad7a4c4a50240ac
+d7fa100b1dc7dc09888398e27c9627ad
+d7fe6a0124e0ba305772a11412b88c6e
+d8019edd432f0c6bda89b6f059fa811e
+d808a0f36b72fc1150fc148902ddb1db
+d80b5c3b3c81b8888d57219083921e2a
+d80e6875fc05ecf7f18a5e02b42419ec
+d810ce4c4250df6a47449a56889e5ca2
+d813a02f69b67c15c264de9de662d4e6
+d8156fa7f4ce075ae2ff5648c7af70af
+d81699faca6949282a6123cec95ea15f
+d8187e607bf10a8f378c9cef9991a9ca
+d819d2cc7e08764cb602eec73b2faced
+d81b1fe3257f1447d70c69b2547a89af
+d82cb7d018ca4621ce5251a70824c32d
+d82ee7ee6da08806cc4b939a109116ee
+d830d16cd5f9004e2a117b4b1f44ad9e
+d8322877fef9442c54599c60faa46a4b
+d83285b92da81f943e6bb4fdb2851a78
+d8345036bd7025c0a63d413d2a8caad5
+d83567685c737fd9be5183ca518e3675
+d83a59bd7155f88bc53a51a809ebd2bc
+d844a5ae46d6422c2671d1441f34b03f
+d84e949be3427539ba2e6b96263a4a8d
+d8549c4c7755eee2c32c47228a6865e0
+d85fcfa0d18f5f38e722c3eb571d0fd6
+d8649e07aa146d0b1438b78729c0d6c7
+d8655ee6b3079f313e2f2bc0a2b85330
+d868991cc8fbb07864d74adf19768d69
+d86dcf799343c9ba02a770cfe400ea8f
+d872927d76a7c4ac047f1f0e26d9e008
+d873c873066f9bd4ba3f1392541c9d1b
+d87a10d761ad4b0925f5d100fda8e5a9
+d87f10a4f615144fcedc8ac46a01b20c
+d88163826f8cbe7412194391fd0e6d33
+d8927654b04bdf9b3c667e529a186c85
+d896d85dee88698aeb1bb3be657e79c4
+d8a1995833b5d2a177a297f3d2c1efeb
+d8a31d7906c297a4048e9a31b29b67cc
+d8a3f287b9666242567c774bba4dcae3
+d8a544c2c500d436687e15958deac97b
+d8a91bf210de063ec1f7990c04459d77
+d8b370f44b0739969b02987f70766f45
+d8b8441ba49e36e098e7991096281dd6
+d8b98b292c8bec0a17c8a3bc9e334587
+d8bbc4ae1f3a5d9eded34f1f777207ab
+d8bdbf53c5b70c7f2fa20371f892972b
+d8c603818314d248c07d3f72c722e660
+d8c8e44bcc02ec8a2a8ae4272fcc2cb7
+d8c9156f667a2a22c53d4b42b2ffe8a7
+d8cc6c2ffa5ad10607f680a72490412f
+d8da7edca4a954d4ac1ea53985878ec2
+d8e1e9febe9d6928806ac258ad6e7d18
+d8e2879b919ff5b80616912f7fb5e8a7
+d8e79fc93d982abc40d4cca9883a6f81
+d8ea0458a00b5b90e98fb92e4677bf6b
+d8ec26932f87b9a5f520a21f51714b7f
+d8ee5fbb48a2823cefa1e0bd39d990c1
+d8f19b008b0c61baefee24b5d347e772
+d8f1affae7af4bec5861723978cea54a
+d8f6f9f3bf26ed61f18b5e20a1fd5e01
+d8ffbf9b4f1d4acbd414860b192d2f25
+d902e21232c7ea8f0b1340880d48f7f2
+d905ae05dac5b176e39d67b33ebb1b21
+d9066c31aeefb22779f5f9d8328ce20c
+d909746215299870da61d4fc0ee230a9
+d90bf9f5a938e125509eefd9bab32f68
+d90e6b83d3e603f49aafc50f6bbbaa99
+d90efde66eb5aa235c92a9e0e5d4b422
+d914cddcf9dd2eaef8b40e40120cfba3
+d918230b0bbce3280c35cb42539cda6c
+d919332afeae73aaf50cd21b2df7dc56
+d921395e87643bb4912e61baf5e35761
+d92215e88c6accb67170dceea64c3f62
+d924ecda071cf0e24f5b54565661bdbd
+d92539e31255a2c22343beee70dfa2ee
+d92749265f65b19a811400391ea49879
+d92be2b1f771a2780a15ffe26a43bb54
+d9379fd640b2d995e27ea7feed45e393
+d93e30d364ed06b54bf21990f979cabb
+d940ba01aed56ace3c972a9c4a3cd8d9
+d94250328ad47c13febb0997ec000de2
+d943d7a77d73e1d90594715d4ea47be3
+d94457ad204976b3006701b4861db57a
+d94989dc39c2dcba447d2d6ca5e8adfe
+d94d4d7ea9acf9d0f755c2978bd73110
+d94eadcbac42b117f9ecba3175b2620a
+d95e6b90e7fc80c171a03149d5965c80
+d9609e23dd9d5d2b38a94fa971488508
+d9624b06e42b1b0722e2e9cc0363e2d5
+d96366c11e4eabbcdb98210a3af6c44c
+d9667dc7af364868ab8c429016ce4f7b
+d9702538dff23d97568b1820b45a8054
+d97488b516254827f09efc511edf1f99
+d977eec604737d13fc28db1082eb81ed
+d978b1ad84a994a137569908dda7fae9
+d97a1d4e95c23b7f31deb2a6fa792b16
+d97f71e7eeac655045dffea6b962831b
+d98465bdb0aa39efc77c83f35d169bdc
+d985bfa5b3cd2fcf6751579ad75ac553
+d9893459048f005c46d163ece0a85126
+d993f7c1bc5e9c2078e850bd2d9d6e57
+d995d7500f74962bf3a89515faefd29f
+d998337d38b91f34c5333e1cd0b60f09
+d99909efe7771eb50e6f75062dc60669
+d99ca886536ef41346f288e3de682a89
+d9a09d38f6aa5564d7a9dead278835a5
+d9a54c25c70a1b390476f0c202e640b4
+d9af211718814a204caba598295ef75d
+d9b200940a1bf8a8268d6c5651e04b8c
+d9b2c09acf6bc653b67d029a0e13bf01
+d9b6e43450c496083b56cdcbdea5d9d1
+d9ba3ee4f2e37dd2fc7551315b960dfb
+d9bb775675837f2306c2104511c22307
+d9c2146019ab635efc4cd9732dc90fda
+d9c2be38f653c9c030b660f877713560
+d9c5db4d5ecbabaf6ce7ce9e0940520f
+d9c92a63b9cb48f9ff7c1ade81bb0f0a
+d9d448e6b2cf3ce2079e714ab01e03fb
+d9d4734371a8ce1b6ce4d45138d6128f
+d9e4bd6fe997ed4ac1b7710d6f492c8e
+d9ee57d304f818fa194765bfac712871
+d9f448a4a538efc0c15127b357f22933
+d9f648b08499bded3711ec7752637f68
+d9f843e103b1400847808a353898629b
+d9fee879d3b4dc8569d0b92ccc70b24c
+d9ff91c1febb18c331681f91019416f4
+d9ffc2214cb1b572cf5f9fd95493a177
+da015c0da2a905bb7a165289f1fd04c9
+da116a76dd54e8eb0bd559f0aa79085c
+da12faede1e1769ca4edf3d8f4d85f9c
+da1a2c9d585a449d85d2e928d0c71af5
+da20ae228d000b845e1c32818a57bed0
+da250b4be9573de5b0ac65b4e57c2a76
+da25a6b4e9d0826db2ccc5da321e972b
+da25e4d8c742c40a86f176a4c4e104bc
+da27b4aa7fb1393e23e924bbda382c54
+da320863ddfb53f82904f8e823599b99
+da3401a0bde4e258e7387405e0b33385
+da34fbc2344a3d97957b09a378067612
+da36b8852bf58755b86d8fa15d985e96
+da36ffc316d799fc186208b0dd1212be
+da394e4d21f565ba02c876dbc55f9a6b
+da3c0d8e138eb0d03ba0813c30a83ccd
+da3f42ed0760b7ee3422444df60bd6e3
+da45dac2185312b580afb74f0f76aa32
+da45ed91acc8de6ff65c44c8bb96a81d
+da47645fbe37efed7ca399f7e3d3e409
+da47ef00be52dafe208965cff24b185a
+da4da2b3118af1cfcd2f27f447e72c04
+da4f681fe9fef5e91514607933ba2903
+da55cf117cca98d21df71b1c1e76b969
+da56f16c1cc41d32c6b51292a02de826
+da5f7c2671accb13980fbed1bd1f844e
+da65596e663dfbb244373f0b0c3a3f5a
+da659a5b63e119351854180407f42c70
+da66a92aa2ff2adff4c3c1225e3c746f
+da6c9b0404cd62b57e6924498eca7c1e
+da6f79343e506c7371f78bb1281fa5b5
+da741b879fbd3fd7a9f6361b0d728c6a
+da7e4ad8e63621f81fe757885c67c9ba
+da7f2c17821f42de29f8fe6d3fa5c8e7
+da855fb318d92b8c51306391716be430
+da8a0e3215f61c34eb4bd200a679e06e
+da93abcaece7512c44ec28159d2a3be7
+da94f39ac31f5b6caa73a8448fcfa08b
+da997b22c6c38da028e6c8f1db668fd1
+da9f21dac400e7588543f9fd9ab70ed7
+da9fa15f9b5364c306170c42f59ab46b
+daac421020a08c69f02e6b75732d96e3
+dab5794acfa95a929396b911438c3571
+dabad457f971451f94af3a01b5dc9df6
+dabb31568c6b6620b45724e61362ddaa
+dac2e148c0c0b58d00ff607b1662918d
+dac31ed8a48236485f436ac0b7a03ac9
+dac5d2c2cfe708d572111e22edaa22ba
+dac8396b64655593451f33c37e041442
+daca9a57d70cc3af4abe00bfd2cc4a6f
+daceec2e69a3943679ecb4cc3e66308a
+dad5e442f39e4545277188c272856f3a
+dad992b172e7dca39c9f34c54adcf593
+dad99b3f96802b3a93fd9752f67f0941
+dadbf71da5b8bc6e7a55e4da08b42b6b
+dade40cac8b541e58189d8137d5f38cf
+dadea8506ceb1792fa4e2f6f3c1cf302
+dae17b08f05610f92c5fe08a2eeac75a
+dae73e2ac6886fec52168cceaf992496
+dae7b5dbcae8a5054261fc039822b183
+daef54c0b701bbb60060210802c204b4
+daf567e2386547907fea3f7e240eb5f0
+daf6a428b0bd511c94e6bc408e2335ad
+dafa97df7b0b9adafc399fc28f592de2
+dafad16a345c8ac4b4c2edd065919557
+dafd11bd033e0dad4a97eae736425c5f
+db08c90149a32bf855246428b941c950
+db0a8b61fbf4f95f9f74e371fd784c41
+db11d36f80e623cface30b2e2cb4582e
+db16f63e8f8a0f1d9d363966aa17c5bb
+db1cffb66e27ca2a5548bb4057561d1b
+db1e81a9ef39ebfb638f61cb27702140
+db25e7de904ca5b74e262318a1301775
+db297c8a800eb727d50af12a48962abf
+db29e56036b17ea80d9db306ca2440d3
+db2f3c106ea91ceaf9f6b6eeb0b2e5eb
+db312b92c3079d6012d373daa48a71bb
+db36eb30437f8346ac31aa03b7961b89
+db37f43b809a74660d815c7b0ce48db3
+db381b4414f950ad7bad1114bbeb177c
+db3fec346bbe722c3f312d6b2f19e2ba
+db4b1b12ef30b17cd8112218335fada3
+db4bc4ca97e8045350a1fc2000ec59f0
+db50adab8d6255bf9b9da5ffa8b9a97b
+db51263ce6d0ecf6af166694b13852ea
+db523f690f938f21f1aa4b7692440499
+db56448652d6220290ebf630ff41d182
+db5e63928a133666181d5e00b3f39d19
+db5e7bdeebdf5c2e828f9a860d74f7e5
+db5f00831622650dc157ffa3267317cd
+db67bbea5cd9bde353b2eeed70ede5bf
+db6b969582378074bde40ebee7daee99
+db6be3cc8ac53c8c3982e20e47c7a689
+db6cadf5df481dbc4a58e58111dbad93
+db7156ebb69fa994380b1c41b3c3e4cb
+db71ac79322da359c244a3e88e3a5571
+db765f4c1a99c347c80a2977e479c27d
+db79157417624be81eceab7db9912b1f
+db81e21b96ecc18eaf26bb7127e4c670
+db82ef2f6b0c96b5ddbb7efac450938b
+db88fa27797cf8046f0edc3d44fbb5cd
+db8d1f5d185dfceb5cd521985507e70f
+db96702c32e4cdd7c841172a45a1ce6e
+db992b9a991b786bbe2e696dbc03069d
+dba5596c284ada069d209ffdcd2ad120
+dba6ef363301742e43fbde3b43a07f4f
+dbaa92e468cb71ca638ba822eb24ebfd
+dbb55b662faf07b01a533b27305ff452
+dbbcc2a005d39fac6e6ce8feb608544d
+dbc8afec7754fbe26dadb7c67a257736
+dbcc69af9a8e07333e9c821748b6a4e3
+dbcff5e344c48be01711c9ef89c57de1
+dbd9325a368223b91a3173eb764f306a
+dbddde0ee1c10d12b6f9e3bbef0e00a1
+dbdf4082316f72ac35b7489634bdb29d
+dbe5e1608cee5fe4ea900118f678b8f0
+dbed3701dadbbaf0c9dd23f08cdb44c2
+dbf08bb9cc3c92bc32b3f93a52294060
+dc073e202becb13926f081c685968a1a
+dc0a06a4957dbf732badf8ed45f3e789
+dc0a7cc1a21a48f72e7f8dfa27e862b0
+dc0aacc043e2eec0382e698a4f1ee837
+dc0b28fac11c8334d63906445faa92d9
+dc0eecf20a1f4ae4fcfec40c973bd565
+dc0f707000ccf7e0591d39cec0b8fdfc
+dc1199f92c5e8a23d0a1b66988c2eb1b
+dc1503500d1029e34a9009a2d1a1b085
+dc1fd54ee2cb7e1d321928e92247ea6c
+dc20ea5ff120bbbef60ea0b8651be8f9
+dc36d0651d2cc30bba8e56b0d485c933
+dc3edc1ac37d1cf5e4b0d61925cea2ea
+dc41c22cf4598807e5cb167e0feee00d
+dc4860916db188163e8f67ca8f27a07f
+dc4a3573d9c08eef89b90c44b14588ea
+dc598d1eef7549c7277ee749055788e8
+dc6078dfe90668def4d5562476c536f2
+dc64230e626f160c7613c07cb6d4004b
+dc6ae39a553d69a19983616c2cd10806
+dc6b02d243d693f0686dab8136e25a65
+dc71ebcdc321a4471103977c22f4e710
+dc753bf2d2b5b59cdf6e92fad590baa4
+dc7b2f57c44c1d98dafb23b71212544a
+dc7b37c7452174a1e2a3333ff289fa04
+dc80f9a9d36e46197c6b58b1b5afb01e
+dc8dd782cc06b269bd30b3cf43774e43
+dc8e04b7733bb653cc9bbfbdc3e13c09
+dc92742f5a003ef6f6fe05187408a0be
+dc94e2aed50b894979e6c9f72b7da8f3
+dca0fc8fa5ddcb8de3b3bdd350be798f
+dca6d845abd21aa85405ff9a569a9e61
+dca8e4173257f70b7204e1eaf42851ce
+dcaa5248a1461a6ab52d910a49f89d8b
+dcaf41fbedfd6e6eeffeb3d9fab31f3f
+dcb3af3ed13f7989e0d50e72ebca3d8b
+dcb620a490be49e0416267ff80d70ae8
+dcbd9b9f8fb42e2cd2853a9ee0bcee00
+dcbf3b4497516ebbda068124980faefb
+dcca532fa8fe9efdc91d6e010461b07e
+dcce839dae90bae619521bf682a7eb5c
+dcd2d5640c9ecfcd8c5182ccd55e97c8
+dcd3de39f563d065bb4e92804aacdd3d
+dcd8559edbbd6331cc07f900d81824f2
+dcda185cb4ee1a1448700d41d4a1f8d0
+dcdb6cbaf5ac8ab194e17516bc6cf772
+dce30d7682ad8e5dcc1e48ae60d3d366
+dce511498dd45c5d66044cf39e8fda42
+dcea51da3f6397f4ace7c06f27eaa95c
+dceaec176112fde09502f50f0929be51
+dcee7f36674cfe9e01510b6c51b578ae
+dcf39fdfe3b8fe7209ab84f668afbaa8
+dcfcf63a407686db00d59a883a074cd9
+dcfdea73a6ccea8094fa4c500bc6d67a
+dd0288d3fe0ab648e55ac420ed251839
+dd0be8da626cfb23fc5761cc5a383ba6
+dd0c763b8c848f2e845bf1ecd8458647
+dd0e0bf4ccec40665ccf3bd76b97d348
+dd123e8193226b009e42a7efc18b78b8
+dd1dbfb858f5fa6943047f353bd718ad
+dd1f19dbb0e728c01e937918e4e4474f
+dd2799598dc410ff1dd05d99a80faf25
+dd29c41cdcd4af9aed6113021c6df120
+dd29cd1b9b565d835321ebf0fea28c4b
+dd2dbe453c9a88426f96f2177c5b981e
+dd2e9ac5ed4f88c2f8564eaaa0dfb9f0
+dd32c17440516a0ff4ddccc6284bd24a
+dd3ab8b9e7ffbc43d6a6935025af81a0
+dd3e657fb116820c824981bc438d215e
+dd429b2e9de41d9a4c6cba85c960320d
+dd4989664be488445564dd6daf18f2c5
+dd4cf29506031e4f3719a7c782ecb649
+dd51e2cbb8134cd5481700abc6ef7d66
+dd5afd2b56dbcb4c4f987aa8f937b2c5
+dd63ad35ab38da7ad093a0427942989e
+dd752d369801691f99cf4c38f40de786
+dd756d67a4c6313967cd7b35295e7252
+dd8541005934d67f437b66c7d5e05a32
+dd85503d98d0c7eaf6e54e5b9c24c3eb
+dd87163490d3087e1db4e611023ccc72
+dd8d4c74d5a1c5f66bf2d94c5c2ac3ac
+dd93b4f911f45ec22cf1866245245b3a
+dd9649701b91f35422a7049708c548c8
+dd9b7f1a65ee495486e8398506bf0c3f
+dda055250ecbe406b444060ceaf67d06
+dda133c8147959ef9035b9b234d5b399
+dda136c29ab46a9aac36fe53ddf1af0c
+dda2583593896c005113b4c4f35d918a
+dda273194a5bd824847b35a94b785ffb
+dda9e01bbb0d9098d6d83a417fb26425
+ddaa1db63e4dc2e59f55b4e12ac8775a
+ddac06c450a6bf7afaf6ae0dc69ef1c0
+ddae9431eee3e00e648b159bca5d49cf
+ddb0d9360922c16b52eeb42bf067f19b
+ddba33398c0d268f6dd48a31081e4df0
+ddbaea5f6ca3f2571bc48ca2014e19cb
+ddbb52f10f1adb8324ad2800eb31e79b
+ddbbde185b36f53af6534351c8b04e78
+ddc17ae9986d59192261c9a238fdb2e9
+ddc4327949a90e273e310d18201e7980
+ddcab7f17ece5e9481bbbeb7d54d827c
+ddcd1b70e18c86ba60b3d21749d7cdb9
+ddce1e84125e7b35ed26c8d1ab868721
+ddce2180972e10abca55ffbf332013af
+ddcf03f5b60f1692432331054a2a14c0
+ddd7083e96bdc010a77fd8f683459d1c
+dddb661bc45641f6458a4933586b8599
+dddbcb0a2f862d105b512d6c540cdad8
+dddf0a2086151c9c013a9686bc3de760
+dde79e63019a6b57ce4ad81c97eeaf43
+dde9f0f95789b08a2ce840cfb773c864
+dded62310346ad81d69d781a565d0440
+ddf01f87d4f6f5b2833b577b3dc79c49
+ddf563956e50383c7cc718705feb71f6
+ddf898c4e9d89704454b7ff74e6b0bab
+de0522882468b04ff421166af127ceee
+de0547c068ccc028ba4cc1f28ed915a5
+de07245562d4661822b66aa05d465a09
+de0eb817ac24d1f9590a7db6c2706031
+de1198bab70f9882fd864b71b355179f
+de12350bc71026755f9cad2188b2036b
+de1a7256739baeef8468e0e859c90e05
+de1bcc8421481f9c47046233eebc8ca4
+de1c152d5fe6563077be2962c98c3eb2
+de20a88c3e30f880dd16b26dd6a6d9e4
+de24b20cbc15bb5669ea1283a4e6a497
+de28ec6967f3ecdc036b8494082c087d
+de2932aaeb6f6807a55af5801d67fb2d
+de2fad058af5c797af7af45cdc1df3e4
+de2fbb79c32a6406c59f7b5437df94d1
+de3050cb40450ef10052b8bc9ff731e2
+de30eacdd67264fd9bdadd51e684dbf8
+de32caadd2e24037cfc1bb83dc8472e6
+de37011f1fde88f49c5830e00367b198
+de41dbb63d6460d33120270181f26486
+de4a0ef8a4b7c887d4a310ffa443d80c
+de4c2f5cffabfa9e96142d143ee06ccb
+de554b9cc5d266ee3f5d450df524d122
+de5fc7a92c45e0e22998f3f2fedc37c0
+de617a8bdd5d8ba456a3b9863475344d
+de6296763515eda2d9daf40af0aadb35
+de63d16942396376e6d69d2101c9b14e
+de63eb8afb9b7dd56df2d0bbae15a74e
+de666e7872e3553313f7ac3018edf3ce
+de696d2f15a582e4fbf0e77ba55b097e
+de69f83dc878641b593e4fc9b0e3d44d
+de7121943692b1d1cb3617c4f4096ea3
+de7631a56d2af81e91e3619475a1f3ef
+de7747f182f7b5ba4ab253fd90922955
+de787d032e0d3faec43c86679039ebad
+de7aae9501f1111d7d5555d106ecd59a
+de8a8e0582af19ca7478f70d7907e444
+de8b484401b2befdbab76788f78b9cb1
+de8b9020e9148c7d58056bd00ca290ba
+de8cd9abd8a6b8564c503008fa80b454
+de91283b7180955608701743f0091c26
+de91f578044ef2546b7d0bb9d7f0db60
+de93a1849f37d802ff1c6e339969d264
+deb3be931bcb7df18211063803c0de66
+deba871f40d8c1c13aaf872a07bdacd4
+dec0e2bc26194a22aee36c61639ea941
+dec205de8532cbf5c79e07c60e35aee6
+dec345f0790b7782474c838312240bb1
+decdab4415516362fa9256a8c31adee6
+ded168536533c1ffeb13d1aea4c3810c
+ded8ec58f5cbfa08ff2ab2e18eceae45
+dedb616afd65a8d77feb326242fed2f5
+dedd758cd74411e6197ac8450f0b983e
+dede891801cd3501f20daeb3433be0ff
+dedf23bd43762b7927c074f4e8379824
+dee3879f69756fb3720955606cb9af4f
+dee38bcb1245eb3ff220433820e7ca54
+dee76fb4736a17b55583a721fe3ec5df
+dee90170e83b7785b0f1162b1734e60f
+deeae1b1a201074d80153c7507112477
+def028c3989b155d3942d50cba64836b
+def4aec227096bdeacf937314f77fe88
+def5ce5870b16967c55c83d96967c5ed
+defe914b5259e9450f4518e01fe8b127
+df06f38a0db8a7d57805069f370d9988
+df0a3de0a4e396179c9f6a104339c3bc
+df0f69e98d236f002c932870f8500f00
+df1245c2749871f109adf896a6236bff
+df17194df770e656f5077692b3a22e31
+df17d47172c7a01302b8658d701291f7
+df1c1521b176fcea5be689123cdee50b
+df22d0a2069ef9ffe206e01bef802b00
+df236aa2a9a49af011a36fb28cb3d710
+df23da74ef635a9b9a27d5f5be3ac7e3
+df2657c882d35a497ae1157ef961d59c
+df310647dd51a6d7509819882e6559a2
+df33fc7dfe8f57b39e25fcc4ef2cdc77
+df34d75e6a699e17ac101fb18a060183
+df441578be29e676816cd63663c358a5
+df47cf07a3681719bc6e14b20ada82b8
+df4f74bf972ffd4eb708e36a3841601e
+df4faffc90f0f8a569fa0daf74a798e0
+df5080eee7cf7ff33635d4523623180c
+df53e6f78306c9f78cabec880d0cb00d
+df58c9ff7abb0eb2d7e6a6356fe333af
+df60b82e4507b29c624eb11d3a140ede
+df65a5c1f0fe997623934e7837935f6e
+df6b53df196526d36fff3c9114d447d6
+df6b8f0e1739204f9c19f61217e09b84
+df6ca321440ea9a8061bcd0087dea18b
+df75a9ea1641de3092b574e13c4d7f66
+df7a4e7a5c624b83b8e55915ec95e637
+df7aafe1d05bd531a3d078786036bf8a
+df7b853289247a694ee7d76abba0d03c
+df83009042a2d4001174c58a7c866b10
+df84a395884b4c7744bcff1683c672fb
+df8605c79ac7323df1720be35be3018e
+df8c05c8deb00a4a0ea4d11b2742cc8b
+df8d594e7e97ee4b8692f6686b3de2c9
+df905241da642fede0390fa167a84f25
+df9185bb89c9bc361da9c79b2bbc6f8e
+df9346437d5079235f564e8b4228feeb
+df956cc9889d3aa1d92667a16cce778b
+df9a0d769276ea02e7ab6165ea249cad
+dfacbfad93ed14ba41cef3b25217d9aa
+dfad2bfeeaafae79a5fa613bfe44c010
+dfadcdc2bf043ed3d889ad9a2d60446e
+dfb0d67df7c8e5bcb50099b443f7fa47
+dfb34e8476804d45586eeaa216f343ae
+dfb5dda48c3effc9eb646f1ff5833689
+dfbae1161cebed893da94d8216620565
+dfbd466270d3438202b1fe3cd3b62da0
+dfbf6ebee47ec23b8ba68246b7858f1f
+dfc0de7f1f8decd685e57d26cbff0af4
+dfc28eaae27ee5bdc44149142967998a
+dfc35e528b8922017b2bec12b4a3072c
+dfc57e405c60c3d56b6273d9cf63c085
+dfc71755b1a7c63256f8081dd3c347c0
+dfcbe8a8b64241421efad6f89bf6fb94
+dfd0d6ebea1fad4611ef569198f34e92
+dfd551e3a12917381ebd30456ffbeab8
+dfd601f1e7e5b598f2eceb6602efe8e5
+dfd84953139680963f110827563084b3
+dfdeffba346e7bce90b684fadc21008c
+dfe16cbe4d26ff5619870314b2371595
+dfeb9f4ae93eebffadf26ea17f735a80
+dfefbf7dc9dd7591d5c38d7852dbad4e
+dff021af78ed0f8bfb34cf469c5d25e4
+dff77364d51fb40cc715d5f0eef4280b
+dff9e46afd2703ab80101d3911da84dd
+e0090608f2961196bee84f3c358a9126
+e00d1d7deb3663032e4b7d27fdb69b6e
+e00e6ecc0cc7ca58e38ad55fa9d0f71a
+e020d24783462fba39456a886632f123
+e02103b229d71bfa5badb2113b905c64
+e024c22940b2144a024a33b1263e1299
+e02cd8ea3cc0ba73145f3b8f452c7f01
+e02f7eb32abe0cdb718ab64d337997a0
+e02f848678a17e3ec55ab71cef8ff786
+e03053620a2c864e29cc869480479009
+e03bbecc3082df3f8ddf33af1901c09c
+e03e39f6d4fead0b47cdf2f59df123ed
+e03edd6ec07f052977e800234aa84a61
+e047459c0ff805c8e76f3e7914f3e015
+e04c7f6fb3b6dd143f343174335dfe74
+e04ce4e7c29b6a2457ea0efa1959d160
+e0514f0005dfa6a66778a37d1b4edc3a
+e053f1d621829553ca3d3da4127977bd
+e05d0ae404b3847e4042d0a2f4e623c7
+e05fd9691635a052d250aa8e0065c3f0
+e0657178bfb5592d0d54a51a9b072206
+e067ec7f5596010fe8eed689f1a4551a
+e0682aab748c34311229b3cceaf74592
+e072456e566556d3006c7fd12bd65c3f
+e073134631cdae70973d69812d72a889
+e07a2d2c7c2565cebdfc7db42bd47fc1
+e07a4f6437ff08ef003df274e6d9b32c
+e0821adbbbb6528a46439cacae81f3f0
+e0869bda88b43259b0e4bf541ce94e5b
+e0888f01667527d9053f2d00cd6c7a40
+e09684f21173033d61c96ad9afe1bc81
+e09e1d564d16bcb8705a0aac0e5db546
+e0a173cc77785cd18de84c8c76492813
+e0a5430ea035205115636b4eaa6147c0
+e0a55856987831db961e83bdb6e46e4c
+e0b3c0697b5591c4b4b4515bff54abf6
+e0be8e4572753d435844efbedec42bf3
+e0bebc7db2f9f759c4658e7fd4c27ed7
+e0bf7738cd335b82e7431cdd27b896a8
+e0c009f9f08af9e755298d7cbb7ca5eb
+e0c685b3aa6b892a7578e2850652892d
+e0c905dae4c9dfba19ebe90a4876b17d
+e0cac92a31a996114b9680e504923af9
+e0ce5a01525b40a00bc3715849da8bef
+e0cf7d5f47c66dec862f5e737fb5984a
+e0d179f43d207a3a3c067a593f16f451
+e0d3d2a9a48b61abb7e5a61f3c6cf086
+e0d81196253f4488526bf02fda47e141
+e0daeaa1e7ed291d842add725c675967
+e0dcec7f7326e8cef57b18452d253ef5
+e0dd3c3790cacc29bf0ff68b34c2e49a
+e0e04191d19d9c343807fa2dcb148e8c
+e0ea8b4057a0b5dc963f1b70c45b13e2
+e0f1edc503b08a0de388187d36e604c4
+e0f5c90ef8c96bc105223b008d62402d
+e103b7845ed5396b68d8369240aec0e9
+e104ee17c4efebd6d3f1ece3ab97f198
+e107e02a1d410b8837220b93f703aab4
+e1139b597c80333d7bb3792ffc35dd6c
+e117de4e11db21ea84f7209117d6c534
+e1196fc5d43629c1951f1fa5b0df4747
+e11bbe28838ddc6ec26efa3136260a49
+e11cf226cfd9cdfe92e05816eaa07151
+e125691d1406407ee69e6968a118351d
+e1263f65821d69d136dae8e4744b12b3
+e12680dd94dfde39f2fb2f2e7fcb07bb
+e1281e67b956c86dddaa877ab8aaf5bf
+e12d75db22c422d36f6b20303b1e5a5d
+e13055bd65c3dbd08aee44ff0d93e8de
+e130673d57a35fd98ed0e63c34956c7b
+e13686a7e67f2446d9881df2815c2199
+e138797899e364025ec529071cae6918
+e13cf245c47077ac0497ffe7fb0b29e5
+e1466559711836355f080b160669f5fd
+e1480fd076cfa8e48b9a57a71733f77c
+e14ef642fd4f0dea66ca3ea3cecb5fde
+e15bd12a2d340650953715dc91b3e550
+e15e95f8fbe3c4133b6f4396be678601
+e160b16a52e2e3d54c530770e9cfd0f9
+e164d978d261df81d6bcbbe26a04750f
+e167d50236c9fb9c04ba7bf071293511
+e1684d441133b33a0aeedd8524743e77
+e168f615e4141466abaf19d415f27699
+e16be6c84ff76df369713bc86c153873
+e16cb8b58da6065be9d24c323eb3ffeb
+e1722956de181dbb662aba8e3a0f6e10
+e172540c05c9180e86cccdbd52aca5ce
+e17305e53c65a5f3af933759d899bd9c
+e178d7061017b47743d1550647b24581
+e17aac871188a22ed7a63f1230b4eac7
+e17d2a87901143319fee1025ba4aee43
+e180034c5febb1895c0e587056c0b386
+e18033a0a82165249fc4398fca2ec65d
+e182a8b5f6c4f573e4839374348790b8
+e187b6ed58163b25cfd6338f92d98067
+e18ab32d7c43cf6670407b3e8e9680ca
+e18b4a77b446a54b13c6dc8028fdfb90
+e18ca862a988bf58a537a24110a1ac49
+e19110e5a945b4650c1557a7e9ef04a9
+e197a09e47a5a8054b3ef78ba6652899
+e19c6c21f83c59a17477fdd8973ab9a0
+e19e83ea459ecb9efa1c4b804ddb9c11
+e1a11b1fe14a9a2f3f89d9fae3300285
+e1a39809b8e30016d7521a4e49a1d3b0
+e1a612e4f739bfaa326f128a8013da62
+e1a94f022eb43bf9b58abad10cf613c0
+e1b0e80443e69a8bac8f210c446c9e0f
+e1b15cd3448c8f95d5b27617e9491091
+e1b2e63cb68a7c8ff39ed4e8dd3f1770
+e1b4d8000bfbe87f7cc5bc02eb858ed2
+e1b6638c49ee74bd79949570d7a4bf14
+e1b6ae581a234431bd042fce2981d124
+e1becdf0d8433cd06dc56aabb5d35981
+e1c3102eb2e47c21348f6eb52245f5f8
+e1c49f658f6265dba73a14e2832a73e5
+e1c832654ecdd28540d6ad8416f4e317
+e1c86e72e9c3cfdb6663b5d1fb2e6930
+e1cfa78c54f912474a6c02ce62e59260
+e1d0660a25c160217bc9359289a1210e
+e1d6503a1874b63826bc861d9fe30966
+e1dd7f5cf84b2e6bcd5c7f5c98243ab5
+e1df33022d815530990fff83693783d6
+e1e02ecd25f989dd30d728623dc66eff
+e1e482fc3a01a8ddcbb058615445e905
+e1ec81ad17116b85d1dedb82a63022ef
+e1ecd4ec4e952d0f416691b88532e121
+e1eea60854e6c6651e295e93dc9f0ac6
+e1ef12d39fb4fd9a635da49c03e157f2
+e1ef3c28b7ada72501a5e75fc160587a
+e1f67f8bc0ee70bbd9024158d63056ec
+e1f7a2d03a3cee1cba74e29ae95e9905
+e1fdcbc61068ec6dd3517225a97ba299
+e1ffd2edb8b7f628340041bad918dfb9
+e202ea8e8621a5dc81e83d45247e2aa7
+e20e5d9d707c42da30f0e0948b58c788
+e20f9d9e4081de967a22f0068922c349
+e21116620a622a6f4d487a0cb6c7fc20
+e2123af97eca391fbfec6d0a997be553
+e212c5c2714593ebac12171ea63ae890
+e216675592f289e67ace39ce4b07d20a
+e2191dcbf0fed4e1eff9825c8c51f4f8
+e21d2d1b4272c087169984add9879276
+e220f9d32edc685f5269851d37e662c9
+e225716664eb621ebab42107cb23f75d
+e225cf97732d06c497b5cdb2ddc62bed
+e227a0a5ae135a02f5c30e32b36d42db
+e22b6c7d30473d655408931e31018a4e
+e231cadefe8c2794a7df1907386104be
+e23534ae42495d891ad3664ba07b7495
+e23a6c419eac71660b98db978adff3fa
+e23cb564bde403922634d42078553383
+e242126b4b1e20798a4504f994a0c9a4
+e24fe098a45a85b3e1aa1565e9bd8c03
+e255e0bc3327380ed5ffc569a89e458f
+e2579b3d711b8e485f4bbf76196a3987
+e2595c12641437d9b0f9de1311232789
+e26051b77e64187222b8c19a26c15633
+e262b5ccb9f1d574958a898be0f4df18
+e26397d4706c65f44fde0a25e1bb0f99
+e2662988c0a481a5ebf179201718918e
+e272987ab92e8770aca13576b1380710
+e279f201542c25f87cb10cfe044faaf2
+e27a87e9be5af4d93d8eb84cec8d68c8
+e282654f19aa9699651abb3877eb324c
+e28376098f1f25de6969923e125b68be
+e28972cf2ab32e39e515daed1caa9cd0
+e28d581ef4bc736accd5cf251585fd4a
+e28fd30df6b92caa4ddcf9f134f96423
+e29018cf123845defe03b1971bae3006
+e295ec3ffeba003e08d8ebacb11d99f4
+e29c5bc36ed2c7db847d2205c89e0cb9
+e2a6ccbac30710d6d45022b9f08bc60c
+e2aa853de99b4f65bb0ff692f7868a7f
+e2ac55f6592c656f8ef7bfb68d93c7fb
+e2b0234da4278a28eb14c7ea48757d3f
+e2b04590767725a6361b74db7bda803e
+e2b31e3e00cf10f1b4a00f0695c42960
+e2be05c0ceb581653fafc5e1c255fe02
+e2c2b659cc72daed3372f685efe00b3a
+e2c6bf02012f6fff08b77039841c71a9
+e2c78a00b93d65dc9990df61510a470b
+e2c884c85c432377e1421cb7c5a2423a
+e2cd5f08cc735d38fa7b6ce3f4858bbb
+e2d413e6524c4249533b820847c6fcf2
+e2d53f79bae5800fde7cac8bab87f5a7
+e2deab68f98ea7dee9ef77828f32a342
+e2e177c543d67a73541fcd3256a19cd3
+e2e4b698d9257bb2d3eb4723740b6ba2
+e2e7aba8207ce0d02352597e1e190bf9
+e2f0cb086cb948143159411bf0c4885b
+e2f4898c4759f461a9c522776f578a5f
+e2f9cece325b6ed7bab6fae48abc5fa8
+e2fdb193213f6b209e12e99fc81fe96a
+e2fde053cd315020ca374f7849196080
+e30ce6f8df1a08d3193f8944cac8d182
+e31496edca2d7403a2d872156fa2656c
+e32aca6287cb252006a3ef32f137badb
+e33488386246c24bf4f4bda2411b6595
+e33709231adaeb9a12f03b836709f311
+e33b76d160d249fffdf8b9fa3a02a315
+e33ea710d821140ff8c263389f9cbd9f
+e33f30f3c27425900fe2b6af63386b84
+e34111218cc6caadb783620a40ed9d03
+e3459eff4c08074578ef0c26dda8825d
+e34d2677ace1244143803eb4c039208c
+e34f97fd447e113b6d84dbf953b539ad
+e35a0dbe76bf10c29c16a176e585bb54
+e35c722339662e24da6e284cd6ec66bd
+e361409cbe10c49befbf678f2f23148c
+e3692d235588b448f2b2a33699a69d93
+e36a6c4cc8b11c3829c36460da7d4233
+e36ea3060194ad834d2f86228ae75bea
+e375c5f23f1313cb48d0439369b15384
+e37844a89e96a9946085c11d47393e98
+e3789566761f923b35384399e6c7b710
+e37923d1e5770565af38461ac47f1b51
+e37a7ce5127dc268a88544a8dde82312
+e37b018cb1a069bc8dd97a3959973ef3
+e37c1cc10e55f30d98c651f988e60c1b
+e37c888ee08bc3cd99f727d7e915fe05
+e381e185748237ff952d31a991a3bb2a
+e386f3b967fcaed24e072e4e0c353b61
+e392521c44f4b91367ddf872f016f42a
+e392cce1253454048e158c0cada26bbf
+e39407886707c9be63b3ceb21b1213ec
+e3952ad396d1e0b41996106990d6a6fe
+e395bf165f8221d077e63088887f640e
+e39654683565664e8ee3451f2c25a55f
+e39ed76870aa6e854e7a3268ba7c9a16
+e39f46d0ed673559a0c02a4786cc5f37
+e3a0d73b6172b3e0458ad80323742e04
+e3a4589351c84a45b41e0576fe4b8b4b
+e3a6ab57f8cf9c8ea0fcc2969ea6e964
+e3aa1b028b85482c563f159777e016e2
+e3aafd05d87352ef1cabcd913846f593
+e3ab6b0f5242ac6e8e767a8a60c72587
+e3b31fc066d0c891bbfd8c02b69fd3a0
+e3b5eaf20d6ec38febf2ed7f870f0ebc
+e3b60cfc9ebc0bf71317bd1c4af7426f
+e3b62884fc04a4e9e6b5bf95fb18827a
+e3b79580dbd00c033b9d6e593801b2c3
+e3b870f3fdb98a8062e622d23c80204b
+e3c0cc1c8e9c4181d4e3e360716648a7
+e3cdfbec4940dd075b19f0e40f95cf33
+e3cf103c84d7759a81e4616a1bf310c5
+e3d7a66f7a236d87fff6f9952be73355
+e3dfb56dcf6b6c7f9e37436d9121cdf7
+e3e0b8df2e15f360479ae9c64a5a35b5
+e40252054393fa8482d8edf63361b2f9
+e40b151b2ff1f384249b6ea08fc58a53
+e40ce85030c5bde4f0f32689ab921bbb
+e41566b8fcdfabee3e4a357f96de7490
+e4167094acfa90109a3630e2a487ec43
+e41cfd737c544bce19a24819ab0e6907
+e42c8358c081203a6763385628a9f495
+e42e3a759a7cb51ec7f53ffeadef724e
+e42f0a01a0653b167d699be1177f913d
+e43081d357b537cc4558fa711bc012de
+e434e96cdf8a8766db72eb322dc10457
+e434fd64dc1cb7829af5edfef1459c0a
+e438d559d795c5e2eb377c5aec9c1bb1
+e43eafa75d8d8ed3d536349c3c93b300
+e446fa34fc2cb59bc9e9b03af21117bb
+e447981117fc89fe56f8f5b819c7c808
+e44856b3ae33f237c1a66f1029a55b56
+e44e4de9a0d8c8202b9a4374a812c328
+e45340763a211b17b1311578539a3bf6
+e4579e5fdb91438821c4a7b87ea52346
+e458909a946c512ce1f36935e7b576b8
+e459c234d8c2dee1683143e857845aef
+e45e5e5daca690d403ffdc2ec2f2f53d
+e461800bbd6e237819f0d11cd850d361
+e466536fdb69abb1e402d6d87da08b41
+e4670871ca2c34cc221e4523b12623b6
+e46f820f4fc103e947bc06d94f3fca6b
+e474746acd66ed666d2d45b16eaa1ffe
+e474b1ad958b6621eacef7407d388dae
+e47d7f331014a7bee769d714d26262c2
+e48118d18eafad8aab2c81dd132f173e
+e48312cdfe66a345a0e1d8e5d05dc86d
+e48d4acca1e518156e34e560aadc44cc
+e4921478b733ed83f21c48af9b60287d
+e4942458d10835d2519228866275974c
+e494ef7935e692c16b5a944514a9f5ca
+e49682ee83c07c3d791d5425890cea5a
+e49a9164573da7eec2b4cbddb9c238d4
+e4a12ea0d9bb8718a92bf5214753b698
+e4a5903794a779ff79880e395283f865
+e4a702cd3ef76a98695e45851e2839f6
+e4a82a117460261beae528291a864c13
+e4ac0d394b4ce4adb2fbd190f9bc480e
+e4acb8268aa897f97065ac62793ca109
+e4b0955aaf1bfb3b1b35da286184d431
+e4b7397e0baf78723737fe74dcd1a509
+e4bd7f8cad4c7cbfb6dd3276cf6c224c
+e4c85da362f699c0d65bab4a8547213e
+e4d34b129414d3f684447a345c1e7d8f
+e4d8e3b300f7bb4ac3e16d5c51a7c859
+e4da535dbdd477e9b2e7c8aeac402d74
+e4dac23780f9ad51a82e20b4d96f7a22
+e4dfad3f23faa1a46ba0fb8d5a1d7a22
+e4e37013b31f0cbb254a402f75002e36
+e4e962daca4e0de2ea6888dd284ea863
+e4f9557e6c90b5b4e7b8bb492cba5257
+e4fc9ef16e0590b7cbff32167c9e1170
+e4ffc798d028319aa627d3c28c0851a0
+e5006b220f7ff16e35ece89956b31bc5
+e50471920608fec75df91865b0d37a68
+e50adf7eaf606c1ed50f8a5a6906b7fd
+e50bb5abc6798c3d26b883ebd7fd5ace
+e50c70b32cbbeabf8f0472989357a363
+e5127b63ed3dd69583def2afa51fc542
+e5134c610bd2091b4aa4377351fedfd1
+e513f1ce95e843522f8ae8b1393fd5b2
+e518a4c4f341b15291f1130bea6bbd1f
+e51aee761ffd39e4dfaed4dca5335962
+e51b9e8526a8d5b41d7012a168cf0c26
+e5271a5ca6303e6a00894f788528e04c
+e5291749f9bad0b0c692ab8eef89be9c
+e52df4cc71b34d278a422a3fa1a250b2
+e530e8c9abb9d2138ba6536f020f4828
+e533d3e5a2a1631fd44c6aa8087d8589
+e53530f63447c911b5572fd9ed0ad205
+e535be89c7e8fe68e82992b672d65ec8
+e53cf13cacaadeafd23dc5644c359053
+e54333be78c06261c81519ad04ed2434
+e550ee59b9391c3383c2d12684bb9674
+e55d432722084ce27db39b26282e2440
+e55f70dfefe38daaa5c7b8e3ed403039
+e5619542de23dff6d2d2e210d4bf26ab
+e562c54cd152e5ca0f5f6ee92036bba8
+e562db0826f14359a25bf6dd2d9aadd2
+e56578789e7f4338516035a51cb85eb3
+e56a110e77815b4afe38b0e5c3b45fe8
+e56ecbcfef35cfc312bafdeb320acf4e
+e57373a5f7220bc8349df6f32a6eabd8
+e574ff2bb8658c7d282f2c46bbf9b983
+e57d06f40f50fb622ad1e9ce8706af4a
+e57e52fb37e7654422f59528cdedb0f0
+e58111ccacdd78b2bc51e19a4c060dd5
+e585c60321c8beeb44fce427da548870
+e586846f5b0d459ec7c720a3febd125f
+e589904a23de9eda6fce42dc8ab60567
+e58d072aa639557f1e5088b55acdd320
+e58e3cf6cdae67e6a0e3afc052513cd5
+e58f79a87ab2c886094fb3627e360f76
+e591c56738b10291a9b5f94a34638839
+e591e1cd123c401d9961ad14caa6b3fe
+e5934f62c94a747fb0d12895844ca6d1
+e594e276b92a616b5924fccacb16ab68
+e59a6238e33af6068f4b5f8c5a83e0bd
+e5a79e07b1862c517dd3de385cd75e31
+e5a89ce3fa86f38dcd944655431189be
+e5af39eea58173567f5e6d19c9170eeb
+e5b05bb8f2788b32cc5745eb81a17800
+e5b2c88cd4d116dac0af512938f67f64
+e5b4288a3ab64569992ecab8cfce458c
+e5b8abeea023545ffc753b3a1a50fe11
+e5c6c2a41430a2484bc5a1c3d9279171
+e5c83c14032eaa0abf90774d0e780b4d
+e5cab9bb6ef849ed4e3d2a1763cc22fc
+e5cf58b5b0ab643c8142e1022451ab04
+e5d028d1720d6fb33d93e71d18925187
+e5d57a7389509e369373217eff7c5977
+e5d6766426e2e1b3f9de50c71ae1d77d
+e5d7281230b6779e85167ecb426e1eed
+e5da6cfad43f77e7ffb3db0f7e2885e5
+e5dbb5e906c6ed23a4061652a63d0d1e
+e5debc22bbd3e9e57f4046fa5d3df3cb
+e5e11b2163fa91afd5ca01fbe967eb2d
+e5e18cc92c3f47666816071742f9ac3a
+e5efc49ee0e69029d4f2d62981261dd1
+e5f3cb30c3fe02eda1c5bf4a08056356
+e5f61ab0ae1c5ea2a5a7a86e1a23f6db
+e5f64ee143f76d964299f17ca0d270b1
+e5f9779842c967282f4d76f6e203508b
+e5fbc2e55f647fe098760778d75f0bf4
+e5fcec949c6fd1da27d5c03fe42fde48
+e5fdab0994c53495e611cb6727310641
+e60cb6a5e50ae470d36a89056bc6a077
+e610a94ddf698913d6b0b2297f622223
+e614868521da51859786eaead8328701
+e618bc0ed55a72d4020623d86b283e39
+e61f7734ca8c0f2fcf9b166411dd0e54
+e621058f22ba4a6459d8c585690dfc9a
+e62200cf708bbf3dac9f3d699f2f12e6
+e628ada71ab7b6eca855f8da419f2905
+e62cf481753b2900b594db6f1f1df99d
+e62eb760373845a4ca9a60e5b9bef647
+e6303d5059ca664d624f7cf4f551c5ad
+e63077712c3878a0dd9086bc4d8a324d
+e638e84fce91126bcc79dda42a13699f
+e63c90127c38ad79ca29ab93c8a61bc1
+e63cb71bc2ca58ce403a30fe2b18b442
+e63efc508f554df4c5ad29342f9a6800
+e63f5e7ec880a2ee555635a3f35f2393
+e6414e1bb3201197314608688b337b17
+e6492cb562112826cac6836ad81b26f8
+e6498eeaa5a9d1687d319bb25e9e3953
+e649d0516bfb58c566fbf6fe1df04d5a
+e64ccee491e84c2309feb649b5b151fd
+e64f0a44d5ada135dfc7503d643c273b
+e650e0c7ff9c8cebf76c901dcc0ad52a
+e65375f900b64a664e726344af7857ba
+e65bab9335eee7afcd5177379a8b3e59
+e65be4f9ead08ec0527043a840266f16
+e65f25a8d168d8005235ca40c07c5348
+e66108cb04944626e1e529d71417584e
+e6734fab79d6b73478cdda9f80220f2e
+e675a5c8b679e4060bd2637a7ab0a73d
+e67cd7e2b182e1d401549036575d2980
+e67efaabf258338ee3a007b18344ebc1
+e680373d27b3498a4af2fff2e060a6ce
+e68606096ed60d2767fca3eec107f828
+e6863b530b9d52e24441f41cfa3a9ef0
+e6895bdd4ab555cac0e088f856c8fcbe
+e68af299d861cca9c55b5dcde3825e50
+e6941a00eb3b15dc874645b744b4ef6b
+e69468bb91083ed483ac4b4cefee8e1e
+e69761ede92373ad876e59bedbbdf472
+e69f8cffea3a8ead836963758ecceac9
+e69fcbf3b1316ba060805f0f2ab138f3
+e6a638e317453e0d7ccb39882b6dfa89
+e6a6d6895cdd319eb8aff36a163370ad
+e6a863173938fd9ea21d418667fa4da0
+e6a99510fa7392ceefd191079a91a82b
+e6aa96e6b230548d82d48417d94a19d6
+e6abf3896c51c9ec3bdfd64133c61fe4
+e6ad46a4b4a8002ef9eebd0dde8c74a8
+e6b13481dd372af1a7898a9c04cef65a
+e6b3dea55ed1b04d58491f8b8a57d872
+e6bbf552069f36858e5381c81b7d36c6
+e6c37572c78fe7f932720f1af00d15c9
+e6cea313b0c2b1230908d8c34163795a
+e6cef5b2d261dc3f678dc1d07131c886
+e6d3a9ad43736a33d803097a9ba5b2a0
+e6d3c2064cafc85de6746a1d6cbbf572
+e6d4c4c560bb4fe833531ed3e590b15f
+e6d580af8fe4858e318728c77f1049e8
+e6d7d2133c68c24cd581e95357b1055c
+e6dd3f82676bf2ca791fce9d8b648d3c
+e6df4435b64a9c99438d3e1ba1c95630
+e6df6feefd00c23ce4989ac9010b7292
+e6e2e1cc646ad7c3a3656ed329a7a901
+e6e7918cfdcec340cf7fda58620e5071
+e6e9e97801f4776916acc0c52dd6031c
+e6ee9a5fefe704f3fc3daf4f05720fa2
+e6f9dbba94ad6804171f2bd740a60923
+e6fb8b7e7c69bc4db0d430b1115e611c
+e6fb9ee979c8871ad0337ad752d259ce
+e6fbd802b65cefffe9b25ed27bd324a1
+e6ff888ac4d54284ca1c677471a65bff
+e701b96f79bb348d97f1cd439a8c032a
+e70a55ec6061c465de69646a0423d2a9
+e70bbd59a1ae4e88d43355ae110466db
+e7125cc74539071479fedce554eadbe9
+e712834f26f3e13a23acf2b3932923ee
+e71297cf62a6cb1204e7fec89959d7c5
+e713100f9ee1b398115eb223b2c38b4c
+e714106ce672c954723962c13449e040
+e726119a397264aa2325a20f664567f7
+e72b48f647b908b68a8d11a210f81deb
+e72b8ef7383309380ba914b5019eb75c
+e733cf595e317cc06b046ed3ebd32745
+e7393c8abae8b8676deebace8c6c711f
+e73d6ba8a713a5b70ff3a3b9ee8b12e3
+e73fc1b64daa6e23fa94be10701a991b
+e74678f410bfcc4e5c599180552a11d3
+e748a8c37c6d480b48d1d083bd2532d0
+e752121dfc0413366060e012ff4d18d4
+e757477a031aabe890b15275942153b0
+e762247960251a8018893bda034db5a1
+e764927021a9fdd3531ca6abd16beab5
+e769627a2947acd1102a546805d74c32
+e76c3353bc9edb77064735033f64fabe
+e76f242e5f3c4c000063421313d9f2d8
+e77244eb3f31876eeeef6b636aeabd86
+e77a0fe6aee9db67a545ddfca3b870c9
+e781800704b94f8d6439dcec652be5ad
+e781ed41ad214c5385c52673f740ceb7
+e787aff2d8d4ab52702f99fd40b76f03
+e78811d39f6c5caecb610567a757f4ab
+e78e1dcb5b50be9a5f5e013af70a0a1b
+e79d3bc1ab4a9ca8ba826b60330d3b9b
+e7a079e0fb75a87a50ffbbc525f0fffd
+e7a4382d7f3851aca597c59948b3a0b5
+e7a4807599066785c7ffeda5de96c671
+e7a4c06dcd65741d51d55a952538afb2
+e7a9d88b3bcce0d985806741522aacbb
+e7b74511ab42b37a68994edb3831efd9
+e7b82e03c7206b1565db2feee33c4be9
+e7bb1eb946107d5145f5aa1af8ce73d5
+e7be5939e1ba730be787f71d5b2f2175
+e7c1c32a9e4c0027c390f589ed274450
+e7c353325464cd49ec33a82c7be32fed
+e7c59dffd86e3b52e3d249594ae50f1f
+e7c6100cca0ad0ca23a4f78bd6ad0ad6
+e7c96fd65a3a22a237951704d6fcd05c
+e7cc08a56dfc1d841267a67a6f3c6e1b
+e7cf52ccf3ee828d918c9e8cfc361471
+e7cfe4208784fc2b05e2711e27329724
+e7d020cec12b1307e390ce4c67b315df
+e7d3874b605300e156b102a0de4b242d
+e7dffb2f4dc326d0ab67ea3ec258c690
+e7e5993bc230140cff23adf73628f0b7
+e7e9c5a0cd1e5b2f3aebda8d0786fb8a
+e7ee7e382a0c90c83f183c3c8ccc2445
+e7f14d64630247db8c909a875e42fa4f
+e7f460706167da81d5ffa64de90239f3
+e7fb3867822fe4d5bdbaf7e25be31a37
+e8006ffb5834e3a4b211287fa351e3ce
+e8011d85bd328ab8ae6f9b1e450f9b7b
+e801865f09ee0a2c223a92aa1899a629
+e802d2d1e17d864a8ed83aa92ac1ce5c
+e803a3ed9a891dfc4aa6cba0f3f88138
+e80543d34b267c504b14aa6801dc2557
+e80721a3620025732d0a40f0dc6f345c
+e808cedec52cdc27012ec60c3b134599
+e80c6e798beacccf0090fb5132e5ba23
+e80fbe3b51ee37c354e64dcf56f853d5
+e8170b6cdcdd12e0052cdc2c12085d70
+e819060a92d73bed455b321c84f53790
+e825b0b0d0308d80e127d942bbb699c4
+e826350decad7c086d4bb2c60beb354c
+e82db3242c894325ea8463eae5a00820
+e82db718c49b171405c0f1cc0c41317b
+e830571032c6ecef920f2143fb0ff476
+e8336976f4dd2105db684450d44ba4bb
+e8381e8576911159830a1c235542813b
+e83a214dd89f4b726e693dddc9412406
+e83af9b10ec171df91235b5d199f2a40
+e83f557f7715b00ae301c3bc793e787d
+e83f8f6542496e3c9a783f4d44ba9d5d
+e840d04c3892abed49d0f1422ec54085
+e8429119d8c1081609db3d227e7945ee
+e843ea49f3b248d3e4938c16b8acf6d4
+e84426d4f9d77876d6d6bd56e6c67f20
+e847147b25afb9a415b31aeaf9ef2833
+e84a736d8b28a49d9753983df14b3988
+e851a7ae33e07ea0e7e2f380ec11593b
+e8534731d29418164f09f88d9b4c0279
+e854a54cb051f1d23a5247cc05f377f4
+e8558c3d1a39debda0553ff720210458
+e8579c2d01e9bdab30f6809324a8cb78
+e85af7abb8994417eb19ebbddf3e499a
+e85ccbe8816235800628467eb99f6a37
+e85ce98555b4d8cec3cbab58559eff5c
+e85e55d8fbe35941c8170e9a9f39b410
+e867186297d9b15372df8a9aff940a20
+e8712d537ce74d94cbd88fff78542a26
+e874d7017e2143fd352b2a5ef35d5791
+e88035056a27f023a799a9ee7246edbb
+e8810bc91563597fd1731562312d0a91
+e883e87904754aea2c5681b704167916
+e88453586ab588908a17e5b3ba6b9b45
+e885d8342b55f1174e99f57c4331820c
+e88e8c32825c242d3fcf676059917948
+e88f3b791557f217aa8f559f959da9c1
+e89f18f0e6dafe1573fbf92f71efd8dd
+e8a06bb2bb32f8a00e296d6dbdd231a7
+e8a1106798486f5783cf43c72381bdb8
+e8a1a322c4a2786ac1395e23aa598d78
+e8aa155fa57006b470817d1dc2777904
+e8ae025149d061d4752b5e2bb17fe953
+e8affceea88cbad27f88d2594c233314
+e8b074752055a509d31bf7385f377103
+e8b507a3f0abb142fe305be73ef58ded
+e8b93e07a14e7f03166a2addbbff1327
+e8ba003ef8549e909e75465205d75874
+e8be95f868fa967b9cfc58b3f735b51c
+e8c3175adf7ba8cad9d69fcd61ec6fa2
+e8c586885792aea6bd1916bde997455d
+e8c82779db22db188b8fd80214167397
+e8ca10f05cb76b4d213099528aba87c2
+e8d7fc269594d4fbd790965c7ce19e76
+e8dd6ee4c7e9bb74aa2c83201f6e5c16
+e8dde1420f3cb489792b7756b61e61b0
+e8ecd0380d1bafaf0b796536d7c7fc67
+e8eeceb162e8213648d912dfc17f2a16
+e8efe4c5857fc6176e0dc17a917a7668
+e9075ed38ae51209b2645d3b5af91230
+e90a116018a8384e9bb1783fbcc2edd4
+e90af448f8e23790218d5688243d56c8
+e90cda6163c68d9a0c35f6b9f9eb5b85
+e90d0180c9cd3bf1e1fe6ea42503fde3
+e911a7093e3d6ab250f1468932599d84
+e9128d4fa22046799efa7de7956b5b3e
+e91313fd91feaad254ed23070a7c0f1b
+e91a144d12b885df10c77375b6d1e0f7
+e91b593dc41289b53df8ffd7e145baa1
+e924ef3c2fc3f189a04e665b33c7d248
+e938857393c688c52cf3627772ce0eb8
+e93fe34e7ee155c79fa27171ed02da23
+e9416ba3275a47b24e1a4797323a37fe
+e94770d16edaae92b154e996811e09b7
+e94c64ebacc8431baf9f6f17c9207abd
+e952fbc0749b8af931f0db3e6ff0248a
+e954e13600848c6bd508a33d1b6c5523
+e95f429f770c221123726850b8ef6e6e
+e9641714540a2899b873cc6b10b8608d
+e964181bc2b1f9018e5f15a88676e95a
+e96845ff7c99ebf4220d41ae11209e4c
+e969b504cbe54a2537843d36d8e46ec4
+e9751e17381af314cd65f4c32f64f47c
+e976fb79b4d98284b0c8c95b7db8f1fc
+e97c4d511e639e2eea75c72f45e8c571
+e97f8c10965dfa4634780c4d54a8b9eb
+e9813099efadf886ed3f70266573bdce
+e9833e1428eaf52674068b01f20a3920
+e9835d7e0ee1a64dc662b9f40a3e4031
+e98d15adb06e4361abd787fa196ff628
+e992dd996485bab3f48a9cc41357cc04
+e997af7c57ece4ad3885b47deccd5380
+e99809e905d01337fc84a7c3521eb49a
+e9a238ec51d656266c0d1e1dcdbc7c86
+e9a763f3a02d31a83cf2a4f4efe703db
+e9a85913a527412c129cddb23d5a3afb
+e9abba148572d9999962128f92578e94
+e9ac8769715d5c5a92a2fa5b6532d24d
+e9ad05b2506387b635f12f212ad7e87d
+e9ad3bd3e05ef6016d774c6941f34b13
+e9b83482bc8aa0fa0d23beddf2ed9836
+e9ba80a2dd82e63b972b6dbdc5865c95
+e9c0c7f57fe22eff13833bd4d6e92eba
+e9c0f36fc5965a44664f9879db8a09f1
+e9c46256e11b450478c7b677c3bdab3f
+e9c58211f982922acc679fc370d05ac7
+e9d3a3515f8a98f06d0539c84aac522c
+e9d6486058f6b71ef53348f304a2674e
+e9dc169abd52e93e49a519155be79a7d
+e9dc4edfb3a49d5142dac341b1178643
+e9e04f85b35ffeb16e62dcedd5599527
+e9f60b81103fa0fcc9d1e467be9d5eb7
+ea01c443d06c6f43b0d2f6085d4ef217
+ea042f2a741a247c55fa04777a8ba6fb
+ea0e7a20260cc6956e5de6dd8949b41e
+ea0f14462e6a6b28fc4424c2f791a270
+ea146cf3ca918b38f549b09febd9b359
+ea1ea0fe3995a95bd9467640d384dcdc
+ea2418453e907f62815e5bf24c61d59d
+ea3303006cf9682e6cc92d1353c9d924
+ea34523fc72622684a90d8618750e1d7
+ea3572ebad77d86156ac9786934f7418
+ea359305a42de000e7928dc4e1a8b37e
+ea3cd9594a222cf560cec820d6b21e4b
+ea46d8209b3624b5bfe1fbc50f2edf5c
+ea4898c72e871d366bc99b53d257ae6f
+ea4eecfc638d6208b80173c78fef0804
+ea531aeb7098ebeab3cd9769777e0bc5
+ea5c5909cbf3948a720a5b7b5114a237
+ea5d73c1e5acce3e1ed748e2890a785d
+ea6082c71913bfe5486ca3faaf65c7f7
+ea6218de12db3ab4a89b19eff7ec80f3
+ea64e480dd6b8fd9ee0fa24841de6711
+ea65959bf5a716aead6fba13f634aaff
+ea711f363601620329b55caa63540add
+ea72e0d8103cc3219da363b7c91ffd77
+ea7389994b09372d484cfdfb67942b92
+ea74e07ea5c6aa53584dbda6c819f141
+ea7893effb2fd2a4dfc9908733c85f94
+ea81016888c288f55ad8f763849656fe
+ea84e942c01ca0261280a1303549e5e0
+ea88166d4203952d2d2241c7c437c2fa
+ea89a393b666e752ccce285fc1da41dc
+ea8f487b415b607f0217242d0b2eef38
+ea8f70bbb2772a842003ca99cb31146f
+ea90cee9f556db8ed4362dec2f93c980
+ea9b19d9c83633b3e1e018599754d478
+ea9d593687a9583b1338411e4cddc833
+eaa036da7fe3634a50130217e321140e
+eaa2401df8ab1a19c7c69526bbcbd106
+eaa6abff5a4adae8e42e2c323dd7af63
+eaa6d1f6b70197f464ba05b7a5a7b558
+eaa7290dffd8180729feae2eb3fdded9
+eaabc63a57edf7362a72e3b396bccf91
+eaac83e0bfbc36b788bf80d07d550565
+eaae9e76a931cb2c0e9bcc45af896116
+eab367ba94d10d2db701115725627f43
+eab9f815c995e65877d2eb62650aabc0
+eabf1060cf023287e121cc7cd17e68a4
+eabf64ce017315be375c90dc6896c3a3
+eace0eef94d323e137ab199a486a0e17
+eacfc8393e2836278b9466b6bc836fd1
+ead4bf399b7dbd1b4be4b9727cb3aa08
+ead588f2dba3ef699573a125b4f98df6
+eade17d99b32e7d0157d9958ee5ba6e0
+eadf0478de92c7fa5ae3693d53d639b0
+eae69929e8157eea4f78352feca21297
+eae9887a6c53d18112ab340aa4dd1a5f
+eb011db7666fa82189396d52311b5a5f
+eb0293ef67743e4d3cafb67f78bbbada
+eb069dee47b3e12272bb1298cae095fa
+eb088e85a158f295b8cf855cfc93c553
+eb09012dc0d25c6f29ea8d215ccfbc61
+eb09a3ee1cfd71f23d5e0cda8c23f868
+eb0f103a9fb95fb00ce936cca6efe986
+eb1101552493ecbd2cbcf9f5933e1e02
+eb123dd91617d541cd9f40f4d649a764
+eb15a1e27856b94a24750951861854b4
+eb16c9cdf13dc653edff10ccef9612e8
+eb26bd3c710ace0d2020630ac75eb3e6
+eb29f9293c10afb7f937d9b729af9c80
+eb319178e8b6a2c47f1acb7735011c50
+eb34de72e0046fbb44b1da8340b56a82
+eb35e2e0e897ab027a3d8aa848e6c721
+eb38285142dfdb56757ff23df7523e89
+eb40b5bd70f4f834d4da99f560acc693
+eb464dc781c64aca17103bc92ac6e9d3
+eb53bfb7a4cf1304042157c0a80be377
+eb57130470b8029aa8fc9cecc059b34a
+eb58a291a6f7a36b87911372734cded3
+eb594d74c073de6b7dcb73c5dd8a7d4a
+eb5ac7b239fe060e7b531d2447ff0072
+eb606f024488bd96838adc6506f2a4fe
+eb61ea35cdc47e0d8da414ea9313f666
+eb622b510cc4e606524200b048683b64
+eb657fda8b533ea2c5b3e05054eac679
+eb6d3cde5cba8ca58260761aa0a530e0
+eb6fe4f587453c3fe9e136734722cdb6
+eb72dbdaa5c0406d0e9d034c209ede72
+eb7a41b5c044c9e97adc4f7f04fb95cf
+eb8005e17df1ceb535a3010e14842f14
+eb8306d2243adf671a63580bd2ada29b
+eb8955d1a0290f28d90d471d80ca1d0e
+eb915142f7e077ef68e80607d3c1d702
+eb91b3e3975f0d09f89526365f46409f
+eb95d55daaff567b73e7648f1d3f3714
+eb9a1427a9a90c245fa729b26b2be9cc
+eb9c4a28baa60e6961c3518a3d07d526
+eba19ea3c86201cb68e934e8cf291816
+eba5860f8aec590cbe911536aff1db8b
+eba5d25e206cc1f6e885b9efcf16018f
+ebab373b279f96da69af44eecb051f27
+ebb34a6cb0e4dae1ee0dba61c94e09f1
+ebb5e094606644e8e897203741e9109e
+ebb745e6d202bfb13ce81c3e5d4f2a73
+ebbf6039ff4ec149691fb8007ae2f868
+ebcd1230042235c0a064e22b49a79041
+ebd81f72ed40aa52a67eb4fa19d1e40c
+ebd8270b2fdcf20abcd9186b6bb2dc1b
+ebd827b6f817ed620a991e9af0affba8
+ebdce99a6127e79d405e3a75573e025d
+ebe21f1c3496b5a04bf753f6393677c5
+ebe5f98255ae768309044ca99f1d593f
+ebea63ddc966d99ea66323c7d89c103e
+ebea92c5d548dc161df65c45dff51308
+ebeb64b448b2b161bd430f2c08f50f2d
+ebebfcabc3f9c343b9b5d9f3125e7446
+ebf7af608d1aa72d33270af812a30d1f
+ebfa5e2997b0ca24fc2e57656400f6bf
+ebfecc270ebed0ecf3534bca8eeb26dd
+ec0399fddedfedddc23113ef1140a0da
+ec06ddb7dfba6fc54ad050d2954c3107
+ec07d049b6201670233821841d4d2a8c
+ec0b63e34607b14f6d40e2880aceca21
+ec0d0a1d9e4dd27c898abb783f8c7647
+ec1712141dd457351235b6365993edc7
+ec2920abd7aaac85f27957fa5c422dcc
+ec2d78de53b2e1d28fa542ed373eefc2
+ec387e7aa60047de01e1eda32979a535
+ec38931fec026344c00eb76d9890f09a
+ec3f0c075ce7c05e929372e5acff2be3
+ec40969996f9463ab0efe766d84666ee
+ec420085d52414c73fb950b763534832
+ec4ae0a2e17969ae0e14b1913633410c
+ec52674c82119c5335ec4f59106d6519
+ec5679c3c9c0838da87f4ca02de47ea4
+ec56fdc025fd671c70eb79e93a6d5e6b
+ec5b097bbe01d1629fc10d33fdd809fb
+ec5c055e8e07faef43cf027c93f2ac63
+ec6144bc96b25616ae5deeebf56b604b
+ec621d602552e74c25727a825db5b397
+ec62c9ac2160965614c2c7704a68479f
+ec722ed19d527aa7b7779df63f320c1b
+ec7b48a5c985d68b4dbc360b68481b4f
+ec7d3feed7adf98eec79324ab0bdd455
+ec7e5c316215c7003e2cccb8f02d2738
+ec7ec0fe330b84163d075e5cacf34891
+ec850482498b6a9ea265093deffa85bc
+ec86105cb3f1b25b1ffa5b1ac44bfee9
+ec88007b20815ec87fda456237985aa6
+ec89eea7862342e13f2d58869c59550f
+ec961c6133c11637f0a24e8529fd8b86
+ec9d11d3729062e012489830bb568c49
+ec9ff1773b843f396c3d30b60b5a3baf
+eca4278a981f64ab0e3a28171cd6f1ee
+eca58849b783959f6e4eb45d97c18a74
+eca9fd0ef067cdafbe9fb57d1c0cba25
+ecad1fcae6c1a82bae09264e82459f88
+ecaf92b2b1928e952dc8c3db3472cfa8
+ecb3763f2fb89bb3758415673de6af43
+ecb9cbf8b0d61edd06328509a07b1ed7
+ecb9e6135ed35ddd7f3551bce1763bf3
+ecbba9799e895894f17cf847d07fc860
+ecbc76ede79625253b073e561d792797
+ecbe1f419a203ff8b64d3bf42cbb7c55
+ecc0caa8264b12925cafe2639f6574a9
+ecc17a8f558f47c0b2393111e58c208b
+ecc2e2a0bb3224944939fad6999e14e6
+ecc4aa2c78712f9b8cabc78230e59bcc
+ecc5677fa8903bc55b1028dd6fa8797e
+ecc88cf6faa820d4c0ed5d8f2de8aa51
+ecc8df3acebb436c87d21a91b2b42374
+eccaeadb9597f6c2a457057f12da8d35
+ecce00c2df2425c810e704f5284f4bb1
+eccf0cfbf0aa74ad8b6468967a4d6aca
+ecd1700135a39ddfb9143f05279ae0ab
+ecd9ba7a7bd8c4cf777bd0bdacb89e01
+ece39d32213bb85259da3c35ce531cab
+ecec33d3fda55dfad62b03593b4a5c82
+ecf39d8b4d226c50bb6485da2bfc641c
+ecf61517c01dfbf2d4852fa35379d887
+ecf74bd6b44b3429a513266420ddc40c
+ecfe9e42f0fb3a81c27b906bb0dce61a
+ed037fad58d76f67b522ce84839a8779
+ed1604193cd33b6ebc197ef4e59d6b38
+ed1608ed641f7e4f00fc4bebaa7f38d2
+ed1c4e300bce98c0683382e76317ad6c
+ed23fc67243f9950e0b21d5910595208
+ed290a55a3a4d2de8b08d11715972375
+ed2f2c40271ca7ee7792c2824e09ce05
+ed346c869699cf46fc00d01c539c89ba
+ed35bf1cae60198deede544b43e4854f
+ed3dde1e493a260a0bc01f029de66733
+ed44009a1a89f08c823dd2dc63db6238
+ed49250a18c9bfbcb10557bfb5203933
+ed4ecde49277fa4c626f5f7ba19a6709
+ed550c928a6a45f76cd5da34aa98af61
+ed55ff6d0188682675954eaec21ea360
+ed584bcb2c2032392fa9991383e7068e
+ed5f953826c43170fd9027a9109ca5d7
+ed689fdd283e2bc42bb935222dde2e25
+ed6ef0412472f41540426497bdb7483b
+ed6f0ff961acd7a0009e9b0631858b99
+ed7635b640857ed5a329d2cc22bf2a21
+ed791857607121cae3da59a5d50d9eda
+ed7acafb9ee2198d3c1d81a71ac5d1e7
+ed7b045b5661fd9bd1d440a457140d54
+ed7bb7519faf689d8ccddd0b8c739a0b
+ed7c0d4d6498af2f6a1f820cc0fb3de0
+ed829807bfb92dc6a4ca5c5c3b6ca984
+ed83795a5d14fde17d911437df4ec9fd
+ed89f1427ae478246dd331350effc303
+ed8acfc3e46d3c50c4bc8289a49f0144
+ed8cffa2cc73f5bdc89d0b3bf80ccc4c
+ed920e3d0ded8cd646294507f6ea2d08
+ed96de03a650134f32e7133c265a068e
+ed996bfbf24580fbe5d951941f46b2c9
+ed9b96c510eb62e0e066b91a067055d4
+ed9c8d83511f48f086575fe5610e6775
+eda1a0340a42a041b5ff47f0788dcfce
+eda57f4fa83b5f9c52e420f67b05179a
+eda58a7dbc5bec6e5d1cc44a235f5bda
+eda5dbd7053463be40e95dd68f7c2672
+eda7d7421fb548971a8059be90d0eeae
+eda85ec28a76326bf6eee98942abf15e
+edad549efe7071a306b442568b371dfc
+edb1d6db125d2238f1b0261571519120
+edb291cd29b4a9ce98dd1b7d5f8d46a2
+edb4510fa6460105bd1def204c4e0e23
+edb85989ab9c231617f1a6c8cbf788aa
+edba128c9585da288367b907f0c385b8
+edc5f826f0277ec9e4fbf2166c6a6759
+edc8fa8f948548b1e7a46c35aeecb9a5
+edcdd20e4cab62ea6e7261c228e9f5d4
+eddbcb14280502430c213441f257c3d7
+ede22fb0b4459ee288ae204defb4d1a4
+ede5ba329320213c6224889ecc6bf23d
+edf1e6b4fc221d811a431750ef70980e
+edf464a5ef51a499c8bd639322cfac60
+edfc1e95fad851c16325a5d55559945b
+edfce63fa7af2390c4aa18fa1a1b0c70
+edfdd8224c976fe2dfab797a0b1154a7
+ee006c8f86ec5b7ef627d5e56ca0b44a
+ee01eafa8620fbc671103a9f608ef159
+ee0556236d0cbab513c97baae5ed2abd
+ee0cfb628cb3c0934d3fe0ac9deead55
+ee18ea954e40247873784defd8721303
+ee1a4b3552fc828bb53c7f66b51ce61b
+ee1d921ed1452df8a6112c99ae43b99d
+ee1f581abd53953f5d8fd508a9d2fb4e
+ee33c2f4a8baeaf210423dc26acb8041
+ee38f739a19c3aae3e0f32d771f5e393
+ee3e19d4ddcd009161b17f14f4dcd46e
+ee4f5aaca0a75bcb1b1886ab8b67dfcd
+ee57fc881012647b32d6915cb9ad1ebb
+ee5db9be5a19de2a8da55168e0a9a83a
+ee6c996d6ac4c1b6873ee3d90fe04202
+ee7040afdf185d951a67a8d36c277ab7
+ee7067c84ef21e458438beb133d1db83
+ee75448142e288a0641070641f4e124b
+ee77886f08ffbce7eeb0d4557371bc80
+ee7af704370b0304453de25294b7a709
+ee7fc988719de4fdeec7c9a8034849f1
+ee83eb93de40be686c45ba5930818c93
+ee88c17517fd5f46c9ce709abc3b4f6f
+ee8ad0cbb240e7b4feb947a2a22bef83
+ee8dd3cfd9a067a2b25a76bedf35ca0f
+ee95077fab6349c1249f4eb3c5072c63
+ee96d4ec7ad26c16db43561bd98fabda
+ee984630d377560f36857c9c4ebed81e
+eea0b03cf79875ddd0b7f312ef3f7026
+eeac79b6584a965f69acdbaa4d20c725
+eead89bf5095dd517b7497fd236408c6
+eeaff5e8246c7d32d64725165dc216e1
+eeb2f0a832776acde876a2e9725dd52d
+eeb2f1bd8bc40b2df59d450da924acd8
+eeb4ab9ecb929359ad6744bde33c2541
+eeb5d415a6f79e7a799935ba9bc79ee4
+eeb5d6991eae35dc4c9a29fe0aca043e
+eebadc6807c38365c94ce34addfe2f68
+eebc8d45dc3ec5d79cdfb7a53e1c1cf1
+eec97d595a9b567e284fae84e1475d98
+eecf4a8e341798ad86dad2721f47ff3b
+eecf6189ee351308e4d0d65548621887
+eed06327e26705e502489eb9756d6c5f
+eed13184423c6c57942059634fb42868
+eed471f1ccbb63ad815530b672ea3f85
+eedb9ac2e82615476d14103baf361899
+eedfa45c9dfb702a475ee7012e1de357
+eee701b2d127ede6c8af5d68a1e70340
+eeec1522b596f21e8194bd65d3db3a38
+eeedf5e90f6a66ed873e37470b874009
+eeee0466cfcf3b389194886dacc46ec7
+eef178f7fdef9f7fdb5cfbb0d5ece62d
+ef03cbbde505f786fdc22b7557673661
+ef08f00ef8fa24563164859440a0b01b
+ef0b8cc4d9fc9f2453d2bdf6139be783
+ef0d3b02ff4f9f789f782800aa332411
+ef0ec695047e96e551c05368131a3cd5
+ef13040b37a91449bdaa05bdcb49c9ef
+ef1330987fd12835dc1b8633ff95ceab
+ef1405deee8e2a1d4201ec58b611ec61
+ef15779facb0ab1d375136bf7c97b42d
+ef17d619ed663bf6ff7d8739cd1e330b
+ef1a4a77247512e53356e292c8619614
+ef1ad4146fe7eda8b88a8eee1ebcb134
+ef1f215f9b78073cfdba59e761f7aa5b
+ef201b0c0671841f1477e111fe61c78e
+ef217a74506c840f5cf1132c79b5869c
+ef24caebd516c961bc765095a5ee4d21
+ef25af4d5f699871f89e93e1fe03c682
+ef2c517ee5cde8d29185238f3d1e3967
+ef2ced26a1c9cf1e16514d5d2520d324
+ef2f17db436cd2da45fd7d3d8ad4d10d
+ef382e9ab8dfde24dfa96fec50f08c4e
+ef423276a20d1e06e815b308d6f38106
+ef4522b94c84d942a61312fcb1891dc0
+ef49d088a01421291b6869aebca0aeb3
+ef5061608aae63fe42e6cc06d812e280
+ef5cad1ae210e815e2428888c4814564
+ef6223b586623009445f6ed05baac2eb
+ef630e646bc928563614d487a96d40c5
+ef63c75fa93e1c5d09afefa3070682f0
+ef6a2afc27ee362dede9a91548ba2a24
+ef6bf406ea3ad4a10a73f8fcfdb88612
+ef6d6f1d7a6094fccc068055058fcc76
+ef6fbbbca0031a189d61823111ee326b
+ef7249ba3188eb9408645a05e9415c33
+ef74096648bf03f76c920fcb33e26cc0
+ef7476ac0860f321acf26417127de35f
+ef7a1501ba8b410576dbf5036b33ac5f
+ef7b0ec494c7f8eba6f2f9884a4336bb
+ef7b4781326faadf01cc09c235862d3a
+ef7cdc91d193fcae278c94351b34886d
+ef8147837e866111e700815fa2456f86
+ef83b236f2d16aa1a8f6f6e0b055f322
+ef88adb17b5d86a6d36658de805e645c
+ef90d7e2cc86943d0b5f4fa7262839e9
+ef91fce6c45c5e7a9bbac85d09582226
+ef94536f55e09dcd23523f705a17763f
+ef960833fbf7ae798e0461e01948ef90
+ef9a07ebc464967cf4b170b83cc77007
+ef9f74182cbddd241f2ef7d1d9501cb2
+efa9823d325ec5b8ac674d520a3b3bd7
+efaa89d1b3f75db504312185e9f9415e
+efaf168bdd4ba45c6dea432cf7790fc5
+efb1d92870a835efd11dd37a60abce16
+efb5ee0c0ec047e2e7014c024fdf3132
+efb807e643c6bdca8ed38e0ffcf04514
+efb81bca84c9d5027d116db686e83958
+efbec6f302f9074d8d9b9f7f2f0568d5
+efbf5ee52880fd1e4572d9cc7e079ba8
+efc1caabf4d6f79426341701c906b459
+efc33f33a82b256fdd433a6987f9c3b1
+efca9aa27c0f408f4a1a401ffeba5fdb
+efcbc541d6ae9cd041dd5788d2abb7eb
+efcc14f17c5ef50222067065871a2c80
+efcd052816f6c1cfd03570e5a5a20364
+efe08a006631effb2bedf98eabef18b8
+efe445e822a5f32e583b467ce029a45f
+efe59ab1ef7324f746b15f9b37498aa9
+efe83bf7cfa2e4b0dfa356c01b5635f3
+eff3bcafda516eb9a9167e8dd8b68f29
+eff68abb18ce770141c38d00db03344d
+eff9f458c15bfb6a8e2e0bf8fbc4b898
+f002f3b02ce018f5e4b112892811548e
+f0114806a5e6d1ec4639d0a9aa0b992e
+f01359a898ed3fed4810ee5eb1ea1ead
+f014175e0e171abcedff06b3800c75c2
+f016438daa8b1b5642d6598d8641c200
+f016e6cedc9e77cbfdefa101eb822c2d
+f01956e2a93fc4d517604fe7703304a1
+f01cd77e537b9a441dd1246afde1c973
+f02968f62d43a1b7c4fb32358b9bd1f1
+f0304a44cb41ea349d8c7677a417303d
+f03351872ea1dc142c8489f397a4749a
+f0347afdd1413aa208bbe8872c0d872d
+f03a982a37a034d0664b69e22db7dceb
+f03b52a80e8f06d201732340ba8fa1ed
+f03c8e0ace27427329abca59b1510ff3
+f03cf744a7d04ec465d54a3708c69977
+f04011559f32d9ef21132841390c3f0d
+f0446b79d4d915690834e2f783de5ad3
+f04d536dd976356d4f5adf503826ddda
+f05f77f3acbbdbeb32301fa9c2468c45
+f0616fb65f2f4c038cea1d1d4ad7a53d
+f062b9acfdc42f309eeadd6a8fb55ae6
+f06620fa44f6e9dd1d759f30a5eb8c28
+f0665391025ff2564eb656346d30147f
+f06b3035d8a61797a04ab55ae882132a
+f0761cdf2a8d015a98c2d7a0a981820a
+f07abaf4fb2a6497a2959cd8140b9528
+f0866c3de928b89e3339db843427828d
+f087a180efdf5332274edbbc48b0e765
+f08af5515f4ff6d1fbd5f366c481a6c1
+f091219c8e290618a83591c658068a56
+f0949f528214c17da4096a46ed4357c7
+f09b173c5f03fe098db2ba689b69a448
+f0a1a98d5e1e7455fc6780b983def29f
+f0a390275f62f9dc1177c46f9bd057e9
+f0a9771358e279aa4ebc022ecf2f85a1
+f0a99cfecb39132f469e4fbd9fecebbd
+f0ac18af2421fded1e82a67115ad47bb
+f0b147a1b6e8f84c86c1e504f7c833de
+f0b4dcdaf08deec0e97e10782f79afc6
+f0b962d451880b5f7790d8c63e2cf366
+f0c83965f8c42f4a4094d4863d8c59a9
+f0c9eaa80bf32654382e3878c3645bb3
+f0d009a588006fbe6f144fdc53f4ed75
+f0dcbe5600bd89f84a8ce982d827d5d7
+f0e067f769671a888ccb728a046a6c1b
+f0ead7fa9d8abe9f2905a81a7903ce0e
+f0ebdba814abc854600c71ea44cd20b5
+f0eeba02eca4b8ae8a9ed6501b3c801b
+f0f285bd9b31c8cfeb266b908a6d9741
+f0f88b1e16b60761129ad6de5bb92cdb
+f10168ee3198c17f8ee0c2e6566aa1f9
+f1021b4e4d686773624e26cc423971c3
+f103a79412935fa01833d01b6a81c011
+f104bb15657cb4a857eba1846e58d88e
+f106ba86083f603f695a30644c7775f4
+f10bea1a3623592c343a0f03df3fae30
+f10e42df74605914db317d308d5ef1f3
+f10f9d6238792d69ec6160c67ecd75d9
+f1194dcc7cff9c8152b384566d6af1a3
+f11bfe4eeb544259b46dc6c737332321
+f121e976ebf3dce5090c9cfe210384fa
+f1263ab84bff9063ebd053341c4a5b47
+f129159075373f8d823fdc0e1f8d9d0c
+f129c64363c4b9f4aa2543c55f8d0eaf
+f12edbba01fafcb1124d6e65b7441535
+f12fb7fbd213ca6ec6e39dbc9eb6cde9
+f12fff5b7b39c8bfa156e24f69cab2fd
+f1318abce5af533e9ac1e1cd97941687
+f13802fe58323e16281f8212349df294
+f13911b1e96eef8d0359e66e22cfd90c
+f1407fede683d782d17bf4f224120020
+f1419ae89c26cc2202a863d8a2e696e5
+f1450de7cc2a1f1f0dd763fdd0fd57c6
+f14546bd0999f28a65d519d13c273759
+f146bf4f9a210e0fec9fb69978a77053
+f1476644f4039eae058e66dfd7836f90
+f148e60d1958c95a2ad552a5da186669
+f14b92a03c3b3aa87e4cc21651aac0a2
+f14c5e1988ca5125598d8617dd4613f6
+f15a03f9c8860eee81816e6656f71e02
+f15acf77ad329dd4c6b53d5e6f1e7fe2
+f160fd14a296c7e4c511621351992554
+f165587c2ce755b7b43924bb8b6f1144
+f165b3d0f9427928354903bbf0f683cb
+f1707c07820e7116d7695df705e30810
+f174739cdad911eec8e7d53a08a1925e
+f1775e07c5f19fe28f28a89bc74d2d3d
+f17e69c6492ce7ee18b43810aa609e06
+f17e9a9bd24182e07c6e6a639127b267
+f184c206cc0c2e3e86f6d926916f7233
+f192b54c5403ab271ad030e30b071961
+f194ff2fab20b66079085f343c6512ee
+f195f762fd3303671088a2d0876d481c
+f1992a053a5cbaa18969e4821afe3b5a
+f19b11caf7602c708f17e3a5e84fe92d
+f19cb57cdd8d562ad1524d51763724b4
+f1a4a9cee02447b9d8f058349007d3b6
+f1a5b5298634d9a9d9ee8f39f5c2c9d4
+f1a84aae6266f5778225f99a5e04c90a
+f1adf33c01078405869c0f45577d773b
+f1b668333e70d0c25c8f5ad0740b4d84
+f1b87a1636410db3a7e894fa5f6d9b6e
+f1bd7cdd4dc275ae30438327b135a7d0
+f1be4a15a7cda0eb1298d9b5bde8fa04
+f1be68315e1679728bc7294b50d50440
+f1c112e9d0fbb8d08879f8d5c8eb20e2
+f1c927e633aa3f2b6add8f30453839cf
+f1cc2d37c5627907f36a7cf78fcb5e42
+f1cc7bf6bda34a6796c05e8b962ee539
+f1cd2c770dcc04c50bfc9d07f462c279
+f1d1415fc0cff2ce1bbcbfc47931d9d6
+f1d793eb2a0be53ae096d0b1780f57f8
+f1d819018d5502e2d08837edb50da392
+f1d9813a045742dba81dd7ea92e5ef14
+f1dc8b926726d45586dcc27ec9cefa00
+f1de1ff3b3d21d4f79673ab36b37da26
+f1df59f1a9834960889cdcef79d070a4
+f1e4975bb58a8c7ee06c70ceb1049245
+f1e638bdde443954f52385fded5d6964
+f1ebd83cdbb1e67a3fc3b1af1cc54094
+f1ef4714a4f7ed212f8b05f7d9a2fb53
+f1fc6d3fd4cdca6e420dbc41245a8980
+f201457ea88831c9aad70993e287de4d
+f201b5fa222fffb54acffc94d1bf6992
+f2051c78f0ca5fd0eb9a05882d500733
+f205ecb46bafc16fa0aa18a47dfb6727
+f20c48438b91cbb64a5afb31506f362d
+f210567c2723d495bdffa1cd3d9461a5
+f21233a554494402309a89b99419ffe8
+f2139c4f7e04a446d73ed7292ebf6d47
+f215eb391d4b1ef8c6a27e5cc51bef90
+f218ff313ba0902454d85ba7da578af1
+f22614dff995026ee77a326918ce2c7d
+f22a2fe424aab20e1281093794fa8c26
+f22d785f05a9d164e0c8cb8832cdaa4a
+f22f98e4f2b6d6b995c5280a4e137a88
+f230834ffece5b42237956addc94fd5e
+f2322489daac1b16efd54a027350653c
+f236167233204bff1df48e965f1fd7aa
+f23aaf7b9ac598b56a30e528c2204a00
+f23adcbe8f76dff9d00fe417e2ea4f0a
+f23e91a9a8e67790d038d18de203163f
+f243fff5dc55575824cba54cc09413b5
+f248943404b018107fcbb92fe891dc97
+f24f193a1cd6ff28881193d3bd649c3d
+f251a2c8ba136cea440d16230bdd86ad
+f251d96bdaa6558b2a7adbfb05a5bc72
+f255490e8ffbde3c0e0e16ab40ee6583
+f25c7c5e43d09e2068e21708ce42be6e
+f260f830ed36c0f0e439eb0572feb89b
+f26381c21160e66374c69ec1335958de
+f26700ba690c02fa9cde5f681a070c04
+f268708bf1fae25ed35f0e0c0306c35d
+f269babc272b4f848234a50f8b179046
+f26bcb6a29fd5c9cea50e48d43581178
+f26fab95cf53b4a3a4d26f48f1bd7bbc
+f2702d449db609d98a693a9cf05773f5
+f2719aa375054f88b066a89b96da1145
+f27bc8008cc77583349797e34ff5ee18
+f283c7d143a72288491f02f6669b4a48
+f283f93c1dbe4f1ef3f37eaed2498bc3
+f29356d6d58da4cf8bf355ec46c1ce0a
+f2940ec3e5bb9817c473153c77cb8f80
+f296c6422933d672e2ea5a5935e1d28b
+f29a423eafd147a67ca98b2642f1628b
+f2a3f85b353b963c33fc9ca9c993caa6
+f2a663366706da5182812899d27b27c8
+f2bcfcc15eb10396d1f84f2fec84c3d3
+f2c54ca5d89fbd1888a2ad09b3db8270
+f2ca9d8450d61623f3f8ff9343f7f994
+f2d28e9f226a4dfecc5261c10bd51b38
+f2d61a33c1974962a604cfcc5b175a45
+f2dba92486d6b0dcf549a3c27f0f1b3a
+f2dc14e873d73403334d7be4598f90bd
+f2dcc5b31a7a3424ccf8e8a3a7887352
+f2dd479dd240f0c0043db63b508ad78d
+f2e2ddf530418b008bcbde2abf486af2
+f2e35bac2bb19cc208dd79e3d7fc14ab
+f2ef15f4026d535458f5ea6cf0a320ff
+f2efd9f2ce308dda6c40606e22530482
+f2f1d167f331ea47af7e25e4d567704e
+f2f4d8b981780d9e7a7fa47af64c8806
+f2f6ce4870f107344d3b05d5d93d41c2
+f2f735638785f8a3dbbdb06992eddc73
+f2fa42c4f6f8ad2387cd52dc0b388aa0
+f2fb2aa71a5801e8088d7cb85a2b079e
+f2fd69bfb850bcc66eff341f8d470d5b
+f2fed8fe8c4b9c629f6eaf72b3db53ca
+f30881d6cc265cc526a50a9854e2eb47
+f308c8c8995cefb8c72a930eeff62643
+f317535dcb1c1fcd8d6e03e79acce760
+f31b692c7992bfa474b1b106d223dba1
+f31cde1944fb770c870b7e4e7c5f957a
+f32325045d6698dd90d76eab0c74a1a8
+f3238186feb50539b86c4df14885fe80
+f32b88838460565af0d6103f598b3603
+f32ef8deedb495695c4d799294f10d55
+f33662146458234cebd658471e4c2d14
+f338f12bd6ba576174a8adf215914260
+f33bbed475d6e2ec26ee27253312606d
+f33ccee674eb9c6402cd410ff8785ad8
+f342e46da8731ea5a701804e36a77185
+f34337710006282f39dcabc8b2264adb
+f346aa077cb84c1da139c96d45c15ea1
+f34aff251243a8824dec9a0e57c3df81
+f34b82082ba25971f8367aecd9abb998
+f34f51ab286de0fc6ad79c123280a71c
+f3519a491550beff36e35d14bd260e4b
+f3539e7bba67d49b04903a35749db6e3
+f35aaf42c442449fb90fd41aea4e0f7d
+f3600ecbd0ab1c670e6306137a8d0354
+f3659220ad8f4e2ed45ba58cec9f1745
+f3712ccc5176e63c5ecfa4071d1f10ee
+f3760d8cca250773202f7901f300b36a
+f3760e30759fa17ad6810127ac5e2b8c
+f3850c7dc24f589bf419085dbb43c4a8
+f38570d6f2aa64982349daf790d94331
+f3874ac1a3236de7905764f2a3f63a9d
+f38af6fe429b4db4f7b4c69c803c4d9d
+f391c7e780ac080b653aeccab717f067
+f3967d41fb95ae9c10a7d17baab3bb33
+f398a5a61fffbac4bc42030bb8f52beb
+f39a157821d96c25af5c6c6021f206e9
+f39aee193504054899561cc3051896ff
+f39bbae14a5c758f77207a1122fae1e3
+f3a40c96f661433696aee365b3381c9b
+f3b0c666754fabe5e045f2aa26c372cd
+f3b966fa0977b968c88ab04ffe38a4ad
+f3befa984d1b1b7c6242dfb203c9b93d
+f3c2701c6140db301b2d824433544017
+f3c7a87e4f2b0e035db526518f89b502
+f3c8a7c8d280e51b8ac6a61e5c2b2798
+f3cee695ac8c7881a211cde849bedb5b
+f3cf08203fb9b17f00ce9b723744031c
+f3d234431f0c88521f5a7a5734b2e216
+f3d5e00ce6bdb0e18c04171777565f8a
+f3d972d7e55fa513c1716b393822f272
+f3eb4b9e25e3001cb25b97b21b8fe5e2
+f3ec3f5f3b18be74d3cd8b93f690f14d
+f3ed750618add38c0174e63e9f6a7dd5
+f3efaf4df8b72ddab0bbcf57886d8cb7
+f3f8274c31ab468d29861d2c5fb18feb
+f3fcaaf1fe41ffc78f604120d9a52bd7
+f3fcbe6dfd593cc171a0e09599e96adb
+f3fe3b68a04507a302d9255067a0785f
+f3ffc49f18807d6bdd2822abce610302
+f401bdb97aaa8018944df2a84524b037
+f408d68913d23e293d055b7ee0e5a276
+f409c74795522e756ec82ea915756353
+f415ee156d2d78573a19450e703a8994
+f418538c955f8ae706409feb7475b1e8
+f42a07cb34d521644f2382d9d94352eb
+f42b245c3a20a68f269e3514a2c5dcf1
+f42f45b3a01f4751a9699056beb49529
+f43244a199acbf0165744dbb9eeaaae8
+f4379e9453a4b5e0ddc1c7a1f827b4b1
+f4385de801b365a756346968cb09668f
+f43b0a557dc3564b86aa904b4bd5cca6
+f44c2c0a8443bb4d759e275d6e39a03c
+f454c9727c0d7de722b5d37ee17aed7a
+f45ba296932e7ea6ceaf57c43ac64850
+f45bb2a5befacadc748e52b5b52ed70a
+f45c10117b233746ebead2359bf1ef33
+f467e5e129151a994265b78830727346
+f46e6ed50105eb643907a98aa3975c72
+f470ed6c4221add74465de13e98f88bb
+f4794aa7fc2b844a96bb2bf1a09a48b8
+f47a0311eab7aa9ddde46cf326e24f8e
+f47c9229b3c19e99bef78eff24a698f9
+f47d463435efa4a438ecf091d87cdb84
+f481312137481cbb0cf2e31a5f2ea517
+f4825c602e88942559f1a8bd7eeec8e6
+f4894934b5113a5fb04e4d419be1360a
+f48b91c087890949427cbc275afbc857
+f4a5369e5e3075215251e605c6127a34
+f4aa3a047d07d0fd5fe49ce0c452733e
+f4aba6c73ce579bc8546d00c3d33d3e6
+f4b3a09d630f3d54301993a53e4b44a5
+f4b6d37437d6f065ff4f0669ee03b1d7
+f4c2d1c8420ba432822968bff0d11ed9
+f4c37681cc2fb17c2de8cc0a12b85670
+f4c64ed80653381f807731e806bce11d
+f4cecd509bd1230a283e70e8f191aeea
+f4cf3984631fa8df37a0434379fb2e4e
+f4d1186943a42747d980279c277cf14c
+f4d1e634d9bd563caf65c71f8d37e1ad
+f4d368d943e2b7fe2831734f3b4337da
+f4d59317bc07a13d16211f2064dfba50
+f4d8148e1aa0f25d0e4dcd2334ad0a86
+f4e1270f665e89fad953ec10ec7b6636
+f4e135a6b0566d24e78187448c52e957
+f4e1e20d642f0954305cfdd4a9509006
+f4e35382b734e979628729c6198b5613
+f4eafd4666b07855464bf3564df9d2e3
+f4f583bb5a19fcbdd534947aebbc43a6
+f4f5a2ef68d5edd3f1a655b48806998a
+f4f9d99b02d81d36b971ba400c5dc77e
+f4fea4c26b8796d581556defd96026f5
+f50151d4be8ca575714daf84eb1eda0a
+f505e48a3b9b570c1211d9306b5b9a91
+f50772c610f23a9ab4b759d0de5cf95b
+f50a508c2b525bbc8b5a0f6a9003f801
+f50db41a3a7dc4a9f4d90383f70363a5
+f51080a0b8e44d358390a75aaf076936
+f5110a23f8b746d3b3a7e0f84d07b347
+f514bdeefd0791ac731e2c0d86e3c7f2
+f5183b91f3182a7bcbabd76eb43b8447
+f51f6a96417b959da827b8fe670a3105
+f521e2aa436ee425c378e687e2663085
+f526e5216827978dfc41951d8dbdc5c5
+f527d7c8e5ffa3afda67f156059deef0
+f5283275f7d5e312bc8bb4380930567e
+f52c5b227c1cf565508b30fc97a99bbd
+f5307615ea38db98214bf9fa24ef0ba2
+f5324e2b8e2c447dd5cacfa91bae05c2
+f534a49c6b232023481613d3e1a4317f
+f5360dcf7ff1c8e6fa3cf586c52a103a
+f536882135e737babe9dc5c480b7cd46
+f53c71ec17067d03cecd68165c2bdc60
+f5423c1f3178d6f8842d808b5d39f052
+f542b47d00e79e3414cf7767b7a13eea
+f54a3742d806e4786b3f800cffa58857
+f54f210519038b5d28fa780c4fb8ffa6
+f55709f5febc992545f7b025d648f299
+f55cc2992713c756b2391749ac786756
+f560c8a07b34b53bdcdfd11fe40728f9
+f5626f73bb6ab25c3fc11ba2f9fe6975
+f56cc61e87f8a314cc070fca2cb010fb
+f577217484a75a1f24d99331f9b568ec
+f577b6fa3054d843c0349cd068174419
+f579bd2266eaa885904a9d5fe5ad215a
+f57cc7cfb0f0450e2e4f41c1032d0bdb
+f57ef3b7b370b81b93b4783aa51801c7
+f5807009b90c772eb78ebfd938bb9486
+f5849791119ec54d7cf797286adbba8d
+f58d8be400ba7a8df88ad40633afe01a
+f591cc3835d869cffdc1b17870b96ed1
+f5924a38ce377d851b182be3b63a5c5d
+f5994435d691e50f81b48b7eab46af08
+f59f0f7c4fb29f25549802118dcbd33d
+f59f93b849591b3b0f27f3ee9e5668f1
+f5a413b2ad93af416b1b767fada2b949
+f5a7fa812ac67d23be78c8d8e90b6aa7
+f5b183e77cf0f00ae9ba96661cb3c19e
+f5b1c63d3c35820088e82792088b188c
+f5b23256a1def25d97477ce53d51df2f
+f5b4936502c820799c6374a0df89d27f
+f5b912d0f24ff9c4bec4a21fbac5fb67
+f5bc183f1d2992908140d041fbbe4668
+f5bce866dee9660b7557b5188c275706
+f5be38ca4433ca47ded89aee6c042c62
+f5bed41b3fc020ca9a9a1293441bea94
+f5bf151cfa1b70ad7a2daf0802d39b74
+f5c1e570e066241f852e32386ac3cf8f
+f5c58d2b79589a94c52e082b2ade9a78
+f5c5f83c754ec91b5571cf898a5c7cc8
+f5c8bbe6edbb743e4adff048d39e3eb5
+f5ca8ed57a7fac7644fa42b01084eca1
+f5cb591c4d6c711fe5d0acedd87ca439
+f5da7c5257f29e4510b14d468bcd6c3d
+f5dbcc8ebc597acc2fb6cff177bf2efd
+f5ddde7ed7d4fd2d8540b350f2b69d5e
+f5deb167ea5cfe2bee7725e7835955b6
+f5e0bef451da7eb167762125911b39f1
+f5e4de9d1d2463ea81b923d3f4bbada4
+f5ea8a00b617ccc79532c035d43f4de4
+f5f1737bd8071b71426c27d81f35d983
+f5fa98ade7069c5cd188c5989b356968
+f5fc5739290e31c31295e6ef2a139afd
+f5fe08d2b8f2cb075868bfdc79130272
+f5fe69fbc0a236093375a2e4415d1053
+f5ff2076ff3a831c1f8d76d3ba1a4c78
+f6025d346d9dbb8c4a8237ab01c019eb
+f60535577ff1f14f2eaafac806597411
+f608124ba52a311d57b33dbf32f95776
+f60a67b7a477046b4790f7bd4dc83e13
+f61169e349aa479ce02c36d96647cd01
+f611f50c8fbc245d187c1ee5dea87a74
+f61c35e11e8bb00bd8a4f7b427566f34
+f61ef535e7f7397945d16ca3a014ca87
+f624444e1ade8c87a625a941e09a4ad4
+f6246ee2746368ff7071b4a2f662d866
+f62b609a0ea76a5b52769eb1e6a75e0c
+f62c7cccd98cb263a6e600093a392245
+f631d1d00e5916d357f9dbc45129de92
+f6320eec85a46aa190605b0865c5c54a
+f6355b04e423eecc1cd8aec680bb731c
+f636b14f826c3edbae7a54bb1199f358
+f6377fe44f8127417416648a3ef9f91a
+f63a16d36870a6b9f50e13544f6294f2
+f63a6f9a235767637b1d1dc12a99c131
+f63b3b17f4c13cdaa3d830c6b975dcfd
+f63de614251a27f88fbd66671dd13f48
+f641fe46b391b75195c33d3135201547
+f64500912148caa49c4a0969e46edb03
+f6455ce1b020e05ccb9c86eb52d66a66
+f6461a6249f0ae5be98d6f623efd54f9
+f646d6b5db7eabe0972e48f53ffcd766
+f649339d9d565cb32267d80cec65bf25
+f64ab672142108f5e35c433a3811ada1
+f64c64c0e36502c8e18e250e1b1cc7cb
+f64c7a5db9cae7cb1caba91778ed3876
+f65659ab61e9029bb688f065794d476b
+f6581ecc0e1cd1608afc7f683ae82ccd
+f6670e57e49dbe96c8bbe2625fbb14c9
+f667b4fb7192dcbe5029560c65d926e4
+f66d4b03d98403a733303e664385eecc
+f66f3bb13da6c9aa3d4a6f2f02d363fe
+f6779cb70600de511d00150c57db8f86
+f6817f298ce1a4e805aaace59ab5419f
+f68f6896e12975dec6d6ceacc10405e1
+f6945e6c3a8039599c7191de19d0118b
+f695ffae7e7d7cf53924b52b9130d1b0
+f6a116236ca8a6ad1c032e7fc1baf8bf
+f6abb7d9d89df6253cb8d757fc33bfa5
+f6ad4a80adb097e23d45cb65a90ebd6b
+f6b5ad8ee5fe35eb639744ece3a342c1
+f6bac9becbee61f37ae1e0c3b9aec92a
+f6bc67bf4cae63ef24b71d2484390678
+f6bf250ff5a219287da9792b03e24de6
+f6c2139e968f0304ea60d0e0c0b8d294
+f6c26fc3a6a0f202ec45fe6a9b9b10b3
+f6c6dc9b03a88609819a49e34c4e4288
+f6ca235a6c4b05dcd1e885fbdae45f1c
+f6d18f905d60fc7b46923679b79e58fa
+f6d754413849b0eed4e5aa981aea2745
+f6d7e95947f14ab8e35e4228334922bf
+f6e2529decf814f8031d57a4374360eb
+f6e467b35d5f92e8759abfcca34e0087
+f6f3fbd5998c086a9f4f3a61b0eba7b1
+f6f435ad3e80313800d5251973a9e3fa
+f6f68d49ae37fd334a552ba324455fdb
+f6fc8fe7c0894fd0076aa765668762e4
+f7023f686f1981090d80b1d9fcd88dc1
+f703e7d307fec9a465df5f2053d83244
+f7084d0dd54fddb9b73f89c77803ecd4
+f7126f8523c107f7ae1737eb065654a8
+f71a30c22504d1ace33bcc747edee685
+f71b4bcb905b228a0334dbda6b924896
+f720afe896abbf76e54d007b839c03d5
+f7267220509d9292907102028270e66d
+f72b8b0d4660d934c1578d581de0fcb1
+f73056cd898d694504d89bc196bbe0a2
+f7376bb06dad23e2ff94525b9d758dd3
+f73c279e4cab87b5c34c0584b103a4ce
+f73c6a783e58ba6272a3ed15a6641933
+f7442d9627d8c9a4c58e249c1c6da641
+f7447f2f888774a1400ea4591ef26fed
+f749444ab4fc76d5ba8e7336437aef16
+f75b4c5182774430950b0949d2bd2841
+f75caaf95b7828cdd4040b6cfcc0c8af
+f761c54567315a5151bb47c95aca90c4
+f762fa1956dee3d27a4fec021348fc61
+f763e1f635dd63c8057a1bcb17812486
+f7680243c5d215e1223ace7770076e36
+f76c67a43295f40b7694643beb35296d
+f76e352612fec84937ef5b4716ec88a5
+f770167f40a151c53a7a2992108c1629
+f7729efb3e20e2cef52d77f147b9d8eb
+f77937b62d392cc4ed342bba4f3e0786
+f77df6c8a9131cb8aa457734ad45f9d6
+f78015a7c718436351786797b35b8149
+f78146dd5187746f87ba49bc0e2aa15d
+f7816f8df4231c5b97cc77e4833dbd91
+f7851ae69ac0e0e8f8271f12a5e2c9b2
+f78709bbac3e57ecdb2be240821b77c6
+f78a753d217cd17a7f4693f1f95be63b
+f791cf3ea537b691ab4834ff2d8462fc
+f7975bad0a78cc7e9c716a8d346ff59a
+f79b1b4c9efa662c91ec7db6ebda8f97
+f7a20485b63536aff4170b457cc43bfe
+f7a4af8f06680d894cf434894184fdff
+f7a6275abb2fe0d978f00c186228ec3c
+f7b0ce131184ce1ff8971fcf4da5bed1
+f7bc7a1dbc2b421ab5c615b43a961357
+f7c08c6740ddff122de9325c6522762c
+f7c376c3a5e371377a84b3e261f3c973
+f7c4e335765f5b261ac8d85f098f574e
+f7cabd1e7cdf163e5bee31377340482e
+f7cfb8fe1fd1592b46accf4d83454ff4
+f7d4a989d34d44b8a4d565cde239822a
+f7e1e4b14eaca6cc4ed08f6cf4414c9f
+f7e361bb8d6d0fd716823310719530b4
+f7e4ad4dfbeb8c06de1d5fadc9023361
+f7e7abfcb75bb658d8958b947f3d524c
+f7e8538d5a7d2999ae8cbbee250a2022
+f7eb58ce3b6b6a48e6d2e4f2351be31f
+f7f6e2ad349fbc2a596e61111bf7b36e
+f7f99ba2603ab425145afd6493b4ab19
+f7f9bc57fcc41ed8184cd17392f0bb44
+f800053b99794880a17205d2bb5505ab
+f8008824e3fe31f75c5e24f91b15a437
+f803a4f059d510604e973050f19f6899
+f8045045c3802bcb2e5ce2fba2226acb
+f80862d7144ee9c8f4ddc1d0ff94fd2d
+f809a30f8022fbc0dea997a640fb168f
+f80eb72043c1917fd909335d225084a3
+f80fd38cb8a46dd6ebff68a8126efd9f
+f8104252e1ffbfb9a2d647727f8e394c
+f8147a80b6570c85575bca5addb5170c
+f81b8de4cd2bf792c196bff8c75b4f49
+f81bb44519ccb358fd953fc837eb87c6
+f82759dfdc562df9a08b2925e3a138af
+f82bf8eba6784abccb5df8c17b28f8ba
+f82e782e1c5c9cbb94c7ee7286b15ab2
+f82e9a23ad7b7a89fec3aa9ebada7cbd
+f8374b3be72cad36fadb16f5a67e8930
+f8377e1feae3876ab6e2d6382fc9ee08
+f842c0b796e648771bf2cf8680be934e
+f847f8c5ee48c2ad59e216f2afef362a
+f8526e53f50cfcd2e541679e49dafd9b
+f85616d6dc9be9d277c0b1ee3b73779d
+f85934fd1b19a332e6ba7a845913520b
+f85bf2fa52d06843295dc693136d7f86
+f861425461a11646eef936605a96017d
+f8625472588cd171d8e35df46831721e
+f863ad0ab3de92cd826b68436d24fbdd
+f86b739e7a8ed4feebd7083d549703d7
+f87203792ab7bc3fd3ad53089758f531
+f87ccebe49000fdabb03ddcf187fbaa9
+f87e24fc16b6186e7391d4af238543f7
+f887b2ced44e50d3be1249b1f0d4e39a
+f887ef0a7dda73b68859e853c9270de5
+f88bc35242dadf4266c97034385db908
+f88dda5c9f5fad47e0c0f3bb795b4d38
+f894ad8d3233058974673b3b9a4cf264
+f89de52bb851f81a500cc7f49f0cc728
+f89ec72f8c0cd06366cac01570d51081
+f8a44c5d0ebd96a0e3b95359649f011d
+f8a48695bb68edb93d6b1a5bf7b439e2
+f8a653aba017d4fb5adb4c959e5cfd41
+f8b04faaa2fca17ea5486ca2365db6a3
+f8b2d0adff80ef5ac0a95dfbb8299653
+f8b825ce9e0800df2d0cdad8f4b37b15
+f8beac1e6683aa0b780c71ac5552aee2
+f8c5aab3ea82d98f8374b5360927743f
+f8c940caa27e5e313e8e0f96c3ecfb3c
+f8cdc68a41ee9f4145353d1fb6286a73
+f8cf0e229a4da1640b81b051635d791a
+f8d26dd0655ef2c22841953936d596ef
+f8d8ca25d60823be1639cdcdfac4f089
+f8dfce0fc9e8e4f85872b63d92f34790
+f8e3c28b4e167391841a2f25ffed10fd
+f8ebe35c6ac4cc180ca649167a5f3fef
+f8ecbae645dde4129d22f553e0d1ff9b
+f8f3ffffbbfab75d237d91ef2822ab61
+f8fc1af17297eae160c7aa9d58a80a81
+f904a9eac07d65d1af0441f343af7127
+f90a1802daa91598675695bf0042bf28
+f90cea63174ed8b6bf37ae3dd47cc599
+f914c77c720289ad55b3e675ff64816d
+f91d4097c44ba6c933855464c3f2fffc
+f925ec176a8cc6f95051d78c17dbc3e0
+f928eb5de7baabdb19edd59d4aede584
+f92be485ccb75afd4a4aeca85adac330
+f92ce1b907f57cf7417d3cc513ba9b11
+f92ce3870ebcd93499c261334d356c39
+f92ed45a55f6a290a356c7766a312740
+f92f9a797f9f0456615610a63228ab63
+f932b78fcc16bce005aae67fdc8a1ca8
+f936ae9c9763b2eeb6abbc4f567159b9
+f937500d9feb283eaf4b3f14082644ab
+f93c7e0fa38531754911868231824468
+f93d6dafcd5e3011941f0602228ce1c4
+f9429199f5c547be10f0e3ab14fc70dd
+f946683e3190902b4b03e1b708cf1f52
+f94881e3cc6aa183f79fec0ef95ec0b5
+f950ea11fbd89f1a70b99a3c37607533
+f953952b7b25dce96cf62663d8dfb65f
+f95719cdab587dc7e7699e3b2125a8ca
+f9605fb6d2b3e92526591d297d9c6a2b
+f9629708dfd934f2cc3fd512f73a1bcf
+f979692cb7b47c5a74dcdf028b9d4922
+f97abeba1fec66fb3c66d8c58696ef59
+f97bf35fd10f13f068f6fb9e15bcc102
+f98777010985cbbdde90b537ae428341
+f98ce57c07016f0874788382bc088c7d
+f98d1f1c28a0a9727951a3ecaea39579
+f99473b28103684d33e0382a8e98a7d9
+f9a092372b94401be06d9636a3c93e26
+f9a0c4f3b68e81b71a6fff9314d9bc5e
+f9a5a5256cec98688a6d9a600df1d661
+f9a887dfa1207631e00a57d30e985b3a
+f9ac22a88db652c7a48df6ec86a5c18b
+f9afed3a019041446aa348bc14b5f14b
+f9b4e7d296c50859cfc4c6a6c1d31bbe
+f9b8c07a0c3a0862e00b9440f897a9a8
+f9bdf4edf2e14cabfcaf06c54c24bb42
+f9bec4a585840c71f1e7c7e5f83c919c
+f9c0174dbba276924761761a633406af
+f9c7b8b705922be28c4017625846df95
+f9c922f7327dd763312b17eed3bc31ea
+f9ca4f576f9cbd85c4f9e3c8ca7d1283
+f9d17038b999da5e31e62b7d5bcbf37f
+f9d642b56791e9ba85d6f569a5218700
+f9dc7709335aa2327f12c6f13ac57800
+f9de7244b5124a7f7cf3c068318147f2
+f9e05a49b1c65b3b1f7daed40b42107c
+f9e0da0085e9033ac59e8c462e2b7252
+f9e2b3179ca9b381e2690ab260ff92bb
+f9e57a9922b397b9fc1f733e7fb23af1
+f9e655a58eb17503647ffbf279a3d3d4
+f9e710b4a12208131fd0dff96c5c93b5
+f9e777c6711d01321fb8308fecab7973
+f9e8ddd1073f417f1499649b8fbaba58
+f9ecb795d1c0722f3dc1cd2a434f8483
+f9f5196d60bce1820e27223893cccb79
+f9f6aec4f9b4ea0553155fed99ef92d1
+f9f9f4b2bbcbcb7209cdb0a435b5f4be
+f9ff5c6d6df78cd4ec9592b82e0e18cd
+fa00a113b96b0825b2b8c9d1bc9244a7
+fa01978eb0d0845e4abbaee8e881054f
+fa0300b8b6ffd74ddf4ecfde9b24767e
+fa05bd051937ce962fc8fac0a0cc238c
+fa09b86333873f6729f75709d56cfb46
+fa0a3dac18ba0f7c5d960898e8b68676
+fa10ac4285c465d1cc809365fe62e8c4
+fa147ad566ecfaab951592498b0592bb
+fa2235e6c7dd64dad660dacd29080e98
+fa26fc9237dcbe3594c56a258f595a02
+fa2c9efb2c8345d4ce2c308e7da95f84
+fa2e0146cf3ddcb7e596bee98dda06de
+fa375b28e5e18293da1434b5464285e3
+fa38bffe134be83bd39185e90993609e
+fa3d8a8aca899b81713dc29c23735f2b
+fa3e46c14d9169c593470b4008c92740
+fa3eef8810fa44e47c4dc4bc7bf6298e
+fa4359b74375cdf5fc3f73bb26fb97e9
+fa4730776e7d079a9dfa4450c36b845d
+fa48b4026b6527b9114de27d81be0ccb
+fa4e75bad011d2ec7e59614babd5091a
+fa504151f0cd4dce604203f8f6f068d8
+fa50d867826ef72dae443150db769c5a
+fa51fefd0c43129c34355d5787673519
+fa54d1579db788c31e03f54ee411510f
+fa5a11ad3c10a3e4a3d5d9f40ab294da
+fa5d576ac9f02c4fe0feca132a5c2b8f
+fa6a0fd2c085cdb1135bc08c0aa33fa3
+fa7296ab1e87045ceceb9093e5f321bb
+fa7d8040580cf953d2002e6b1a0e1d6b
+fa838b620ffc6b8f65235e3b3d453c49
+fa8e6aec8ff3735a84d076e3a5cd4a24
+fa8eb7da7e8e5669e6e5969cd9194d71
+fa962c1f8d72f95920253d5ca587e7ab
+fa995e6763115c07533e2bbce9486ddf
+fa9da74959283856c15192f2f6714b5a
+faa700453d118197208de1a1a8fcaaef
+faa89e951f6c93d085b942ae1de6db80
+faaa3dd2f6970b3257c3bdc5035892bf
+fab49f99ef09f4d2a7bec718e82e0a95
+fab65b0acd689ba2ae111a2679f5b91c
+fab7895af41d9dbac71400a4127c4ed9
+fab9871f7a6683cbf2560359f23c77f2
+fab9eff579527152a4434a79a6738315
+fabb5c59a47c7a13db14960d9e13374c
+fac4b5017bc451994fdc79fadf675541
+fac6184d18bb11a485959d3b5d494dce
+fac8ab022c0e7ef6276d69369ec7989f
+fad67e54c7d83f57c2637d31577ae9fe
+fad7ef725b8aed057408a25958c250a3
+fad896395e8fc5a91ed882ee2e47fe72
+fae0d439a8a45e7ae8ab5286c046020b
+fae604a99d67644fd3f1b42183b62337
+faeb936e46621cf84418c76a3219240b
+faee4ea9afc5d2e1a47d207a5309895e
+faf1af78fab2487a3e097868f6d07fee
+faff8f3380fb9c707df85ddea1d5fb45
+fb017f1a3666def770a8b8629b4f9b50
+fb01d1026f994c768f9f86b04fd04941
+fb081a7fda5be8d93755d385268051a1
+fb089f94f283a813f545caa87ff855c1
+fb1295221427a79c0340399a2ba63711
+fb13611a83817133b6cafdef4d48c91f
+fb1924537552ddc531b7000ba4c8a74a
+fb19db90990df53fc882727217547611
+fb1c0c27470c8e0a25698ea751732275
+fb1f9d9d695c2da150674ffb33a83ea7
+fb22ea4fa551ab36438f29ffb35cf939
+fb29dc7ea8d1c118b759f974d08e741a
+fb31f9d26247df95578ae094e3cbd187
+fb338021445092021ca507eecf36a8f4
+fb407f6b15679aa83a9e59db6815d177
+fb46fb5d28a3ca9b504a4420bb04f596
+fb5434842ff1a0fcc3b3da0f5ae6625e
+fb563f4db0b89516da60531ce32e6a47
+fb56eae47ee161a8346258c28b234d99
+fb57f8fc44f509852a161595319d3bfd
+fb5b973d3fbc66756ea86f086e66d4d2
+fb5e6495e1b8fc7f2e8f66704a4b6ce8
+fb5f84772a3dae6ac3b39aca11c3df0b
+fb62f780373a8d9a7cf57664839762ae
+fb65c7dc03e3df76b395b43e43577a5a
+fb6bb9d71a3c98a7a7235e89e7940b12
+fb6fa1323406695e86969a294249f273
+fb733df05d7adb6e632d4dc62712f850
+fb762801e562c83026b0bb4c3fc510a1
+fb7a0c166bb6f3070c8d6ec05dd0f8c7
+fb808c8c3ab523bd27f8a31dc27b7535
+fb824b004559da48703d3249de88ab3b
+fb8b8a136ba81a6abd9acdd4506e2d40
+fb9017301e4a6d603b5c3584294cceef
+fb939cdb55b13de3e0db4246f7e1c777
+fb97e4d8a1cdcd62713aa842dd5dea65
+fb98a84ac5ee650d6e626b5feaa2c618
+fb9ec1e839409bfc2c8048b14bf3e9a7
+fba0a5f8bfc01b482bc2cb6d5b9c7e4b
+fba2f9fbf07892cc8198eb63fe89bdd4
+fba3e0ecab90f9d11b34e7a2747dc13e
+fba3ed6e2bdaccdda6c28e3ed7012bc6
+fba6a6676fa921f1de8afb231f9d409e
+fbad716f8440017866f39025f1a196cb
+fbb18042bdf4151aa95b310ec9ffeb38
+fbb4bfef808258683f6af955fe7e7d69
+fbb5c9d75a7b91e1850ee5f05839a5b1
+fbbb0c620cf88cc86737fb8c5c64906a
+fbc0edaef1a3a9437d8234915af6346f
+fbc3f6922d51f42329a2fa3b7e213d4b
+fbc5926241d54fdcb75347dd62b0cb9f
+fbc8bd87f82556a18cfe91e635c9e681
+fbd00d79d6a00541b2165011f3c7dab0
+fbd0b5f6043d4a994be075d87964e8bc
+fbd1e40cceb5e688700b226430098357
+fbd92a61d0b67861072a62db1c55b3a9
+fbdbf09237afebcbcbb5e7c5e714068b
+fbdc6b1f6022752ce6168a436ee4c95f
+fbe262f49b737942364b8ab3ef0b3f34
+fbe460cc3760db27829031cd98595d7c
+fbe5f3c9ac4ae1782061ef8451cbf46e
+fbe656e2a158a085f289478e63bc7475
+fbe75d82be35cdde11a46e5e894586d2
+fbea1b01e5507201b1390e29b7690d0f
+fbf23a68067e1f5e3f41898bf8f76270
+fbf296136e6a1f1da969d632d5358a42
+fbf92432e88a9f67ae281693f5c99ffd
+fc00697d792e85e3f43e9173fc71333f
+fc012b03b1bcba86faf4a545dc8f0a59
+fc023fb452f2c9271d62e7e187d5e6c9
+fc0be796b417926fa5c2a2809abf64c3
+fc0c3f161bac218703c2ed52d7b2a784
+fc0d0a15bec6adaead413017a0d5343e
+fc1089c8edc35d903af0607a01640cd0
+fc11552d8e395597f16b7e8fd79aaeac
+fc11bb3ac7377c3c88db6756715d741c
+fc11cd6ce6881fd29d4156eedbde93fb
+fc18ef9b365239a411eddf6457e96e49
+fc1a19ca4b90f4fb51701516b2481239
+fc1d3170cccfcd5853e37ce4729107f2
+fc1fa3629c39cf3eff868749b06a16b5
+fc22b71b75d299ae32ac627f8e92326e
+fc24531bb6b612960177a8305bccb1f1
+fc249a2f1396870057ad45e8f4dda017
+fc265c7558c0a907d10e94d1c6888adc
+fc29b3db67ec4b38313d7e9f67f332ca
+fc346a9803ad3e72813cb498dafc2ba3
+fc3810de7638d218c98364ae47a7109b
+fc3954813a6b9d0ca92adf723fd138d3
+fc3d6b560e667372413eb7fe1691b268
+fc409791dd1c9a1e44e796ca6981a045
+fc4bf1623d66390b1366584ca5f7da74
+fc4f1c036e6bc21579f05fae9bce8f37
+fc50c3f708976b7c64a0ad23c82831b3
+fc52233641d5c613b209b2dbe9a1f2b2
+fc56476e538ca38cd9243b9958e7aeae
+fc5b01c5714e419acc0b0dd6c38f3fdf
+fc5dc67c759865b4b78746cd03535ed4
+fc6174e5864957af53ee1ea3ac4a3c09
+fc62f433628e389a705e80c6574a0f66
+fc666250be329f146fbc66be050be2b4
+fc6972ba8e5919bd95caf3d9de543cc1
+fc6d9d2eb6a74a6716b7eb91a2292bde
+fc6f15fb4a3b4b43d6915576cf096a15
+fc7c9d2b1d2b1b20d2c70e083d0646e9
+fc8174ee6ccfeb7f8ba09969aef9b8d0
+fc83fb0fa8953deb39a6cc1b39b3b8c6
+fc8b97c3cb6b15cebc69a67c2f1d191f
+fc8dd5d947e330bc8d31ba285ede5a51
+fc964a0290259c9fc605555ec4a3bd56
+fc97296809c1ea00d1cfa01ed2e25624
+fc9af53c64a1d60eef0cbb3ce8830792
+fcb2b215a71e03d202fab51a0e2499d7
+fcb303d15bc83e94107edc4999effccf
+fcb8b4fd1f1b539c8a2414ad366da700
+fcb8d5bb3b6f8cfeeae8a036679cc493
+fcbbe2a3a73071f3745cc2d3e981e7f2
+fcbdf00155ecaa74b63995e4c93aaa0e
+fcbe9d6dc973d2971dadbe2e26d3be5e
+fcc4a872257764710fb9ac92fe749a89
+fcc627633ae4161d4badf8e9b85abcde
+fcc6f18734966d80b1133b3dd79a4be6
+fcc80212b0e0c37640c2e3b94280043b
+fcc9168258a8c53a2679b4398f948315
+fcd1763cb95a5438899dae62e7523beb
+fcd2f2364532fc6cf60e576b7d633e25
+fcdc5c5445ce000e8d63836f98f1bdb3
+fcdd5911b681da6d764f3aef53cfea04
+fce2d214a8fe8ad5dd3d6fa99ca726bf
+fce6d08af9e01cb22975a6a3f90009e1
+fce8998efd3b636c509409a2e7efc626
+fceaca71a86fa5d2c1426060747bbc5b
+fcefbd9a7a8ee10f0851b948c1509901
+fcf166e9b07084c52e56d34024090b14
+fcf20d0afbc70c3a330ae6fe844cbb01
+fcf2a5e325d5281021d1c2845810ff63
+fcf3aedad8a7456e973e09e59af6f0de
+fcfbcc7af26872f24884bbf80b75ff5f
+fcfccb533264308cbb6ac8ab417829c2
+fd01caaf3181668ca5d9fbd65c7a1d15
+fd062d7de1d16fb189f9f65e90d51b11
+fd062ea33c146f6d661037cea6ce1ccf
+fd079c54537a30c2a7dffec6a24db0e3
+fd081dff2a98ab0716cc0d155aabbed4
+fd09a6d593307e81dcb8f63bca026e97
+fd0ee0e2b08abc61a6e4a6e61b2aad81
+fd12ef2c93a6ef7653f4898ab27df971
+fd1444c780f9a969ef9e55e13b671471
+fd19932a5d81fc9dcabaabac2daca035
+fd1d462854c3bbe7680e06d8a07b0c6a
+fd20c40371557ad7c8d7f70d7a1a7848
+fd22f429a80fac17c52fa8a167fcb63b
+fd2339a6b83dd628bd7939008799ffa5
+fd2afefdf0c2424907763863344c2705
+fd2b300f150e011e41968639c7378f3c
+fd31876328cf86684aa47a739c4bda76
+fd32c4a85aa34dbe51f7449ca6da635e
+fd39eb64b0d7d81cdd3a4dc3f44d967b
+fd39ffd0a8d646e4f76bfd385833543f
+fd3ad774c3a8bef21e804a02548eb5db
+fd3c17a3afc6c89ec23a6e37fa3ba25a
+fd3eda09ffc6ec510f85c88538cf5395
+fd40fb17ae3fcf90935276128090012f
+fd423f903e5a1a3d746f29268f929176
+fd4428791ef1f8e75569c3e1c715da1f
+fd49f52370378aae74152cb3b1ecceb7
+fd674f4ff1506c34cf7d9d17002ee155
+fd6cd47d9c0ffc6995130247c7797809
+fd6ef63b6dab9c54ad53096023cb78c8
+fd6f3500071e747c33de5634631aa088
+fd7001af36561310393623fe0bd63175
+fd714515b0cfa2579a273479a2b714dd
+fd7e8c69413803d51ba18f4c13630e52
+fd818b2f6a65e374126bee689c310b52
+fd875fdecacbb7fce43e07b03998c349
+fd881b09ba980e349c818dd359ed0a73
+fd9acd7d1fe07fa97bd8998e6c684bba
+fd9b31a7e8f15614a5749f5801b31176
+fda49b7d8969d5760164d276776c10fe
+fda909dc0854bb78e6fe4f31c9112736
+fda9c4ade4e315c7326d1c43dde1be9f
+fdaae9c5ef125fc3491609555e79e250
+fdabd8d997b19e8aa416b0f702022bc1
+fdaed45bf9dc61e5087990fbc93d23e9
+fdaf465c0f20e3730fca93abfae8ebc6
+fdb1a394b867ed58a8d302e84658a58c
+fdb3694ef71ee5c58a626bec8ef73877
+fdb68d18a66772632620d9a9ad353d35
+fdb7fe66042032dae5cec18eb101e47f
+fdbda8736e7cac9c9e2102f7d0dd0771
+fdc3572c7bb890a3a1666c80cb1b58e3
+fdc4afe74880691b7169e6b4c64beba7
+fdc68b6ede67cf3fac8bef036d5cb5df
+fdd0d66794b9c01bd98deeff7f237bf9
+fdd55c04f1ecd3e9a0170a89a7eb6fc5
+fddc66a6049f15a2ac9335112ea003e3
+fddcc782ef4ebbee16a19255274b883d
+fde0f771e88d4515d5258d35537c23d1
+fde36d1747ec7cc9085fc9b8d4df64b5
+fde50e611451e737af52951b44b38c39
+fde572e2a46017a209cb7363a10c74eb
+fde6d86a03d44f660cebc6029379425d
+fdea716637af928698d158ebd9f0b036
+fdecd15430104d1cc27995cacdd24d23
+fdee3f95389ca55e49e52f273699b691
+fdf739b8a12074a524e3bc88fda1dce0
+fdf76759174cfd9e25fdd23e5f263c08
+fe0128aad8de6412eb103e1241abf185
+fe01ee02f1ea0ceaef1ef4363a81405f
+fe08303214ad9353127c14b6f0da073a
+fe0aac9a17699e7e1dd875fe76204fee
+fe0c2fa96596de96d9b24e73b865997d
+fe0c7500f6d98963f0b8ab0da4fc1bf4
+fe0da82b3d7d9db97e96f4aaa0d6a33e
+fe13f7c7b4306585439160e287089067
+fe15fffee1fd535463472be3dc09c360
+fe1d88ab6c33ffec4e6fdb12f9c46ee6
+fe2c5574c9c0292ab8981f8fd8dea837
+fe3350bb4c1483910f4ef6befddfa83f
+fe3522355333a257462c6a998da6c027
+fe37af1121acc8eea99038b5449dc42c
+fe3faed9ba35d7700a1829ac43040da8
+fe4302edc88561f0247d0ef1dac0d5d4
+fe439b38a13bdb8df49b6a46ed2a3f40
+fe4861c16670b46abdb7233b498d6b09
+fe48fce1093ac1ea73fe5801af68a64a
+fe4afebbc7eff059485846198c812a91
+fe56878bf49aba131992500c61be3d4f
+fe5978aba3beaac52dc67e93fde647ed
+fe5a207aa868d990e1cc99df1ff69ca1
+fe5c07a8cbb65ad630626e793bae9c07
+fe689ff12979381ac939a82725f14b5c
+fe6b58abff1e0181af3593b3352ac5c2
+fe748248c18a90a4be14d0edd16fe09d
+fe7e14d43bbfc0e0aa5aaffdd4077eb6
+fe826116269e6dc22fac3d927e9aee48
+fe84cabfed2b16dd6f95ab2bc663d163
+fe85fba83877d96aa1202b631a24fbc9
+fe8b84c3fd2e847cde501e2b52205bc8
+fe8d31e8c9cdccfa8dfb9a0c39c48afb
+fe96f563555fa64109ff27de153f8e68
+fe9af4332c84650bd962178c16209751
+fe9e03a8013f452eab395047fd68a2f8
+fea28a5746e45a0b12e676b1ca44bc14
+fea6e0fef29727269d12a02d03e8879b
+fea7a3e4b1b779bb0ae814a765b8e873
+fea9044824bc24433835d73fb2baa82b
+feb3f68293b09c5b146eb73ea1bfcafe
+feb73e866bfe9a24f4380b89b41c91dc
+febc05bb5e2619915f57bed34496a080
+febe63320d1abf4e5788f4b92cb1a14e
+fec1627ebbf9c2e0b19aa1abdeace369
+fec31e3c5636d034db7d77b74d392837
+fece65a24bfa92478d9aabb5e10524ea
+fed13a5e2c97591385ea77a3f810bd70
+fed288c923ce63d5747893c906b4d2ff
+fedb8d83f3f99ba774319ee865b2bcec
+fee08b0ce490733f4f40ef2c16eac7a4
+feea4177c2112af966a5966d9f415fa4
+feec501f02a92df68cac935fe8c7d80f
+fef4175f6ca217ce3c1b15deae3526ff
+fef5aa3e1897be2436e28c5aded3c308
+fef7884338438ce445b9a64408d5836a
+fef8a361d5dfd33ecba109224ee5038f
+ff08b4ab5b226db93ae9358bcb6aa73f
+ff0962b8540fc4426d9ab8c5f804ad8e
+ff0a6713c28202159927b3463281355e
+ff0a962245ae339a165e36b643aeeaf4
+ff0afc56b8e788821134edbcc68ff703
+ff116155f8c0f0b3c51d17f26beb6911
+ff136b6f3da2ccacfe8286dd561c9289
+ff17ed00fa3884f4cc42a4b0f0c2465f
+ff1949fc0a0ca76f47548b466bfb635b
+ff247086752290cccbf4ad67b5250166
+ff24f928bdcb760355e825b5df17e010
+ff25b948ce2fe844ab640c4d6ece3538
+ff2607011d5a5d67351c9b17c5ab745b
+ff266ec90858b3d0dcbc0a7441b41d84
+ff2a0cfd542bd2318d7bc0f64a78d0f6
+ff2b3eb773a53660896b753067686cb3
+ff2c8c5bd21d88286073227b2b17fa9e
+ff2efaf48bb3a229db962e709c6d95de
+ff35d32a44f393599be1a3ab2ee94a9b
+ff37d21a9793558aa890ba553a2c2270
+ff408bbf0e9dcce6d4fe50a85371ea31
+ff47df32fa4daec649bdb7680a342718
+ff495554aab44edb5e62f653fac69326
+ff5185fa1dce45618224432060810e3b
+ff556f0b9393c3fed13e0f5d36ab8dae
+ff61bb10d210bb0c72b0ecc6f45b722d
+ff6286edf5e8e6eeebad4ffe5bb97b22
+ff6347cdbff3d963ef396f29c89dd5d2
+ff6afe7f97c8b8df422be97d48feaddb
+ff6c6c2075f04020241e54dfc5db741a
+ff6d609348ba719262b24664d4005fb9
+ff72d7b87a310e97ec6c9c8e8ce4ab77
+ff748c8f9d27f8f484613fbdaad00799
+ff7ae88de9f08a441636378aa4ea2021
+ff7c4a92fe91727f62cc71270016a319
+ff7f7dd10730508f2921ac5a14d6d5c7
+ff8204a4476dc0467dbadae97251bf6e
+ff831717a5809c0c5e8a97e514f6294c
+ff864d7a4df0d05b11a501d58831b14a
+ff87819215bc249e2383f3c6eca832c1
+ff8acd12b05e64f5a6277f1cab9e9b1b
+ff91d654536517f0d97b9fc32ccf8d47
+ff93ee2524c5ceeb4f9e875a8f4524b8
+ff96cfc14006dcd5cd2f5055e02692a7
+ff9b66d3fa3e59ad7d5187c5fc32dfce
+ff9d56068b5c792c2412a86509af099d
+ffa4c7c35cbb60bd5bac8c2692805b67
+ffa622a3c8bf0e0afc36215800b166a9
+ffab254e799fd42d10da6d4c9f32bf1c
+ffab9ae62ea5149cebc770d69ab1fc3b
+ffabb8920899a83a51d88dc6ba5e2596
+ffaea6b3910d55fd6763508599326c3a
+ffb6c4885c962d804ee755a94076b408
+ffb74266d52bf044cff87eab01bcf2dc
+ffb7dcf84173252ff46d602e9f22e577
+ffbb402e50ae32f31b0f54368603c4ff
+ffbcac9b7410e5c1d7c0c92b424d8a44
+ffbcd43aa88c27bbaf8e2fd6907faaed
+ffcc56cfee46a62a7594c29b401bf8cf
+ffd38187be49ba0f49119fe65b09cd0e
+ffd3d80bf0be1a7d0603e9be1e6405ac
+ffd68d3fb874785c712b4d0e9a3e3c9d
+ffdbabfd29ea1c65e46c7e60c16766ad
+ffdcb5d25eaf9605a33859fc29c1f3a2
+ffddc05f4964f02f82dae3920d11eb63
+ffe00046a95ddb1b7ac23ede3b3ba5ba
+ffe69d829af68ded36787aadf32bbf95
+ffe78d515dbed78b8a75415c98633ce1
+fff0ab39c75cf5441fcece68da746c7c
+fff2eed02d5934c5443f7b727bcdb8bd
+fffccc91ba9f9e0e5d63a0167a71701b \ No newline at end of file
diff --git a/searx/data/engines_languages.json b/searx/data/engines_languages.json
index 83701e6..e293eb1 100644
--- a/searx/data/engines_languages.json
+++ b/searx/data/engines_languages.json
@@ -34,7 +34,6 @@
"de-CH",
"de-DE",
"de-LI",
- "de-LU",
"dv-MV",
"el-GR",
"en-AG",
@@ -51,7 +50,6 @@
"en-CK",
"en-CX",
"en-CY",
- "en-DM",
"en-FJ",
"en-FK",
"en-FM",
@@ -74,6 +72,7 @@
"en-LR",
"en-LS",
"en-MH",
+ "en-MM",
"en-MP",
"en-MS",
"en-MU",
@@ -115,6 +114,7 @@
"es-CL",
"es-CO",
"es-CR",
+ "es-DM",
"es-DO",
"es-EC",
"es-ES",
@@ -155,6 +155,7 @@
"fr-GP",
"fr-HT",
"fr-KM",
+ "fr-LU",
"fr-MC",
"fr-MF",
"fr-MG",
@@ -273,7 +274,6 @@
"de-CH",
"de-DE",
"de-LI",
- "de-LU",
"dv-MV",
"el-GR",
"en-AG",
@@ -290,7 +290,6 @@
"en-CK",
"en-CX",
"en-CY",
- "en-DM",
"en-FJ",
"en-FK",
"en-FM",
@@ -313,6 +312,7 @@
"en-LR",
"en-LS",
"en-MH",
+ "en-MM",
"en-MP",
"en-MS",
"en-MU",
@@ -354,6 +354,7 @@
"es-CL",
"es-CO",
"es-CR",
+ "es-DM",
"es-DO",
"es-EC",
"es-ES",
@@ -394,6 +395,7 @@
"fr-GP",
"fr-HT",
"fr-KM",
+ "fr-LU",
"fr-MC",
"fr-MF",
"fr-MG",
@@ -512,7 +514,6 @@
"de-CH",
"de-DE",
"de-LI",
- "de-LU",
"dv-MV",
"el-GR",
"en-AG",
@@ -529,7 +530,6 @@
"en-CK",
"en-CX",
"en-CY",
- "en-DM",
"en-FJ",
"en-FK",
"en-FM",
@@ -552,6 +552,7 @@
"en-LR",
"en-LS",
"en-MH",
+ "en-MM",
"en-MP",
"en-MS",
"en-MU",
@@ -593,6 +594,7 @@
"es-CL",
"es-CO",
"es-CR",
+ "es-DM",
"es-DO",
"es-EC",
"es-ES",
@@ -633,6 +635,7 @@
"fr-GP",
"fr-HT",
"fr-KM",
+ "fr-LU",
"fr-MC",
"fr-MF",
"fr-MG",
@@ -751,7 +754,6 @@
"de-CH",
"de-DE",
"de-LI",
- "de-LU",
"dv-MV",
"el-GR",
"en-AG",
@@ -768,7 +770,6 @@
"en-CK",
"en-CX",
"en-CY",
- "en-DM",
"en-FJ",
"en-FK",
"en-FM",
@@ -791,6 +792,7 @@
"en-LR",
"en-LS",
"en-MH",
+ "en-MM",
"en-MP",
"en-MS",
"en-MU",
@@ -832,6 +834,7 @@
"es-CL",
"es-CO",
"es-CR",
+ "es-DM",
"es-DO",
"es-EC",
"es-ES",
@@ -872,6 +875,7 @@
"fr-GP",
"fr-HT",
"fr-KM",
+ "fr-LU",
"fr-MC",
"fr-MF",
"fr-MG",
@@ -24752,7 +24756,6 @@
"wt-WT",
"zh-CN"
],
- "gigablast": [],
"google": {
"af": {
"name": "Afrikaans"
@@ -24761,19 +24764,19 @@
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
},
"be": {
- "name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
+ "name": "\u0431\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
},
"bg": {
- "name": "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
},
"ca": {
- "name": "Catal\u00e0"
+ "name": "catal\u00e0"
},
"cs": {
- "name": "\u010ce\u0161tina"
+ "name": "\u010de\u0161tina"
},
"da": {
- "name": "Dansk"
+ "name": "dansk"
},
"de": {
"name": "Deutsch"
@@ -24785,43 +24788,43 @@
"name": "English"
},
"eo": {
- "name": "Esperanto"
+ "name": "esperanto"
},
"es": {
- "name": "Espa\u00f1ol"
+ "name": "espa\u00f1ol"
},
"et": {
- "name": "Eesti"
+ "name": "eesti"
},
"fa": {
"name": "\u0641\u0627\u0631\u0633\u06cc"
},
"fi": {
- "name": "Suomi"
+ "name": "suomi"
},
"fr": {
- "name": "Fran\u00e7ais"
+ "name": "fran\u00e7ais"
},
"hi": {
"name": "\u0939\u093f\u0928\u094d\u0926\u0940"
},
"hr": {
- "name": "Hrvatski"
+ "name": "hrvatski"
},
"hu": {
- "name": "Magyar"
+ "name": "magyar"
},
"hy": {
- "name": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576"
+ "name": "\u0570\u0561\u0575\u0565\u0580\u0565\u0576"
},
"id": {
"name": "Indonesia"
},
"is": {
- "name": "\u00cdslenska"
+ "name": "\u00edslenska"
},
"it": {
- "name": "Italiano"
+ "name": "italiano"
},
"iw": {
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
@@ -24833,40 +24836,40 @@
"name": "\ud55c\uad6d\uc5b4"
},
"lt": {
- "name": "Lietuvi\u0173"
+ "name": "lietuvi\u0173"
},
"lv": {
- "name": "Latvie\u0161u"
+ "name": "latvie\u0161u"
},
"nl": {
"name": "Nederlands"
},
"no": {
- "name": "Norsk"
+ "name": "norsk"
},
"pl": {
- "name": "Polski"
+ "name": "polski"
},
"pt": {
- "name": "Portugu\u00eas"
+ "name": "portugu\u00eas"
},
"ro": {
- "name": "Rom\u00e2n\u0103"
+ "name": "rom\u00e2n\u0103"
},
"ru": {
- "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ "name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"
},
"sk": {
- "name": "Sloven\u010dina"
+ "name": "sloven\u010dina"
},
"sl": {
- "name": "Sloven\u0161\u010dina"
+ "name": "sloven\u0161\u010dina"
},
"sr": {
- "name": "\u0421\u0440\u043f\u0441\u043a\u0438"
+ "name": "\u0441\u0440\u043f\u0441\u043a\u0438"
},
"sv": {
- "name": "Svenska"
+ "name": "svenska"
},
"sw": {
"name": "Kiswahili"
@@ -24881,7 +24884,147 @@
"name": "T\u00fcrk\u00e7e"
},
"uk": {
- "name": "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
+ "name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
+ },
+ "vi": {
+ "name": "Ti\u1ebfng Vi\u1ec7t"
+ },
+ "zh-CN": {
+ "name": "\u4e2d\u6587 (\u7b80\u4f53)"
+ },
+ "zh-TW": {
+ "name": "\u4e2d\u6587 (\u7e41\u9ad4)"
+ }
+ },
+ "google images": {
+ "af": {
+ "name": "Afrikaans"
+ },
+ "ar": {
+ "name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
+ },
+ "be": {
+ "name": "\u0431\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
+ },
+ "bg": {
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
+ },
+ "ca": {
+ "name": "catal\u00e0"
+ },
+ "cs": {
+ "name": "\u010de\u0161tina"
+ },
+ "da": {
+ "name": "dansk"
+ },
+ "de": {
+ "name": "Deutsch"
+ },
+ "el": {
+ "name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
+ },
+ "en": {
+ "name": "English"
+ },
+ "eo": {
+ "name": "esperanto"
+ },
+ "es": {
+ "name": "espa\u00f1ol"
+ },
+ "et": {
+ "name": "eesti"
+ },
+ "fa": {
+ "name": "\u0641\u0627\u0631\u0633\u06cc"
+ },
+ "fi": {
+ "name": "suomi"
+ },
+ "fr": {
+ "name": "fran\u00e7ais"
+ },
+ "hi": {
+ "name": "\u0939\u093f\u0928\u094d\u0926\u0940"
+ },
+ "hr": {
+ "name": "hrvatski"
+ },
+ "hu": {
+ "name": "magyar"
+ },
+ "hy": {
+ "name": "\u0570\u0561\u0575\u0565\u0580\u0565\u0576"
+ },
+ "id": {
+ "name": "Indonesia"
+ },
+ "is": {
+ "name": "\u00edslenska"
+ },
+ "it": {
+ "name": "italiano"
+ },
+ "iw": {
+ "name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
+ },
+ "ja": {
+ "name": "\u65e5\u672c\u8a9e"
+ },
+ "ko": {
+ "name": "\ud55c\uad6d\uc5b4"
+ },
+ "lt": {
+ "name": "lietuvi\u0173"
+ },
+ "lv": {
+ "name": "latvie\u0161u"
+ },
+ "nl": {
+ "name": "Nederlands"
+ },
+ "no": {
+ "name": "norsk"
+ },
+ "pl": {
+ "name": "polski"
+ },
+ "pt": {
+ "name": "portugu\u00eas"
+ },
+ "ro": {
+ "name": "rom\u00e2n\u0103"
+ },
+ "ru": {
+ "name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"
+ },
+ "sk": {
+ "name": "sloven\u010dina"
+ },
+ "sl": {
+ "name": "sloven\u0161\u010dina"
+ },
+ "sr": {
+ "name": "\u0441\u0440\u043f\u0441\u043a\u0438"
+ },
+ "sv": {
+ "name": "svenska"
+ },
+ "sw": {
+ "name": "Kiswahili"
+ },
+ "th": {
+ "name": "\u0e44\u0e17\u0e22"
+ },
+ "tl": {
+ "name": "Filipino"
+ },
+ "tr": {
+ "name": "T\u00fcrk\u00e7e"
+ },
+ "uk": {
+ "name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
},
"vi": {
"name": "Ti\u1ebfng Vi\u1ec7t"
@@ -24901,19 +25044,19 @@
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
},
"be": {
- "name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
+ "name": "\u0431\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
},
"bg": {
- "name": "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
},
"ca": {
- "name": "Catal\u00e0"
+ "name": "catal\u00e0"
},
"cs": {
- "name": "\u010ce\u0161tina"
+ "name": "\u010de\u0161tina"
},
"da": {
- "name": "Dansk"
+ "name": "dansk"
},
"de": {
"name": "Deutsch"
@@ -24925,43 +25068,43 @@
"name": "English"
},
"eo": {
- "name": "Esperanto"
+ "name": "esperanto"
},
"es": {
- "name": "Espa\u00f1ol"
+ "name": "espa\u00f1ol"
},
"et": {
- "name": "Eesti"
+ "name": "eesti"
},
"fa": {
"name": "\u0641\u0627\u0631\u0633\u06cc"
},
"fi": {
- "name": "Suomi"
+ "name": "suomi"
},
"fr": {
- "name": "Fran\u00e7ais"
+ "name": "fran\u00e7ais"
},
"hi": {
"name": "\u0939\u093f\u0928\u094d\u0926\u0940"
},
"hr": {
- "name": "Hrvatski"
+ "name": "hrvatski"
},
"hu": {
- "name": "Magyar"
+ "name": "magyar"
},
"hy": {
- "name": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576"
+ "name": "\u0570\u0561\u0575\u0565\u0580\u0565\u0576"
},
"id": {
"name": "Indonesia"
},
"is": {
- "name": "\u00cdslenska"
+ "name": "\u00edslenska"
},
"it": {
- "name": "Italiano"
+ "name": "italiano"
},
"iw": {
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
@@ -24973,40 +25116,40 @@
"name": "\ud55c\uad6d\uc5b4"
},
"lt": {
- "name": "Lietuvi\u0173"
+ "name": "lietuvi\u0173"
},
"lv": {
- "name": "Latvie\u0161u"
+ "name": "latvie\u0161u"
},
"nl": {
"name": "Nederlands"
},
"no": {
- "name": "Norsk"
+ "name": "norsk"
},
"pl": {
- "name": "Polski"
+ "name": "polski"
},
"pt": {
- "name": "Portugu\u00eas"
+ "name": "portugu\u00eas"
},
"ro": {
- "name": "Rom\u00e2n\u0103"
+ "name": "rom\u00e2n\u0103"
},
"ru": {
- "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ "name": "\u0440\u0443\u0441\u0441\u043a\u0438\u0439"
},
"sk": {
- "name": "Sloven\u010dina"
+ "name": "sloven\u010dina"
},
"sl": {
- "name": "Sloven\u0161\u010dina"
+ "name": "sloven\u0161\u010dina"
},
"sr": {
- "name": "\u0421\u0440\u043f\u0441\u043a\u0438"
+ "name": "\u0441\u0440\u043f\u0441\u043a\u0438"
},
"sv": {
- "name": "Svenska"
+ "name": "svenska"
},
"sw": {
"name": "Kiswahili"
@@ -25021,7 +25164,7 @@
"name": "T\u00fcrk\u00e7e"
},
"uk": {
- "name": "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
+ "name": "\u0443\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
},
"vi": {
"name": "Ti\u1ebfng Vi\u1ec7t"
@@ -25033,405 +25176,1321 @@
"name": "\u4e2d\u6587 (\u7e41\u9ad4)"
}
},
- "qwant": [
- "bg-BG",
- "br-FR",
- "ca-AD",
- "ca-ES",
- "ca-FR",
- "co-FR",
- "cs-CZ",
- "cy-GB",
- "da-DK",
- "de-AT",
- "de-CH",
- "de-DE",
- "el-GR",
- "en-AU",
- "en-CA",
- "en-GB",
- "en-IE",
- "en-IN",
- "en-MY",
- "en-NZ",
- "en-PH",
- "en-SG",
- "en-US",
- "es-AD",
- "es-AR",
- "es-CL",
- "es-ES",
- "es-MX",
- "et-EE",
- "eu-ES",
- "eu-FR",
- "fi-FI",
- "fr-AD",
- "fr-BE",
- "fr-CA",
- "fr-CH",
- "fr-FR",
- "gd-GB",
- "he-IL",
- "hu-HU",
- "it-CH",
- "it-IT",
- "ja-JP",
- "ko-KR",
- "ms-MY",
- "nl-BE",
- "nl-NL",
- "no-NO",
- "pl-PL",
- "pt-AD",
- "pt-BR",
- "pt-PT",
- "ro-RO",
- "ru-RU",
- "sv-SE",
- "th-TH",
- "tr-TR"
- ],
- "qwant images": [
- "bg-BG",
- "br-FR",
- "ca-AD",
- "ca-ES",
- "ca-FR",
- "co-FR",
- "cs-CZ",
- "cy-GB",
- "da-DK",
- "de-AT",
- "de-CH",
- "de-DE",
- "el-GR",
- "en-AU",
- "en-CA",
- "en-GB",
- "en-IE",
- "en-IN",
- "en-MY",
- "en-NZ",
- "en-PH",
- "en-SG",
- "en-US",
- "es-AD",
- "es-AR",
- "es-CL",
- "es-ES",
- "es-MX",
- "et-EE",
- "eu-ES",
- "eu-FR",
- "fi-FI",
- "fr-AD",
- "fr-BE",
- "fr-CA",
- "fr-CH",
- "fr-FR",
- "gd-GB",
- "he-IL",
- "hu-HU",
- "it-CH",
- "it-IT",
- "ja-JP",
- "ko-KR",
- "ms-MY",
- "nl-BE",
- "nl-NL",
- "no-NO",
- "pl-PL",
- "pt-AD",
- "pt-BR",
- "pt-PT",
- "ro-RO",
- "ru-RU",
- "sv-SE",
- "th-TH",
- "tr-TR"
- ],
- "qwant news": [
- "bg-BG",
- "br-FR",
- "ca-AD",
- "ca-ES",
- "ca-FR",
- "co-FR",
- "cs-CZ",
- "cy-GB",
- "da-DK",
- "de-AT",
- "de-CH",
- "de-DE",
- "el-GR",
- "en-AU",
- "en-CA",
- "en-GB",
- "en-IE",
- "en-IN",
- "en-MY",
- "en-NZ",
- "en-PH",
- "en-SG",
- "en-US",
- "es-AD",
- "es-AR",
- "es-CL",
- "es-ES",
- "es-MX",
- "et-EE",
- "eu-ES",
- "eu-FR",
- "fi-FI",
- "fr-AD",
- "fr-BE",
- "fr-CA",
- "fr-CH",
- "fr-FR",
- "gd-GB",
- "he-IL",
- "hu-HU",
- "it-CH",
- "it-IT",
- "ja-JP",
- "ko-KR",
- "ms-MY",
- "nl-BE",
- "nl-NL",
- "no-NO",
- "pl-PL",
- "pt-AD",
- "pt-BR",
- "pt-PT",
- "ro-RO",
- "ru-RU",
- "sv-SE",
- "th-TH",
- "tr-TR"
- ],
- "qwant social": [
- "bg-BG",
- "br-FR",
- "ca-AD",
- "ca-ES",
- "ca-FR",
- "co-FR",
- "cs-CZ",
- "cy-GB",
- "da-DK",
- "de-AT",
- "de-CH",
- "de-DE",
- "el-GR",
- "en-AU",
- "en-CA",
- "en-GB",
- "en-IE",
- "en-IN",
- "en-MY",
- "en-NZ",
- "en-PH",
- "en-SG",
- "en-US",
- "es-AD",
- "es-AR",
- "es-CL",
- "es-ES",
- "es-MX",
- "et-EE",
- "eu-ES",
- "eu-FR",
- "fi-FI",
- "fr-AD",
- "fr-BE",
- "fr-CA",
- "fr-CH",
- "fr-FR",
- "gd-GB",
- "he-IL",
- "hu-HU",
- "it-CH",
- "it-IT",
- "ja-JP",
- "ko-KR",
- "ms-MY",
- "nl-BE",
- "nl-NL",
- "no-NO",
- "pl-PL",
- "pt-AD",
- "pt-BR",
- "pt-PT",
- "ro-RO",
- "ru-RU",
- "sv-SE",
- "th-TH",
- "tr-TR"
+ "peertube": [
+ "aa",
+ "ab",
+ "af",
+ "ak",
+ "am",
+ "an",
+ "ar",
+ "as",
+ "ase",
+ "av",
+ "avk",
+ "ay",
+ "az",
+ "ba",
+ "be",
+ "bfi",
+ "bg",
+ "bi",
+ "bm",
+ "bn",
+ "bo",
+ "br",
+ "bs",
+ "bzs",
+ "ca",
+ "ce",
+ "ch",
+ "co",
+ "cr",
+ "cs",
+ "cse",
+ "csl",
+ "cv",
+ "cy",
+ "da",
+ "de",
+ "dsl",
+ "dv",
+ "dz",
+ "ee",
+ "el",
+ "en",
+ "eo",
+ "es",
+ "et",
+ "eu",
+ "fa",
+ "ff",
+ "fi",
+ "fj",
+ "fo",
+ "fr",
+ "fsl",
+ "fy",
+ "ga",
+ "gd",
+ "gl",
+ "gn",
+ "gsg",
+ "gu",
+ "gv",
+ "ha",
+ "he",
+ "hi",
+ "ho",
+ "hr",
+ "ht",
+ "hu",
+ "hy",
+ "hz",
+ "id",
+ "ig",
+ "ii",
+ "ik",
+ "is",
+ "it",
+ "iu",
+ "ja",
+ "jbo",
+ "jsl",
+ "jv",
+ "ka",
+ "kg",
+ "ki",
+ "kj",
+ "kk",
+ "kl",
+ "km",
+ "kn",
+ "ko",
+ "kr",
+ "ks",
+ "ku",
+ "kv",
+ "kw",
+ "ky",
+ "lb",
+ "lg",
+ "li",
+ "ln",
+ "lo",
+ "lt",
+ "lu",
+ "lv",
+ "mg",
+ "mh",
+ "mi",
+ "mk",
+ "ml",
+ "mn",
+ "mr",
+ "ms",
+ "mt",
+ "my",
+ "na",
+ "nb",
+ "nd",
+ "ne",
+ "ng",
+ "nl",
+ "nn",
+ "no",
+ "nr",
+ "nv",
+ "ny",
+ "oc",
+ "oj",
+ "om",
+ "or",
+ "os",
+ "pa",
+ "pks",
+ "pl",
+ "ps",
+ "pt",
+ "qu",
+ "rm",
+ "rn",
+ "ro",
+ "rsl",
+ "ru",
+ "rw",
+ "sc",
+ "sd",
+ "sdl",
+ "se",
+ "sfs",
+ "sg",
+ "sh",
+ "si",
+ "sk",
+ "sl",
+ "sm",
+ "sn",
+ "so",
+ "sq",
+ "sr",
+ "ss",
+ "st",
+ "su",
+ "sv",
+ "sw",
+ "swl",
+ "ta",
+ "te",
+ "tg",
+ "th",
+ "ti",
+ "tk",
+ "tl",
+ "tlh",
+ "tn",
+ "to",
+ "tr",
+ "ts",
+ "tt",
+ "tw",
+ "ty",
+ "ug",
+ "uk",
+ "ur",
+ "uz",
+ "ve",
+ "vi",
+ "wa",
+ "wo",
+ "xh",
+ "yi",
+ "yo",
+ "za",
+ "zh",
+ "zu"
],
+ "qwant": {
+ "bg-BG": {
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
+ },
+ "br-FR": {
+ "name": "Brezhoneg"
+ },
+ "ca-AD": {
+ "name": "Catal\u00e0"
+ },
+ "ca-ES": {
+ "name": "Catal\u00e0"
+ },
+ "ca-FR": {
+ "name": "Catal\u00e0"
+ },
+ "co-FR": {
+ "name": "Corsu"
+ },
+ "cs-CZ": {
+ "name": "\u010cesky"
+ },
+ "cy-GB": {
+ "name": "Welsh"
+ },
+ "da-DK": {
+ "name": "Dansk"
+ },
+ "de-AT": {
+ "name": "Deutsch"
+ },
+ "de-CH": {
+ "name": "Deutsch"
+ },
+ "de-DE": {
+ "name": "Deutsch"
+ },
+ "el-GR": {
+ "name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
+ },
+ "en-AU": {
+ "name": "English"
+ },
+ "en-CA": {
+ "name": "English"
+ },
+ "en-GB": {
+ "name": "English"
+ },
+ "en-IE": {
+ "name": "English"
+ },
+ "en-IN": {
+ "name": "English"
+ },
+ "en-MY": {
+ "name": "English"
+ },
+ "en-NZ": {
+ "name": "English"
+ },
+ "en-PH": {
+ "name": "English"
+ },
+ "en-SG": {
+ "name": "English"
+ },
+ "en-US": {
+ "name": "English"
+ },
+ "es-AD": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-AR": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-CL": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-ES": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-MX": {
+ "name": "Espa\u00f1ol"
+ },
+ "et-EE": {
+ "name": "Eesti keel"
+ },
+ "eu-ES": {
+ "name": "Euskara"
+ },
+ "eu-FR": {
+ "name": "Euskara"
+ },
+ "fi-FI": {
+ "name": "Suomen kieli"
+ },
+ "fr-AD": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-BE": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CA": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CH": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-FR": {
+ "name": "Fran\u00e7ais"
+ },
+ "gd-GB": {
+ "name": "Scottish"
+ },
+ "he-IL": {
+ "name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
+ },
+ "hu-HU": {
+ "name": "magyar"
+ },
+ "it-CH": {
+ "name": "Italiano"
+ },
+ "it-IT": {
+ "name": "Italiano"
+ },
+ "ja-JP": {
+ "name": "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054)"
+ },
+ "ko-KR": {
+ "name": "\ud55c\uad6d\uc5b4"
+ },
+ "ms-MY": {
+ "name": "\u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064a\u0648"
+ },
+ "nb-NO": {
+ "name": "Norsk"
+ },
+ "nl-BE": {
+ "name": "Nederlands"
+ },
+ "nl-NL": {
+ "name": "Nederlands"
+ },
+ "pl-PL": {
+ "name": "Polski"
+ },
+ "pt-AD": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-BR": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-PT": {
+ "name": "Portugu\u00eas"
+ },
+ "ro-RO": {
+ "name": "Rom\u00e2n\u0103"
+ },
+ "ru-RU": {
+ "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ },
+ "sv-SE": {
+ "name": "Svenska"
+ },
+ "th-TH": {
+ "name": "\u0e44\u0e17\u0e22"
+ },
+ "tr-TR": {
+ "name": "T\u00fcrk\u00e7e"
+ }
+ },
+ "qwant images": {
+ "bg-BG": {
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
+ },
+ "br-FR": {
+ "name": "Brezhoneg"
+ },
+ "ca-AD": {
+ "name": "Catal\u00e0"
+ },
+ "ca-ES": {
+ "name": "Catal\u00e0"
+ },
+ "ca-FR": {
+ "name": "Catal\u00e0"
+ },
+ "co-FR": {
+ "name": "Corsu"
+ },
+ "cs-CZ": {
+ "name": "\u010cesky"
+ },
+ "cy-GB": {
+ "name": "Welsh"
+ },
+ "da-DK": {
+ "name": "Dansk"
+ },
+ "de-AT": {
+ "name": "Deutsch"
+ },
+ "de-CH": {
+ "name": "Deutsch"
+ },
+ "de-DE": {
+ "name": "Deutsch"
+ },
+ "el-GR": {
+ "name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
+ },
+ "en-AU": {
+ "name": "English"
+ },
+ "en-CA": {
+ "name": "English"
+ },
+ "en-GB": {
+ "name": "English"
+ },
+ "en-IE": {
+ "name": "English"
+ },
+ "en-IN": {
+ "name": "English"
+ },
+ "en-MY": {
+ "name": "English"
+ },
+ "en-NZ": {
+ "name": "English"
+ },
+ "en-PH": {
+ "name": "English"
+ },
+ "en-SG": {
+ "name": "English"
+ },
+ "en-US": {
+ "name": "English"
+ },
+ "es-AD": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-AR": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-CL": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-ES": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-MX": {
+ "name": "Espa\u00f1ol"
+ },
+ "et-EE": {
+ "name": "Eesti keel"
+ },
+ "eu-ES": {
+ "name": "Euskara"
+ },
+ "eu-FR": {
+ "name": "Euskara"
+ },
+ "fi-FI": {
+ "name": "Suomen kieli"
+ },
+ "fr-AD": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-BE": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CA": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CH": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-FR": {
+ "name": "Fran\u00e7ais"
+ },
+ "gd-GB": {
+ "name": "Scottish"
+ },
+ "he-IL": {
+ "name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
+ },
+ "hu-HU": {
+ "name": "magyar"
+ },
+ "it-CH": {
+ "name": "Italiano"
+ },
+ "it-IT": {
+ "name": "Italiano"
+ },
+ "ja-JP": {
+ "name": "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054)"
+ },
+ "ko-KR": {
+ "name": "\ud55c\uad6d\uc5b4"
+ },
+ "ms-MY": {
+ "name": "\u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064a\u0648"
+ },
+ "nb-NO": {
+ "name": "Norsk"
+ },
+ "nl-BE": {
+ "name": "Nederlands"
+ },
+ "nl-NL": {
+ "name": "Nederlands"
+ },
+ "pl-PL": {
+ "name": "Polski"
+ },
+ "pt-AD": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-BR": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-PT": {
+ "name": "Portugu\u00eas"
+ },
+ "ro-RO": {
+ "name": "Rom\u00e2n\u0103"
+ },
+ "ru-RU": {
+ "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ },
+ "sv-SE": {
+ "name": "Svenska"
+ },
+ "th-TH": {
+ "name": "\u0e44\u0e17\u0e22"
+ },
+ "tr-TR": {
+ "name": "T\u00fcrk\u00e7e"
+ }
+ },
+ "qwant news": {
+ "bg-BG": {
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
+ },
+ "br-FR": {
+ "name": "Brezhoneg"
+ },
+ "ca-AD": {
+ "name": "Catal\u00e0"
+ },
+ "ca-ES": {
+ "name": "Catal\u00e0"
+ },
+ "ca-FR": {
+ "name": "Catal\u00e0"
+ },
+ "co-FR": {
+ "name": "Corsu"
+ },
+ "cs-CZ": {
+ "name": "\u010cesky"
+ },
+ "cy-GB": {
+ "name": "Welsh"
+ },
+ "da-DK": {
+ "name": "Dansk"
+ },
+ "de-AT": {
+ "name": "Deutsch"
+ },
+ "de-CH": {
+ "name": "Deutsch"
+ },
+ "de-DE": {
+ "name": "Deutsch"
+ },
+ "el-GR": {
+ "name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
+ },
+ "en-AU": {
+ "name": "English"
+ },
+ "en-CA": {
+ "name": "English"
+ },
+ "en-GB": {
+ "name": "English"
+ },
+ "en-IE": {
+ "name": "English"
+ },
+ "en-IN": {
+ "name": "English"
+ },
+ "en-MY": {
+ "name": "English"
+ },
+ "en-NZ": {
+ "name": "English"
+ },
+ "en-PH": {
+ "name": "English"
+ },
+ "en-SG": {
+ "name": "English"
+ },
+ "en-US": {
+ "name": "English"
+ },
+ "es-AD": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-AR": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-CL": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-ES": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-MX": {
+ "name": "Espa\u00f1ol"
+ },
+ "et-EE": {
+ "name": "Eesti keel"
+ },
+ "eu-ES": {
+ "name": "Euskara"
+ },
+ "eu-FR": {
+ "name": "Euskara"
+ },
+ "fi-FI": {
+ "name": "Suomen kieli"
+ },
+ "fr-AD": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-BE": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CA": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CH": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-FR": {
+ "name": "Fran\u00e7ais"
+ },
+ "gd-GB": {
+ "name": "Scottish"
+ },
+ "he-IL": {
+ "name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
+ },
+ "hu-HU": {
+ "name": "magyar"
+ },
+ "it-CH": {
+ "name": "Italiano"
+ },
+ "it-IT": {
+ "name": "Italiano"
+ },
+ "ja-JP": {
+ "name": "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054)"
+ },
+ "ko-KR": {
+ "name": "\ud55c\uad6d\uc5b4"
+ },
+ "ms-MY": {
+ "name": "\u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064a\u0648"
+ },
+ "nb-NO": {
+ "name": "Norsk"
+ },
+ "nl-BE": {
+ "name": "Nederlands"
+ },
+ "nl-NL": {
+ "name": "Nederlands"
+ },
+ "pl-PL": {
+ "name": "Polski"
+ },
+ "pt-AD": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-BR": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-PT": {
+ "name": "Portugu\u00eas"
+ },
+ "ro-RO": {
+ "name": "Rom\u00e2n\u0103"
+ },
+ "ru-RU": {
+ "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ },
+ "sv-SE": {
+ "name": "Svenska"
+ },
+ "th-TH": {
+ "name": "\u0e44\u0e17\u0e22"
+ },
+ "tr-TR": {
+ "name": "T\u00fcrk\u00e7e"
+ }
+ },
+ "qwant social": {
+ "bg-BG": {
+ "name": "\u0431\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438 \u0435\u0437\u0438\u043a"
+ },
+ "br-FR": {
+ "name": "Brezhoneg"
+ },
+ "ca-AD": {
+ "name": "Catal\u00e0"
+ },
+ "ca-ES": {
+ "name": "Catal\u00e0"
+ },
+ "ca-FR": {
+ "name": "Catal\u00e0"
+ },
+ "co-FR": {
+ "name": "Corsu"
+ },
+ "cs-CZ": {
+ "name": "\u010cesky"
+ },
+ "cy-GB": {
+ "name": "Welsh"
+ },
+ "da-DK": {
+ "name": "Dansk"
+ },
+ "de-AT": {
+ "name": "Deutsch"
+ },
+ "de-CH": {
+ "name": "Deutsch"
+ },
+ "de-DE": {
+ "name": "Deutsch"
+ },
+ "el-GR": {
+ "name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
+ },
+ "en-AU": {
+ "name": "English"
+ },
+ "en-CA": {
+ "name": "English"
+ },
+ "en-GB": {
+ "name": "English"
+ },
+ "en-IE": {
+ "name": "English"
+ },
+ "en-IN": {
+ "name": "English"
+ },
+ "en-MY": {
+ "name": "English"
+ },
+ "en-NZ": {
+ "name": "English"
+ },
+ "en-PH": {
+ "name": "English"
+ },
+ "en-SG": {
+ "name": "English"
+ },
+ "en-US": {
+ "name": "English"
+ },
+ "es-AD": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-AR": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-CL": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-ES": {
+ "name": "Espa\u00f1ol"
+ },
+ "es-MX": {
+ "name": "Espa\u00f1ol"
+ },
+ "et-EE": {
+ "name": "Eesti keel"
+ },
+ "eu-ES": {
+ "name": "Euskara"
+ },
+ "eu-FR": {
+ "name": "Euskara"
+ },
+ "fi-FI": {
+ "name": "Suomen kieli"
+ },
+ "fr-AD": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-BE": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CA": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-CH": {
+ "name": "Fran\u00e7ais"
+ },
+ "fr-FR": {
+ "name": "Fran\u00e7ais"
+ },
+ "gd-GB": {
+ "name": "Scottish"
+ },
+ "he-IL": {
+ "name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
+ },
+ "hu-HU": {
+ "name": "magyar"
+ },
+ "it-CH": {
+ "name": "Italiano"
+ },
+ "it-IT": {
+ "name": "Italiano"
+ },
+ "ja-JP": {
+ "name": "\u65e5\u672c\u8a9e (\u306b\u307b\u3093\u3054)"
+ },
+ "ko-KR": {
+ "name": "\ud55c\uad6d\uc5b4"
+ },
+ "ms-MY": {
+ "name": "\u0628\u0647\u0627\u0633 \u0645\u0644\u0627\u064a\u0648"
+ },
+ "nb-NO": {
+ "name": "Norsk"
+ },
+ "nl-BE": {
+ "name": "Nederlands"
+ },
+ "nl-NL": {
+ "name": "Nederlands"
+ },
+ "pl-PL": {
+ "name": "Polski"
+ },
+ "pt-AD": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-BR": {
+ "name": "Portugu\u00eas"
+ },
+ "pt-PT": {
+ "name": "Portugu\u00eas"
+ },
+ "ro-RO": {
+ "name": "Rom\u00e2n\u0103"
+ },
+ "ru-RU": {
+ "name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
+ },
+ "sv-SE": {
+ "name": "Svenska"
+ },
+ "th-TH": {
+ "name": "\u0e44\u0e17\u0e22"
+ },
+ "tr-TR": {
+ "name": "T\u00fcrk\u00e7e"
+ }
+ },
+ "startpage": {
+ "af": {
+ "alias": "afrikaans"
+ },
+ "am": {
+ "alias": "amharic"
+ },
+ "ar": {
+ "alias": "arabic"
+ },
+ "az": {
+ "alias": "azerbaijani"
+ },
+ "be": {
+ "alias": "belarusian"
+ },
+ "bg": {
+ "alias": "bulgarian"
+ },
+ "bn": {
+ "alias": "bengali"
+ },
+ "bs": {
+ "alias": "bosnian"
+ },
+ "ca": {
+ "alias": "catalan"
+ },
+ "cs": {
+ "alias": "czech"
+ },
+ "cy": {
+ "alias": "welsh"
+ },
+ "da": {
+ "alias": "dansk"
+ },
+ "de": {
+ "alias": "deutsch"
+ },
+ "el": {
+ "alias": "greek"
+ },
+ "en": {
+ "alias": "english"
+ },
+ "en-GB": {
+ "alias": "english_uk"
+ },
+ "eo": {
+ "alias": "esperanto"
+ },
+ "es": {
+ "alias": "espanol"
+ },
+ "et": {
+ "alias": "estonian"
+ },
+ "eu": {
+ "alias": "basque"
+ },
+ "fa": {
+ "alias": "persian"
+ },
+ "fi": {
+ "alias": "suomi"
+ },
+ "fo": {
+ "alias": "faroese"
+ },
+ "fr": {
+ "alias": "francais"
+ },
+ "fy": {
+ "alias": "frisian"
+ },
+ "ga": {
+ "alias": "irish"
+ },
+ "gd": {
+ "alias": "gaelic"
+ },
+ "gl": {
+ "alias": "galician"
+ },
+ "gu": {
+ "alias": "gujarati"
+ },
+ "he": {
+ "alias": "hebrew"
+ },
+ "hi": {
+ "alias": "hindi"
+ },
+ "hr": {
+ "alias": "croatian"
+ },
+ "hu": {
+ "alias": "hungarian"
+ },
+ "ia": {
+ "alias": "interlingua"
+ },
+ "id": {
+ "alias": "indonesian"
+ },
+ "is": {
+ "alias": "icelandic"
+ },
+ "it": {
+ "alias": "italiano"
+ },
+ "ja": {
+ "alias": "nihongo"
+ },
+ "jv": {
+ "alias": "javanese"
+ },
+ "ka": {
+ "alias": "georgian"
+ },
+ "kn": {
+ "alias": "kannada"
+ },
+ "ko": {
+ "alias": "hangul"
+ },
+ "la": {
+ "alias": "latin"
+ },
+ "lt": {
+ "alias": "lithuanian"
+ },
+ "lv": {
+ "alias": "latvian"
+ },
+ "mai": {
+ "alias": "bihari"
+ },
+ "mk": {
+ "alias": "macedonian"
+ },
+ "ml": {
+ "alias": "malayam"
+ },
+ "mr": {
+ "alias": "marathi"
+ },
+ "ms": {
+ "alias": "malay"
+ },
+ "mt": {
+ "alias": "maltese"
+ },
+ "nb": {
+ "alias": "norsk"
+ },
+ "ne": {
+ "alias": "nepali"
+ },
+ "nl": {
+ "alias": "nederlands"
+ },
+ "oc": {
+ "alias": "occitan"
+ },
+ "pa": {
+ "alias": "punjabi"
+ },
+ "pl": {
+ "alias": "polski"
+ },
+ "pt": {
+ "alias": "portugues"
+ },
+ "ro": {
+ "alias": "romanian"
+ },
+ "ru": {
+ "alias": "russian"
+ },
+ "si": {
+ "alias": "sinhalese"
+ },
+ "sk": {
+ "alias": "slovak"
+ },
+ "sl": {
+ "alias": "slovenian"
+ },
+ "sq": {
+ "alias": "albanian"
+ },
+ "sr": {
+ "alias": "serbian"
+ },
+ "su": {
+ "alias": "sudanese"
+ },
+ "sv": {
+ "alias": "svenska"
+ },
+ "sw": {
+ "alias": "swahili"
+ },
+ "ta": {
+ "alias": "tamil"
+ },
+ "te": {
+ "alias": "telugu"
+ },
+ "th": {
+ "alias": "thai"
+ },
+ "ti": {
+ "alias": "tigrinya"
+ },
+ "tl": {
+ "alias": "tagalog"
+ },
+ "tr": {
+ "alias": "turkce"
+ },
+ "uk": {
+ "alias": "ukrainian"
+ },
+ "ur": {
+ "alias": "urdu"
+ },
+ "uz": {
+ "alias": "uzbek"
+ },
+ "vi": {
+ "alias": "vietnamese"
+ },
+ "xh": {
+ "alias": "xhosa"
+ },
+ "zh": {
+ "alias": "jiantizhongwen"
+ },
+ "zh-HK": {
+ "alias": "fantizhengwen"
+ },
+ "zh-TW": {
+ "alias": "fantizhengwen"
+ },
+ "zu": {
+ "alias": "zulu"
+ }
+ },
"wikidata": {
"ab": {
- "articles": 6031,
+ "articles": 6080,
"english_name": "Abkhazian",
"name": "\u0410\u04a7\u0441\u0443\u0430"
},
"ace": {
- "articles": 10323,
+ "articles": 10353,
"english_name": "Acehnese",
"name": "Bahsa Ac\u00e8h"
},
"ady": {
- "articles": 417,
+ "articles": 421,
"english_name": "Adyghe",
"name": "\u0410\u0434\u044b\u0433\u044d\u0431\u0437\u044d"
},
"af": {
- "articles": 89423,
+ "articles": 93802,
"english_name": "Afrikaans",
"name": "Afrikaans"
},
"ak": {
- "articles": 795,
+ "articles": 879,
"english_name": "Akan",
"name": "Akana"
},
"als": {
- "articles": 27014,
+ "articles": 27329,
"english_name": "Alemannic",
"name": "Alemannisch"
},
"am": {
- "articles": 14831,
+ "articles": 14875,
"english_name": "Amharic",
"name": "\u12a0\u121b\u122d\u129b"
},
"an": {
- "articles": 36741,
+ "articles": 38095,
"english_name": "Aragonese",
"name": "Aragon\u00e9s"
},
"ang": {
- "articles": 3187,
+ "articles": 3294,
"english_name": "Anglo-Saxon",
"name": "Englisc"
},
"ar": {
- "articles": 1031588,
+ "articles": 1065982,
"english_name": "Arabic",
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
},
"arc": {
- "articles": 1647,
+ "articles": 1764,
"english_name": "Aramaic",
"name": "\u0710\u072a\u0721\u071d\u0710"
},
+ "ary": {
+ "articles": 2554,
+ "english_name": "Moroccan Arabic",
+ "name": "\u0627\u0644\u062f\u0627\u0631\u062c\u0629"
+ },
"arz": {
- "articles": 145685,
+ "articles": 1098659,
"english_name": "Egyptian Arabic",
"name": "\u0645\u0635\u0631\u0649 (Ma\u1e63ri)"
},
"as": {
- "articles": 6381,
+ "articles": 7230,
"english_name": "Assamese",
"name": "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be"
},
"ast": {
- "articles": 100187,
+ "articles": 107460,
"english_name": "Asturian",
"name": "Asturianu"
},
"atj": {
- "articles": 1167,
+ "articles": 1259,
"english_name": "Atikamekw",
"name": "Atikamekw"
},
"av": {
- "articles": 2422,
+ "articles": 2451,
"english_name": "Avar",
"name": "\u0410\u0432\u0430\u0440"
},
+ "avk": {
+ "articles": 9484,
+ "english_name": "Kotava",
+ "name": "Kotava"
+ },
+ "awa": {
+ "articles": 2406,
+ "english_name": "Awadhi",
+ "name": "\u0905\u0935\u0927\u0940"
+ },
"ay": {
- "articles": 4646,
+ "articles": 4852,
"english_name": "Aymara",
"name": "Aymar"
},
"az": {
- "articles": 155848,
+ "articles": 173155,
"english_name": "Azerbaijani",
"name": "Az\u0259rbaycanca"
},
"azb": {
- "articles": 183161,
+ "articles": 239463,
"english_name": "South Azerbaijani",
"name": "\u062a\u06c6\u0631\u06a9\u062c\u0647"
},
"ba": {
- "articles": 51161,
+ "articles": 53560,
"english_name": "Bashkir",
"name": "\u0411\u0430\u0448\u04a1\u043e\u0440\u0442"
},
"ban": {
- "articles": 2258,
+ "articles": 3899,
"english_name": "Balinese",
"name": "Bali"
},
"bar": {
- "articles": 30891,
+ "articles": 31394,
"english_name": "Bavarian",
"name": "Boarisch"
},
"bat-smg": {
- "articles": 16858,
+ "articles": 16893,
"english_name": "Samogitian",
"name": "\u017demait\u0117\u0161ka"
},
"bcl": {
- "articles": 9363,
+ "articles": 10546,
"english_name": "Central Bicolano",
"name": "Bikol"
},
"be": {
- "articles": 185723,
+ "articles": 195563,
"english_name": "Belarusian",
"name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
},
"be-tarask": {
- "articles": 69136,
+ "articles": 71188,
"english_name": "Belarusian (Tara\u0161kievica)",
"name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)"
},
"bg": {
- "articles": 260031,
+ "articles": 265773,
"english_name": "Bulgarian",
"name": "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
},
"bh": {
- "articles": 7033,
+ "articles": 7342,
"english_name": "Bhojpuri",
"name": "\u092d\u094b\u091c\u092a\u0941\u0930\u0940"
},
"bi": {
- "articles": 1219,
+ "articles": 1230,
"english_name": "Bislama",
"name": "Bislama"
},
"bjn": {
- "articles": 2973,
+ "articles": 3256,
"english_name": "Banjar",
"name": "Bahasa Banjar"
},
"bm": {
- "articles": 664,
+ "articles": 668,
"english_name": "Bambara",
"name": "Bamanankan"
},
"bn": {
- "articles": 82134,
+ "articles": 94608,
"english_name": "Bengali",
"name": "\u09ac\u09be\u0982\u09b2\u09be"
},
"bo": {
- "articles": 5887,
+ "articles": 5920,
"english_name": "Tibetan",
"name": "\u0f56\u0f7c\u0f51\u0f0b\u0f66\u0f90\u0f51"
},
@@ -25441,147 +26500,147 @@
"name": "\u0987\u09ae\u09be\u09b0 \u09a0\u09be\u09b0/\u09ac\u09bf\u09b7\u09cd\u09a3\u09c1\u09aa\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0"
},
"br": {
- "articles": 67768,
+ "articles": 68639,
"english_name": "Breton",
"name": "Brezhoneg"
},
"bs": {
- "articles": 82109,
+ "articles": 84169,
"english_name": "Bosnian",
"name": "Bosanski"
},
"bug": {
- "articles": 14127,
+ "articles": 14139,
"english_name": "Buginese",
"name": "Basa Ugi"
},
"bxr": {
- "articles": 2163,
+ "articles": 2172,
"english_name": "Buryat",
"name": "\u0411\u0443\u0440\u044f\u0430\u0434"
},
"ca": {
- "articles": 638512,
+ "articles": 657438,
"english_name": "Catalan",
"name": "Catal\u00e0"
},
"cbk-zam": {
- "articles": 3023,
+ "articles": 3092,
"english_name": "Zamboanga Chavacano",
"name": "Chavacano de Zamboanga"
},
"cdo": {
- "articles": 15445,
+ "articles": 15490,
"english_name": "Min Dong",
"name": "M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304"
},
"ce": {
- "articles": 254141,
+ "articles": 288306,
"english_name": "Chechen",
"name": "\u041d\u043e\u0445\u0447\u0438\u0439\u043d"
},
"ceb": {
- "articles": 5378538,
+ "articles": 5337062,
"english_name": "Cebuano",
"name": "Sinugboanong Binisaya"
},
"ch": {
- "articles": 513,
+ "articles": 512,
"english_name": "Chamorro",
"name": "Chamoru"
},
"chr": {
- "articles": 834,
+ "articles": 917,
"english_name": "Cherokee",
"name": "\u13e3\u13b3\u13a9"
},
"chy": {
- "articles": 618,
+ "articles": 619,
"english_name": "Cheyenne",
"name": "Tsets\u00eahest\u00e2hese"
},
"ckb": {
- "articles": 25522,
+ "articles": 26975,
"english_name": "Sorani",
"name": "Soran\u00ee / \u06a9\u0648\u0631\u062f\u06cc"
},
"co": {
- "articles": 5788,
+ "articles": 5824,
"english_name": "Corsican",
"name": "Corsu"
},
"cr": {
- "articles": 104,
+ "articles": 117,
"english_name": "Cree",
"name": "Nehiyaw"
},
"crh": {
- "articles": 7046,
+ "articles": 7713,
"english_name": "Crimean Tatar",
"name": "Q\u0131r\u0131mtatarca"
},
"cs": {
- "articles": 447036,
+ "articles": 462637,
"english_name": "Czech",
"name": "\u010ce\u0161tina"
},
"csb": {
- "articles": 5329,
+ "articles": 5352,
"english_name": "Kashubian",
"name": "Kasz\u00ebbsczi"
},
"cu": {
- "articles": 702,
+ "articles": 743,
"english_name": "Old Church Slavonic",
"name": "\u0421\u043b\u043e\u0432\u0463\u043d\u044c\u0441\u043a\u044a"
},
"cv": {
- "articles": 42681,
+ "articles": 43604,
"english_name": "Chuvash",
"name": "\u0427\u0103\u0432\u0430\u0448"
},
"cy": {
- "articles": 107176,
+ "articles": 131787,
"english_name": "Welsh",
"name": "Cymraeg"
},
"da": {
- "articles": 257264,
+ "articles": 261215,
"english_name": "Danish",
"name": "Dansk"
},
"de": {
- "articles": 2402917,
+ "articles": 2481560,
"english_name": "German",
"name": "Deutsch"
},
"din": {
- "articles": 122,
+ "articles": 116,
"english_name": "Dinka",
"name": "Thu\u0254\u014bj\u00e4\u014b"
},
"diq": {
- "articles": 13329,
+ "articles": 31162,
"english_name": "Zazaki",
"name": "Zazaki"
},
"dsb": {
- "articles": 3251,
+ "articles": 3279,
"english_name": "Lower Sorbian",
"name": "Dolnoserbski"
},
"dty": {
- "articles": 3242,
+ "articles": 3287,
"english_name": "Doteli",
"name": "\u0921\u094b\u091f\u0947\u0932\u0940"
},
"dv": {
- "articles": 3002,
+ "articles": 2958,
"english_name": "Divehi",
"name": "\u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0"
},
"dz": {
- "articles": 222,
+ "articles": 219,
"english_name": "Dzongkha",
"name": "\u0f47\u0f7c\u0f44\u0f0b\u0f41"
},
@@ -25591,102 +26650,102 @@
"name": "E\u028begbe"
},
"el": {
- "articles": 174096,
+ "articles": 181844,
"english_name": "Greek",
"name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
},
"eml": {
- "articles": 12321,
+ "articles": 12521,
"english_name": "Emilian-Romagnol",
"name": "Emili\u00e0n e rumagn\u00f2l"
},
"en": {
- "articles": 6023622,
+ "articles": 6161541,
"english_name": "English",
"name": "English"
},
"eo": {
- "articles": 275593,
+ "articles": 285283,
"english_name": "Esperanto",
"name": "Esperanto"
},
"es": {
- "articles": 1579723,
+ "articles": 1627598,
"english_name": "Spanish",
"name": "Espa\u00f1ol"
},
"et": {
- "articles": 206326,
+ "articles": 212088,
"english_name": "Estonian",
"name": "Eesti"
},
"eu": {
- "articles": 351277,
+ "articles": 364789,
"english_name": "Basque",
"name": "Euskara"
},
"ext": {
- "articles": 3180,
+ "articles": 3222,
"english_name": "Extremaduran",
"name": "Estreme\u00f1u"
},
"fa": {
- "articles": 712079,
+ "articles": 746175,
"english_name": "Persian",
"name": "\u0641\u0627\u0631\u0633\u06cc"
},
"ff": {
- "articles": 238,
+ "articles": 272,
"english_name": "Fula",
"name": "Fulfulde"
},
"fi": {
- "articles": 479513,
+ "articles": 493428,
"english_name": "Finnish",
"name": "Suomi"
},
"fiu-vro": {
- "articles": 5533,
+ "articles": 5589,
"english_name": "V\u00f5ro",
"name": "V\u00f5ro"
},
"fj": {
- "articles": 780,
+ "articles": 1070,
"english_name": "Fijian",
"name": "Na Vosa Vakaviti"
},
"fo": {
- "articles": 13305,
+ "articles": 13378,
"english_name": "Faroese",
"name": "F\u00f8royskt"
},
"fr": {
- "articles": 2184872,
+ "articles": 2250872,
"english_name": "French",
"name": "Fran\u00e7ais"
},
"frp": {
- "articles": 3529,
+ "articles": 4080,
"english_name": "Franco-Proven\u00e7al",
"name": "Arpitan"
},
"frr": {
- "articles": 10273,
+ "articles": 11200,
"english_name": "North Frisian",
"name": "Nordfriisk"
},
"fur": {
- "articles": 3338,
+ "articles": 3419,
"english_name": "Friulian",
"name": "Furlan"
},
"fy": {
- "articles": 43513,
+ "articles": 44493,
"english_name": "West Frisian",
"name": "Frysk"
},
"ga": {
- "articles": 52203,
+ "articles": 53585,
"english_name": "Irish",
"name": "Gaeilge"
},
@@ -25696,137 +26755,137 @@
"name": "Gagauz"
},
"gan": {
- "articles": 6430,
+ "articles": 6435,
"english_name": "Gan",
"name": "\u8d1b\u8a9e"
},
"gcr": {
- "articles": 1001,
+ "articles": 1033,
"english_name": "Guianan Creole",
"name": "Kriy\u00f2l Gwiyannen"
},
"gd": {
- "articles": 15062,
+ "articles": 15136,
"english_name": "Scottish Gaelic",
"name": "G\u00e0idhlig"
},
"gl": {
- "articles": 161843,
+ "articles": 166957,
"english_name": "Galician",
"name": "Galego"
},
"glk": {
- "articles": 5931,
+ "articles": 6029,
"english_name": "Gilaki",
"name": "\u06af\u06cc\u0644\u06a9\u06cc"
},
"gn": {
- "articles": 3763,
+ "articles": 3863,
"english_name": "Guarani",
"name": "Ava\u00f1e'\u1ebd"
},
"gom": {
- "articles": 3723,
+ "articles": 3719,
"english_name": "Goan Konkani",
"name": "\u0917\u094b\u0902\u092f\u091a\u0940 \u0915\u094b\u0902\u0915\u0923\u0940 / G\u00f5ychi Konknni"
},
"gor": {
- "articles": 2542,
+ "articles": 9012,
"english_name": "Gorontalo",
"name": "Hulontalo"
},
"got": {
- "articles": 825,
+ "articles": 829,
"english_name": "Gothic",
"name": "\ud800\udf32\ud800\udf3f\ud800\udf44\ud800\udf39\ud800\udf43\ud800\udf3a"
},
"gu": {
- "articles": 28880,
+ "articles": 29088,
"english_name": "Gujarati",
"name": "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0"
},
"gv": {
- "articles": 4996,
+ "articles": 5010,
"english_name": "Manx",
"name": "Gaelg"
},
"ha": {
- "articles": 4631,
+ "articles": 5321,
"english_name": "Hausa",
"name": "Hausa / \u0647\u064e\u0648\u064f\u0633\u064e"
},
"hak": {
- "articles": 9277,
+ "articles": 9366,
"english_name": "Hakka",
"name": "Hak-k\u00e2-fa / \u5ba2\u5bb6\u8a71"
},
"haw": {
- "articles": 3862,
+ "articles": 2265,
"english_name": "Hawaiian",
"name": "Hawai`i"
},
"he": {
- "articles": 259224,
+ "articles": 275788,
"english_name": "Hebrew",
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
},
"hi": {
- "articles": 136564,
+ "articles": 141828,
"english_name": "Hindi",
"name": "\u0939\u093f\u0928\u094d\u0926\u0940"
},
"hif": {
- "articles": 9774,
+ "articles": 9797,
"english_name": "Fiji Hindi",
"name": "Fiji Hindi"
},
"hr": {
- "articles": 215457,
+ "articles": 222117,
"english_name": "Croatian",
"name": "Hrvatski"
},
"hsb": {
- "articles": 13546,
+ "articles": 13598,
"english_name": "Upper Sorbian",
"name": "Hornjoserbsce"
},
"ht": {
- "articles": 57995,
+ "articles": 59897,
"english_name": "Haitian",
"name": "Kr\u00e8yol ayisyen"
},
"hu": {
- "articles": 465402,
+ "articles": 475889,
"english_name": "Hungarian",
"name": "Magyar"
},
"hy": {
- "articles": 264666,
+ "articles": 275577,
"english_name": "Armenian",
"name": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576"
},
"hyw": {
- "articles": 7830,
+ "articles": 8406,
"english_name": "Western Armenian",
"name": "\u0531\u0580\u0565\u0582\u0574\u057f\u0561\u0570\u0561\u0575\u0565\u0580\u0567\u0576"
},
"ia": {
- "articles": 22095,
+ "articles": 22551,
"english_name": "Interlingua",
"name": "Interlingua"
},
"id": {
- "articles": 521569,
+ "articles": 545873,
"english_name": "Indonesian",
"name": "Bahasa Indonesia"
},
"ie": {
- "articles": 4723,
+ "articles": 5079,
"english_name": "Interlingue",
"name": "Interlingue"
},
"ig": {
- "articles": 1448,
+ "articles": 1533,
"english_name": "Igbo",
"name": "Igbo"
},
@@ -25836,112 +26895,112 @@
"name": "I\u00f1upiak"
},
"ilo": {
- "articles": 14221,
+ "articles": 15249,
"english_name": "Ilokano",
"name": "Ilokano"
},
"inh": {
- "articles": 1225,
+ "articles": 1478,
"english_name": "Ingush",
"name": "\u0413\u04cf\u0430\u043b\u0433\u04cf\u0430\u0439"
},
"io": {
- "articles": 29252,
+ "articles": 29785,
"english_name": "Ido",
"name": "Ido"
},
"is": {
- "articles": 49128,
+ "articles": 50516,
"english_name": "Icelandic",
"name": "\u00cdslenska"
},
"it": {
- "articles": 1585945,
+ "articles": 1636112,
"english_name": "Italian",
"name": "Italiano"
},
"iu": {
- "articles": 403,
+ "articles": 472,
"english_name": "Inuktitut",
"name": "\u1403\u14c4\u1483\u144e\u1450\u1466"
},
"ja": {
- "articles": 1192319,
+ "articles": 1228979,
"english_name": "Japanese",
"name": "\u65e5\u672c\u8a9e"
},
"jam": {
- "articles": 1648,
+ "articles": 1660,
"english_name": "Jamaican Patois",
"name": "Jumiekan Kryuol"
},
"jbo": {
- "articles": 1251,
+ "articles": 1256,
"english_name": "Lojban",
"name": "Lojban"
},
"jv": {
- "articles": 57275,
+ "articles": 58065,
"english_name": "Javanese",
"name": "Basa Jawa"
},
"ka": {
- "articles": 135269,
+ "articles": 140486,
"english_name": "Georgian",
"name": "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8"
},
"kaa": {
- "articles": 1883,
+ "articles": 1865,
"english_name": "Karakalpak",
"name": "Qaraqalpaqsha"
},
"kab": {
- "articles": 4508,
+ "articles": 4832,
"english_name": "Kabyle",
"name": "Taqbaylit"
},
"kbd": {
- "articles": 1584,
+ "articles": 1586,
"english_name": "Kabardian Circassian",
"name": "\u0410\u0434\u044b\u0433\u044d\u0431\u0437\u044d (Adighabze)"
},
"kbp": {
- "articles": 1603,
+ "articles": 1612,
"english_name": "Kabiye",
"name": "Kab\u0269y\u025b"
},
"kg": {
- "articles": 1197,
+ "articles": 1212,
"english_name": "Kongo",
"name": "KiKongo"
},
"ki": {
- "articles": 1368,
+ "articles": 1366,
"english_name": "Kikuyu",
"name": "G\u0129k\u0169y\u0169"
},
"kk": {
- "articles": 226239,
+ "articles": 227051,
"english_name": "Kazakh",
"name": "\u049a\u0430\u0437\u0430\u049b\u0448\u0430"
},
"kl": {
- "articles": 1669,
+ "articles": 833,
"english_name": "Greenlandic",
"name": "Kalaallisut"
},
"km": {
- "articles": 7994,
+ "articles": 8292,
"english_name": "Khmer",
"name": "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"
},
"kn": {
- "articles": 25796,
+ "articles": 26549,
"english_name": "Kannada",
"name": "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1"
},
"ko": {
- "articles": 485688,
+ "articles": 520943,
"english_name": "Korean",
"name": "\ud55c\uad6d\uc5b4"
},
@@ -25951,482 +27010,487 @@
"name": "\u041f\u0435\u0440\u0435\u043c \u041a\u043e\u043c\u0438 (Perem Komi)"
},
"krc": {
- "articles": 2037,
+ "articles": 2048,
"english_name": "Karachay-Balkar",
"name": "\u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440 (Qarachay-Malqar)"
},
"ks": {
- "articles": 368,
+ "articles": 422,
"english_name": "Kashmiri",
"name": "\u0915\u0936\u094d\u092e\u0940\u0930\u0940 / \u0643\u0634\u0645\u064a\u0631\u064a"
},
"ksh": {
- "articles": 2861,
+ "articles": 2878,
"english_name": "Ripuarian",
"name": "Ripoarisch"
},
"ku": {
- "articles": 26872,
+ "articles": 31973,
"english_name": "Kurdish",
"name": "Kurd\u00ee / \u0643\u0648\u0631\u062f\u06cc"
},
"kv": {
- "articles": 5333,
+ "articles": 5347,
"english_name": "Komi",
"name": "\u041a\u043e\u043c\u0438"
},
"kw": {
- "articles": 3939,
+ "articles": 4196,
"english_name": "Cornish",
"name": "Kernewek/Karnuack"
},
"ky": {
- "articles": 79759,
+ "articles": 80385,
"english_name": "Kirghiz",
"name": "\u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430"
},
"la": {
- "articles": 132249,
+ "articles": 133666,
"english_name": "Latin",
"name": "Latina"
},
"lad": {
- "articles": 3545,
+ "articles": 3554,
"english_name": "Ladino",
"name": "Dzhudezmo"
},
"lb": {
- "articles": 57817,
+ "articles": 58769,
"english_name": "Luxembourgish",
"name": "L\u00ebtzebuergesch"
},
"lbe": {
- "articles": 1220,
+ "articles": 1223,
"english_name": "Lak",
"name": "\u041b\u0430\u043a\u043a\u0443"
},
"lez": {
- "articles": 4057,
+ "articles": 4109,
"english_name": "Lezgian",
"name": "\u041b\u0435\u0437\u0433\u0438 \u0447\u0406\u0430\u043b (Lezgi \u010d\u2019al)"
},
"lfn": {
- "articles": 3723,
+ "articles": 3983,
"english_name": "Lingua Franca Nova",
"name": "Lingua franca nova"
},
"lg": {
- "articles": 1178,
+ "articles": 1197,
"english_name": "Luganda",
"name": "Luganda"
},
"li": {
- "articles": 12737,
+ "articles": 13098,
"english_name": "Limburgish",
"name": "Limburgs"
},
"lij": {
- "articles": 3682,
+ "articles": 4277,
"english_name": "Ligurian",
"name": "L\u00edguru"
},
+ "lld": {
+ "articles": 916,
+ "english_name": "Ladin",
+ "name": "Ladin"
+ },
"lmo": {
- "articles": 39359,
+ "articles": 42884,
"english_name": "Lombard",
"name": "Lumbaart"
},
"ln": {
- "articles": 3136,
+ "articles": 3175,
"english_name": "Lingala",
"name": "Lingala"
},
"lo": {
- "articles": 3545,
+ "articles": 3566,
"english_name": "Lao",
"name": "\u0ea5\u0eb2\u0ea7"
},
"lrc": {
- "articles": 5360,
+ "articles": 5714,
"english_name": "Northern Luri",
"name": "\u0644\u06ca\u0631\u06cc \u0634\u0648\u0645\u0627\u0644\u06cc"
},
"lt": {
- "articles": 198453,
+ "articles": 200796,
"english_name": "Lithuanian",
"name": "Lietuvi\u0173"
},
"ltg": {
- "articles": 932,
+ "articles": 1001,
"english_name": "Latgalian",
"name": "Latga\u013cu"
},
"lv": {
- "articles": 100417,
+ "articles": 103239,
"english_name": "Latvian",
"name": "Latvie\u0161u"
},
"mai": {
- "articles": 13512,
+ "articles": 13600,
"english_name": "Maithili",
"name": "\u092e\u0948\u0925\u093f\u0932\u0940"
},
"map-bms": {
- "articles": 13344,
+ "articles": 13382,
"english_name": "Banyumasan",
"name": "Basa Banyumasan"
},
"mdf": {
- "articles": 1192,
+ "articles": 1196,
"english_name": "Moksha",
"name": "\u041c\u043e\u043a\u0448\u0435\u043d\u044c (Mokshanj K\u00e4lj)"
},
"mg": {
- "articles": 92711,
+ "articles": 93211,
"english_name": "Malagasy",
"name": "Malagasy"
},
"mhr": {
- "articles": 10108,
+ "articles": 10204,
"english_name": "Meadow Mari",
"name": "\u041e\u043b\u044b\u043a \u041c\u0430\u0440\u0438\u0439 (Olyk Marij)"
},
"mi": {
- "articles": 7159,
+ "articles": 7166,
"english_name": "Maori",
"name": "M\u0101ori"
},
"min": {
- "articles": 223738,
+ "articles": 224076,
"english_name": "Minangkabau",
"name": "Minangkabau"
},
"mk": {
- "articles": 104303,
+ "articles": 108023,
"english_name": "Macedonian",
"name": "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438"
},
"ml": {
- "articles": 67743,
+ "articles": 70483,
"english_name": "Malayalam",
"name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02"
},
"mn": {
- "articles": 19010,
+ "articles": 19621,
"english_name": "Mongolian",
"name": "\u041c\u043e\u043d\u0433\u043e\u043b"
},
"mnw": {
- "articles": 470,
+ "articles": 642,
"english_name": "Mon",
"name": "\u1019\u1014\u103a"
},
"mr": {
- "articles": 56283,
+ "articles": 61619,
"english_name": "Marathi",
"name": "\u092e\u0930\u093e\u0920\u0940"
},
"mrj": {
- "articles": 10270,
+ "articles": 10275,
"english_name": "Hill Mari",
"name": "\u041a\u044b\u0440\u044b\u043a \u041c\u0430\u0440\u044b (Kyryk Mary)"
},
"ms": {
- "articles": 334930,
+ "articles": 343278,
"english_name": "Malay",
"name": "Bahasa Melayu"
},
"mt": {
- "articles": 3442,
+ "articles": 3614,
"english_name": "Maltese",
"name": "Malti"
},
"mwl": {
- "articles": 3783,
+ "articles": 3828,
"english_name": "Mirandese",
"name": "Mirand\u00e9s"
},
"my": {
- "articles": 45399,
+ "articles": 47334,
"english_name": "Burmese",
"name": "\u1019\u103c\u1014\u103a\u1019\u102c\u1018\u102c\u101e\u102c"
},
"myv": {
- "articles": 5871,
+ "articles": 6196,
"english_name": "Erzya",
"name": "\u042d\u0440\u0437\u044f\u043d\u044c (Erzjanj Kelj)"
},
"mzn": {
- "articles": 13127,
+ "articles": 13157,
"english_name": "Mazandarani",
"name": "\u0645\u064e\u0632\u0650\u0631\u0648\u0646\u064a"
},
"na": {
- "articles": 1309,
+ "articles": 1483,
"english_name": "Nauruan",
"name": "dorerin Naoero"
},
"nah": {
- "articles": 6976,
+ "articles": 7003,
"english_name": "Nahuatl",
"name": "N\u0101huatl"
},
"nap": {
- "articles": 14561,
+ "articles": 14609,
"english_name": "Neapolitan",
"name": "Nnapulitano"
},
"nds": {
- "articles": 61186,
+ "articles": 75834,
"english_name": "Low Saxon",
"name": "Plattd\u00fc\u00fctsch"
},
"nds-nl": {
- "articles": 6935,
+ "articles": 7082,
"english_name": "Dutch Low Saxon",
"name": "Nedersaksisch"
},
"ne": {
- "articles": 34031,
+ "articles": 33466,
"english_name": "Nepali",
"name": "\u0928\u0947\u092a\u093e\u0932\u0940"
},
"new": {
- "articles": 72233,
+ "articles": 72289,
"english_name": "Newar",
"name": "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e"
},
"nl": {
- "articles": 1998535,
+ "articles": 2032886,
"english_name": "Dutch",
"name": "Nederlands"
},
"nn": {
- "articles": 151775,
+ "articles": 154370,
"english_name": "Norwegian (Nynorsk)",
"name": "Nynorsk"
},
"no": {
- "articles": 529258,
+ "articles": 546147,
"english_name": "Norwegian (Bokm\u00e5l)",
"name": "Norsk (Bokm\u00e5l)"
},
"nov": {
- "articles": 1671,
+ "articles": 1679,
"english_name": "Novial",
"name": "Novial"
},
"nqo": {
- "articles": 546,
+ "articles": 718,
"english_name": "N\u2019Ko",
"name": "\u07d2\u07de\u07cf"
},
"nrm": {
- "articles": 4332,
+ "articles": 4515,
"english_name": "Norman",
"name": "Nouormand/Normaund"
},
"nso": {
- "articles": 8175,
+ "articles": 8205,
"english_name": "Northern Sotho",
"name": "Sepedi"
},
"nv": {
- "articles": 12264,
+ "articles": 15865,
"english_name": "Navajo",
"name": "Din\u00e9 bizaad"
},
"ny": {
- "articles": 565,
+ "articles": 733,
"english_name": "Chichewa",
"name": "Chichewa"
},
"oc": {
- "articles": 87871,
+ "articles": 86161,
"english_name": "Occitan",
"name": "Occitan"
},
"olo": {
- "articles": 3236,
+ "articles": 3403,
"english_name": "Livvi-Karelian",
"name": "Karjalan"
},
"om": {
- "articles": 786,
+ "articles": 847,
"english_name": "Oromo",
"name": "Oromoo"
},
"or": {
- "articles": 15579,
+ "articles": 15917,
"english_name": "Oriya",
"name": "\u0b13\u0b21\u0b3c\u0b3f\u0b06"
},
"os": {
- "articles": 11884,
+ "articles": 12458,
"english_name": "Ossetian",
"name": "\u0418\u0440\u043e\u043d\u0430\u0443"
},
"pa": {
- "articles": 33858,
+ "articles": 34752,
"english_name": "Punjabi",
"name": "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40"
},
"pag": {
- "articles": 2531,
+ "articles": 2663,
"english_name": "Pangasinan",
"name": "Pangasinan"
},
"pam": {
- "articles": 8637,
+ "articles": 8695,
"english_name": "Kapampangan",
"name": "Kapampangan"
},
"pap": {
- "articles": 1941,
+ "articles": 2002,
"english_name": "Papiamentu",
"name": "Papiamentu"
},
"pcd": {
- "articles": 4666,
+ "articles": 4865,
"english_name": "Picard",
"name": "Picard"
},
"pdc": {
- "articles": 1877,
+ "articles": 1894,
"english_name": "Pennsylvania German",
"name": "Deitsch"
},
"pfl": {
- "articles": 2647,
+ "articles": 2678,
"english_name": "Palatinate German",
"name": "P\u00e4lzisch"
},
"pi": {
- "articles": 2540,
+ "articles": 2543,
"english_name": "Pali",
"name": "\u092a\u093e\u0934\u093f"
},
"pih": {
- "articles": 796,
+ "articles": 803,
"english_name": "Norfolk",
"name": "Norfuk"
},
"pl": {
- "articles": 1386843,
+ "articles": 1427892,
"english_name": "Polish",
"name": "Polski"
},
"pms": {
- "articles": 64598,
+ "articles": 64812,
"english_name": "Piedmontese",
"name": "Piemont\u00e8is"
},
"pnb": {
- "articles": 52557,
+ "articles": 53656,
"english_name": "Western Punjabi",
"name": "\u0634\u0627\u06c1 \u0645\u06a9\u06be\u06cc \u067e\u0646\u062c\u0627\u0628\u06cc (Sh\u0101hmukh\u012b Pa\u00f1j\u0101b\u012b)"
},
"pnt": {
- "articles": 467,
+ "articles": 469,
"english_name": "Pontic",
"name": "\u03a0\u03bf\u03bd\u03c4\u03b9\u03b1\u03ba\u03ac"
},
"ps": {
- "articles": 10997,
+ "articles": 11544,
"english_name": "Pashto",
"name": "\u067e\u069a\u062a\u0648"
},
"pt": {
- "articles": 1021915,
+ "articles": 1043641,
"english_name": "Portuguese",
"name": "Portugu\u00eas"
},
"qu": {
- "articles": 21801,
+ "articles": 22691,
"english_name": "Quechua",
"name": "Runa Simi"
},
"rm": {
- "articles": 3646,
+ "articles": 3695,
"english_name": "Romansh",
"name": "Rumantsch"
},
"rmy": {
- "articles": 675,
+ "articles": 676,
"english_name": "Romani",
"name": "romani - \u0930\u094b\u092e\u093e\u0928\u0940"
},
"rn": {
- "articles": 615,
+ "articles": 616,
"english_name": "Kirundi",
"name": "Kirundi"
},
"ro": {
- "articles": 404592,
+ "articles": 412071,
"english_name": "Romanian",
"name": "Rom\u00e2n\u0103"
},
"roa-rup": {
- "articles": 1225,
+ "articles": 1233,
"english_name": "Aromanian",
"name": "Arm\u00e3neashce"
},
"roa-tara": {
- "articles": 9249,
+ "articles": 9302,
"english_name": "Tarantino",
"name": "Tarand\u00edne"
},
"ru": {
- "articles": 1600812,
+ "articles": 1661738,
"english_name": "Russian",
"name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
},
"rue": {
- "articles": 7447,
+ "articles": 7813,
"english_name": "Rusyn",
"name": "\u0420\u0443\u0441\u0438\u043d\u044c\u0441\u043a\u044b\u0439"
},
"rw": {
- "articles": 1820,
+ "articles": 1852,
"english_name": "Kinyarwanda",
"name": "Ikinyarwanda"
},
"sa": {
- "articles": 11456,
+ "articles": 11462,
"english_name": "Sanskrit",
"name": "\u0938\u0902\u0938\u094d\u0915\u0943\u0924\u092e\u094d"
},
"sah": {
- "articles": 12199,
+ "articles": 12759,
"english_name": "Sakha",
"name": "\u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430 (Saxa Tyla)"
},
"sat": {
- "articles": 2470,
+ "articles": 4535,
"english_name": "Santali",
"name": "\u1c65\u1c5f\u1c71\u1c5b\u1c5f\u1c72\u1c64"
},
"sc": {
- "articles": 6371,
+ "articles": 6686,
"english_name": "Sardinian",
"name": "Sardu"
},
"scn": {
- "articles": 26074,
+ "articles": 26058,
"english_name": "Sicilian",
"name": "Sicilianu"
},
"sco": {
- "articles": 56578,
+ "articles": 56568,
"english_name": "Scots",
"name": "Scots"
},
"sd": {
- "articles": 12956,
+ "articles": 13687,
"english_name": "Sindhi",
"name": "\u0633\u0646\u068c\u064a\u060c \u0633\u0646\u062f\u06be\u06cc \u060c \u0938\u093f\u0928\u094d\u0927"
},
"se": {
- "articles": 7612,
+ "articles": 7695,
"english_name": "Northern Sami",
"name": "S\u00e1megiella"
},
@@ -26436,297 +27500,297 @@
"name": "S\u00e4ng\u00f6"
},
"sh": {
- "articles": 451031,
+ "articles": 452863,
"english_name": "Serbo-Croatian",
"name": "Srpskohrvatski / \u0421\u0440\u043f\u0441\u043a\u043e\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438"
},
"shn": {
- "articles": 6745,
+ "articles": 7293,
"english_name": "Shan",
"name": "\u101c\u102d\u1075\u103a\u1088\u1010\u1086\u1038"
},
"si": {
- "articles": 15543,
+ "articles": 15855,
"english_name": "Sinhalese",
"name": "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd"
},
"simple": {
- "articles": 155539,
+ "articles": 172453,
"english_name": "Simple English",
"name": "Simple English"
},
"sk": {
- "articles": 232538,
+ "articles": 234573,
"english_name": "Slovak",
"name": "Sloven\u010dina"
},
"sl": {
- "articles": 167090,
+ "articles": 169414,
"english_name": "Slovenian",
"name": "Sloven\u0161\u010dina"
},
"sm": {
- "articles": 823,
+ "articles": 855,
"english_name": "Samoan",
"name": "Gagana Samoa"
},
"sn": {
- "articles": 4996,
+ "articles": 5991,
"english_name": "Shona",
"name": "chiShona"
},
"so": {
- "articles": 5752,
+ "articles": 5805,
"english_name": "Somali",
"name": "Soomaali"
},
"sq": {
- "articles": 78674,
+ "articles": 81381,
"english_name": "Albanian",
"name": "Shqip"
},
"sr": {
- "articles": 630590,
+ "articles": 638284,
"english_name": "Serbian",
"name": "\u0421\u0440\u043f\u0441\u043a\u0438 / Srpski"
},
"srn": {
- "articles": 1076,
+ "articles": 1070,
"english_name": "Sranan",
"name": "Sranantongo"
},
"ss": {
- "articles": 504,
+ "articles": 518,
"english_name": "Swati",
"name": "SiSwati"
},
"st": {
- "articles": 656,
+ "articles": 768,
"english_name": "Sesotho",
"name": "Sesotho"
},
"stq": {
- "articles": 4017,
+ "articles": 4025,
"english_name": "Saterland Frisian",
"name": "Seeltersk"
},
"su": {
- "articles": 59863,
+ "articles": 60527,
"english_name": "Sundanese",
"name": "Basa Sunda"
},
"sv": {
- "articles": 3738262,
+ "articles": 3675733,
"english_name": "Swedish",
"name": "Svenska"
},
"sw": {
- "articles": 55888,
+ "articles": 60346,
"english_name": "Swahili",
"name": "Kiswahili"
},
"szl": {
- "articles": 51946,
+ "articles": 52432,
"english_name": "Silesian",
"name": "\u015al\u016fnski"
},
"szy": {
- "articles": 1748,
+ "articles": 1812,
"english_name": "Sakizaya",
"name": "Sakizaya"
},
"ta": {
- "articles": 127284,
+ "articles": 131072,
"english_name": "Tamil",
"name": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
},
"tcy": {
- "articles": 1271,
+ "articles": 1397,
"english_name": "Tulu",
"name": "\u0ca4\u0cc1\u0cb3\u0cc1"
},
"te": {
- "articles": 70262,
+ "articles": 69631,
"english_name": "Telugu",
"name": "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41"
},
"tet": {
- "articles": 1475,
+ "articles": 1479,
"english_name": "Tetum",
"name": "Tetun"
},
"tg": {
- "articles": 100460,
+ "articles": 101656,
"english_name": "Tajik",
"name": "\u0422\u043e\u04b7\u0438\u043a\u04e3"
},
"th": {
- "articles": 135321,
+ "articles": 139928,
"english_name": "Thai",
"name": "\u0e44\u0e17\u0e22"
},
"ti": {
- "articles": 202,
+ "articles": 195,
"english_name": "Tigrinya",
"name": "\u1275\u130d\u122d\u129b"
},
"tk": {
- "articles": 5656,
+ "articles": 5821,
"english_name": "Turkmen",
"name": "T\u00fcrkmen"
},
"tl": {
- "articles": 75674,
+ "articles": 68568,
"english_name": "Tagalog",
"name": "Tagalog"
},
"tn": {
- "articles": 710,
+ "articles": 712,
"english_name": "Tswana",
"name": "Setswana"
},
"to": {
- "articles": 1738,
+ "articles": 1740,
"english_name": "Tongan",
"name": "faka Tonga"
},
"tpi": {
- "articles": 1608,
+ "articles": 1625,
"english_name": "Tok Pisin",
"name": "Tok Pisin"
},
"tr": {
- "articles": 343072,
+ "articles": 365938,
"english_name": "Turkish",
"name": "T\u00fcrk\u00e7e"
},
"ts": {
- "articles": 683,
+ "articles": 700,
"english_name": "Tsonga",
"name": "Xitsonga"
},
"tt": {
- "articles": 89002,
+ "articles": 136712,
"english_name": "Tatar",
"name": "Tatar\u00e7a / \u0422\u0430\u0442\u0430\u0440\u0447\u0430"
},
"tum": {
- "articles": 586,
+ "articles": 588,
"english_name": "Tumbuka",
"name": "chiTumbuka"
},
"tw": {
- "articles": 705,
+ "articles": 708,
"english_name": "Twi",
"name": "Twi"
},
"ty": {
- "articles": 1204,
+ "articles": 1208,
"english_name": "Tahitian",
"name": "Reo M\u0101`ohi"
},
"tyv": {
- "articles": 1987,
+ "articles": 2704,
"english_name": "Tuvan",
"name": "\u0422\u044b\u0432\u0430"
},
"udm": {
- "articles": 4848,
+ "articles": 4948,
"english_name": "Udmurt",
"name": "\u0423\u0434\u043c\u0443\u0440\u0442 \u043a\u044b\u043b"
},
"ug": {
- "articles": 4244,
+ "articles": 4364,
"english_name": "Uyghur",
"name": "\u0626\u06c7\u064a\u063a\u06c7\u0631 \u062a\u0649\u0644\u0649"
},
"uk": {
- "articles": 993357,
+ "articles": 1044506,
"english_name": "Ukrainian",
"name": "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
},
"ur": {
- "articles": 151971,
+ "articles": 157319,
"english_name": "Urdu",
"name": "\u0627\u0631\u062f\u0648"
},
"uz": {
- "articles": 133433,
+ "articles": 136238,
"english_name": "Uzbek",
"name": "O\u2018zbek"
},
"ve": {
- "articles": 368,
+ "articles": 370,
"english_name": "Venda",
"name": "Tshivenda"
},
"vec": {
- "articles": 19577,
+ "articles": 62971,
"english_name": "Venetian",
"name": "V\u00e8neto"
},
"vep": {
- "articles": 6395,
+ "articles": 6601,
"english_name": "Vepsian",
"name": "Veps\u00e4n"
},
"vi": {
- "articles": 1241042,
+ "articles": 1255776,
"english_name": "Vietnamese",
"name": "Ti\u1ebfng Vi\u1ec7t"
},
"vls": {
- "articles": 7079,
+ "articles": 7225,
"english_name": "West Flemish",
"name": "West-Vlams"
},
"vo": {
- "articles": 124156,
+ "articles": 125021,
"english_name": "Volap\u00fck",
"name": "Volap\u00fck"
},
"wa": {
- "articles": 15627,
+ "articles": 14141,
"english_name": "Walloon",
"name": "Walon"
},
"war": {
- "articles": 1263934,
+ "articles": 1264408,
"english_name": "Waray-Waray",
"name": "Winaray"
},
"wo": {
- "articles": 1387,
+ "articles": 1421,
"english_name": "Wolof",
"name": "Wolof"
},
"wuu": {
- "articles": 28716,
+ "articles": 39058,
"english_name": "Wu",
"name": "\u5434\u8bed"
},
"xal": {
- "articles": 2082,
+ "articles": 2085,
"english_name": "Kalmyk",
"name": "\u0425\u0430\u043b\u044c\u043c\u0433"
},
"xh": {
- "articles": 1043,
+ "articles": 1057,
"english_name": "Xhosa",
"name": "isiXhosa"
},
"xmf": {
- "articles": 13670,
+ "articles": 14930,
"english_name": "Mingrelian",
"name": "\u10db\u10d0\u10e0\u10d2\u10d0\u10da\u10e3\u10e0\u10d8 (Margaluri)"
},
"yi": {
- "articles": 14999,
+ "articles": 14885,
"english_name": "Yiddish",
"name": "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9"
},
"yo": {
- "articles": 32321,
+ "articles": 32714,
"english_name": "Yoruba",
"name": "Yor\u00f9b\u00e1"
},
@@ -26736,199 +27800,214 @@
"name": "Cuengh"
},
"zea": {
- "articles": 4727,
+ "articles": 4741,
"english_name": "Zeelandic",
"name": "Ze\u00eauws"
},
"zh": {
- "articles": 1099382,
+ "articles": 1147282,
"english_name": "Chinese",
"name": "\u4e2d\u6587"
},
"zh-classical": {
- "articles": 10187,
+ "articles": 10450,
"english_name": "Classical Chinese",
"name": "\u53e4\u6587 / \u6587\u8a00\u6587"
},
"zh-min-nan": {
- "articles": 264433,
+ "articles": 405686,
"english_name": "Min Nan",
"name": "B\u00e2n-l\u00e2m-g\u00fa"
},
"zh-yue": {
- "articles": 77673,
+ "articles": 102328,
"english_name": "Cantonese",
"name": "\u7cb5\u8a9e"
},
"zu": {
- "articles": 1382,
+ "articles": 4070,
"english_name": "Zulu",
"name": "isiZulu"
}
},
"wikipedia": {
"ab": {
- "articles": 6031,
+ "articles": 6080,
"english_name": "Abkhazian",
"name": "\u0410\u04a7\u0441\u0443\u0430"
},
"ace": {
- "articles": 10323,
+ "articles": 10353,
"english_name": "Acehnese",
"name": "Bahsa Ac\u00e8h"
},
"ady": {
- "articles": 417,
+ "articles": 421,
"english_name": "Adyghe",
"name": "\u0410\u0434\u044b\u0433\u044d\u0431\u0437\u044d"
},
"af": {
- "articles": 89423,
+ "articles": 93802,
"english_name": "Afrikaans",
"name": "Afrikaans"
},
"ak": {
- "articles": 795,
+ "articles": 879,
"english_name": "Akan",
"name": "Akana"
},
"als": {
- "articles": 27014,
+ "articles": 27329,
"english_name": "Alemannic",
"name": "Alemannisch"
},
"am": {
- "articles": 14831,
+ "articles": 14875,
"english_name": "Amharic",
"name": "\u12a0\u121b\u122d\u129b"
},
"an": {
- "articles": 36741,
+ "articles": 38095,
"english_name": "Aragonese",
"name": "Aragon\u00e9s"
},
"ang": {
- "articles": 3187,
+ "articles": 3294,
"english_name": "Anglo-Saxon",
"name": "Englisc"
},
"ar": {
- "articles": 1031588,
+ "articles": 1065982,
"english_name": "Arabic",
"name": "\u0627\u0644\u0639\u0631\u0628\u064a\u0629"
},
"arc": {
- "articles": 1647,
+ "articles": 1764,
"english_name": "Aramaic",
"name": "\u0710\u072a\u0721\u071d\u0710"
},
+ "ary": {
+ "articles": 2554,
+ "english_name": "Moroccan Arabic",
+ "name": "\u0627\u0644\u062f\u0627\u0631\u062c\u0629"
+ },
"arz": {
- "articles": 145685,
+ "articles": 1098659,
"english_name": "Egyptian Arabic",
"name": "\u0645\u0635\u0631\u0649 (Ma\u1e63ri)"
},
"as": {
- "articles": 6381,
+ "articles": 7230,
"english_name": "Assamese",
"name": "\u0985\u09b8\u09ae\u09c0\u09af\u09bc\u09be"
},
"ast": {
- "articles": 100187,
+ "articles": 107460,
"english_name": "Asturian",
"name": "Asturianu"
},
"atj": {
- "articles": 1167,
+ "articles": 1259,
"english_name": "Atikamekw",
"name": "Atikamekw"
},
"av": {
- "articles": 2422,
+ "articles": 2451,
"english_name": "Avar",
"name": "\u0410\u0432\u0430\u0440"
},
+ "avk": {
+ "articles": 9484,
+ "english_name": "Kotava",
+ "name": "Kotava"
+ },
+ "awa": {
+ "articles": 2406,
+ "english_name": "Awadhi",
+ "name": "\u0905\u0935\u0927\u0940"
+ },
"ay": {
- "articles": 4646,
+ "articles": 4852,
"english_name": "Aymara",
"name": "Aymar"
},
"az": {
- "articles": 155848,
+ "articles": 173155,
"english_name": "Azerbaijani",
"name": "Az\u0259rbaycanca"
},
"azb": {
- "articles": 183161,
+ "articles": 239463,
"english_name": "South Azerbaijani",
"name": "\u062a\u06c6\u0631\u06a9\u062c\u0647"
},
"ba": {
- "articles": 51161,
+ "articles": 53560,
"english_name": "Bashkir",
"name": "\u0411\u0430\u0448\u04a1\u043e\u0440\u0442"
},
"ban": {
- "articles": 2258,
+ "articles": 3899,
"english_name": "Balinese",
"name": "Bali"
},
"bar": {
- "articles": 30891,
+ "articles": 31394,
"english_name": "Bavarian",
"name": "Boarisch"
},
"bat-smg": {
- "articles": 16858,
+ "articles": 16893,
"english_name": "Samogitian",
"name": "\u017demait\u0117\u0161ka"
},
"bcl": {
- "articles": 9363,
+ "articles": 10546,
"english_name": "Central Bicolano",
"name": "Bikol"
},
"be": {
- "articles": 185723,
+ "articles": 195563,
"english_name": "Belarusian",
"name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f"
},
"be-tarask": {
- "articles": 69136,
+ "articles": 71188,
"english_name": "Belarusian (Tara\u0161kievica)",
"name": "\u0411\u0435\u043b\u0430\u0440\u0443\u0441\u043a\u0430\u044f (\u0442\u0430\u0440\u0430\u0448\u043a\u0435\u0432\u0456\u0446\u0430)"
},
"bg": {
- "articles": 260031,
+ "articles": 265773,
"english_name": "Bulgarian",
"name": "\u0411\u044a\u043b\u0433\u0430\u0440\u0441\u043a\u0438"
},
"bh": {
- "articles": 7033,
+ "articles": 7342,
"english_name": "Bhojpuri",
"name": "\u092d\u094b\u091c\u092a\u0941\u0930\u0940"
},
"bi": {
- "articles": 1219,
+ "articles": 1230,
"english_name": "Bislama",
"name": "Bislama"
},
"bjn": {
- "articles": 2973,
+ "articles": 3256,
"english_name": "Banjar",
"name": "Bahasa Banjar"
},
"bm": {
- "articles": 664,
+ "articles": 668,
"english_name": "Bambara",
"name": "Bamanankan"
},
"bn": {
- "articles": 82134,
+ "articles": 94608,
"english_name": "Bengali",
"name": "\u09ac\u09be\u0982\u09b2\u09be"
},
"bo": {
- "articles": 5887,
+ "articles": 5920,
"english_name": "Tibetan",
"name": "\u0f56\u0f7c\u0f51\u0f0b\u0f66\u0f90\u0f51"
},
@@ -26938,147 +28017,147 @@
"name": "\u0987\u09ae\u09be\u09b0 \u09a0\u09be\u09b0/\u09ac\u09bf\u09b7\u09cd\u09a3\u09c1\u09aa\u09cd\u09b0\u09bf\u09af\u09bc\u09be \u09ae\u09a3\u09bf\u09aa\u09c1\u09b0\u09c0"
},
"br": {
- "articles": 67768,
+ "articles": 68639,
"english_name": "Breton",
"name": "Brezhoneg"
},
"bs": {
- "articles": 82109,
+ "articles": 84169,
"english_name": "Bosnian",
"name": "Bosanski"
},
"bug": {
- "articles": 14127,
+ "articles": 14139,
"english_name": "Buginese",
"name": "Basa Ugi"
},
"bxr": {
- "articles": 2163,
+ "articles": 2172,
"english_name": "Buryat",
"name": "\u0411\u0443\u0440\u044f\u0430\u0434"
},
"ca": {
- "articles": 638512,
+ "articles": 657438,
"english_name": "Catalan",
"name": "Catal\u00e0"
},
"cbk-zam": {
- "articles": 3023,
+ "articles": 3092,
"english_name": "Zamboanga Chavacano",
"name": "Chavacano de Zamboanga"
},
"cdo": {
- "articles": 15445,
+ "articles": 15490,
"english_name": "Min Dong",
"name": "M\u00ecng-d\u0115\u0324ng-ng\u1e73\u0304"
},
"ce": {
- "articles": 254141,
+ "articles": 288306,
"english_name": "Chechen",
"name": "\u041d\u043e\u0445\u0447\u0438\u0439\u043d"
},
"ceb": {
- "articles": 5378538,
+ "articles": 5337062,
"english_name": "Cebuano",
"name": "Sinugboanong Binisaya"
},
"ch": {
- "articles": 513,
+ "articles": 512,
"english_name": "Chamorro",
"name": "Chamoru"
},
"chr": {
- "articles": 834,
+ "articles": 917,
"english_name": "Cherokee",
"name": "\u13e3\u13b3\u13a9"
},
"chy": {
- "articles": 618,
+ "articles": 619,
"english_name": "Cheyenne",
"name": "Tsets\u00eahest\u00e2hese"
},
"ckb": {
- "articles": 25522,
+ "articles": 26975,
"english_name": "Sorani",
"name": "Soran\u00ee / \u06a9\u0648\u0631\u062f\u06cc"
},
"co": {
- "articles": 5788,
+ "articles": 5824,
"english_name": "Corsican",
"name": "Corsu"
},
"cr": {
- "articles": 104,
+ "articles": 117,
"english_name": "Cree",
"name": "Nehiyaw"
},
"crh": {
- "articles": 7046,
+ "articles": 7713,
"english_name": "Crimean Tatar",
"name": "Q\u0131r\u0131mtatarca"
},
"cs": {
- "articles": 447036,
+ "articles": 462637,
"english_name": "Czech",
"name": "\u010ce\u0161tina"
},
"csb": {
- "articles": 5329,
+ "articles": 5352,
"english_name": "Kashubian",
"name": "Kasz\u00ebbsczi"
},
"cu": {
- "articles": 702,
+ "articles": 743,
"english_name": "Old Church Slavonic",
"name": "\u0421\u043b\u043e\u0432\u0463\u043d\u044c\u0441\u043a\u044a"
},
"cv": {
- "articles": 42681,
+ "articles": 43604,
"english_name": "Chuvash",
"name": "\u0427\u0103\u0432\u0430\u0448"
},
"cy": {
- "articles": 107176,
+ "articles": 131787,
"english_name": "Welsh",
"name": "Cymraeg"
},
"da": {
- "articles": 257264,
+ "articles": 261215,
"english_name": "Danish",
"name": "Dansk"
},
"de": {
- "articles": 2402917,
+ "articles": 2481560,
"english_name": "German",
"name": "Deutsch"
},
"din": {
- "articles": 122,
+ "articles": 116,
"english_name": "Dinka",
"name": "Thu\u0254\u014bj\u00e4\u014b"
},
"diq": {
- "articles": 13329,
+ "articles": 31162,
"english_name": "Zazaki",
"name": "Zazaki"
},
"dsb": {
- "articles": 3251,
+ "articles": 3279,
"english_name": "Lower Sorbian",
"name": "Dolnoserbski"
},
"dty": {
- "articles": 3242,
+ "articles": 3287,
"english_name": "Doteli",
"name": "\u0921\u094b\u091f\u0947\u0932\u0940"
},
"dv": {
- "articles": 3002,
+ "articles": 2958,
"english_name": "Divehi",
"name": "\u078b\u07a8\u0788\u07ac\u0780\u07a8\u0784\u07a6\u0790\u07b0"
},
"dz": {
- "articles": 222,
+ "articles": 219,
"english_name": "Dzongkha",
"name": "\u0f47\u0f7c\u0f44\u0f0b\u0f41"
},
@@ -27088,102 +28167,102 @@
"name": "E\u028begbe"
},
"el": {
- "articles": 174096,
+ "articles": 181844,
"english_name": "Greek",
"name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac"
},
"eml": {
- "articles": 12321,
+ "articles": 12521,
"english_name": "Emilian-Romagnol",
"name": "Emili\u00e0n e rumagn\u00f2l"
},
"en": {
- "articles": 6023622,
+ "articles": 6161541,
"english_name": "English",
"name": "English"
},
"eo": {
- "articles": 275593,
+ "articles": 285283,
"english_name": "Esperanto",
"name": "Esperanto"
},
"es": {
- "articles": 1579723,
+ "articles": 1627598,
"english_name": "Spanish",
"name": "Espa\u00f1ol"
},
"et": {
- "articles": 206326,
+ "articles": 212088,
"english_name": "Estonian",
"name": "Eesti"
},
"eu": {
- "articles": 351277,
+ "articles": 364789,
"english_name": "Basque",
"name": "Euskara"
},
"ext": {
- "articles": 3180,
+ "articles": 3222,
"english_name": "Extremaduran",
"name": "Estreme\u00f1u"
},
"fa": {
- "articles": 712079,
+ "articles": 746175,
"english_name": "Persian",
"name": "\u0641\u0627\u0631\u0633\u06cc"
},
"ff": {
- "articles": 238,
+ "articles": 272,
"english_name": "Fula",
"name": "Fulfulde"
},
"fi": {
- "articles": 479513,
+ "articles": 493428,
"english_name": "Finnish",
"name": "Suomi"
},
"fiu-vro": {
- "articles": 5533,
+ "articles": 5589,
"english_name": "V\u00f5ro",
"name": "V\u00f5ro"
},
"fj": {
- "articles": 780,
+ "articles": 1070,
"english_name": "Fijian",
"name": "Na Vosa Vakaviti"
},
"fo": {
- "articles": 13305,
+ "articles": 13378,
"english_name": "Faroese",
"name": "F\u00f8royskt"
},
"fr": {
- "articles": 2184872,
+ "articles": 2250872,
"english_name": "French",
"name": "Fran\u00e7ais"
},
"frp": {
- "articles": 3529,
+ "articles": 4080,
"english_name": "Franco-Proven\u00e7al",
"name": "Arpitan"
},
"frr": {
- "articles": 10273,
+ "articles": 11200,
"english_name": "North Frisian",
"name": "Nordfriisk"
},
"fur": {
- "articles": 3338,
+ "articles": 3419,
"english_name": "Friulian",
"name": "Furlan"
},
"fy": {
- "articles": 43513,
+ "articles": 44493,
"english_name": "West Frisian",
"name": "Frysk"
},
"ga": {
- "articles": 52203,
+ "articles": 53585,
"english_name": "Irish",
"name": "Gaeilge"
},
@@ -27193,137 +28272,137 @@
"name": "Gagauz"
},
"gan": {
- "articles": 6430,
+ "articles": 6435,
"english_name": "Gan",
"name": "\u8d1b\u8a9e"
},
"gcr": {
- "articles": 1001,
+ "articles": 1033,
"english_name": "Guianan Creole",
"name": "Kriy\u00f2l Gwiyannen"
},
"gd": {
- "articles": 15062,
+ "articles": 15136,
"english_name": "Scottish Gaelic",
"name": "G\u00e0idhlig"
},
"gl": {
- "articles": 161843,
+ "articles": 166957,
"english_name": "Galician",
"name": "Galego"
},
"glk": {
- "articles": 5931,
+ "articles": 6029,
"english_name": "Gilaki",
"name": "\u06af\u06cc\u0644\u06a9\u06cc"
},
"gn": {
- "articles": 3763,
+ "articles": 3863,
"english_name": "Guarani",
"name": "Ava\u00f1e'\u1ebd"
},
"gom": {
- "articles": 3723,
+ "articles": 3719,
"english_name": "Goan Konkani",
"name": "\u0917\u094b\u0902\u092f\u091a\u0940 \u0915\u094b\u0902\u0915\u0923\u0940 / G\u00f5ychi Konknni"
},
"gor": {
- "articles": 2542,
+ "articles": 9012,
"english_name": "Gorontalo",
"name": "Hulontalo"
},
"got": {
- "articles": 825,
+ "articles": 829,
"english_name": "Gothic",
"name": "\ud800\udf32\ud800\udf3f\ud800\udf44\ud800\udf39\ud800\udf43\ud800\udf3a"
},
"gu": {
- "articles": 28880,
+ "articles": 29088,
"english_name": "Gujarati",
"name": "\u0a97\u0ac1\u0a9c\u0ab0\u0abe\u0aa4\u0ac0"
},
"gv": {
- "articles": 4996,
+ "articles": 5010,
"english_name": "Manx",
"name": "Gaelg"
},
"ha": {
- "articles": 4631,
+ "articles": 5321,
"english_name": "Hausa",
"name": "Hausa / \u0647\u064e\u0648\u064f\u0633\u064e"
},
"hak": {
- "articles": 9277,
+ "articles": 9366,
"english_name": "Hakka",
"name": "Hak-k\u00e2-fa / \u5ba2\u5bb6\u8a71"
},
"haw": {
- "articles": 3862,
+ "articles": 2265,
"english_name": "Hawaiian",
"name": "Hawai`i"
},
"he": {
- "articles": 259224,
+ "articles": 275788,
"english_name": "Hebrew",
"name": "\u05e2\u05d1\u05e8\u05d9\u05ea"
},
"hi": {
- "articles": 136564,
+ "articles": 141828,
"english_name": "Hindi",
"name": "\u0939\u093f\u0928\u094d\u0926\u0940"
},
"hif": {
- "articles": 9774,
+ "articles": 9797,
"english_name": "Fiji Hindi",
"name": "Fiji Hindi"
},
"hr": {
- "articles": 215457,
+ "articles": 222117,
"english_name": "Croatian",
"name": "Hrvatski"
},
"hsb": {
- "articles": 13546,
+ "articles": 13598,
"english_name": "Upper Sorbian",
"name": "Hornjoserbsce"
},
"ht": {
- "articles": 57995,
+ "articles": 59897,
"english_name": "Haitian",
"name": "Kr\u00e8yol ayisyen"
},
"hu": {
- "articles": 465402,
+ "articles": 475889,
"english_name": "Hungarian",
"name": "Magyar"
},
"hy": {
- "articles": 264666,
+ "articles": 275577,
"english_name": "Armenian",
"name": "\u0540\u0561\u0575\u0565\u0580\u0565\u0576"
},
"hyw": {
- "articles": 7830,
+ "articles": 8406,
"english_name": "Western Armenian",
"name": "\u0531\u0580\u0565\u0582\u0574\u057f\u0561\u0570\u0561\u0575\u0565\u0580\u0567\u0576"
},
"ia": {
- "articles": 22095,
+ "articles": 22551,
"english_name": "Interlingua",
"name": "Interlingua"
},
"id": {
- "articles": 521569,
+ "articles": 545873,
"english_name": "Indonesian",
"name": "Bahasa Indonesia"
},
"ie": {
- "articles": 4723,
+ "articles": 5079,
"english_name": "Interlingue",
"name": "Interlingue"
},
"ig": {
- "articles": 1448,
+ "articles": 1533,
"english_name": "Igbo",
"name": "Igbo"
},
@@ -27333,112 +28412,112 @@
"name": "I\u00f1upiak"
},
"ilo": {
- "articles": 14221,
+ "articles": 15249,
"english_name": "Ilokano",
"name": "Ilokano"
},
"inh": {
- "articles": 1225,
+ "articles": 1478,
"english_name": "Ingush",
"name": "\u0413\u04cf\u0430\u043b\u0433\u04cf\u0430\u0439"
},
"io": {
- "articles": 29252,
+ "articles": 29785,
"english_name": "Ido",
"name": "Ido"
},
"is": {
- "articles": 49128,
+ "articles": 50516,
"english_name": "Icelandic",
"name": "\u00cdslenska"
},
"it": {
- "articles": 1585945,
+ "articles": 1636112,
"english_name": "Italian",
"name": "Italiano"
},
"iu": {
- "articles": 403,
+ "articles": 472,
"english_name": "Inuktitut",
"name": "\u1403\u14c4\u1483\u144e\u1450\u1466"
},
"ja": {
- "articles": 1192319,
+ "articles": 1228979,
"english_name": "Japanese",
"name": "\u65e5\u672c\u8a9e"
},
"jam": {
- "articles": 1648,
+ "articles": 1660,
"english_name": "Jamaican Patois",
"name": "Jumiekan Kryuol"
},
"jbo": {
- "articles": 1251,
+ "articles": 1256,
"english_name": "Lojban",
"name": "Lojban"
},
"jv": {
- "articles": 57275,
+ "articles": 58065,
"english_name": "Javanese",
"name": "Basa Jawa"
},
"ka": {
- "articles": 135269,
+ "articles": 140486,
"english_name": "Georgian",
"name": "\u10e5\u10d0\u10e0\u10d7\u10e3\u10da\u10d8"
},
"kaa": {
- "articles": 1883,
+ "articles": 1865,
"english_name": "Karakalpak",
"name": "Qaraqalpaqsha"
},
"kab": {
- "articles": 4508,
+ "articles": 4832,
"english_name": "Kabyle",
"name": "Taqbaylit"
},
"kbd": {
- "articles": 1584,
+ "articles": 1586,
"english_name": "Kabardian Circassian",
"name": "\u0410\u0434\u044b\u0433\u044d\u0431\u0437\u044d (Adighabze)"
},
"kbp": {
- "articles": 1603,
+ "articles": 1612,
"english_name": "Kabiye",
"name": "Kab\u0269y\u025b"
},
"kg": {
- "articles": 1197,
+ "articles": 1212,
"english_name": "Kongo",
"name": "KiKongo"
},
"ki": {
- "articles": 1368,
+ "articles": 1366,
"english_name": "Kikuyu",
"name": "G\u0129k\u0169y\u0169"
},
"kk": {
- "articles": 226239,
+ "articles": 227051,
"english_name": "Kazakh",
"name": "\u049a\u0430\u0437\u0430\u049b\u0448\u0430"
},
"kl": {
- "articles": 1669,
+ "articles": 833,
"english_name": "Greenlandic",
"name": "Kalaallisut"
},
"km": {
- "articles": 7994,
+ "articles": 8292,
"english_name": "Khmer",
"name": "\u1797\u17b6\u179f\u17b6\u1781\u17d2\u1798\u17c2\u179a"
},
"kn": {
- "articles": 25796,
+ "articles": 26549,
"english_name": "Kannada",
"name": "\u0c95\u0ca8\u0ccd\u0ca8\u0ca1"
},
"ko": {
- "articles": 485688,
+ "articles": 520943,
"english_name": "Korean",
"name": "\ud55c\uad6d\uc5b4"
},
@@ -27448,482 +28527,487 @@
"name": "\u041f\u0435\u0440\u0435\u043c \u041a\u043e\u043c\u0438 (Perem Komi)"
},
"krc": {
- "articles": 2037,
+ "articles": 2048,
"english_name": "Karachay-Balkar",
"name": "\u041a\u044a\u0430\u0440\u0430\u0447\u0430\u0439-\u041c\u0430\u043b\u043a\u044a\u0430\u0440 (Qarachay-Malqar)"
},
"ks": {
- "articles": 368,
+ "articles": 422,
"english_name": "Kashmiri",
"name": "\u0915\u0936\u094d\u092e\u0940\u0930\u0940 / \u0643\u0634\u0645\u064a\u0631\u064a"
},
"ksh": {
- "articles": 2861,
+ "articles": 2878,
"english_name": "Ripuarian",
"name": "Ripoarisch"
},
"ku": {
- "articles": 26872,
+ "articles": 31973,
"english_name": "Kurdish",
"name": "Kurd\u00ee / \u0643\u0648\u0631\u062f\u06cc"
},
"kv": {
- "articles": 5333,
+ "articles": 5347,
"english_name": "Komi",
"name": "\u041a\u043e\u043c\u0438"
},
"kw": {
- "articles": 3939,
+ "articles": 4196,
"english_name": "Cornish",
"name": "Kernewek/Karnuack"
},
"ky": {
- "articles": 79759,
+ "articles": 80385,
"english_name": "Kirghiz",
"name": "\u041a\u044b\u0440\u0433\u044b\u0437\u0447\u0430"
},
"la": {
- "articles": 132249,
+ "articles": 133666,
"english_name": "Latin",
"name": "Latina"
},
"lad": {
- "articles": 3545,
+ "articles": 3554,
"english_name": "Ladino",
"name": "Dzhudezmo"
},
"lb": {
- "articles": 57817,
+ "articles": 58769,
"english_name": "Luxembourgish",
"name": "L\u00ebtzebuergesch"
},
"lbe": {
- "articles": 1220,
+ "articles": 1223,
"english_name": "Lak",
"name": "\u041b\u0430\u043a\u043a\u0443"
},
"lez": {
- "articles": 4057,
+ "articles": 4109,
"english_name": "Lezgian",
"name": "\u041b\u0435\u0437\u0433\u0438 \u0447\u0406\u0430\u043b (Lezgi \u010d\u2019al)"
},
"lfn": {
- "articles": 3723,
+ "articles": 3983,
"english_name": "Lingua Franca Nova",
"name": "Lingua franca nova"
},
"lg": {
- "articles": 1178,
+ "articles": 1197,
"english_name": "Luganda",
"name": "Luganda"
},
"li": {
- "articles": 12737,
+ "articles": 13098,
"english_name": "Limburgish",
"name": "Limburgs"
},
"lij": {
- "articles": 3682,
+ "articles": 4277,
"english_name": "Ligurian",
"name": "L\u00edguru"
},
+ "lld": {
+ "articles": 916,
+ "english_name": "Ladin",
+ "name": "Ladin"
+ },
"lmo": {
- "articles": 39359,
+ "articles": 42884,
"english_name": "Lombard",
"name": "Lumbaart"
},
"ln": {
- "articles": 3136,
+ "articles": 3175,
"english_name": "Lingala",
"name": "Lingala"
},
"lo": {
- "articles": 3545,
+ "articles": 3566,
"english_name": "Lao",
"name": "\u0ea5\u0eb2\u0ea7"
},
"lrc": {
- "articles": 5360,
+ "articles": 5714,
"english_name": "Northern Luri",
"name": "\u0644\u06ca\u0631\u06cc \u0634\u0648\u0645\u0627\u0644\u06cc"
},
"lt": {
- "articles": 198453,
+ "articles": 200796,
"english_name": "Lithuanian",
"name": "Lietuvi\u0173"
},
"ltg": {
- "articles": 932,
+ "articles": 1001,
"english_name": "Latgalian",
"name": "Latga\u013cu"
},
"lv": {
- "articles": 100417,
+ "articles": 103239,
"english_name": "Latvian",
"name": "Latvie\u0161u"
},
"mai": {
- "articles": 13512,
+ "articles": 13600,
"english_name": "Maithili",
"name": "\u092e\u0948\u0925\u093f\u0932\u0940"
},
"map-bms": {
- "articles": 13344,
+ "articles": 13382,
"english_name": "Banyumasan",
"name": "Basa Banyumasan"
},
"mdf": {
- "articles": 1192,
+ "articles": 1196,
"english_name": "Moksha",
"name": "\u041c\u043e\u043a\u0448\u0435\u043d\u044c (Mokshanj K\u00e4lj)"
},
"mg": {
- "articles": 92711,
+ "articles": 93211,
"english_name": "Malagasy",
"name": "Malagasy"
},
"mhr": {
- "articles": 10108,
+ "articles": 10204,
"english_name": "Meadow Mari",
"name": "\u041e\u043b\u044b\u043a \u041c\u0430\u0440\u0438\u0439 (Olyk Marij)"
},
"mi": {
- "articles": 7159,
+ "articles": 7166,
"english_name": "Maori",
"name": "M\u0101ori"
},
"min": {
- "articles": 223738,
+ "articles": 224076,
"english_name": "Minangkabau",
"name": "Minangkabau"
},
"mk": {
- "articles": 104303,
+ "articles": 108023,
"english_name": "Macedonian",
"name": "\u041c\u0430\u043a\u0435\u0434\u043e\u043d\u0441\u043a\u0438"
},
"ml": {
- "articles": 67743,
+ "articles": 70483,
"english_name": "Malayalam",
"name": "\u0d2e\u0d32\u0d2f\u0d3e\u0d33\u0d02"
},
"mn": {
- "articles": 19010,
+ "articles": 19621,
"english_name": "Mongolian",
"name": "\u041c\u043e\u043d\u0433\u043e\u043b"
},
"mnw": {
- "articles": 470,
+ "articles": 642,
"english_name": "Mon",
"name": "\u1019\u1014\u103a"
},
"mr": {
- "articles": 56283,
+ "articles": 61619,
"english_name": "Marathi",
"name": "\u092e\u0930\u093e\u0920\u0940"
},
"mrj": {
- "articles": 10270,
+ "articles": 10275,
"english_name": "Hill Mari",
"name": "\u041a\u044b\u0440\u044b\u043a \u041c\u0430\u0440\u044b (Kyryk Mary)"
},
"ms": {
- "articles": 334930,
+ "articles": 343278,
"english_name": "Malay",
"name": "Bahasa Melayu"
},
"mt": {
- "articles": 3442,
+ "articles": 3614,
"english_name": "Maltese",
"name": "Malti"
},
"mwl": {
- "articles": 3783,
+ "articles": 3828,
"english_name": "Mirandese",
"name": "Mirand\u00e9s"
},
"my": {
- "articles": 45399,
+ "articles": 47334,
"english_name": "Burmese",
"name": "\u1019\u103c\u1014\u103a\u1019\u102c\u1018\u102c\u101e\u102c"
},
"myv": {
- "articles": 5871,
+ "articles": 6196,
"english_name": "Erzya",
"name": "\u042d\u0440\u0437\u044f\u043d\u044c (Erzjanj Kelj)"
},
"mzn": {
- "articles": 13127,
+ "articles": 13157,
"english_name": "Mazandarani",
"name": "\u0645\u064e\u0632\u0650\u0631\u0648\u0646\u064a"
},
"na": {
- "articles": 1309,
+ "articles": 1483,
"english_name": "Nauruan",
"name": "dorerin Naoero"
},
"nah": {
- "articles": 6976,
+ "articles": 7003,
"english_name": "Nahuatl",
"name": "N\u0101huatl"
},
"nap": {
- "articles": 14561,
+ "articles": 14609,
"english_name": "Neapolitan",
"name": "Nnapulitano"
},
"nds": {
- "articles": 61186,
+ "articles": 75834,
"english_name": "Low Saxon",
"name": "Plattd\u00fc\u00fctsch"
},
"nds-nl": {
- "articles": 6935,
+ "articles": 7082,
"english_name": "Dutch Low Saxon",
"name": "Nedersaksisch"
},
"ne": {
- "articles": 34031,
+ "articles": 33466,
"english_name": "Nepali",
"name": "\u0928\u0947\u092a\u093e\u0932\u0940"
},
"new": {
- "articles": 72233,
+ "articles": 72289,
"english_name": "Newar",
"name": "\u0928\u0947\u092a\u093e\u0932 \u092d\u093e\u0937\u093e"
},
"nl": {
- "articles": 1998535,
+ "articles": 2032886,
"english_name": "Dutch",
"name": "Nederlands"
},
"nn": {
- "articles": 151775,
+ "articles": 154370,
"english_name": "Norwegian (Nynorsk)",
"name": "Nynorsk"
},
"no": {
- "articles": 529258,
+ "articles": 546147,
"english_name": "Norwegian (Bokm\u00e5l)",
"name": "Norsk (Bokm\u00e5l)"
},
"nov": {
- "articles": 1671,
+ "articles": 1679,
"english_name": "Novial",
"name": "Novial"
},
"nqo": {
- "articles": 546,
+ "articles": 718,
"english_name": "N\u2019Ko",
"name": "\u07d2\u07de\u07cf"
},
"nrm": {
- "articles": 4332,
+ "articles": 4515,
"english_name": "Norman",
"name": "Nouormand/Normaund"
},
"nso": {
- "articles": 8175,
+ "articles": 8205,
"english_name": "Northern Sotho",
"name": "Sepedi"
},
"nv": {
- "articles": 12264,
+ "articles": 15865,
"english_name": "Navajo",
"name": "Din\u00e9 bizaad"
},
"ny": {
- "articles": 565,
+ "articles": 733,
"english_name": "Chichewa",
"name": "Chichewa"
},
"oc": {
- "articles": 87871,
+ "articles": 86161,
"english_name": "Occitan",
"name": "Occitan"
},
"olo": {
- "articles": 3236,
+ "articles": 3403,
"english_name": "Livvi-Karelian",
"name": "Karjalan"
},
"om": {
- "articles": 786,
+ "articles": 847,
"english_name": "Oromo",
"name": "Oromoo"
},
"or": {
- "articles": 15579,
+ "articles": 15917,
"english_name": "Oriya",
"name": "\u0b13\u0b21\u0b3c\u0b3f\u0b06"
},
"os": {
- "articles": 11884,
+ "articles": 12458,
"english_name": "Ossetian",
"name": "\u0418\u0440\u043e\u043d\u0430\u0443"
},
"pa": {
- "articles": 33858,
+ "articles": 34752,
"english_name": "Punjabi",
"name": "\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40"
},
"pag": {
- "articles": 2531,
+ "articles": 2663,
"english_name": "Pangasinan",
"name": "Pangasinan"
},
"pam": {
- "articles": 8637,
+ "articles": 8695,
"english_name": "Kapampangan",
"name": "Kapampangan"
},
"pap": {
- "articles": 1941,
+ "articles": 2002,
"english_name": "Papiamentu",
"name": "Papiamentu"
},
"pcd": {
- "articles": 4666,
+ "articles": 4865,
"english_name": "Picard",
"name": "Picard"
},
"pdc": {
- "articles": 1877,
+ "articles": 1894,
"english_name": "Pennsylvania German",
"name": "Deitsch"
},
"pfl": {
- "articles": 2647,
+ "articles": 2678,
"english_name": "Palatinate German",
"name": "P\u00e4lzisch"
},
"pi": {
- "articles": 2540,
+ "articles": 2543,
"english_name": "Pali",
"name": "\u092a\u093e\u0934\u093f"
},
"pih": {
- "articles": 796,
+ "articles": 803,
"english_name": "Norfolk",
"name": "Norfuk"
},
"pl": {
- "articles": 1386843,
+ "articles": 1427892,
"english_name": "Polish",
"name": "Polski"
},
"pms": {
- "articles": 64598,
+ "articles": 64812,
"english_name": "Piedmontese",
"name": "Piemont\u00e8is"
},
"pnb": {
- "articles": 52557,
+ "articles": 53656,
"english_name": "Western Punjabi",
"name": "\u0634\u0627\u06c1 \u0645\u06a9\u06be\u06cc \u067e\u0646\u062c\u0627\u0628\u06cc (Sh\u0101hmukh\u012b Pa\u00f1j\u0101b\u012b)"
},
"pnt": {
- "articles": 467,
+ "articles": 469,
"english_name": "Pontic",
"name": "\u03a0\u03bf\u03bd\u03c4\u03b9\u03b1\u03ba\u03ac"
},
"ps": {
- "articles": 10997,
+ "articles": 11544,
"english_name": "Pashto",
"name": "\u067e\u069a\u062a\u0648"
},
"pt": {
- "articles": 1021915,
+ "articles": 1043641,
"english_name": "Portuguese",
"name": "Portugu\u00eas"
},
"qu": {
- "articles": 21801,
+ "articles": 22691,
"english_name": "Quechua",
"name": "Runa Simi"
},
"rm": {
- "articles": 3646,
+ "articles": 3695,
"english_name": "Romansh",
"name": "Rumantsch"
},
"rmy": {
- "articles": 675,
+ "articles": 676,
"english_name": "Romani",
"name": "romani - \u0930\u094b\u092e\u093e\u0928\u0940"
},
"rn": {
- "articles": 615,
+ "articles": 616,
"english_name": "Kirundi",
"name": "Kirundi"
},
"ro": {
- "articles": 404592,
+ "articles": 412071,
"english_name": "Romanian",
"name": "Rom\u00e2n\u0103"
},
"roa-rup": {
- "articles": 1225,
+ "articles": 1233,
"english_name": "Aromanian",
"name": "Arm\u00e3neashce"
},
"roa-tara": {
- "articles": 9249,
+ "articles": 9302,
"english_name": "Tarantino",
"name": "Tarand\u00edne"
},
"ru": {
- "articles": 1600812,
+ "articles": 1661738,
"english_name": "Russian",
"name": "\u0420\u0443\u0441\u0441\u043a\u0438\u0439"
},
"rue": {
- "articles": 7447,
+ "articles": 7813,
"english_name": "Rusyn",
"name": "\u0420\u0443\u0441\u0438\u043d\u044c\u0441\u043a\u044b\u0439"
},
"rw": {
- "articles": 1820,
+ "articles": 1852,
"english_name": "Kinyarwanda",
"name": "Ikinyarwanda"
},
"sa": {
- "articles": 11456,
+ "articles": 11462,
"english_name": "Sanskrit",
"name": "\u0938\u0902\u0938\u094d\u0915\u0943\u0924\u092e\u094d"
},
"sah": {
- "articles": 12199,
+ "articles": 12759,
"english_name": "Sakha",
"name": "\u0421\u0430\u0445\u0430 \u0442\u044b\u043b\u0430 (Saxa Tyla)"
},
"sat": {
- "articles": 2470,
+ "articles": 4535,
"english_name": "Santali",
"name": "\u1c65\u1c5f\u1c71\u1c5b\u1c5f\u1c72\u1c64"
},
"sc": {
- "articles": 6371,
+ "articles": 6686,
"english_name": "Sardinian",
"name": "Sardu"
},
"scn": {
- "articles": 26074,
+ "articles": 26058,
"english_name": "Sicilian",
"name": "Sicilianu"
},
"sco": {
- "articles": 56578,
+ "articles": 56568,
"english_name": "Scots",
"name": "Scots"
},
"sd": {
- "articles": 12956,
+ "articles": 13687,
"english_name": "Sindhi",
"name": "\u0633\u0646\u068c\u064a\u060c \u0633\u0646\u062f\u06be\u06cc \u060c \u0938\u093f\u0928\u094d\u0927"
},
"se": {
- "articles": 7612,
+ "articles": 7695,
"english_name": "Northern Sami",
"name": "S\u00e1megiella"
},
@@ -27933,297 +29017,297 @@
"name": "S\u00e4ng\u00f6"
},
"sh": {
- "articles": 451031,
+ "articles": 452863,
"english_name": "Serbo-Croatian",
"name": "Srpskohrvatski / \u0421\u0440\u043f\u0441\u043a\u043e\u0445\u0440\u0432\u0430\u0442\u0441\u043a\u0438"
},
"shn": {
- "articles": 6745,
+ "articles": 7293,
"english_name": "Shan",
"name": "\u101c\u102d\u1075\u103a\u1088\u1010\u1086\u1038"
},
"si": {
- "articles": 15543,
+ "articles": 15855,
"english_name": "Sinhalese",
"name": "\u0dc3\u0dd2\u0d82\u0dc4\u0dbd"
},
"simple": {
- "articles": 155539,
+ "articles": 172453,
"english_name": "Simple English",
"name": "Simple English"
},
"sk": {
- "articles": 232538,
+ "articles": 234573,
"english_name": "Slovak",
"name": "Sloven\u010dina"
},
"sl": {
- "articles": 167090,
+ "articles": 169414,
"english_name": "Slovenian",
"name": "Sloven\u0161\u010dina"
},
"sm": {
- "articles": 823,
+ "articles": 855,
"english_name": "Samoan",
"name": "Gagana Samoa"
},
"sn": {
- "articles": 4996,
+ "articles": 5991,
"english_name": "Shona",
"name": "chiShona"
},
"so": {
- "articles": 5752,
+ "articles": 5805,
"english_name": "Somali",
"name": "Soomaali"
},
"sq": {
- "articles": 78674,
+ "articles": 81381,
"english_name": "Albanian",
"name": "Shqip"
},
"sr": {
- "articles": 630590,
+ "articles": 638284,
"english_name": "Serbian",
"name": "\u0421\u0440\u043f\u0441\u043a\u0438 / Srpski"
},
"srn": {
- "articles": 1076,
+ "articles": 1070,
"english_name": "Sranan",
"name": "Sranantongo"
},
"ss": {
- "articles": 504,
+ "articles": 518,
"english_name": "Swati",
"name": "SiSwati"
},
"st": {
- "articles": 656,
+ "articles": 768,
"english_name": "Sesotho",
"name": "Sesotho"
},
"stq": {
- "articles": 4017,
+ "articles": 4025,
"english_name": "Saterland Frisian",
"name": "Seeltersk"
},
"su": {
- "articles": 59863,
+ "articles": 60527,
"english_name": "Sundanese",
"name": "Basa Sunda"
},
"sv": {
- "articles": 3738262,
+ "articles": 3675733,
"english_name": "Swedish",
"name": "Svenska"
},
"sw": {
- "articles": 55888,
+ "articles": 60346,
"english_name": "Swahili",
"name": "Kiswahili"
},
"szl": {
- "articles": 51946,
+ "articles": 52432,
"english_name": "Silesian",
"name": "\u015al\u016fnski"
},
"szy": {
- "articles": 1748,
+ "articles": 1812,
"english_name": "Sakizaya",
"name": "Sakizaya"
},
"ta": {
- "articles": 127284,
+ "articles": 131072,
"english_name": "Tamil",
"name": "\u0ba4\u0bae\u0bbf\u0bb4\u0bcd"
},
"tcy": {
- "articles": 1271,
+ "articles": 1397,
"english_name": "Tulu",
"name": "\u0ca4\u0cc1\u0cb3\u0cc1"
},
"te": {
- "articles": 70262,
+ "articles": 69631,
"english_name": "Telugu",
"name": "\u0c24\u0c46\u0c32\u0c41\u0c17\u0c41"
},
"tet": {
- "articles": 1475,
+ "articles": 1479,
"english_name": "Tetum",
"name": "Tetun"
},
"tg": {
- "articles": 100460,
+ "articles": 101656,
"english_name": "Tajik",
"name": "\u0422\u043e\u04b7\u0438\u043a\u04e3"
},
"th": {
- "articles": 135321,
+ "articles": 139928,
"english_name": "Thai",
"name": "\u0e44\u0e17\u0e22"
},
"ti": {
- "articles": 202,
+ "articles": 195,
"english_name": "Tigrinya",
"name": "\u1275\u130d\u122d\u129b"
},
"tk": {
- "articles": 5656,
+ "articles": 5821,
"english_name": "Turkmen",
"name": "T\u00fcrkmen"
},
"tl": {
- "articles": 75674,
+ "articles": 68568,
"english_name": "Tagalog",
"name": "Tagalog"
},
"tn": {
- "articles": 710,
+ "articles": 712,
"english_name": "Tswana",
"name": "Setswana"
},
"to": {
- "articles": 1738,
+ "articles": 1740,
"english_name": "Tongan",
"name": "faka Tonga"
},
"tpi": {
- "articles": 1608,
+ "articles": 1625,
"english_name": "Tok Pisin",
"name": "Tok Pisin"
},
"tr": {
- "articles": 343072,
+ "articles": 365938,
"english_name": "Turkish",
"name": "T\u00fcrk\u00e7e"
},
"ts": {
- "articles": 683,
+ "articles": 700,
"english_name": "Tsonga",
"name": "Xitsonga"
},
"tt": {
- "articles": 89002,
+ "articles": 136712,
"english_name": "Tatar",
"name": "Tatar\u00e7a / \u0422\u0430\u0442\u0430\u0440\u0447\u0430"
},
"tum": {
- "articles": 586,
+ "articles": 588,
"english_name": "Tumbuka",
"name": "chiTumbuka"
},
"tw": {
- "articles": 705,
+ "articles": 708,
"english_name": "Twi",
"name": "Twi"
},
"ty": {
- "articles": 1204,
+ "articles": 1208,
"english_name": "Tahitian",
"name": "Reo M\u0101`ohi"
},
"tyv": {
- "articles": 1987,
+ "articles": 2704,
"english_name": "Tuvan",
"name": "\u0422\u044b\u0432\u0430"
},
"udm": {
- "articles": 4848,
+ "articles": 4948,
"english_name": "Udmurt",
"name": "\u0423\u0434\u043c\u0443\u0440\u0442 \u043a\u044b\u043b"
},
"ug": {
- "articles": 4244,
+ "articles": 4364,
"english_name": "Uyghur",
"name": "\u0626\u06c7\u064a\u063a\u06c7\u0631 \u062a\u0649\u0644\u0649"
},
"uk": {
- "articles": 993357,
+ "articles": 1044506,
"english_name": "Ukrainian",
"name": "\u0423\u043a\u0440\u0430\u0457\u043d\u0441\u044c\u043a\u0430"
},
"ur": {
- "articles": 151971,
+ "articles": 157319,
"english_name": "Urdu",
"name": "\u0627\u0631\u062f\u0648"
},
"uz": {
- "articles": 133433,
+ "articles": 136238,
"english_name": "Uzbek",
"name": "O\u2018zbek"
},
"ve": {
- "articles": 368,
+ "articles": 370,
"english_name": "Venda",
"name": "Tshivenda"
},
"vec": {
- "articles": 19577,
+ "articles": 62971,
"english_name": "Venetian",
"name": "V\u00e8neto"
},
"vep": {
- "articles": 6395,
+ "articles": 6601,
"english_name": "Vepsian",
"name": "Veps\u00e4n"
},
"vi": {
- "articles": 1241042,
+ "articles": 1255776,
"english_name": "Vietnamese",
"name": "Ti\u1ebfng Vi\u1ec7t"
},
"vls": {
- "articles": 7079,
+ "articles": 7225,
"english_name": "West Flemish",
"name": "West-Vlams"
},
"vo": {
- "articles": 124156,
+ "articles": 125021,
"english_name": "Volap\u00fck",
"name": "Volap\u00fck"
},
"wa": {
- "articles": 15627,
+ "articles": 14141,
"english_name": "Walloon",
"name": "Walon"
},
"war": {
- "articles": 1263934,
+ "articles": 1264408,
"english_name": "Waray-Waray",
"name": "Winaray"
},
"wo": {
- "articles": 1387,
+ "articles": 1421,
"english_name": "Wolof",
"name": "Wolof"
},
"wuu": {
- "articles": 28716,
+ "articles": 39058,
"english_name": "Wu",
"name": "\u5434\u8bed"
},
"xal": {
- "articles": 2082,
+ "articles": 2085,
"english_name": "Kalmyk",
"name": "\u0425\u0430\u043b\u044c\u043c\u0433"
},
"xh": {
- "articles": 1043,
+ "articles": 1057,
"english_name": "Xhosa",
"name": "isiXhosa"
},
"xmf": {
- "articles": 13670,
+ "articles": 14930,
"english_name": "Mingrelian",
"name": "\u10db\u10d0\u10e0\u10d2\u10d0\u10da\u10e3\u10e0\u10d8 (Margaluri)"
},
"yi": {
- "articles": 14999,
+ "articles": 14885,
"english_name": "Yiddish",
"name": "\u05d9\u05d9\u05b4\u05d3\u05d9\u05e9"
},
"yo": {
- "articles": 32321,
+ "articles": 32714,
"english_name": "Yoruba",
"name": "Yor\u00f9b\u00e1"
},
@@ -28233,32 +29317,32 @@
"name": "Cuengh"
},
"zea": {
- "articles": 4727,
+ "articles": 4741,
"english_name": "Zeelandic",
"name": "Ze\u00eauws"
},
"zh": {
- "articles": 1099382,
+ "articles": 1147282,
"english_name": "Chinese",
"name": "\u4e2d\u6587"
},
"zh-classical": {
- "articles": 10187,
+ "articles": 10450,
"english_name": "Classical Chinese",
"name": "\u53e4\u6587 / \u6587\u8a00\u6587"
},
"zh-min-nan": {
- "articles": 264433,
+ "articles": 405686,
"english_name": "Min Nan",
"name": "B\u00e2n-l\u00e2m-g\u00fa"
},
"zh-yue": {
- "articles": 77673,
+ "articles": 102328,
"english_name": "Cantonese",
"name": "\u7cb5\u8a9e"
},
"zu": {
- "articles": 1382,
+ "articles": 4070,
"english_name": "Zulu",
"name": "isiZulu"
}
diff --git a/searx/data/external_urls.json b/searx/data/external_urls.json
new file mode 100644
index 0000000..75b153a
--- /dev/null
+++ b/searx/data/external_urls.json
@@ -0,0 +1,156 @@
+{
+ "facebook_profile": {
+ "category_name": "Facebook",
+ "url_name": "Facebook profile",
+ "urls": {
+ "default": "https://facebook.com/$1"
+ }
+ },
+ "youtube_channel": {
+ "category_name": "YouTube",
+ "url_name": "YouTube channel",
+ "urls": {
+ "default": "https://www.youtube.com/channel/$1"
+ }
+ },
+ "youtube_video": {
+ "category_name": "YouTube",
+ "url_name": "YouTube video",
+ "urls": {
+ "default": "https://www.youtube.com/watch?v=$1"
+ }
+ },
+ "twitter_profile": {
+ "category_name": "Twitter",
+ "url_name": "Twitter profile",
+ "urls": {
+ "default": "https://twitter.com/$1"
+ }
+ },
+ "instagram_profile": {
+ "category_name": "Instagram",
+ "url_name": "Instagram profile",
+ "urls": {
+ "default": "https://www.instagram.com/$1"
+ }
+ },
+ "imdb_title": {
+ "category_name": "IMDB",
+ "url_name": "IMDB title",
+ "urls": {
+ "default": "https://www.imdb.com/title/$1"
+ }
+ },
+ "imdb_name": {
+ "category_name": "IMDB",
+ "url_name": "IMDB name",
+ "urls": {
+ "default": "https://www.imdb.com/name/$1"
+ }
+ },
+ "imdb_character": {
+ "category_name": "IMDB",
+ "url_name": "IMDB character",
+ "urls": {
+ "default": "https://www.imdb.com/character/$1"
+ }
+ },
+ "imdb_company": {
+ "category_name": "IMDB",
+ "url_name": "IMDB company",
+ "urls": {
+ "default": "https://www.imdb.com/company/$1"
+ }
+ },
+ "imdb_event": {
+ "category_name": "IMDB",
+ "url_name": "IMDB event",
+ "urls": {
+ "default": "https://www.imdb.com/event/$1"
+ }
+ },
+ "rotten_tomatoes": {
+ "category_name": "Rotten tomatoes",
+ "url_name": "Rotten tomatoes title",
+ "urls": {
+ "default": "https://www.rottentomatoes.com/$1"
+ }
+ },
+ "spotify_artist_id": {
+ "category_name": "Spotify",
+ "url_name": "Spotify artist",
+ "urls": {
+ "default": "https://open.spotify.com/artist/$1"
+ }
+ },
+ "itunes_artist_id": {
+ "category_name": "iTunes",
+ "url_name": "iTunes artist",
+ "urls": {
+ "default": "https://music.apple.com/us/artist/$1"
+ }
+ },
+ "soundcloud_id": {
+ "category_name": "Soundcloud",
+ "url_name": "Soundcloud artist",
+ "urls": {
+ "default": "https://soundcloud.com/$1"
+ }
+ },
+ "netflix_id": {
+ "category_name": "Netflix",
+ "url_name": "Netflix movie",
+ "urls": {
+ "default": "https://www.netflix.com/watch/$1"
+ }
+ },
+ "github_profile": {
+ "category_name": "Github",
+ "url_name": "Github profile",
+ "urls": {
+ "default": "https://wwww.github.com/$1"
+ }
+ },
+ "musicbrainz_artist": {
+ "category_name": "Musicbrainz",
+ "url_name": "Musicbrainz artist",
+ "urls": {
+ "default": "http://musicbrainz.org/artist/$1"
+ }
+ },
+ "musicbrainz_work": {
+ "category_name": "Musicbrainz",
+ "url_name": "Musicbrainz work",
+ "urls": {
+ "default": "http://musicbrainz.org/work/$1"
+ }
+ },
+ "musicbrainz_release_group": {
+ "category_name": "Musicbrainz",
+ "url_name": "Musicbrainz release group",
+ "urls": {
+ "default": "http://musicbrainz.org/release-group/$1"
+ }
+ },
+ "musicbrainz_label": {
+ "category_name": "Musicbrainz",
+ "url_name": "Musicbrainz label",
+ "urls": {
+ "default": "http://musicbrainz.org/label/$1"
+ }
+ },
+ "wikimedia_image": {
+ "category_name": "Wikipedia",
+ "url_name": "Wikipedia image",
+ "urls": {
+ "default": "https://commons.wikimedia.org/wiki/Special:FilePath/$1?width=500&height=400"
+ }
+ },
+ "map": {
+ "category_name": "Map",
+ "url_name": "geo map",
+ "urls": {
+ "default": "https://www.openstreetmap.org/?lat=${latitude}&lon=${longitude}&zoom=${zoom}&layers=M"
+ }
+ }
+} \ No newline at end of file
diff --git a/searx/data/wikidata_units.json b/searx/data/wikidata_units.json
new file mode 100644
index 0000000..966e5e8
--- /dev/null
+++ b/searx/data/wikidata_units.json
@@ -0,0 +1,1006 @@
+{
+ "Q199": "1",
+ "Q100149279": "°We",
+ "Q100995": "lb",
+ "Q1022113": "cm³",
+ "Q102573": "Bq",
+ "Q103246": "Sv",
+ "Q103510": "bar",
+ "Q10380431": "TJ",
+ "Q1040401": "das",
+ "Q1040427": "hs",
+ "Q1042866": "Zibit",
+ "Q1050958": "inHg",
+ "Q1051665": "m/s²",
+ "Q1052397": "rad",
+ "Q1054140": "Mm",
+ "Q10543042": "Ym",
+ "Q1057069": "hg",
+ "Q1063756": "rad/s",
+ "Q1063786": "in²",
+ "Q1065153": "mrad",
+ "Q1066138": "Ps",
+ "Q1067722": "Fg",
+ "Q1069725": "p.",
+ "Q1084321": "Tb/s",
+ "Q1086691": "fg",
+ "Q1091257": "tex",
+ "Q1092296": "a",
+ "Q1104069": "CAD$",
+ "Q11061003": "μm²",
+ "Q11061005": "nm²",
+ "Q1131660": "st",
+ "Q1137675": "cr",
+ "Q1140444": "Zbit",
+ "Q1140577": "Ybit",
+ "Q1152074": "Pbit",
+ "Q1152323": "Tbit",
+ "Q1165799": "mil",
+ "Q11776930": "Mg",
+ "Q11830636": "psf",
+ "Q11929860": "kpc",
+ "Q1194225": "lbf",
+ "Q1194580": "Mibit",
+ "Q1195111": "Ebit",
+ "Q1196837": "ω_P",
+ "Q1197459": "Ms",
+ "Q11982285": "Em³",
+ "Q11982288": "Zm³",
+ "Q11982289": "Tm³",
+ "Q12011178": "Zs",
+ "Q1204894": "Gibit",
+ "Q12257695": "Eb/s",
+ "Q12257696": "EB/s",
+ "Q12261466": "kB/s",
+ "Q12265780": "Pb/s",
+ "Q12265783": "PB/s",
+ "Q12269121": "Yb/s",
+ "Q12269122": "YB/s",
+ "Q12269308": "Zb/s",
+ "Q12269309": "ZB/s",
+ "Q1247300": "cm H₂O",
+ "Q12714022": "sh cwt",
+ "Q12789864": "GeV",
+ "Q12874593": "W h",
+ "Q128822": "kn",
+ "Q13035094": "J/mol",
+ "Q130964": "cal",
+ "Q131255": "F",
+ "Q13147228": "g/cm³",
+ "Q1322380": "Ts",
+ "Q1323615": "oz t",
+ "Q132643": "kr",
+ "Q13400897": "g",
+ "Q13479685": "mm wg",
+ "Q1351253": "Eibit",
+ "Q1351334": "Pibit",
+ "Q13542672": "Ry",
+ "Q13548586": "THz",
+ "Q13582667": "kgf/cm²",
+ "Q1361854": "dwt",
+ "Q1363007": "slug",
+ "Q1374438": "ks",
+ "Q13753469": "MB/s",
+ "Q1377051": "Gs",
+ "Q1394540": "bm",
+ "Q1396128": "F",
+ "Q1413142": "Gb",
+ "Q14158377": "A_P",
+ "Q14623803": "MDa",
+ "Q14623804": "kDa",
+ "Q1472674": "Sv",
+ "Q14754979": "Zg",
+ "Q14786969": "MJ",
+ "Q14913554": "Ys",
+ "Q14914907": "th",
+ "Q14916719": "Gpc",
+ "Q14923662": "Pm³",
+ "Q1511773": "LSd",
+ "Q15120301": "l atm",
+ "Q1542309": "xu",
+ "Q1545979": "ft³",
+ "Q1550511": "yd²",
+ "Q15551713": "Sh",
+ "Q1569733": "St",
+ "Q15784325": "apc",
+ "Q160680": "Br",
+ "Q160857": "hp",
+ "Q1628990": "hph",
+ "Q163343": "T",
+ "Q163354": "H",
+ "Q1640501": "hyl",
+ "Q1645498": "μg",
+ "Q16859309": "lb·ft",
+ "Q169893": "S",
+ "Q170804": "Wb",
+ "Q17093295": "m/h",
+ "Q17255465": "v_P",
+ "Q173117": "R$",
+ "Q1741429": "kpm",
+ "Q174467": "Lm",
+ "Q174728": "cm",
+ "Q174789": "mm",
+ "Q175821": "μm",
+ "Q1768929": "p",
+ "Q1770733": "Tg",
+ "Q1772386": "dg",
+ "Q177493": "Gs",
+ "Q177612": "sr",
+ "Q1777507": "fs",
+ "Q177974": "atm",
+ "Q178506": "bbl",
+ "Q178674": "nm",
+ "Q1793863": "sn",
+ "Q179836": "lx",
+ "Q180154": "km/h",
+ "Q180892": "M☉",
+ "Q1815100": "cl",
+ "Q182098": "kWh",
+ "Q1823150": "μW",
+ "Q182429": "m/s",
+ "Q1826195": "dl",
+ "Q18413919": "cm/s",
+ "Q184172": "FF",
+ "Q185078": "a",
+ "Q185153": "erg",
+ "Q185648": "Torr",
+ "Q185759": "span",
+ "Q1872619": "zs",
+ "Q189097": "₧",
+ "Q190095": "Gy",
+ "Q190951": "S$",
+ "Q191118": "t",
+ "Q1913097": "fg",
+ "Q1916026": "μV",
+ "Q192027": "Bd",
+ "Q192274": "pm",
+ "Q193098": "KD",
+ "Q1935515": "mA s",
+ "Q19392152": "TL",
+ "Q193933": "dpt",
+ "Q194339": "B$",
+ "Q1970718": "mam",
+ "Q1972579": "pdl",
+ "Q199462": "LE",
+ "Q199471": "Afs",
+ "Q200323": "dm",
+ "Q200337": "Kz",
+ "Q201880": "LL",
+ "Q201933": "dyn",
+ "Q2029156": "quad",
+ "Q2029519": "hl",
+ "Q203567": "₦",
+ "Q2042279": "m H₂O",
+ "Q204737": "៛",
+ "Q2051195": "GWh",
+ "Q2055118": "ppb",
+ "Q2064166": "fc",
+ "Q206600": "ރ",
+ "Q20706220": "cmm",
+ "Q20706221": "dmm",
+ "Q2080811": "vol%",
+ "Q208526": "NT$",
+ "Q208528": "gon",
+ "Q208634": "kat",
+ "Q208788": "fm",
+ "Q209351": "b",
+ "Q209426": "′",
+ "Q21006887": "ppm",
+ "Q2100949": "P",
+ "Q21014455": "m/min",
+ "Q210472": "B/.",
+ "Q21061369": "g/kg",
+ "Q21062777": "MPa",
+ "Q21064807": "kPa",
+ "Q21064845": "mol/L",
+ "Q21075844": "ml/l",
+ "Q21077820": "mg/m³",
+ "Q21091747": "mg/kg",
+ "Q211256": "mph",
+ "Q211580": "BTU (th)",
+ "Q212120": "A h",
+ "Q2140397": "in³",
+ "Q214377": "ell",
+ "Q2143992": "kHz",
+ "Q21489891": "nm³",
+ "Q21489892": "Gm³",
+ "Q21489893": "Mm³",
+ "Q21489894": "μm³",
+ "Q21500224": "mas",
+ "Q2151240": "mag",
+ "Q215571": "N m",
+ "Q21604951": "g/m³",
+ "Q2165290": "yd³",
+ "Q216880": "kp",
+ "Q217208": "a",
+ "Q2175964": "dm³",
+ "Q218593": "in",
+ "Q2199357": "dec",
+ "Q22137107": "mas/y",
+ "Q2215478": "ppt",
+ "Q2221356": "mW h",
+ "Q22350885": "da",
+ "Q2243141": "Gb/s",
+ "Q2254856": "ca",
+ "Q22673229": "ft/min",
+ "Q2269250": "kb/s",
+ "Q2282891": "μl",
+ "Q2282906": "ng",
+ "Q229354": "Ci",
+ "Q232291": "mi²",
+ "Q2332346": "ml",
+ "Q23823681": "TW",
+ "Q23925410": "gal (UK)",
+ "Q23925413": "gal (US)",
+ "Q23931040": "dam²",
+ "Q23931103": "nmi²",
+ "Q2414435": "$b.",
+ "Q242988": "Lib$",
+ "Q2438073": "ag",
+ "Q2448803": "mV",
+ "Q2451296": "μF",
+ "Q246868": "lot",
+ "Q2474258": "mSv",
+ "Q2483628": "as",
+ "Q2489298": "cm²",
+ "Q249439": "q_P",
+ "Q2518569": "nSv",
+ "Q253276": "mi",
+ "Q25472681": "GB/s",
+ "Q25472693": "TB/s",
+ "Q25499149": "oct",
+ "Q25511288": "mb",
+ "Q2553708": "MV",
+ "Q2554092": "kV",
+ "Q259502": "AU$",
+ "Q260126": "rem",
+ "Q2612219": "Pg",
+ "Q261247": "ct",
+ "Q2619500": "foe",
+ "Q2636421": "nH",
+ "Q2637946": "dal",
+ "Q2642547": "ha",
+ "Q2652700": "Osm",
+ "Q2655272": "Eg",
+ "Q2659078": "TW h",
+ "Q2670039": "₶",
+ "Q26708069": "kcal",
+ "Q267391": "K",
+ "Q2679083": "μH",
+ "Q2682463": "nF",
+ "Q2691798": "cg",
+ "Q271206": "sud£",
+ "Q2737347": "mm²",
+ "Q2739114": "μSv",
+ "Q275112": "Bz$",
+ "Q2756030": "pF",
+ "Q2757753": "PW h",
+ "Q2762458": "ys",
+ "Q27864215": "μW h",
+ "Q2793566": "GV",
+ "Q27949241": "R",
+ "Q2799294": "Gg",
+ "Q281096": "cd/m²",
+ "Q28719934": "keV",
+ "Q28924752": "g/mol",
+ "Q28924753": "kg/mol",
+ "Q2924137": "mH",
+ "Q296936": "toe",
+ "Q29924639": "kVA",
+ "Q30001811": "aBq",
+ "Q30001813": "aC",
+ "Q30001814": "aHz",
+ "Q30001815": "aJ",
+ "Q30001816": "akat",
+ "Q30001818": "aL",
+ "Q30001819": "alm",
+ "Q30001820": "alx",
+ "Q30001822": "aN",
+ "Q30001823": "aΩ",
+ "Q30001825": "aPa",
+ "Q30001826": "arad",
+ "Q30001827": "aS",
+ "Q30001828": "aSv",
+ "Q30001829": "asr",
+ "Q30001830": "aT",
+ "Q30001831": "aV",
+ "Q30001832": "aW",
+ "Q30001833": "aWb",
+ "Q3013059": "kyr",
+ "Q3194304": "kbit",
+ "Q3207456": "mW",
+ "Q321017": "R",
+ "Q3221356": "ym",
+ "Q3239557": "pg",
+ "Q3241121": "mg",
+ "Q324923": "Hart",
+ "Q3249364": "cs",
+ "Q3251645": "ds",
+ "Q3267417": "Tm",
+ "Q3270676": "zm",
+ "Q32750621": "liq pt (US)",
+ "Q32750759": "fl oz (US)",
+ "Q32750816": "bu (US)",
+ "Q32751272": "dry pt (US)",
+ "Q32751296": "bbl (US)",
+ "Q3276763": "GHz",
+ "Q3277907": "Em",
+ "Q3277915": "Zm",
+ "Q3277919": "Pm",
+ "Q3312063": "fL",
+ "Q3320608": "kW",
+ "Q3331719": "dm²",
+ "Q3332689": "ToR",
+ "Q3332814": "Mbit",
+ "Q3396758": "daa",
+ "Q3414243": "rps",
+ "Q3421309": "R_J",
+ "Q3495543": "mbar",
+ "Q355198": "px",
+ "Q3674704": "km/s",
+ "Q3675550": "mm³",
+ "Q3712659": "$",
+ "Q376660": "nat",
+ "Q37732658": "°R",
+ "Q3773454": "Mpc",
+ "Q3815076": "Kibit",
+ "Q3833309": "£",
+ "Q3858002": "mA h",
+ "Q3867152": "ft/s²",
+ "Q389062": "Tibit",
+ "Q3902688": "pl",
+ "Q3902709": "ps",
+ "Q39360235": "US lea",
+ "Q39360471": "nl",
+ "Q39362962": "µin",
+ "Q39363132": "UK lg",
+ "Q39363209": "UK nl",
+ "Q39380159": "US nmi",
+ "Q39462789": "µin²",
+ "Q39467934": "kgf/m²",
+ "Q39469927": "N/m²",
+ "Q39617688": "cwt long",
+ "Q39617818": "t lb",
+ "Q39628023": "y",
+ "Q39699418": "cm/s²",
+ "Q39708248": "S",
+ "Q39709980": "bd",
+ "Q39710113": "bhp EDR",
+ "Q3972226": "kL",
+ "Q4041686": "iwg",
+ "Q4068266": "Ʒ",
+ "Q4176683": "aC",
+ "Q420266": "oz. fl.",
+ "Q42319606": "people/m²",
+ "Q4243638": "km³",
+ "Q4456994": "mF",
+ "Q469356": "tn. sh.",
+ "Q476572": "Ha",
+ "Q482798": "yd",
+ "Q483261": "Da",
+ "Q483725": "A.M.",
+ "Q484092": "lm",
+ "Q4861171": "H",
+ "Q494083": "fur",
+ "Q4989854": "kJ",
+ "Q500515": "Gal",
+ "Q5042194": "£",
+ "Q50808017": "kg m²",
+ "Q5139563": "hPa",
+ "Q514845": "pz",
+ "Q5195628": "hm³",
+ "Q5198770": "dam³",
+ "Q524410": "byr",
+ "Q53393488": "PHz",
+ "Q53393490": "EHz",
+ "Q53393494": "ZHz",
+ "Q53393498": "YHz",
+ "Q53393659": "ML",
+ "Q53393664": "GL",
+ "Q53393674": "ZL",
+ "Q53393678": "YL",
+ "Q53393771": "yL",
+ "Q53393868": "GJ",
+ "Q53393886": "PJ",
+ "Q53393890": "EJ",
+ "Q53448786": "yHz",
+ "Q53448790": "zHz",
+ "Q53448794": "fHz",
+ "Q53448797": "pHz",
+ "Q53448801": "nHz",
+ "Q53448806": "μHz",
+ "Q53448808": "mHz",
+ "Q53448813": "cHz",
+ "Q53448817": "dHz",
+ "Q53448820": "daHz",
+ "Q53448826": "hHz",
+ "Q53448828": "yJ",
+ "Q53448832": "zJ",
+ "Q53448842": "pJ",
+ "Q53448844": "nJ",
+ "Q53448847": "μJ",
+ "Q53448851": "mJ",
+ "Q53448856": "cJ",
+ "Q53448860": "dJ",
+ "Q53448864": "daJ",
+ "Q53448875": "hJ",
+ "Q53448879": "yPa",
+ "Q53448883": "zPa",
+ "Q53448886": "fPa",
+ "Q53448892": "pPa",
+ "Q53448897": "nPa",
+ "Q53448900": "μPa",
+ "Q53448906": "mPa",
+ "Q53448909": "cPa",
+ "Q53448914": "dPa",
+ "Q53448918": "daPa",
+ "Q53448922": "GPa",
+ "Q53448927": "TPa",
+ "Q53448931": "PPa",
+ "Q53448936": "EPa",
+ "Q53448939": "ZPa",
+ "Q53448943": "YPa",
+ "Q53448949": "yV",
+ "Q53448952": "zV",
+ "Q53448957": "fV",
+ "Q53448960": "pV",
+ "Q53448965": "nV",
+ "Q53448969": "cV",
+ "Q53448973": "dV",
+ "Q53448977": "daV",
+ "Q53448981": "hV",
+ "Q53448985": "TV",
+ "Q53448990": "PV",
+ "Q53448994": "EV",
+ "Q53448996": "ZV",
+ "Q53449001": "YV",
+ "Q53449006": "yW",
+ "Q53449008": "zW",
+ "Q53449013": "fW",
+ "Q53449018": "pW",
+ "Q53449021": "nW",
+ "Q53449025": "cW",
+ "Q53449029": "dW",
+ "Q53449033": "daW",
+ "Q53449036": "hW",
+ "Q53449040": "PW",
+ "Q53449045": "EW",
+ "Q53449049": "ZW",
+ "Q53449054": "YW",
+ "Q53561461": "wf",
+ "Q53561822": "wf",
+ "Q53651160": "zm³",
+ "Q53651201": "Ym³",
+ "Q53651356": "ym³",
+ "Q53651512": "pm³",
+ "Q53651713": "fm³",
+ "Q536785": "ρ_P",
+ "Q53951982": "Mt",
+ "Q53952048": "kt",
+ "Q54006645": "ZWb",
+ "Q54081925": "ZSv",
+ "Q54082468": "ZS",
+ "Q54083144": "ZΩ",
+ "Q54083318": "ZN",
+ "Q54083566": "Zlm",
+ "Q54083579": "Zlx",
+ "Q54083712": "ZBq",
+ "Q54083746": "ZC",
+ "Q54083766": "ZF",
+ "Q54083779": "ZGy",
+ "Q54083795": "ZH",
+ "Q54083813": "Zkat",
+ "Q5409016": "MVA",
+ "Q5465723": "ft-pdl",
+ "Q549389": "bit/s",
+ "Q550341": "V A",
+ "Q552299": "ch",
+ "Q55442349": "U/L",
+ "Q55726194": "mg/L",
+ "Q56156859": "mmol",
+ "Q56156949": "μmol",
+ "Q56157046": "nmol",
+ "Q56157048": "pmol",
+ "Q56160603": "fmol",
+ "Q56302633": "UM",
+ "Q56317116": "mgal",
+ "Q56317622": "Q_P",
+ "Q56318907": "kbar",
+ "Q56349362": "Bs.S",
+ "Q56402798": "kN",
+ "Q5711261": "am³",
+ "Q581432": "‴",
+ "Q5879479": "GW",
+ "Q6003257": "am",
+ "Q6009164": "MW h",
+ "Q6014364": "in/s",
+ "Q603071": "E°",
+ "Q605704": "doz",
+ "Q60742631": "AU/yr",
+ "Q608697": "Mx",
+ "Q610135": "G",
+ "Q613726": "Yg",
+ "Q6170164": "yg",
+ "Q6171168": "zg",
+ "Q61756607": "yd",
+ "Q61793198": "rd",
+ "Q61794766": "ch (US survey)",
+ "Q61994988": "Wth",
+ "Q61995006": "KWth",
+ "Q626299": "psi",
+ "Q630369": "var",
+ "Q636200": "U",
+ "Q640907": "sb",
+ "Q6414556": "kip",
+ "Q648908": "bya",
+ "Q64996135": "gal (US)/min",
+ "Q65028392": "mm/yr",
+ "Q651336": "M_J",
+ "Q6517513": "dag",
+ "Q667419": "UK t",
+ "Q681996": "M⊕",
+ "Q685662": "p_P",
+ "Q6859652": "mm Hg",
+ "Q686163": "$",
+ "Q68725821": "°Rø",
+ "Q68726230": "°De",
+ "Q68726625": "°N",
+ "Q69362731": "°C",
+ "Q69363953": "K",
+ "Q693944": "gr",
+ "Q6982035": "MW",
+ "Q69878540": "fl oz (UK)",
+ "Q70378044": "dmol",
+ "Q70378549": "dK",
+ "Q70393458": "kmol",
+ "Q70395375": "Tmol",
+ "Q70395643": "Mmol",
+ "Q70395830": "kK",
+ "Q70396179": "mK",
+ "Q70397275": "μK",
+ "Q70397725": "cmol",
+ "Q70397932": "cK",
+ "Q70398457": "nK",
+ "Q70398619": "MK",
+ "Q70398813": "Gmol",
+ "Q70398991": "GK",
+ "Q70440025": "daK",
+ "Q70440438": "hK",
+ "Q70440620": "damol",
+ "Q70440823": "hmol",
+ "Q70443020": "EK",
+ "Q70443154": "yK",
+ "Q70443282": "zK",
+ "Q70443367": "fK",
+ "Q70443453": "TK",
+ "Q70443757": "pK",
+ "Q70443901": "YK",
+ "Q70444029": "PK",
+ "Q70444141": "Emol",
+ "Q70444284": "ymol",
+ "Q70444386": "zmol",
+ "Q70444514": "Ymol",
+ "Q70444609": "Pmol",
+ "Q712226": "km²",
+ "Q72081071": "MeV",
+ "Q723733": "ms",
+ "Q730251": "ft·lbf",
+ "Q732707": "MHz",
+ "Q73408": "K",
+ "Q7350781": "Mb/s",
+ "Q743895": "bpm",
+ "Q748716": "ft/s",
+ "Q750178": "‱",
+ "Q752197": "kJ/mol",
+ "Q7672057": "TU",
+ "Q777017": "dBm",
+ "Q78754556": "rot",
+ "Q78756901": "rev",
+ "Q78757683": "windings",
+ "Q79726": "kB",
+ "Q79735": "MB",
+ "Q79738": "GB",
+ "Q79741": "TB",
+ "Q79744": "PB",
+ "Q79745": "EB",
+ "Q79747": "ZB",
+ "Q7974920": "W s",
+ "Q79752": "YB",
+ "Q79756": "KiB",
+ "Q79758": "MiB",
+ "Q79765": "GiB",
+ "Q79769": "TiB",
+ "Q79774": "PiB",
+ "Q79777": "EiB",
+ "Q79779": "ZiB",
+ "Q79781": "YiB",
+ "Q80237579": "J/nm",
+ "Q809678": "Ba",
+ "Q81062869": "W/nm",
+ "Q81073100": "W/(sr nm)",
+ "Q81292": "acre",
+ "Q81454": "Å",
+ "Q8229770": "B/s",
+ "Q828224": "km",
+ "Q829073": "\"",
+ "Q83216": "cd",
+ "Q83327": "eV",
+ "Q834105": "g/L",
+ "Q835916": "IU",
+ "Q838801": "ns",
+ "Q842015": "μs",
+ "Q842981": "thm (US)",
+ "Q844211": "kg/m³",
+ "Q844338": "hm",
+ "Q844976": "Oe",
+ "Q845958": "¥",
+ "Q848856": "dam",
+ "Q851872": "o",
+ "Q854546": "Gm",
+ "Q855161": "Yibit",
+ "Q856240": "ft³/min",
+ "Q857027": "ft²",
+ "Q85854198": "MN",
+ "Q864818": "abA",
+ "Q87262709": "kΩ",
+ "Q87416053": "MΩ",
+ "Q88296091": "tsp",
+ "Q9026416": "MWth",
+ "Q9048643": "nl",
+ "Q905912": "L",
+ "Q906223": "Es",
+ "Q909066": "at",
+ "Q911730": "nx",
+ "Q914151": "P_P",
+ "Q915169": "F_P",
+ "Q93318": "nmi",
+ "Q940052": "q",
+ "Q94076025": "dalm",
+ "Q94076717": "dakat",
+ "Q942092": "BWI$",
+ "Q94414053": "Prad",
+ "Q94414499": "PC",
+ "Q94415026": "Grad",
+ "Q94415255": "GC",
+ "Q94415438": "Yrad",
+ "Q94415526": "YC",
+ "Q94415782": "Mrad",
+ "Q94416260": "GN",
+ "Q94416535": "cN",
+ "Q94416879": "YN",
+ "Q94417138": "PN",
+ "Q94417481": "μGy",
+ "Q94417583": "μS",
+ "Q94417598": "μT",
+ "Q94417933": "μlm",
+ "Q94418102": "μN",
+ "Q94418220": "μsr",
+ "Q94418481": "μBq",
+ "Q94479580": "GΩ",
+ "Q94480021": "PΩ",
+ "Q94480081": "YΩ",
+ "Q94480128": "cΩ",
+ "Q94480131": "TΩ",
+ "Q94480136": "pΩ",
+ "Q94480254": "nΩ",
+ "Q94480476": "dΩ",
+ "Q94480633": "EΩ",
+ "Q94480967": "daΩ",
+ "Q94481176": "hΩ",
+ "Q94481339": "fΩ",
+ "Q94481646": "yΩ",
+ "Q94487174": "zΩ",
+ "Q94487366": "mΩ",
+ "Q94487561": "μΩ",
+ "Q94487750": "kGy",
+ "Q94488007": "klx",
+ "Q94488361": "MF",
+ "Q94488759": "GBq",
+ "Q94489041": "PBq",
+ "Q94489223": "YBq",
+ "Q94489429": "MBq",
+ "Q94489465": "kBq",
+ "Q94489476": "TBq",
+ "Q94489494": "kWb",
+ "Q94489520": "kS",
+ "Q94490951": "klm",
+ "Q94491129": "kkat",
+ "Q94634634": "cC",
+ "Q94634655": "MC",
+ "Q94634666": "kC",
+ "Q94634677": "TC",
+ "Q94634684": "μC",
+ "Q94634699": "mC",
+ "Q94693759": "csr",
+ "Q94693773": "msr",
+ "Q94693786": "mWb",
+ "Q94693805": "μWb",
+ "Q94693819": "GS",
+ "Q94693849": "cS",
+ "Q94693918": "MS",
+ "Q94694019": "TS",
+ "Q94694096": "pS",
+ "Q94694154": "nS",
+ "Q94694206": "mS",
+ "Q94731530": "mlm",
+ "Q94731808": "mkat",
+ "Q94731887": "μkat",
+ "Q94732218": "nkat",
+ "Q94732627": "pkat",
+ "Q94733432": "fkat",
+ "Q94733760": "cGy",
+ "Q94734107": "dGy",
+ "Q94734232": "mGy",
+ "Q94734359": "daGy",
+ "Q94734468": "aGy",
+ "Q94734527": "pGy",
+ "Q94734593": "nGy",
+ "Q94734689": "kT",
+ "Q94734788": "mT",
+ "Q94939947": "Gkat",
+ "Q94940018": "Pkat",
+ "Q94940081": "ykat",
+ "Q94940160": "dkat",
+ "Q94940232": "Ekat",
+ "Q94940295": "Ykat",
+ "Q94940582": "Tkat",
+ "Q94940892": "hkat",
+ "Q94941461": "zkat",
+ "Q94942602": "MGy",
+ "Q94942863": "GGy",
+ "Q94986863": "YWb",
+ "Q94986889": "PWb",
+ "Q94986906": "cWb",
+ "Q94986920": "GWb",
+ "Q94986942": "MWb",
+ "Q94986962": "TWb",
+ "Q95178536": "Mlm",
+ "Q95178777": "Tlm",
+ "Q95178881": "clm",
+ "Q95179024": "plm",
+ "Q95179137": "nlm",
+ "Q95179382": "hlm",
+ "Q95179467": "flm",
+ "Q95179608": "zlm",
+ "Q95179695": "Mkat",
+ "Q95179788": "ckat",
+ "Q95179882": "PGy",
+ "Q95377836": "PF",
+ "Q95377853": "YF",
+ "Q95378017": "kF",
+ "Q95378296": "TF",
+ "Q95379145": "cF",
+ "Q95379382": "GF",
+ "Q95379491": "daC",
+ "Q95379580": "hC",
+ "Q95379588": "dC",
+ "Q95379596": "EC",
+ "Q95445986": "nC",
+ "Q95446327": "pC",
+ "Q95446670": "fC",
+ "Q95447079": "zC",
+ "Q95447237": "yC",
+ "Q95447253": "fF",
+ "Q95447263": "zF",
+ "Q95447276": "aF",
+ "Q95447555": "dF",
+ "Q95447863": "EF",
+ "Q95448262": "yF",
+ "Q95448479": "hF",
+ "Q95448689": "daF",
+ "Q95448950": "kSv",
+ "Q95559229": "GSv",
+ "Q95559368": "YSv",
+ "Q95559441": "MSv",
+ "Q95559576": "TSv",
+ "Q95559603": "PSv",
+ "Q95609154": "nWb",
+ "Q95609210": "fWb",
+ "Q95609261": "zWb",
+ "Q95609291": "dWb",
+ "Q95609317": "EWb",
+ "Q95676212": "pWb",
+ "Q95676232": "yWb",
+ "Q95676243": "hWb",
+ "Q95676250": "daWb",
+ "Q95676257": "PS",
+ "Q95676260": "YS",
+ "Q95676273": "zS",
+ "Q95676275": "fS",
+ "Q95676279": "yS",
+ "Q95676287": "hS",
+ "Q95676291": "daS",
+ "Q95676297": "dS",
+ "Q95676298": "ES",
+ "Q95720731": "YGy",
+ "Q95720734": "TGy",
+ "Q95720736": "fGy",
+ "Q95720739": "yGy",
+ "Q95720741": "zGy",
+ "Q95720742": "EGy",
+ "Q95720746": "hGy",
+ "Q95720749": "mlx",
+ "Q95720758": "μlx",
+ "Q95720773": "dalx",
+ "Q95720777": "hlx",
+ "Q95720781": "dlx",
+ "Q95720786": "clx",
+ "Q95857671": "zSv",
+ "Q95859071": "fSv",
+ "Q95860960": "daSv",
+ "Q95861107": "hSv",
+ "Q95861296": "dSv",
+ "Q95862182": "ESv",
+ "Q95863358": "cSv",
+ "Q95863591": "ySv",
+ "Q95863894": "pSv",
+ "Q95864194": "zBq",
+ "Q95864378": "fBq",
+ "Q95864695": "daBq",
+ "Q95864940": "hBq",
+ "Q95865286": "dBq",
+ "Q95865530": "EBq",
+ "Q95865716": "cBq",
+ "Q95865877": "yBq",
+ "Q95866173": "pBq",
+ "Q95866344": "nBq",
+ "Q95866767": "mBq",
+ "Q95867993": "mN",
+ "Q95948345": "crad",
+ "Q95948364": "drad",
+ "Q95948734": "daN",
+ "Q95948739": "hN",
+ "Q95948747": "dN",
+ "Q95976839": "Plm",
+ "Q95976853": "Glm",
+ "Q95976869": "Ylm",
+ "Q95976889": "ylm",
+ "Q95976917": "dlm",
+ "Q95976919": "Elm",
+ "Q95976921": "nT",
+ "Q95993516": "TN",
+ "Q95993522": "nN",
+ "Q95993524": "fN",
+ "Q95993526": "yN",
+ "Q95993528": "zN",
+ "Q95993530": "EN",
+ "Q95993532": "pN",
+ "Q95993537": "μrad",
+ "Q95993542": "nrad",
+ "Q95993547": "frad",
+ "Q95993553": "prad",
+ "Q95993554": "darad",
+ "Q95993557": "hrad",
+ "Q95993619": "pT",
+ "Q96025401": "daT",
+ "Q96025405": "Trad",
+ "Q96025407": "Zrad",
+ "Q96025409": "zrad",
+ "Q96025413": "yrad",
+ "Q96025414": "Erad",
+ "Q96025419": "Ylx",
+ "Q96025422": "Glx",
+ "Q96025427": "Plx",
+ "Q96025431": "Mlx",
+ "Q96025433": "Tlx",
+ "Q96025435": "nlx",
+ "Q96025441": "flx",
+ "Q96050953": "GH",
+ "Q96051010": "PH",
+ "Q96051029": "YH",
+ "Q96051052": "cH",
+ "Q96051074": "TH",
+ "Q96051106": "MH",
+ "Q96051123": "kH",
+ "Q96051126": "fH",
+ "Q96051133": "yH",
+ "Q96051139": "hH",
+ "Q96051142": "dH",
+ "Q96051144": "EH",
+ "Q96051150": "pH",
+ "Q96051160": "daH",
+ "Q96051186": "zH",
+ "Q96051199": "aH",
+ "Q96051245": "ylx",
+ "Q96051267": "Elx",
+ "Q96051282": "plx",
+ "Q96051312": "zlx",
+ "Q96070067": "PT",
+ "Q96070074": "YT",
+ "Q96070076": "GT",
+ "Q96070087": "cT",
+ "Q96070103": "MT",
+ "Q96070125": "hT",
+ "Q96070145": "fT",
+ "Q96070174": "TT",
+ "Q96070195": "zT",
+ "Q96070247": "yT",
+ "Q96070254": "dT",
+ "Q96070264": "ET",
+ "Q96070276": "m°C",
+ "Q96070318": "dsr",
+ "Q96070329": "nsr",
+ "Q96070341": "psr",
+ "Q96095866": "fsr",
+ "Q96095897": "zsr",
+ "Q96095917": "ysr",
+ "Q96095927": "dasr",
+ "Q96095928": "hsr",
+ "Q96095931": "ksr",
+ "Q96095933": "Msr",
+ "Q96095939": "Gsr",
+ "Q96095941": "μ°C",
+ "Q96095955": "n°C",
+ "Q96095960": "k°C",
+ "Q96106290": "Tsr",
+ "Q96106298": "Psr",
+ "Q96106311": "Esr",
+ "Q96106319": "Zsr",
+ "Q96106332": "Ysr",
+ "Q96106346": "c°C",
+ "Q96106360": "d°C",
+ "Q96106368": "da°C",
+ "Q96106385": "h°C",
+ "Q96106393": "M°C",
+ "Q96236286": "G°C",
+ "Q97059641": "p°C",
+ "Q97059652": "T°C",
+ "Q97143826": "P°C",
+ "Q97143831": "y°C",
+ "Q97143835": "f°C",
+ "Q97143838": "Z°C",
+ "Q97143842": "E°C",
+ "Q97143843": "z°C",
+ "Q97143849": "Y°C",
+ "Q97143851": "a°C",
+ "Q98538634": "eV/m²",
+ "Q98635536": "eV/m",
+ "Q98642859": "eV m²/kg",
+ "Q11229": "%",
+ "Q11570": "kg",
+ "Q11573": "m",
+ "Q11574": "s",
+ "Q11579": "K",
+ "Q11582": "L",
+ "Q12129": "pc",
+ "Q12438": "N",
+ "Q16068": "DM",
+ "Q1811": "ua",
+ "Q20764": "Myr",
+ "Q2101": "e",
+ "Q25235": "h",
+ "Q25236": "W",
+ "Q25250": "V",
+ "Q25267": "°C",
+ "Q25269": "J",
+ "Q25272": "A",
+ "Q25343": "m²",
+ "Q25406": "C",
+ "Q25517": "m³",
+ "Q33680": "rad",
+ "Q35852": "ha",
+ "Q36384": "equiv",
+ "Q3710": "ft",
+ "Q39274": "Sv",
+ "Q39369": "Hz",
+ "Q41509": "mol",
+ "Q41803": "g",
+ "Q42289": "°F",
+ "Q4406": "TV$",
+ "Q44395": "Pa",
+ "Q4587": "Le",
+ "Q4588": "WS$",
+ "Q4592": "F$",
+ "Q4596": "Rs",
+ "Q4597": "$",
+ "Q47083": "Ω",
+ "Q48013": "oz",
+ "Q50094": "Np",
+ "Q50098": "B",
+ "Q531": "ly",
+ "Q5329": "dB",
+ "Q573": "d",
+ "Q577": "a",
+ "Q7727": "min",
+ "Q8799": "B"
+} \ No newline at end of file
diff --git a/searx/engines/1337x.py b/searx/engines/1337x.py
index 0de04bd..1847887 100644
--- a/searx/engines/1337x.py
+++ b/searx/engines/1337x.py
@@ -1,7 +1,7 @@
+from urllib.parse import quote, urljoin
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.utils import get_torrent_size
-from searx.url_utils import quote, urljoin
+from searx.utils import extract_text, get_torrent_size, eval_xpath, eval_xpath_list, eval_xpath_getindex
+
url = 'https://1337x.to/'
search_url = url + 'search/{search_term}/{pageno}/'
@@ -20,12 +20,12 @@ def response(resp):
dom = html.fromstring(resp.text)
- for result in dom.xpath('//table[contains(@class, "table-list")]/tbody//tr'):
- href = urljoin(url, result.xpath('./td[contains(@class, "name")]/a[2]/@href')[0])
- title = extract_text(result.xpath('./td[contains(@class, "name")]/a[2]'))
- seed = extract_text(result.xpath('.//td[contains(@class, "seeds")]'))
- leech = extract_text(result.xpath('.//td[contains(@class, "leeches")]'))
- filesize_info = extract_text(result.xpath('.//td[contains(@class, "size")]/text()'))
+ for result in eval_xpath_list(dom, '//table[contains(@class, "table-list")]/tbody//tr'):
+ href = urljoin(url, eval_xpath_getindex(result, './td[contains(@class, "name")]/a[2]/@href', 0))
+ title = extract_text(eval_xpath(result, './td[contains(@class, "name")]/a[2]'))
+ seed = extract_text(eval_xpath(result, './/td[contains(@class, "seeds")]'))
+ leech = extract_text(eval_xpath(result, './/td[contains(@class, "leeches")]'))
+ filesize_info = extract_text(eval_xpath(result, './/td[contains(@class, "size")]/text()'))
filesize, filesize_multiplier = filesize_info.split()
filesize = get_torrent_size(filesize, filesize_multiplier)
diff --git a/searx/engines/__init__.py b/searx/engines/__init__.py
index 48c02e2..b2a9b25 100644
--- a/searx/engines/__init__.py
+++ b/searx/engines/__init__.py
@@ -19,14 +19,14 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
import sys
import threading
from os.path import realpath, dirname
-from io import open
from babel.localedata import locale_identifiers
+from urllib.parse import urlparse
from flask_babel import gettext
from operator import itemgetter
-from json import loads
-from requests import get
from searx import settings
from searx import logger
+from searx.data import ENGINES_LANGUAGES
+from searx.poolrequests import get, get_proxy_cycles
from searx.utils import load_module, match_language, get_engine_from_settings
@@ -38,7 +38,6 @@ engines = {}
categories = {'general': []}
-languages = loads(open(engine_dir + '/../data/engines_languages.json', 'r', encoding='utf-8').read())
babel_langs = [lang_parts[0] + '-' + lang_parts[-1] if len(lang_parts) > 1 else lang_parts[0]
for lang_parts in (lang_code.split('_') for lang_code in locale_identifiers())]
@@ -74,20 +73,25 @@ def load_engine(engine_data):
try:
engine = load_module(engine_module + '.py', engine_dir)
+ except (SyntaxError, KeyboardInterrupt, SystemExit, SystemError, ImportError, RuntimeError):
+ logger.exception('Fatal exception in engine "{}"'.format(engine_module))
+ sys.exit(1)
except:
logger.exception('Cannot load engine "{}"'.format(engine_module))
return None
- for param_name in engine_data:
+ for param_name, param_value in engine_data.items():
if param_name == 'engine':
- continue
- if param_name == 'categories':
- if engine_data['categories'] == 'none':
+ pass
+ elif param_name == 'categories':
+ if param_value == 'none':
engine.categories = []
else:
- engine.categories = list(map(str.strip, engine_data['categories'].split(',')))
- continue
- setattr(engine, param_name, engine_data[param_name])
+ engine.categories = list(map(str.strip, param_value.split(',')))
+ elif param_name == 'proxies':
+ engine.proxies = get_proxy_cycles(param_value)
+ else:
+ setattr(engine, param_name, param_value)
for arg_name, arg_value in engine_default_args.items():
if not hasattr(engine, arg_name):
@@ -105,8 +109,8 @@ def load_engine(engine_data):
sys.exit(1)
# assign supported languages from json file
- if engine_data['name'] in languages:
- setattr(engine, 'supported_languages', languages[engine_data['name']])
+ if engine_data['name'] in ENGINES_LANGUAGES:
+ setattr(engine, 'supported_languages', ENGINES_LANGUAGES[engine_data['name']])
# find custom aliases for non standard language codes
if hasattr(engine, 'supported_languages'):
@@ -129,8 +133,9 @@ def load_engine(engine_data):
lambda: engine._fetch_supported_languages(get(engine.supported_languages_url)))
engine.stats = {
+ 'sent_search_count': 0, # sent search
+ 'search_count': 0, # succesful search
'result_count': 0,
- 'search_count': 0,
'engine_time': 0,
'engine_time_count': 0,
'score_count': 0,
@@ -141,6 +146,17 @@ def load_engine(engine_data):
engine.stats['page_load_time'] = 0
engine.stats['page_load_count'] = 0
+ # tor related settings
+ if settings['outgoing'].get('using_tor_proxy'):
+ # use onion url if using tor.
+ if hasattr(engine, 'onion_url'):
+ engine.search_url = engine.onion_url + getattr(engine, 'search_path', '')
+ elif 'onions' in engine.categories:
+ # exclude onion engines if not using tor.
+ return None
+
+ engine.timeout += settings['outgoing'].get('extra_proxy_timeout', 0)
+
for category_name in engine.categories:
categories.setdefault(category_name, []).append(engine)
@@ -220,7 +236,7 @@ def get_engines_stats(preferences):
results = to_percentage(results, max_results)
scores = to_percentage(scores, max_score)
scores_per_result = to_percentage(scores_per_result, max_score_per_result)
- erros = to_percentage(errors, max_errors)
+ errors = to_percentage(errors, max_errors)
return [
(
@@ -251,8 +267,9 @@ def get_engines_stats(preferences):
def load_engines(engine_list):
- global engines
+ global engines, engine_shortcuts
engines.clear()
+ engine_shortcuts.clear()
for engine_data in engine_list:
engine = load_engine(engine_data)
if engine is not None:
@@ -264,8 +281,12 @@ def initialize_engines(engine_list):
load_engines(engine_list)
def engine_init(engine_name, init_fn):
- init_fn(get_engine_from_settings(engine_name))
- logger.debug('%s engine: Initialized', engine_name)
+ try:
+ init_fn(get_engine_from_settings(engine_name))
+ except Exception:
+ logger.exception('%s engine: Fail to initialize', engine_name)
+ else:
+ logger.debug('%s engine: Initialized', engine_name)
for engine_name, engine in engines.items():
if hasattr(engine, 'init'):
@@ -273,3 +294,34 @@ def initialize_engines(engine_list):
if init_fn:
logger.debug('%s engine: Starting background initialization', engine_name)
threading.Thread(target=engine_init, args=(engine_name, init_fn)).start()
+
+ _set_https_support_for_engine(engine)
+
+
+def _set_https_support_for_engine(engine):
+ # check HTTPS support if it is not disabled
+ if not engine.offline and not hasattr(engine, 'https_support'):
+ params = engine.request('http_test', {
+ 'method': 'GET',
+ 'headers': {},
+ 'data': {},
+ 'url': '',
+ 'cookies': {},
+ 'verify': True,
+ 'auth': None,
+ 'pageno': 1,
+ 'time_range': None,
+ 'language': '',
+ 'safesearch': False,
+ 'is_test': True,
+ 'category': 'files',
+ 'raise_for_status': True,
+ })
+
+ if 'url' not in params:
+ return
+
+ parsed_url = urlparse(params['url'])
+ https_support = parsed_url.scheme == 'https'
+
+ setattr(engine, 'https_support', https_support)
diff --git a/searx/engines/acgsou.py b/searx/engines/acgsou.py
index cca28f0..637443e 100644
--- a/searx/engines/acgsou.py
+++ b/searx/engines/acgsou.py
@@ -9,17 +9,16 @@
@parse url, title, content, seed, leech, torrentfile
"""
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
-from searx.utils import get_torrent_size, int_or_zero
+from searx.utils import extract_text, get_torrent_size, eval_xpath_list, eval_xpath_getindex
# engine dependent config
categories = ['files', 'images', 'videos', 'music']
paging = True
# search-url
-base_url = 'http://www.acgsou.com/'
+base_url = 'https://www.acgsou.com/'
search_url = base_url + 'search.php?{query}&page={offset}'
# xpath queries
xpath_results = '//table[contains(@class, "list_style table_fixed")]//tr[not(th)]'
@@ -38,32 +37,28 @@ def request(query, params):
def response(resp):
results = []
dom = html.fromstring(resp.text)
- for result in dom.xpath(xpath_results):
+ for result in eval_xpath_list(dom, xpath_results):
# defaults
filesize = 0
- magnet_link = "magnet:?xt=urn:btih:{}&tr=http://tracker.acgsou.com:2710/announce"
- torrent_link = ""
+ magnet_link = "magnet:?xt=urn:btih:{}&tr=https://tracker.acgsou.com:2710/announce"
- try:
- category = extract_text(result.xpath(xpath_category)[0])
- except:
- pass
-
- page_a = result.xpath(xpath_title)[0]
+ category = extract_text(eval_xpath_getindex(result, xpath_category, 0, default=[]))
+ page_a = eval_xpath_getindex(result, xpath_title, 0)
title = extract_text(page_a)
href = base_url + page_a.attrib.get('href')
magnet_link = magnet_link.format(page_a.attrib.get('href')[5:-5])
- try:
- filesize_info = result.xpath(xpath_filesize)[0]
- filesize = filesize_info[:-2]
- filesize_multiplier = filesize_info[-2:]
- filesize = get_torrent_size(filesize, filesize_multiplier)
- except:
- pass
+ filesize_info = eval_xpath_getindex(result, xpath_filesize, 0, default=None)
+ if filesize_info:
+ try:
+ filesize = filesize_info[:-2]
+ filesize_multiplier = filesize_info[-2:]
+ filesize = get_torrent_size(filesize, filesize_multiplier)
+ except:
+ pass
# I didn't add download/seed/leech count since as I figured out they are generated randomly everytime
- content = u'Category: "{category}".'
+ content = 'Category: "{category}".'
content = content.format(category=category)
results.append({'url': href,
diff --git a/searx/engines/ahmia.py b/searx/engines/ahmia.py
new file mode 100644
index 0000000..7a2ae00
--- /dev/null
+++ b/searx/engines/ahmia.py
@@ -0,0 +1,82 @@
+"""
+ Ahmia (Onions)
+
+ @website http://msydqstlz2kzerdg.onion
+ @provides-api no
+
+ @using-api no
+ @results HTML
+ @stable no
+ @parse url, title, content
+"""
+
+from urllib.parse import urlencode, urlparse, parse_qs
+from lxml.html import fromstring
+from searx.engines.xpath import extract_url, extract_text, eval_xpath_list, eval_xpath
+
+# engine config
+categories = ['onions']
+paging = True
+page_size = 10
+
+# search url
+search_url = 'http://msydqstlz2kzerdg.onion/search/?{query}'
+time_range_support = True
+time_range_dict = {'day': 1,
+ 'week': 7,
+ 'month': 30}
+
+# xpaths
+results_xpath = '//li[@class="result"]'
+url_xpath = './h4/a/@href'
+title_xpath = './h4/a[1]'
+content_xpath = './/p[1]'
+correction_xpath = '//*[@id="didYouMean"]//a'
+number_of_results_xpath = '//*[@id="totalResults"]'
+
+
+def request(query, params):
+ params['url'] = search_url.format(query=urlencode({'q': query}))
+
+ if params['time_range'] in time_range_dict:
+ params['url'] += '&' + urlencode({'d': time_range_dict[params['time_range']]})
+
+ return params
+
+
+def response(resp):
+ results = []
+ dom = fromstring(resp.text)
+
+ # trim results so there's not way too many at once
+ first_result_index = page_size * (resp.search_params.get('pageno', 1) - 1)
+ all_results = eval_xpath_list(dom, results_xpath)
+ trimmed_results = all_results[first_result_index:first_result_index + page_size]
+
+ # get results
+ for result in trimmed_results:
+ # remove ahmia url and extract the actual url for the result
+ raw_url = extract_url(eval_xpath_list(result, url_xpath, min_len=1), search_url)
+ cleaned_url = parse_qs(urlparse(raw_url).query).get('redirect_url', [''])[0]
+
+ title = extract_text(eval_xpath(result, title_xpath))
+ content = extract_text(eval_xpath(result, content_xpath))
+
+ results.append({'url': cleaned_url,
+ 'title': title,
+ 'content': content,
+ 'is_onion': True})
+
+ # get spelling corrections
+ for correction in eval_xpath_list(dom, correction_xpath):
+ results.append({'correction': extract_text(correction)})
+
+ # get number of results
+ number_of_results = eval_xpath(dom, number_of_results_xpath)
+ if number_of_results:
+ try:
+ results.append({'number_of_results': int(extract_text(number_of_results))})
+ except:
+ pass
+
+ return results
diff --git a/searx/engines/apkmirror.py b/searx/engines/apkmirror.py
index f2ee12b..3a948dc 100644
--- a/searx/engines/apkmirror.py
+++ b/searx/engines/apkmirror.py
@@ -9,9 +9,10 @@
@parse url, title, thumbnail_src
"""
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
+from searx.utils import extract_text, eval_xpath_list, eval_xpath_getindex
+
# engine dependent config
categories = ['it']
@@ -41,12 +42,13 @@ def response(resp):
dom = html.fromstring(resp.text)
# parse results
- for result in dom.xpath('.//div[@id="content"]/div[@class="listWidget"]/div[@class="appRow"]'):
+ for result in eval_xpath_list(dom, './/div[@id="content"]/div[@class="listWidget"]/div[@class="appRow"]'):
- link = result.xpath('.//h5/a')[0]
+ link = eval_xpath_getindex(result, './/h5/a', 0)
url = base_url + link.attrib.get('href') + '#downloads'
title = extract_text(link)
- thumbnail_src = base_url + result.xpath('.//img')[0].attrib.get('src').replace('&w=32&h=32', '&w=64&h=64')
+ thumbnail_src = base_url\
+ + eval_xpath_getindex(result, './/img', 0).attrib.get('src').replace('&w=32&h=32', '&w=64&h=64')
res = {
'url': url,
diff --git a/searx/engines/archlinux.py b/searx/engines/archlinux.py
index dce862f..04117c0 100644
--- a/searx/engines/archlinux.py
+++ b/searx/engines/archlinux.py
@@ -11,9 +11,9 @@
@parse url, title
"""
+from urllib.parse import urlencode, urljoin
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode, urljoin
+from searx.utils import extract_text, eval_xpath_list, eval_xpath_getindex
# engine dependent config
categories = ['it']
@@ -105,7 +105,7 @@ def request(query, params):
# if our language is hosted on the main site, we need to add its name
# to the query in order to narrow the results to that language
if language in main_langs:
- query += b' (' + main_langs[language] + b')'
+ query += ' (' + main_langs[language] + ')'
# prepare the request parameters
query = urlencode({'search': query})
@@ -131,8 +131,8 @@ def response(resp):
dom = html.fromstring(resp.text)
# parse results
- for result in dom.xpath(xpath_results):
- link = result.xpath(xpath_link)[0]
+ for result in eval_xpath_list(dom, xpath_results):
+ link = eval_xpath_getindex(result, xpath_link, 0)
href = urljoin(base_url, link.attrib.get('href'))
title = extract_text(link)
diff --git a/searx/engines/arxiv.py b/searx/engines/arxiv.py
index e3c871d..1190de3 100644
--- a/searx/engines/arxiv.py
+++ b/searx/engines/arxiv.py
@@ -13,13 +13,13 @@
from lxml import html
from datetime import datetime
-from searx.url_utils import urlencode
+from searx.utils import eval_xpath_list, eval_xpath_getindex
categories = ['science']
paging = True
-base_url = 'http://export.arxiv.org/api/query?search_query=all:'\
+base_url = 'https://export.arxiv.org/api/query?search_query=all:'\
+ '{query}&start={offset}&max_results={number_of_results}'
# engine dependent config
@@ -30,7 +30,7 @@ def request(query, params):
# basic search
offset = (params['pageno'] - 1) * number_of_results
- string_args = dict(query=query.decode('utf-8'),
+ string_args = dict(query=query,
offset=offset,
number_of_results=number_of_results)
@@ -43,29 +43,26 @@ def response(resp):
results = []
dom = html.fromstring(resp.content)
- search_results = dom.xpath('//entry')
- for entry in search_results:
- title = entry.xpath('.//title')[0].text
+ for entry in eval_xpath_list(dom, '//entry'):
+ title = eval_xpath_getindex(entry, './/title', 0).text
- url = entry.xpath('.//id')[0].text
+ url = eval_xpath_getindex(entry, './/id', 0).text
content_string = '{doi_content}{abstract_content}'
- abstract = entry.xpath('.//summary')[0].text
+ abstract = eval_xpath_getindex(entry, './/summary', 0).text
# If a doi is available, add it to the snipppet
- try:
- doi_content = entry.xpath('.//link[@title="doi"]')[0].text
- content = content_string.format(doi_content=doi_content, abstract_content=abstract)
- except:
- content = content_string.format(doi_content="", abstract_content=abstract)
+ doi_element = eval_xpath_getindex(entry, './/link[@title="doi"]', 0, default=None)
+ doi_content = doi_element.text if doi_element is not None else ''
+ content = content_string.format(doi_content=doi_content, abstract_content=abstract)
if len(content) > 300:
- content = content[0:300] + "..."
+ content = content[0:300] + "..."
# TODO: center snippet on query term
- publishedDate = datetime.strptime(entry.xpath('.//published')[0].text, '%Y-%m-%dT%H:%M:%SZ')
+ publishedDate = datetime.strptime(eval_xpath_getindex(entry, './/published', 0).text, '%Y-%m-%dT%H:%M:%SZ')
res_dict = {'url': url,
'title': title,
diff --git a/searx/engines/base.py b/searx/engines/base.py
index f1b1cf6..3648d7e 100755
--- a/searx/engines/base.py
+++ b/searx/engines/base.py
@@ -13,10 +13,10 @@
More info on api: http://base-search.net/about/download/base_interface.pdf
"""
+from urllib.parse import urlencode
from lxml import etree
from datetime import datetime
import re
-from searx.url_utils import urlencode
from searx.utils import searx_useragent
@@ -55,7 +55,7 @@ shorcut_dict = {
def request(query, params):
# replace shortcuts with API advanced search keywords
for key in shorcut_dict.keys():
- query = re.sub(key, shorcut_dict[key], str(query))
+ query = re.sub(key, shorcut_dict[key], query)
# basic search
offset = (params['pageno'] - 1) * number_of_results
@@ -80,10 +80,7 @@ def response(resp):
date = datetime.now() # needed in case no dcdate is available for an item
for item in entry:
- if item.attrib["name"] == "dchdate":
- harvestDate = item.text
-
- elif item.attrib["name"] == "dcdate":
+ if item.attrib["name"] == "dcdate":
date = item.text
elif item.attrib["name"] == "dctitle":
diff --git a/searx/engines/bing.py b/searx/engines/bing.py
index afb776a..f0882fc 100644
--- a/searx/engines/bing.py
+++ b/searx/engines/bing.py
@@ -14,11 +14,10 @@
"""
import re
+from urllib.parse import urlencode
from lxml import html
-from searx import logger, utils
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
-from searx.utils import match_language, gen_useragent, eval_xpath
+from searx import logger
+from searx.utils import eval_xpath, extract_text, match_language
logger = logger.getChild('bing engine')
@@ -47,7 +46,7 @@ def request(query, params):
else:
lang = match_language(params['language'], supported_languages, language_aliases)
- query = u'language:{} {}'.format(lang.split('-')[0].upper(), query.decode('utf-8')).encode('utf-8')
+ query = 'language:{} {}'.format(lang.split('-')[0].upper(), query)
search_path = search_string.format(
query=urlencode({'q': query}),
@@ -99,7 +98,6 @@ def response(resp):
result_len = int(result_len_container)
except Exception as e:
logger.debug('result error :\n%s', e)
- pass
if result_len and _get_offset_from_pageno(resp.search_params.get("pageno", 0)) > result_len:
return []
diff --git a/searx/engines/bing_images.py b/searx/engines/bing_images.py
index 138ed11..2bcf82b 100644
--- a/searx/engines/bing_images.py
+++ b/searx/engines/bing_images.py
@@ -12,13 +12,13 @@
"""
+from urllib.parse import urlencode
from lxml import html
from json import loads
-import re
-from searx.url_utils import urlencode
from searx.utils import match_language
-from searx.engines.bing import _fetch_supported_languages, supported_languages_url, language_aliases
+from searx.engines.bing import language_aliases
+from searx.engines.bing import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
# engine dependent config
categories = ['images']
@@ -80,19 +80,18 @@ def response(resp):
# parse results
for result in dom.xpath('//div[@class="imgpt"]'):
-
- img_format = result.xpath('./div[contains(@class, "img_info")]/span/text()')[0]
- # Microsoft seems to experiment with this code so don't make the path too specific,
- # just catch the text section for the first anchor in img_info assuming this to be
- # the originating site.
- source = result.xpath('./div[contains(@class, "img_info")]//a/text()')[0]
-
try:
+ img_format = result.xpath('./div[contains(@class, "img_info")]/span/text()')[0]
+ # Microsoft seems to experiment with this code so don't make the path too specific,
+ # just catch the text section for the first anchor in img_info assuming this to be
+ # the originating site.
+ source = result.xpath('./div[contains(@class, "img_info")]//a/text()')[0]
+
m = loads(result.xpath('./a/@m')[0])
# strip 'Unicode private use area' highlighting, they render to Tux
# the Linux penguin and a standing diamond on my machine...
- title = m.get('t', '').replace(u'\ue000', '').replace(u'\ue001', '')
+ title = m.get('t', '').replace('\ue000', '').replace('\ue001', '')
results.append({'template': 'images.html',
'url': m['purl'],
'thumbnail_src': m['turl'],
diff --git a/searx/engines/bing_news.py b/searx/engines/bing_news.py
index d13be77..b95def4 100644
--- a/searx/engines/bing_news.py
+++ b/searx/engines/bing_news.py
@@ -13,11 +13,12 @@
from datetime import datetime
from dateutil import parser
+from urllib.parse import urlencode, urlparse, parse_qsl
from lxml import etree
-from searx.utils import list_get, match_language
-from searx.url_utils import urlencode, urlparse, parse_qsl
-
-from searx.engines.bing import _fetch_supported_languages, supported_languages_url, language_aliases
+from lxml.etree import XPath
+from searx.utils import match_language, eval_xpath_getindex
+from searx.engines.bing import language_aliases
+from searx.engines.bing import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
# engine dependent config
categories = ['news']
@@ -94,12 +95,12 @@ def response(resp):
# parse results
for item in rss.xpath('./channel/item'):
# url / title / content
- url = url_cleanup(item.xpath('./link/text()')[0])
- title = list_get(item.xpath('./title/text()'), 0, url)
- content = list_get(item.xpath('./description/text()'), 0, '')
+ url = url_cleanup(eval_xpath_getindex(item, './link/text()', 0, default=None))
+ title = eval_xpath_getindex(item, './title/text()', 0, default=url)
+ content = eval_xpath_getindex(item, './description/text()', 0, default='')
# publishedDate
- publishedDate = list_get(item.xpath('./pubDate/text()'), 0)
+ publishedDate = eval_xpath_getindex(item, './pubDate/text()', 0, default=None)
try:
publishedDate = parser.parse(publishedDate, dayfirst=False)
except TypeError:
@@ -108,7 +109,7 @@ def response(resp):
publishedDate = datetime.now()
# thumbnail
- thumbnail = list_get(item.xpath('./News:Image/text()', namespaces=ns), 0)
+ thumbnail = eval_xpath_getindex(item, XPath('./News:Image/text()', namespaces=ns), 0, default=None)
if thumbnail is not None:
thumbnail = image_url_cleanup(thumbnail)
diff --git a/searx/engines/bing_videos.py b/searx/engines/bing_videos.py
index f048f0d..143c71a 100644
--- a/searx/engines/bing_videos.py
+++ b/searx/engines/bing_videos.py
@@ -12,10 +12,11 @@
from json import loads
from lxml import html
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from searx.utils import match_language
-from searx.engines.bing import _fetch_supported_languages, supported_languages_url, language_aliases
+from searx.engines.bing import language_aliases
+from searx.engines.bing import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
categories = ['videos']
paging = True
diff --git a/searx/engines/btdigg.py b/searx/engines/btdigg.py
index 82eedc2..72bda8d 100644
--- a/searx/engines/btdigg.py
+++ b/searx/engines/btdigg.py
@@ -11,10 +11,8 @@
"""
from lxml import html
-from operator import itemgetter
-from searx.engines.xpath import extract_text
-from searx.url_utils import quote, urljoin
-from searx.utils import get_torrent_size
+from urllib.parse import quote, urljoin
+from searx.utils import extract_text, get_torrent_size
# engine dependent config
categories = ['videos', 'music', 'files']
diff --git a/searx/engines/command.py b/searx/engines/command.py
new file mode 100644
index 0000000..0268d52
--- /dev/null
+++ b/searx/engines/command.py
@@ -0,0 +1,183 @@
+'''
+searx is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+searx is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with searx. If not, see < http://www.gnu.org/licenses/ >.
+'''
+
+
+import re
+from os.path import expanduser, isabs, realpath, commonprefix
+from shlex import split as shlex_split
+from subprocess import Popen, PIPE
+from threading import Thread
+
+from searx import logger
+
+
+offline = True
+paging = True
+command = []
+delimiter = {}
+parse_regex = {}
+query_type = ''
+query_enum = []
+environment_variables = {}
+working_dir = realpath('.')
+result_separator = '\n'
+result_template = 'key-value.html'
+timeout = 4.0
+
+_command_logger = logger.getChild('command')
+_compiled_parse_regex = {}
+
+
+def init(engine_settings):
+ check_parsing_options(engine_settings)
+
+ if 'command' not in engine_settings:
+ raise ValueError('engine command : missing configuration key: command')
+
+ global command, working_dir, result_template, delimiter, parse_regex, timeout, environment_variables
+
+ command = engine_settings['command']
+
+ if 'working_dir' in engine_settings:
+ working_dir = engine_settings['working_dir']
+ if not isabs(engine_settings['working_dir']):
+ working_dir = realpath(working_dir)
+
+ if 'parse_regex' in engine_settings:
+ parse_regex = engine_settings['parse_regex']
+ for result_key, regex in parse_regex.items():
+ _compiled_parse_regex[result_key] = re.compile(regex, flags=re.MULTILINE)
+ if 'delimiter' in engine_settings:
+ delimiter = engine_settings['delimiter']
+
+ if 'environment_variables' in engine_settings:
+ environment_variables = engine_settings['environment_variables']
+
+
+def search(query, params):
+ cmd = _get_command_to_run(query)
+ if not cmd:
+ return []
+
+ results = []
+ reader_thread = Thread(target=_get_results_from_process, args=(results, cmd, params['pageno']))
+ reader_thread.start()
+ reader_thread.join(timeout=timeout)
+
+ return results
+
+
+def _get_command_to_run(query):
+ params = shlex_split(query)
+ __check_query_params(params)
+
+ cmd = []
+ for c in command:
+ if c == '{{QUERY}}':
+ cmd.extend(params)
+ else:
+ cmd.append(c)
+
+ return cmd
+
+
+def _get_results_from_process(results, cmd, pageno):
+ leftover = ''
+ count = 0
+ start, end = __get_results_limits(pageno)
+ with Popen(cmd, stdout=PIPE, stderr=PIPE, env=environment_variables) as process:
+ line = process.stdout.readline()
+ while line:
+ buf = leftover + line.decode('utf-8')
+ raw_results = buf.split(result_separator)
+ if raw_results[-1]:
+ leftover = raw_results[-1]
+ raw_results = raw_results[:-1]
+
+ for raw_result in raw_results:
+ result = __parse_single_result(raw_result)
+ if result is None:
+ _command_logger.debug('skipped result:', raw_result)
+ continue
+
+ if start <= count and count <= end:
+ result['template'] = result_template
+ results.append(result)
+
+ count += 1
+ if end < count:
+ return results
+
+ line = process.stdout.readline()
+
+ return_code = process.wait(timeout=timeout)
+ if return_code != 0:
+ raise RuntimeError('non-zero return code when running command', cmd, return_code)
+
+
+def __get_results_limits(pageno):
+ start = (pageno - 1) * 10
+ end = start + 9
+ return start, end
+
+
+def __check_query_params(params):
+ if not query_type:
+ return
+
+ if query_type == 'path':
+ query_path = params[-1]
+ query_path = expanduser(query_path)
+ if commonprefix([realpath(query_path), working_dir]) != working_dir:
+ raise ValueError('requested path is outside of configured working directory')
+ elif query_type == 'enum' and len(query_enum) > 0:
+ for param in params:
+ if param not in query_enum:
+ raise ValueError('submitted query params is not allowed', param, 'allowed params:', query_enum)
+
+
+def check_parsing_options(engine_settings):
+ """ Checks if delimiter based parsing or regex parsing is configured correctly """
+
+ if 'delimiter' not in engine_settings and 'parse_regex' not in engine_settings:
+ raise ValueError('failed to init settings for parsing lines: missing delimiter or parse_regex')
+ if 'delimiter' in engine_settings and 'parse_regex' in engine_settings:
+ raise ValueError('failed to init settings for parsing lines: too many settings')
+
+ if 'delimiter' in engine_settings:
+ if 'chars' not in engine_settings['delimiter'] or 'keys' not in engine_settings['delimiter']:
+ raise ValueError
+
+
+def __parse_single_result(raw_result):
+ """ Parses command line output based on configuration """
+
+ result = {}
+
+ if delimiter:
+ elements = raw_result.split(delimiter['chars'], maxsplit=len(delimiter['keys']) - 1)
+ if len(elements) != len(delimiter['keys']):
+ return {}
+ for i in range(len(elements)):
+ result[delimiter['keys'][i]] = elements[i]
+
+ if parse_regex:
+ for result_key, regex in _compiled_parse_regex.items():
+ found = regex.search(raw_result)
+ if not found:
+ return {}
+ result[result_key] = raw_result[found.start():found.end()]
+
+ return result
diff --git a/searx/engines/currency_convert.py b/searx/engines/currency_convert.py
index 8eab8f6..87e21d0 100644
--- a/searx/engines/currency_convert.py
+++ b/searx/engines/currency_convert.py
@@ -1,42 +1,35 @@
import json
import re
-import os
-import sys
import unicodedata
+from searx.data import CURRENCIES # NOQA
-from io import open
-from datetime import datetime
-
-if sys.version_info[0] == 3:
- unicode = str
categories = []
url = 'https://duckduckgo.com/js/spice/currency/1/{0}/{1}'
weight = 100
-parser_re = re.compile(b'.*?(\\d+(?:\\.\\d+)?) ([^.0-9]+) (?:in|to) ([^.0-9]+)', re.I)
-
-db = 1
+parser_re = re.compile('.*?(\\d+(?:\\.\\d+)?) ([^.0-9]+) (?:in|to) ([^.0-9]+)', re.I)
+https_support = True
def normalize_name(name):
- name = name.decode('utf-8').lower().replace('-', ' ').rstrip('s')
+ name = name.lower().replace('-', ' ').rstrip('s')
name = re.sub(' +', ' ', name)
return unicodedata.normalize('NFKD', name).lower()
def name_to_iso4217(name):
- global db
+ global CURRENCIES
name = normalize_name(name)
- currencies = db['names'].get(name, [name])
- return currencies[0]
+ currency = CURRENCIES['names'].get(name, [name])
+ return currency[0]
def iso4217_to_name(iso4217, language):
- global db
+ global CURRENCIES
- return db['iso4217'].get(iso4217, {}).get(language, iso4217)
+ return CURRENCIES['iso4217'].get(iso4217, {}).get(language, iso4217)
def request(query, params):
@@ -49,8 +42,6 @@ def request(query, params):
from_currency = name_to_iso4217(from_currency.strip())
to_currency = name_to_iso4217(to_currency.strip())
- q = (from_currency + to_currency).upper()
-
params['url'] = url.format(from_currency, to_currency)
params['amount'] = amount
params['from'] = from_currency
@@ -85,15 +76,3 @@ def response(resp):
results.append({'answer': answer, 'url': url})
return results
-
-
-def load():
- global db
-
- current_dir = os.path.dirname(os.path.realpath(__file__))
- json_data = open(current_dir + "/../data/currencies.json", 'r', encoding='utf-8').read()
-
- db = json.loads(json_data)
-
-
-load()
diff --git a/searx/engines/dailymotion.py b/searx/engines/dailymotion.py
index 1038e64..1e24e41 100644
--- a/searx/engines/dailymotion.py
+++ b/searx/engines/dailymotion.py
@@ -14,7 +14,7 @@
from json import loads
from datetime import datetime
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from searx.utils import match_language, html_to_text
# engine dependent config
diff --git a/searx/engines/deezer.py b/searx/engines/deezer.py
index af63478..48c0429 100644
--- a/searx/engines/deezer.py
+++ b/searx/engines/deezer.py
@@ -11,7 +11,7 @@
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
# engine dependent config
categories = ['music']
@@ -50,7 +50,7 @@ def response(resp):
if url.startswith('http://'):
url = 'https' + url[4:]
- content = u'{} - {} - {}'.format(
+ content = '{} - {} - {}'.format(
result['artist']['name'],
result['album']['title'],
result['title'])
diff --git a/searx/engines/deviantart.py b/searx/engines/deviantart.py
index a0e27e6..0378929 100644
--- a/searx/engines/deviantart.py
+++ b/searx/engines/deviantart.py
@@ -7,75 +7,70 @@
@using-api no (TODO, rewrite to api)
@results HTML
@stable no (HTML can change)
- @parse url, title, thumbnail_src, img_src
+ @parse url, title, img_src
@todo rewrite to api
"""
+# pylint: disable=missing-function-docstring
+from urllib.parse import urlencode
from lxml import html
-import re
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
# engine dependent config
categories = ['images']
paging = True
time_range_support = True
-# search-url
-base_url = 'https://www.deviantart.com/'
-search_url = base_url + 'search?page={page}&{query}'
-time_range_url = '&order={range}'
-
-time_range_dict = {'day': 11,
- 'week': 14,
- 'month': 15}
+time_range_dict = {
+ 'day': 'popular-24-hours',
+ 'week': 'popular-1-week',
+ 'month': 'popular-1-month',
+ 'year': 'most-recent',
+}
+# search-url
+base_url = 'https://www.deviantart.com'
-# do search-request
def request(query, params):
- if params['time_range'] and params['time_range'] not in time_range_dict:
- return params
- params['url'] = search_url.format(page=params['pageno'],
- query=urlencode({'q': query}))
+ # https://www.deviantart.com/search/deviations?page=5&q=foo
+
+ query = {
+ 'page' : params['pageno'],
+ 'q' : query,
+ }
if params['time_range'] in time_range_dict:
- params['url'] += time_range_url.format(range=time_range_dict[params['time_range']])
+ query['order'] = time_range_dict[params['time_range']]
- return params
+ params['url'] = base_url + '/search/deviations?' + urlencode(query)
+ return params
-# get response from search-request
def response(resp):
- results = []
- # return empty array if a redirection code is returned
- if resp.status_code == 302:
- return []
+ results = []
dom = html.fromstring(resp.text)
- # parse results
for row in dom.xpath('//div[contains(@data-hook, "content_row")]'):
for result in row.xpath('./div'):
- link = result.xpath('.//a[@data-hook="deviation_link"]')[0]
- url = link.attrib.get('href')
- title = link.attrib.get('title')
- thumbnail_src = result.xpath('.//img')[0].attrib.get('src')
- img_src = thumbnail_src
-
- # http to https, remove domain sharding
- thumbnail_src = re.sub(r"https?://(th|fc)\d+.", "https://th01.", thumbnail_src)
- thumbnail_src = re.sub(r"http://", "https://", thumbnail_src)
-
- url = re.sub(r"http://(.*)\.deviantart\.com/", "https://\\1.deviantart.com/", url)
-
- # append result
- results.append({'url': url,
- 'title': title,
- 'img_src': img_src,
- 'thumbnail_src': thumbnail_src,
- 'template': 'images.html'})
-
- # return results
+
+ a_tag = result.xpath('.//a[@data-hook="deviation_link"]')[0]
+ noscript_tag = a_tag.xpath('.//noscript')
+
+ if noscript_tag:
+ img_tag = noscript_tag[0].xpath('.//img')
+ else:
+ img_tag = a_tag.xpath('.//img')
+ if not img_tag:
+ continue
+ img_tag = img_tag[0]
+
+ results.append({
+ 'template': 'images.html',
+ 'url': a_tag.attrib.get('href'),
+ 'img_src': img_tag.attrib.get('src'),
+ 'title': img_tag.attrib.get('alt'),
+ })
+
return results
diff --git a/searx/engines/dictzone.py b/searx/engines/dictzone.py
index 423af09..727eb65 100644
--- a/searx/engines/dictzone.py
+++ b/searx/engines/dictzone.py
@@ -10,16 +10,17 @@
"""
import re
+from urllib.parse import urljoin
from lxml import html
from searx.utils import is_valid_lang, eval_xpath
-from searx.url_utils import urljoin
categories = ['general']
-url = u'https://dictzone.com/{from_lang}-{to_lang}-dictionary/{query}'
+url = 'https://dictzone.com/{from_lang}-{to_lang}-dictionary/{query}'
weight = 100
-parser_re = re.compile(b'.*?([a-z]+)-([a-z]+) ([^ ]+)$', re.I)
+parser_re = re.compile('.*?([a-z]+)-([a-z]+) ([^ ]+)$', re.I)
results_xpath = './/table[@id="r"]/tr'
+https_support = True
def request(query, params):
@@ -37,7 +38,7 @@ def request(query, params):
params['url'] = url.format(from_lang=from_lang[2],
to_lang=to_lang[2],
- query=query.decode('utf-8'))
+ query=query)
return params
diff --git a/searx/engines/digbt.py b/searx/engines/digbt.py
index ff2f945..b1a90fb 100644
--- a/searx/engines/digbt.py
+++ b/searx/engines/digbt.py
@@ -10,14 +10,10 @@
@parse url, title, content, magnetlink
"""
-from sys import version_info
+from urllib.parse import urljoin
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.utils import get_torrent_size
-from searx.url_utils import urljoin
+from searx.utils import extract_text, get_torrent_size
-if version_info[0] == 3:
- unicode = str
categories = ['videos', 'music', 'files']
paging = True
diff --git a/searx/engines/digg.py b/searx/engines/digg.py
index 073410e..85f727f 100644
--- a/searx/engines/digg.py
+++ b/searx/engines/digg.py
@@ -1,7 +1,7 @@
"""
Digg (News, Social media)
- @website https://digg.com/
+ @website https://digg.com
@provide-api no
@using-api no
@@ -9,61 +9,58 @@
@stable no (HTML can change)
@parse url, title, content, publishedDate, thumbnail
"""
+# pylint: disable=missing-function-docstring
-import random
-import string
-from dateutil import parser
from json import loads
-from lxml import html
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from datetime import datetime
+from lxml import html
+
# engine dependent config
categories = ['news', 'social media']
paging = True
+base_url = 'https://digg.com'
# search-url
-base_url = 'https://digg.com/'
-search_url = base_url + 'api/search/?{query}&from={position}&size=20&format=html'
-
-# specific xpath variables
-results_xpath = '//article'
-link_xpath = './/small[@class="time"]//a'
-title_xpath = './/h2//a//text()'
-content_xpath = './/p//text()'
-pubdate_xpath = './/time'
-
-digg_cookie_chars = string.ascii_uppercase + string.ascii_lowercase +\
- string.digits + "+_"
+search_url = base_url + (
+ '/api/search/'
+ '?{query}'
+ '&from={position}'
+ '&size=20'
+ '&format=html'
+)
-
-# do search-request
def request(query, params):
offset = (params['pageno'] - 1) * 20
- params['url'] = search_url.format(position=offset,
- query=urlencode({'q': query}))
- params['cookies']['frontend.auid'] = ''.join(random.choice(
- digg_cookie_chars) for _ in range(22))
+ params['url'] = search_url.format(
+ query = urlencode({'q': query}),
+ position = offset,
+ )
return params
-
-# get response from search-request
def response(resp):
results = []
- search_result = loads(resp.text)
-
# parse results
- for result in search_result['mapped']:
+ for result in loads(resp.text)['mapped']:
+
+ # strip html tags and superfluous quotation marks from content
+ content = html.document_fromstring(
+ result['excerpt']
+ ).text_content()
- published = datetime.strptime(result['created']['ISO'], "%Y-%m-%d %H:%M:%S")
- # append result
- results.append({'url': result['url'],
- 'title': result['title'],
- 'content': result['excerpt'],
- 'template': 'videos.html',
- 'publishedDate': published,
- 'thumbnail': result['images']['thumbImage']})
+ # 'created': {'ISO': '2020-10-16T14:09:55Z', ...}
+ published = datetime.strptime(
+ result['created']['ISO'], '%Y-%m-%dT%H:%M:%SZ'
+ )
+ results.append({
+ 'url': result['url'],
+ 'title': result['title'],
+ 'content' : content,
+ 'template': 'videos.html',
+ 'publishedDate': published,
+ 'thumbnail': result['images']['thumbImage'],
+ })
- # return results
return results
diff --git a/searx/engines/doku.py b/searx/engines/doku.py
index d20e660..e1b10d6 100644
--- a/searx/engines/doku.py
+++ b/searx/engines/doku.py
@@ -9,10 +9,9 @@
# @stable yes
# @parse (general) url, title, content
+from urllib.parse import urlencode
from lxml.html import fromstring
-from searx.engines.xpath import extract_text
-from searx.utils import eval_xpath
-from searx.url_utils import urlencode
+from searx.utils import extract_text, eval_xpath
# engine dependent config
categories = ['general'] # TODO , 'images', 'music', 'videos', 'files'
diff --git a/searx/engines/duckduckgo.py b/searx/engines/duckduckgo.py
index 6e07b50..c1c9846 100644
--- a/searx/engines/duckduckgo.py
+++ b/searx/engines/duckduckgo.py
@@ -15,14 +15,11 @@
from lxml.html import fromstring
from json import loads
-from searx.engines.xpath import extract_text
-from searx.poolrequests import get
-from searx.url_utils import urlencode
-from searx.utils import match_language, eval_xpath
+from searx.utils import extract_text, match_language, eval_xpath
# engine dependent config
categories = ['general']
-paging = True
+paging = False
language_support = True
supported_languages_url = 'https://duckduckgo.com/util/u172.js'
time_range_support = True
@@ -38,9 +35,7 @@ language_aliases = {
}
# search-url
-url = 'https://duckduckgo.com/html?{query}&s={offset}&dc={dc_param}'
-time_range_url = '&df={range}'
-
+url = 'https://html.duckduckgo.com/html'
time_range_dict = {'day': 'd',
'week': 'w',
'month': 'm'}
@@ -54,11 +49,11 @@ correction_xpath = '//div[@id="did_you_mean"]//a'
# match query's language to a region code that duckduckgo will accept
-def get_region_code(lang, lang_list=[]):
+def get_region_code(lang, lang_list=None):
if lang == 'all':
return None
- lang_code = match_language(lang, lang_list, language_aliases, 'wt-WT')
+ lang_code = match_language(lang, lang_list or [], language_aliases, 'wt-WT')
lang_parts = lang_code.split('-')
# country code goes first
@@ -66,36 +61,21 @@ def get_region_code(lang, lang_list=[]):
def request(query, params):
- if params['time_range'] not in (None, 'None', '') and params['time_range'] not in time_range_dict:
+ if params['time_range'] is not None and params['time_range'] not in time_range_dict:
return params
- offset = (params['pageno'] - 1) * 30
+ params['url'] = url
+ params['method'] = 'POST'
+ params['data']['b'] = ''
+ params['data']['q'] = query
+ params['data']['df'] = ''
region_code = get_region_code(params['language'], supported_languages)
- params['url'] = 'https://duckduckgo.com/html/'
- if params['pageno'] > 1:
- params['method'] = 'POST'
- params['data']['q'] = query
- params['data']['s'] = offset
- params['data']['dc'] = 30
- params['data']['nextParams'] = ''
- params['data']['v'] = 'l'
- params['data']['o'] = 'json'
- params['data']['api'] = '/d.js'
- if params['time_range'] in time_range_dict:
- params['data']['df'] = time_range_dict[params['time_range']]
- if region_code:
- params['data']['kl'] = region_code
- else:
- if region_code:
- params['url'] = url.format(
- query=urlencode({'q': query, 'kl': region_code}), offset=offset, dc_param=offset)
- else:
- params['url'] = url.format(
- query=urlencode({'q': query}), offset=offset, dc_param=offset)
-
- if params['time_range'] in time_range_dict:
- params['url'] += time_range_url.format(range=time_range_dict[params['time_range']])
+ if region_code:
+ params['data']['kl'] = region_code
+ params['cookies']['kl'] = region_code
+ if params['time_range'] in time_range_dict:
+ params['data']['df'] = time_range_dict[params['time_range']]
return params
diff --git a/searx/engines/duckduckgo_definitions.py b/searx/engines/duckduckgo_definitions.py
index 79d10c3..1d1c84b 100644
--- a/searx/engines/duckduckgo_definitions.py
+++ b/searx/engines/duckduckgo_definitions.py
@@ -10,31 +10,55 @@ DuckDuckGo (definitions)
"""
import json
+from urllib.parse import urlencode, urlparse, urljoin
from lxml import html
-from re import compile
-from searx.engines.xpath import extract_text
-from searx.engines.duckduckgo import _fetch_supported_languages, supported_languages_url, language_aliases
-from searx.url_utils import urlencode
-from searx.utils import html_to_text, match_language
-url = 'https://api.duckduckgo.com/'\
+from searx import logger
+from searx.data import WIKIDATA_UNITS
+from searx.engines.duckduckgo import language_aliases
+from searx.engines.duckduckgo import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
+from searx.utils import extract_text, html_to_text, match_language, get_string_replaces_function
+from searx.external_urls import get_external_url, get_earth_coordinates_url, area_to_osm_zoom
+
+logger = logger.getChild('duckduckgo_definitions')
+
+URL = 'https://api.duckduckgo.com/'\
+ '?{query}&format=json&pretty=0&no_redirect=1&d=1'
-http_regex = compile(r'^http:')
+WIKIDATA_PREFIX = [
+ 'http://www.wikidata.org/entity/',
+ 'https://www.wikidata.org/entity/'
+]
+
+replace_http_by_https = get_string_replaces_function({'http:': 'https:'})
+
+
+def is_broken_text(text):
+ """ duckduckgo may return something like "<a href="xxxx">http://somewhere Related website<a/>"
+
+ The href URL is broken, the "Related website" may contains some HTML.
+
+ The best solution seems to ignore these results.
+ """
+ return text.startswith('http') and ' ' in text
-def result_to_text(url, text, htmlResult):
+def result_to_text(text, htmlResult):
# TODO : remove result ending with "Meaning" or "Category"
+ result = None
dom = html.fromstring(htmlResult)
a = dom.xpath('//a')
if len(a) >= 1:
- return extract_text(a[0])
+ result = extract_text(a[0])
else:
- return text
+ result = text
+ if not is_broken_text(result):
+ return result
+ return None
def request(query, params):
- params['url'] = url.format(query=urlencode({'q': query}))
+ params['url'] = URL.format(query=urlencode({'q': query}))
language = match_language(params['language'], supported_languages, language_aliases)
language = language.split('-')[0]
params['headers']['Accept-Language'] = language
@@ -46,6 +70,14 @@ def response(resp):
search_res = json.loads(resp.text)
+ # search_res.get('Entity') possible values (not exhaustive) :
+ # * continent / country / department / location / waterfall
+ # * actor / musician / artist
+ # * book / performing art / film / television / media franchise / concert tour / playwright
+ # * prepared food
+ # * website / software / os / programming language / file format / software engineer
+ # * compagny
+
content = ''
heading = search_res.get('Heading', '')
attributes = []
@@ -56,7 +88,8 @@ def response(resp):
# add answer if there is one
answer = search_res.get('Answer', '')
if answer:
- if search_res.get('AnswerType', '') not in ['calc']:
+ logger.debug('AnswerType="%s" Answer="%s"', search_res.get('AnswerType'), answer)
+ if search_res.get('AnswerType') not in ['calc', 'ip']:
results.append({'answer': html_to_text(answer)})
# add infobox
@@ -67,42 +100,38 @@ def response(resp):
content = content + search_res.get('Abstract', '')
# image
- image = search_res.get('Image', '')
+ image = search_res.get('Image')
image = None if image == '' else image
-
- # attributes
- if 'Infobox' in search_res:
- infobox = search_res.get('Infobox', None)
- if 'content' in infobox:
- for info in infobox.get('content'):
- attributes.append({'label': info.get('label'),
- 'value': info.get('value')})
+ if image is not None and urlparse(image).netloc == '':
+ image = urljoin('https://duckduckgo.com', image)
# urls
+ # Official website, Wikipedia page
for ddg_result in search_res.get('Results', []):
- if 'FirstURL' in ddg_result:
- firstURL = ddg_result.get('FirstURL', '')
- text = ddg_result.get('Text', '')
+ firstURL = ddg_result.get('FirstURL')
+ text = ddg_result.get('Text')
+ if firstURL is not None and text is not None:
urls.append({'title': text, 'url': firstURL})
results.append({'title': heading, 'url': firstURL})
# related topics
for ddg_result in search_res.get('RelatedTopics', []):
if 'FirstURL' in ddg_result:
- suggestion = result_to_text(ddg_result.get('FirstURL', None),
- ddg_result.get('Text', None),
- ddg_result.get('Result', None))
- if suggestion != heading:
- results.append({'suggestion': suggestion})
+ firstURL = ddg_result.get('FirstURL')
+ text = ddg_result.get('Text')
+ if not is_broken_text(text):
+ suggestion = result_to_text(text,
+ ddg_result.get('Result'))
+ if suggestion != heading and suggestion is not None:
+ results.append({'suggestion': suggestion})
elif 'Topics' in ddg_result:
suggestions = []
relatedTopics.append({'name': ddg_result.get('Name', ''),
- 'suggestions': suggestions})
+ 'suggestions': suggestions})
for topic_result in ddg_result.get('Topics', []):
- suggestion = result_to_text(topic_result.get('FirstURL', None),
- topic_result.get('Text', None),
- topic_result.get('Result', None))
- if suggestion != heading:
+ suggestion = result_to_text(topic_result.get('Text'),
+ topic_result.get('Result'))
+ if suggestion != heading and suggestion is not None:
suggestions.append(suggestion)
# abstract
@@ -111,7 +140,10 @@ def response(resp):
# add as result ? problem always in english
infobox_id = abstractURL
urls.append({'title': search_res.get('AbstractSource'),
- 'url': abstractURL})
+ 'url': abstractURL,
+ 'official': True})
+ results.append({'url': abstractURL,
+ 'title': heading})
# definition
definitionURL = search_res.get('DefinitionURL', '')
@@ -119,53 +151,107 @@ def response(resp):
# add as result ? as answer ? problem always in english
infobox_id = definitionURL
urls.append({'title': search_res.get('DefinitionSource'),
- 'url': definitionURL})
+ 'url': definitionURL})
# to merge with wikidata's infobox
if infobox_id:
- infobox_id = http_regex.sub('https:', infobox_id)
-
- # entity
- entity = search_res.get('Entity', None)
- # TODO continent / country / department / location / waterfall /
- # mountain range :
- # link to map search, get weather, near by locations
- # TODO musician : link to music search
- # TODO concert tour : ??
- # TODO film / actor / television / media franchise :
- # links to IMDB / rottentomatoes (or scrap result)
- # TODO music : link tu musicbrainz / last.fm
- # TODO book : ??
- # TODO artist / playwright : ??
- # TODO compagny : ??
- # TODO software / os : ??
- # TODO software engineer : ??
- # TODO prepared food : ??
- # TODO website : ??
- # TODO performing art : ??
- # TODO prepared food : ??
- # TODO programming language : ??
- # TODO file format : ??
+ infobox_id = replace_http_by_https(infobox_id)
+
+ # attributes
+ # some will be converted to urls
+ if 'Infobox' in search_res:
+ infobox = search_res.get('Infobox')
+ if 'content' in infobox:
+ osm_zoom = 17
+ coordinates = None
+ for info in infobox.get('content'):
+ data_type = info.get('data_type')
+ data_label = info.get('label')
+ data_value = info.get('value')
+
+ # Workaround: ddg may return a double quote
+ if data_value == '""':
+ continue
+
+ # Is it an external URL ?
+ # * imdb_id / facebook_profile / youtube_channel / youtube_video / twitter_profile
+ # * instagram_profile / rotten_tomatoes / spotify_artist_id / itunes_artist_id / soundcloud_id
+ # * netflix_id
+ external_url = get_external_url(data_type, data_value)
+ if external_url is not None:
+ urls.append({'title': data_label,
+ 'url': external_url})
+ elif data_type in ['instance', 'wiki_maps_trigger', 'google_play_artist_id']:
+ # ignore instance: Wikidata value from "Instance Of" (Qxxxx)
+ # ignore wiki_maps_trigger: reference to a javascript
+ # ignore google_play_artist_id: service shutdown
+ pass
+ elif data_type == 'string' and data_label == 'Website':
+ # There is already an URL for the website
+ pass
+ elif data_type == 'area':
+ attributes.append({'label': data_label,
+ 'value': area_to_str(data_value),
+ 'entity': 'P2046'})
+ osm_zoom = area_to_osm_zoom(data_value.get('amount'))
+ elif data_type == 'coordinates':
+ if data_value.get('globe') == 'http://www.wikidata.org/entity/Q2':
+ # coordinate on Earth
+ # get the zoom information from the area
+ coordinates = info
+ else:
+ # coordinate NOT on Earth
+ attributes.append({'label': data_label,
+ 'value': data_value,
+ 'entity': 'P625'})
+ elif data_type == 'string':
+ attributes.append({'label': data_label,
+ 'value': data_value})
+
+ if coordinates:
+ data_label = coordinates.get('label')
+ data_value = coordinates.get('value')
+ latitude = data_value.get('latitude')
+ longitude = data_value.get('longitude')
+ url = get_earth_coordinates_url(latitude, longitude, osm_zoom)
+ urls.append({'title': 'OpenStreetMap',
+ 'url': url,
+ 'entity': 'P625'})
if len(heading) > 0:
# TODO get infobox.meta.value where .label='article_title'
if image is None and len(attributes) == 0 and len(urls) == 1 and\
len(relatedTopics) == 0 and len(content) == 0:
- results.append({
- 'url': urls[0]['url'],
- 'title': heading,
- 'content': content
- })
+ results.append({'url': urls[0]['url'],
+ 'title': heading,
+ 'content': content})
else:
- results.append({
- 'infobox': heading,
- 'id': infobox_id,
- 'entity': entity,
- 'content': content,
- 'img_src': image,
- 'attributes': attributes,
- 'urls': urls,
- 'relatedTopics': relatedTopics
- })
+ results.append({'infobox': heading,
+ 'id': infobox_id,
+ 'content': content,
+ 'img_src': image,
+ 'attributes': attributes,
+ 'urls': urls,
+ 'relatedTopics': relatedTopics})
return results
+
+
+def unit_to_str(unit):
+ for prefix in WIKIDATA_PREFIX:
+ if unit.startswith(prefix):
+ wikidata_entity = unit[len(prefix):]
+ return WIKIDATA_UNITS.get(wikidata_entity, unit)
+ return unit
+
+
+def area_to_str(area):
+ """parse {'unit': 'http://www.wikidata.org/entity/Q712226', 'amount': '+20.99'}"""
+ unit = unit_to_str(area.get('unit'))
+ if unit is not None:
+ try:
+ amount = float(area.get('amount'))
+ return '{} {}'.format(amount, unit)
+ except ValueError:
+ pass
+ return '{} {}'.format(area.get('amount', ''), area.get('unit', ''))
diff --git a/searx/engines/duckduckgo_images.py b/searx/engines/duckduckgo_images.py
index 89924b7..009f81c 100644
--- a/searx/engines/duckduckgo_images.py
+++ b/searx/engines/duckduckgo_images.py
@@ -14,13 +14,11 @@
"""
from json import loads
-from searx.engines.xpath import extract_text
-from searx.engines.duckduckgo import (
- _fetch_supported_languages, supported_languages_url,
- get_region_code, language_aliases
-)
+from urllib.parse import urlencode
+from searx.exceptions import SearxEngineAPIException
+from searx.engines.duckduckgo import get_region_code
+from searx.engines.duckduckgo import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
from searx.poolrequests import get
-from searx.url_utils import urlencode
# engine dependent config
categories = ['images']
@@ -40,7 +38,7 @@ def get_vqd(query, headers):
res = get(query_url, headers=headers)
content = res.text
if content.find('vqd=\'') == -1:
- raise Exception('Request failed')
+ raise SearxEngineAPIException('Request failed')
vqd = content[content.find('vqd=\'') + 5:]
vqd = vqd[:vqd.find('\'')]
return vqd
@@ -74,10 +72,7 @@ def response(resp):
results = []
content = resp.text
- try:
- res_json = loads(content)
- except:
- raise Exception('Cannot parse results')
+ res_json = loads(content)
# parse results
for result in res_json['results']:
diff --git a/searx/engines/duden.py b/searx/engines/duden.py
index cf2f1a2..1475fb8 100644
--- a/searx/engines/duden.py
+++ b/searx/engines/duden.py
@@ -8,12 +8,10 @@
@parse url, title, content
"""
-from lxml import html, etree
import re
-from searx.engines.xpath import extract_text
-from searx.utils import eval_xpath
-from searx.url_utils import quote, urljoin
-from searx import logger
+from urllib.parse import quote, urljoin
+from lxml import html
+from searx.utils import extract_text, eval_xpath, eval_xpath_list, eval_xpath_getindex
categories = ['general']
paging = True
@@ -41,6 +39,9 @@ def request(query, params):
params['url'] = search_url_fmt.format(query=quote(query))
else:
params['url'] = search_url.format(offset=offset, query=quote(query))
+ # after the last page of results, spelling corrections are returned after a HTTP redirect
+ # whatever the page number is
+ params['soft_max_redirects'] = 1
return params
@@ -52,29 +53,21 @@ def response(resp):
dom = html.fromstring(resp.text)
- try:
- number_of_results_string =\
- re.sub('[^0-9]', '',
- eval_xpath(dom, '//a[@class="active" and contains(@href,"/suchen/dudenonline")]/span/text()')[0])
-
+ number_of_results_element =\
+ eval_xpath_getindex(dom, '//a[@class="active" and contains(@href,"/suchen/dudenonline")]/span/text()',
+ 0, default=None)
+ if number_of_results_element is not None:
+ number_of_results_string = re.sub('[^0-9]', '', number_of_results_element)
results.append({'number_of_results': int(number_of_results_string)})
- except:
- logger.debug("Couldn't read number of results.")
- pass
-
- for result in eval_xpath(dom, '//section[not(contains(@class, "essay"))]'):
- try:
- url = eval_xpath(result, './/h2/a')[0].get('href')
- url = urljoin(base_url, url)
- title = eval_xpath(result, 'string(.//h2/a)').strip()
- content = extract_text(eval_xpath(result, './/p'))
- # append result
- results.append({'url': url,
- 'title': title,
- 'content': content})
- except:
- logger.debug('result parse error in:\n%s', etree.tostring(result, pretty_print=True))
- continue
+ for result in eval_xpath_list(dom, '//section[not(contains(@class, "essay"))]'):
+ url = eval_xpath_getindex(result, './/h2/a', 0).get('href')
+ url = urljoin(base_url, url)
+ title = eval_xpath(result, 'string(.//h2/a)').strip()
+ content = extract_text(eval_xpath(result, './/p'))
+ # append result
+ results.append({'url': url,
+ 'title': title,
+ 'content': content})
return results
diff --git a/searx/engines/ebay.py b/searx/engines/ebay.py
new file mode 100644
index 0000000..e2e5ded
--- /dev/null
+++ b/searx/engines/ebay.py
@@ -0,0 +1,68 @@
+# Ebay (Videos, Music, Files)
+#
+# @website https://www.ebay.com
+# @provide-api no (nothing found)
+#
+# @using-api no
+# @results HTML (using search portal)
+# @stable yes (HTML can change)
+# @parse url, title, content, price, shipping, source
+
+from lxml import html
+from searx.engines.xpath import extract_text
+from urllib.parse import quote
+
+categories = ['shopping']
+paging = True
+
+url = 'https://www.ebay.com'
+search_url = url + '/sch/i.html?_nkw={query}&_sacat={pageno}'
+
+results_xpath = '//li[contains(@class, "s-item")]'
+url_xpath = './/a[@class="s-item__link"]/@href'
+title_xpath = './/h3[@class="s-item__title"]'
+content_xpath = './/div[@span="SECONDARY_INFO"]'
+price_xpath = './/div[contains(@class, "s-item__detail")]/span[@class="s-item__price"][1]/text()'
+shipping_xpath = './/span[contains(@class, "s-item__shipping")]/text()'
+source_country_xpath = './/span[contains(@class, "s-item__location")]/text()'
+thumbnail_xpath = './/img[@class="s-item__image-img"]/@src'
+
+
+def request(query, params):
+ params['url'] = search_url.format(query=quote(query), pageno=params['pageno'])
+ return params
+
+
+def response(resp):
+ results = []
+
+ dom = html.fromstring(resp.text)
+ results_dom = dom.xpath(results_xpath)
+ if not results_dom:
+ return []
+
+ for result_dom in results_dom:
+ url = extract_text(result_dom.xpath(url_xpath))
+ title = extract_text(result_dom.xpath(title_xpath))
+ content = extract_text(result_dom.xpath(content_xpath))
+ price = extract_text(result_dom.xpath(price_xpath))
+ shipping = extract_text(result_dom.xpath(shipping_xpath))
+ source_country = extract_text(result_dom.xpath(source_country_xpath))
+ thumbnail = extract_text(result_dom.xpath(thumbnail_xpath))
+
+ if title == "":
+ continue
+
+ results.append({
+ 'url': url,
+ 'title': title,
+ 'content': content,
+ 'price': price,
+ 'shipping': shipping,
+ 'source_country': source_country,
+ 'thumbnail': thumbnail,
+ 'template': 'products.html',
+
+ })
+
+ return results
diff --git a/searx/engines/elasticsearch.py b/searx/engines/elasticsearch.py
new file mode 100644
index 0000000..081736c
--- /dev/null
+++ b/searx/engines/elasticsearch.py
@@ -0,0 +1,140 @@
+from json import loads, dumps
+from requests.auth import HTTPBasicAuth
+from searx.exceptions import SearxEngineAPIException
+
+
+base_url = 'http://localhost:9200'
+username = ''
+password = ''
+index = ''
+search_url = base_url + '/' + index + '/_search'
+query_type = 'match'
+custom_query_json = {}
+show_metadata = False
+categories = ['general']
+
+
+def init(engine_settings):
+ if 'query_type' in engine_settings and engine_settings['query_type'] not in _available_query_types:
+ raise ValueError('unsupported query type', engine_settings['query_type'])
+
+ if index == '':
+ raise ValueError('index cannot be empty')
+
+
+def request(query, params):
+ if query_type not in _available_query_types:
+ return params
+
+ if username and password:
+ params['auth'] = HTTPBasicAuth(username, password)
+
+ params['url'] = search_url
+ params['method'] = 'GET'
+ params['data'] = dumps(_available_query_types[query_type](query))
+ params['headers']['Content-Type'] = 'application/json'
+
+ return params
+
+
+def _match_query(query):
+ """
+ The standard for full text queries.
+ searx format: "key:value" e.g. city:berlin
+ REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html
+ """
+
+ try:
+ key, value = query.split(':')
+ except:
+ raise ValueError('query format must be "key:value"')
+
+ return {"query": {"match": {key: {'query': value}}}}
+
+
+def _simple_query_string_query(query):
+ """
+ Accepts query strings, but it is less strict than query_string
+ The field used can be specified in index.query.default_field in Elasticsearch.
+ REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-simple-query-string-query.html
+ """
+
+ return {'query': {'simple_query_string': {'query': query}}}
+
+
+def _term_query(query):
+ """
+ Accepts one term and the name of the field.
+ searx format: "key:value" e.g. city:berlin
+ REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html
+ """
+
+ try:
+ key, value = query.split(':')
+ except:
+ raise ValueError('query format must be key:value')
+
+ return {'query': {'term': {key: value}}}
+
+
+def _terms_query(query):
+ """
+ Accepts multiple terms and the name of the field.
+ searx format: "key:value1,value2" e.g. city:berlin,paris
+ REF: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-query.html
+ """
+
+ try:
+ key, values = query.split(':')
+ except:
+ raise ValueError('query format must be key:value1,value2')
+
+ return {'query': {'terms': {key: values.split(',')}}}
+
+
+def _custom_query(query):
+ key, value = query.split(':')
+ custom_query = custom_query_json
+ for query_key, query_value in custom_query.items():
+ if query_key == '{{KEY}}':
+ custom_query[key] = custom_query.pop(query_key)
+ if query_value == '{{VALUE}}':
+ custom_query[query_key] = value
+ return custom_query
+
+
+def response(resp):
+ results = []
+
+ resp_json = loads(resp.text)
+ if 'error' in resp_json:
+ raise SearxEngineAPIException(resp_json['error'])
+
+ for result in resp_json['hits']['hits']:
+ r = {key: str(value) if not key.startswith('_') else value for key, value in result['_source'].items()}
+ r['template'] = 'key-value.html'
+
+ if show_metadata:
+ r['metadata'] = {'index': result['_index'],
+ 'id': result['_id'],
+ 'score': result['_score']}
+
+ results.append(r)
+
+ return results
+
+
+_available_query_types = {
+ # Full text queries
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html
+ 'match': _match_query,
+ 'simple_query_string': _simple_query_string_query,
+
+ # Term-level queries
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html
+ 'term': _term_query,
+ 'terms': _terms_query,
+
+ # Query JSON defined by the instance administrator.
+ 'custom': _custom_query,
+}
diff --git a/searx/engines/etools.py b/searx/engines/etools.py
index a9eb098..a0762d1 100644
--- a/searx/engines/etools.py
+++ b/searx/engines/etools.py
@@ -10,9 +10,8 @@
"""
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import quote
-from searx.utils import eval_xpath
+from urllib.parse import quote
+from searx.utils import extract_text, eval_xpath
categories = ['general']
paging = False
diff --git a/searx/engines/fdroid.py b/searx/engines/fdroid.py
index 4066dc7..3d37db4 100644
--- a/searx/engines/fdroid.py
+++ b/searx/engines/fdroid.py
@@ -9,9 +9,9 @@
@parse url, title, content
"""
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
+from searx.utils import extract_text
# engine dependent config
categories = ['files']
diff --git a/searx/engines/filecrop.py b/searx/engines/filecrop.py
deleted file mode 100644
index ed57a6b..0000000
--- a/searx/engines/filecrop.py
+++ /dev/null
@@ -1,88 +0,0 @@
-from searx.url_utils import urlencode
-
-try:
- from HTMLParser import HTMLParser
-except:
- from html.parser import HTMLParser
-
-url = 'http://www.filecrop.com/'
-search_url = url + '/search.php?{query}&size_i=0&size_f=100000000&engine_r=1&engine_d=1&engine_e=1&engine_4=1&engine_m=1&pos={index}' # noqa
-
-paging = True
-
-
-class FilecropResultParser(HTMLParser):
-
- def __init__(self):
- HTMLParser.__init__(self)
- self.__start_processing = False
-
- self.results = []
- self.result = {}
-
- self.tr_counter = 0
- self.data_counter = 0
-
- def handle_starttag(self, tag, attrs):
-
- if tag == 'tr':
- if ('bgcolor', '#edeff5') in attrs or\
- ('bgcolor', '#ffffff') in attrs:
- self.__start_processing = True
-
- if not self.__start_processing:
- return
-
- if tag == 'label':
- self.result['title'] = [attr[1] for attr in attrs
- if attr[0] == 'title'][0]
- elif tag == 'a' and ('rel', 'nofollow') in attrs\
- and ('class', 'sourcelink') in attrs:
- if 'content' in self.result:
- self.result['content'] += [attr[1] for attr in attrs
- if attr[0] == 'title'][0]
- else:
- self.result['content'] = [attr[1] for attr in attrs
- if attr[0] == 'title'][0]
- self.result['content'] += ' '
- elif tag == 'a':
- self.result['url'] = url + [attr[1] for attr in attrs
- if attr[0] == 'href'][0]
-
- def handle_endtag(self, tag):
- if self.__start_processing is False:
- return
-
- if tag == 'tr':
- self.tr_counter += 1
-
- if self.tr_counter == 2:
- self.__start_processing = False
- self.tr_counter = 0
- self.data_counter = 0
- self.results.append(self.result)
- self.result = {}
-
- def handle_data(self, data):
- if not self.__start_processing:
- return
-
- if 'content' in self.result:
- self.result['content'] += data + ' '
- else:
- self.result['content'] = data + ' '
-
- self.data_counter += 1
-
-
-def request(query, params):
- index = 1 + (params['pageno'] - 1) * 30
- params['url'] = search_url.format(query=urlencode({'w': query}), index=index)
- return params
-
-
-def response(resp):
- parser = FilecropResultParser()
- parser.feed(resp.text)
-
- return parser.results
diff --git a/searx/engines/flickr.py b/searx/engines/flickr.py
index de17693..b23c447 100644
--- a/searx/engines/flickr.py
+++ b/searx/engines/flickr.py
@@ -14,7 +14,7 @@
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
categories = ['images']
diff --git a/searx/engines/flickr_noapi.py b/searx/engines/flickr_noapi.py
index 1cbb3e0..4bcf837 100644
--- a/searx/engines/flickr_noapi.py
+++ b/searx/engines/flickr_noapi.py
@@ -15,8 +15,8 @@
from json import loads
from time import time
import re
+from urllib.parse import urlencode
from searx.engines import logger
-from searx.url_utils import urlencode
from searx.utils import ecma_unescape, html_to_text
logger = logger.getChild('flickr-noapi')
@@ -117,10 +117,10 @@ def response(resp):
'img_format': img_format,
'template': 'images.html'
}
- result['author'] = author.encode('utf-8', 'ignore').decode('utf-8')
- result['source'] = source.encode('utf-8', 'ignore').decode('utf-8')
- result['title'] = title.encode('utf-8', 'ignore').decode('utf-8')
- result['content'] = content.encode('utf-8', 'ignore').decode('utf-8')
+ result['author'] = author.encode(errors='ignore').decode()
+ result['source'] = source.encode(errors='ignore').decode()
+ result['title'] = title.encode(errors='ignore').decode()
+ result['content'] = content.encode(errors='ignore').decode()
results.append(result)
return results
diff --git a/searx/engines/framalibre.py b/searx/engines/framalibre.py
index f3441fa..e3d0564 100644
--- a/searx/engines/framalibre.py
+++ b/searx/engines/framalibre.py
@@ -10,13 +10,10 @@
@parse url, title, content, thumbnail, img_src
"""
-try:
- from cgi import escape
-except:
- from html import escape
+from html import escape
+from urllib.parse import urljoin, urlencode
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urljoin, urlencode
+from searx.utils import extract_text
# engine dependent config
categories = ['it']
diff --git a/searx/engines/frinkiac.py b/searx/engines/frinkiac.py
index a67b42d..5b174a6 100644
--- a/searx/engines/frinkiac.py
+++ b/searx/engines/frinkiac.py
@@ -10,7 +10,7 @@ Frinkiac (Images)
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
categories = ['images']
diff --git a/searx/engines/genius.py b/searx/engines/genius.py
index aa5afad..2bfbfdd 100644
--- a/searx/engines/genius.py
+++ b/searx/engines/genius.py
@@ -11,7 +11,7 @@ Genius
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from datetime import datetime
# engine dependent config
@@ -36,7 +36,7 @@ def parse_lyric(hit):
try:
content = hit['highlights'][0]['value']
except:
- content = None
+ content = ''
timestamp = hit['result']['lyrics_updated_at']
result = {'url': hit['result']['url'],
'title': hit['result']['full_title'],
@@ -51,7 +51,7 @@ def parse_lyric(hit):
def parse_artist(hit):
result = {'url': hit['result']['url'],
'title': hit['result']['name'],
- 'content': None,
+ 'content': '',
'thumbnail': hit['result']['image_url'],
'template': 'videos.html'}
return result
@@ -61,6 +61,7 @@ def parse_album(hit):
result = {'url': hit['result']['url'],
'title': hit['result']['full_title'],
'thumbnail': hit['result']['cover_art_url'],
+ 'content': '',
# 'thumbnail': hit['result']['cover_art_thumbnail_url'],
'template': 'videos.html'}
try:
@@ -81,9 +82,7 @@ def response(resp):
json = loads(resp.text)
hits = [hit for section in json['response']['sections'] for hit in section['hits']]
for hit in hits:
- try:
- func = parse[hit['type']]
- except KeyError:
- continue
- results.append(func(hit))
+ func = parse.get(hit['type'])
+ if func:
+ results.append(func(hit))
return results
diff --git a/searx/engines/gentoo.py b/searx/engines/gentoo.py
index a7a966c..16b3e69 100644
--- a/searx/engines/gentoo.py
+++ b/searx/engines/gentoo.py
@@ -11,9 +11,9 @@
@parse url, title
"""
+from urllib.parse import urlencode, urljoin
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode, urljoin
+from searx.utils import extract_text
# engine dependent config
categories = ['it']
@@ -90,7 +90,7 @@ def request(query, params):
# if our language is hosted on the main site, we need to add its name
# to the query in order to narrow the results to that language
if language in main_langs:
- query += b' (' + (main_langs[language]).encode('utf-8') + b')'
+ query += ' (' + main_langs[language] + ')'
# prepare the request parameters
query = urlencode({'search': query})
diff --git a/searx/engines/gigablast.py b/searx/engines/gigablast.py
index b139c2a..1d71b18 100644
--- a/searx/engines/gigablast.py
+++ b/searx/engines/gigablast.py
@@ -14,8 +14,8 @@
import re
from json import loads
+from urllib.parse import urlencode
# from searx import logger
-from searx.url_utils import urlencode
from searx.poolrequests import get
# engine dependent config
diff --git a/searx/engines/github.py b/searx/engines/github.py
index eaa00da..80b50ce 100644
--- a/searx/engines/github.py
+++ b/searx/engines/github.py
@@ -11,7 +11,7 @@
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
# engine dependent config
categories = ['it']
diff --git a/searx/engines/google.py b/searx/engines/google.py
index 093ad6b..17ab21f 100644
--- a/searx/engines/google.py
+++ b/searx/engines/google.py
@@ -18,12 +18,12 @@ Definitions`_.
# pylint: disable=invalid-name, missing-function-docstring
+from urllib.parse import urlencode, urlparse
from lxml import html
-from flask_babel import gettext
-from searx.engines.xpath import extract_text
from searx import logger
-from searx.url_utils import urlencode, urlparse
-from searx.utils import match_language, eval_xpath
+from searx.utils import match_language, extract_text, eval_xpath, eval_xpath_list, eval_xpath_getindex
+from searx.exceptions import SearxEngineCaptchaException
+
logger = logger.getChild('google engine')
@@ -116,12 +116,12 @@ g_section_with_header = './g-section-with-header'
# the title is a h3 tag relative to the result group
title_xpath = './/h3[1]'
-# in the result group there is <div class="r" ../> it's first child is a <a
-# href=...> (on some results, the <a> is the first "descendant", not ""child")
-href_xpath = './/div[@class="r"]//a/@href'
+# in the result group there is <div class="yuRUbf" ../> it's first child is a <a
+# href=...>
+href_xpath = './/div[@class="yuRUbf"]//a/@href'
-# in the result group there is <div class="s" ../> containing he *content*
-content_xpath = './/div[@class="s"]'
+# in the result group there is <div class="IsZvec" ../> containing he *content*
+content_xpath = './/div[@class="IsZvec"]'
# Suggestions are links placed in a *card-section*, we extract only the text
# from the links not the links itself.
@@ -132,14 +132,6 @@ suggestion_xpath = '//div[contains(@class, "card-section")]//a'
spelling_suggestion_xpath = '//div[@class="med"]/p/a'
-def extract_text_from_dom(result, xpath):
- """returns extract_text on the first result selected by the xpath or None"""
- r = eval_xpath(result, xpath)
- if len(r) > 0:
- return extract_text(r[0])
- return None
-
-
def get_lang_country(params, lang_list, custom_aliases):
"""Returns a tuple with *langauage* on its first and *country* on its second
position."""
@@ -211,10 +203,10 @@ def response(resp):
# detect google sorry
resp_url = urlparse(resp.url)
if resp_url.netloc == 'sorry.google.com' or resp_url.path == '/sorry/IndexRedirect':
- raise RuntimeWarning('sorry.google.com')
+ raise SearxEngineCaptchaException()
if resp_url.path.startswith('/sorry'):
- raise RuntimeWarning(gettext('CAPTCHA required'))
+ raise SearxEngineCaptchaException()
# which subdomain ?
# subdomain = resp.search_params.get('google_subdomain')
@@ -230,18 +222,17 @@ def response(resp):
logger.debug("did not found 'answer'")
# results --> number_of_results
- try:
- _txt = eval_xpath(dom, '//div[@id="result-stats"]//text()')[0]
- _digit = ''.join([n for n in _txt if n.isdigit()])
- number_of_results = int(_digit)
- results.append({'number_of_results': number_of_results})
-
- except Exception as e: # pylint: disable=broad-except
- logger.debug("did not 'number_of_results'")
- logger.error(e, exc_info=True)
+ try:
+ _txt = eval_xpath_getindex(dom, '//div[@id="result-stats"]//text()', 0)
+ _digit = ''.join([n for n in _txt if n.isdigit()])
+ number_of_results = int(_digit)
+ results.append({'number_of_results': number_of_results})
+ except Exception as e: # pylint: disable=broad-except
+ logger.debug("did not 'number_of_results'")
+ logger.error(e, exc_info=True)
# parse results
- for result in eval_xpath(dom, results_xpath):
+ for result in eval_xpath_list(dom, results_xpath):
# google *sections*
if extract_text(eval_xpath(result, g_section_with_header)):
@@ -249,9 +240,14 @@ def response(resp):
continue
try:
- title = extract_text(eval_xpath(result, title_xpath)[0])
- url = eval_xpath(result, href_xpath)[0]
- content = extract_text_from_dom(result, content_xpath)
+ title_tag = eval_xpath_getindex(result, title_xpath, 0, default=None)
+ if title_tag is None:
+ # this not one of the common google results *section*
+ logger.debug('ingoring <div class="g" ../> section: missing title')
+ continue
+ title = extract_text(title_tag)
+ url = eval_xpath_getindex(result, href_xpath, 0)
+ content = extract_text(eval_xpath_getindex(result, content_xpath, 0, default=None), allow_none=True)
results.append({
'url': url,
'title': title,
@@ -266,11 +262,11 @@ def response(resp):
continue
# parse suggestion
- for suggestion in eval_xpath(dom, suggestion_xpath):
+ for suggestion in eval_xpath_list(dom, suggestion_xpath):
# append suggestion
results.append({'suggestion': extract_text(suggestion)})
- for correction in eval_xpath(dom, spelling_suggestion_xpath):
+ for correction in eval_xpath_list(dom, spelling_suggestion_xpath):
results.append({'correction': extract_text(correction)})
# return results
@@ -282,11 +278,11 @@ def _fetch_supported_languages(resp):
ret_val = {}
dom = html.fromstring(resp.text)
- radio_buttons = eval_xpath(dom, '//*[@id="langSec"]//input[@name="lang"]')
+ radio_buttons = eval_xpath_list(dom, '//*[@id="langSec"]//input[@name="lr"]')
for x in radio_buttons:
name = x.get("data-name")
- code = x.get("value")
+ code = x.get("value").split('_')[-1]
ret_val[code] = {"name": name}
return ret_val
diff --git a/searx/engines/google_images.py b/searx/engines/google_images.py
index 6ec242b..9ef1be7 100644
--- a/searx/engines/google_images.py
+++ b/searx/engines/google_images.py
@@ -24,19 +24,12 @@ Definitions`_.
"""
+from urllib.parse import urlencode, urlparse, unquote
from lxml import html
-from flask_babel import gettext
from searx import logger
-from searx.url_utils import urlencode, urlparse
-from searx.utils import eval_xpath
-from searx.engines.xpath import extract_text
-
-# pylint: disable=unused-import
-from searx.engines.google import (
- supported_languages_url,
- _fetch_supported_languages,
-)
-# pylint: enable=unused-import
+from searx.exceptions import SearxEngineCaptchaException
+from searx.utils import extract_text, eval_xpath
+from searx.engines.google import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
from searx.engines.google import (
get_lang_country,
@@ -77,6 +70,19 @@ def scrap_out_thumbs(dom):
return ret_val
+def scrap_img_by_id(script, data_id):
+ """Get full image URL by data-id in parent element
+ """
+ img_url = ''
+ _script = script.split('\n')
+ for i, line in enumerate(_script):
+ if 'gstatic.com/images' in line and data_id in line:
+ url_line = _script[i + 1]
+ img_url = url_line.split('"')[1]
+ img_url = unquote(img_url.replace(r'\u00', r'%'))
+ return img_url
+
+
def request(query, params):
"""Google-Video search request"""
@@ -122,10 +128,10 @@ def response(resp):
# detect google sorry
resp_url = urlparse(resp.url)
if resp_url.netloc == 'sorry.google.com' or resp_url.path == '/sorry/IndexRedirect':
- raise RuntimeWarning('sorry.google.com')
+ raise SearxEngineCaptchaException()
if resp_url.path.startswith('/sorry'):
- raise RuntimeWarning(gettext('CAPTCHA required'))
+ raise SearxEngineCaptchaException()
# which subdomain ?
# subdomain = resp.search_params.get('google_subdomain')
@@ -133,6 +139,7 @@ def response(resp):
# convert the text to dom
dom = html.fromstring(resp.text)
img_bas64_map = scrap_out_thumbs(dom)
+ img_src_script = eval_xpath(dom, '//script[contains(., "AF_initDataCallback({key: ")]')[1].text
# parse results
#
@@ -142,8 +149,7 @@ def response(resp):
# <div jsmodel="tTXmib"> / <div jsaction="..." data-id="..."
# The data-id matches to a item in a json-data structure in::
# <script nonce="I+vqelcy/01CKiBJi5Z1Ow">AF_initDataCallback({key: 'ds:1', ... data:function(){return [ ...
- # In this structure the ling to the origin PNG, JPG or whatever is given
- # (we do not blow out the link there, you could still implement that)
+ # In this structure the link to the origin PNG, JPG or whatever is given
# first link per image-div contains a <img> with the data-iid for bas64 encoded image data::
# <img class="rg_i Q4LuWd" data-iid="0"
# second link per image-div is the target link::
@@ -186,12 +192,17 @@ def response(resp):
pub_descr = extract_text(pub_nodes[0])
pub_source = extract_text(pub_nodes[1])
+ img_src_id = eval_xpath(img_node, '../../../@data-id')[0]
+ src_url = scrap_img_by_id(img_src_script, img_src_id)
+ if not src_url:
+ src_url = thumbnail_src
+
results.append({
'url': url,
'title': img_alt,
'content': pub_descr,
'source': pub_source,
- 'img_src': url,
+ 'img_src': src_url,
# 'img_format': img_format,
'thumbnail_src': thumbnail_src,
'template': 'images.html'
diff --git a/searx/engines/google_news.py b/searx/engines/google_news.py
index c9cc754..f1b7cfa 100644
--- a/searx/engines/google_news.py
+++ b/searx/engines/google_news.py
@@ -10,10 +10,10 @@
@parse url, title, content, publishedDate
"""
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.google import _fetch_supported_languages, supported_languages_url
-from searx.url_utils import urlencode
from searx.utils import match_language
+from searx.engines.google import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
# search-url
categories = ['news']
diff --git a/searx/engines/google_videos.py b/searx/engines/google_videos.py
index fd6b2e3..eedefbf 100644
--- a/searx/engines/google_videos.py
+++ b/searx/engines/google_videos.py
@@ -11,10 +11,9 @@
"""
from datetime import date, timedelta
-from json import loads
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
+from searx.utils import extract_text, eval_xpath, eval_xpath_list, eval_xpath_getindex
import re
# engine dependent config
@@ -67,11 +66,11 @@ def response(resp):
dom = html.fromstring(resp.text)
# parse results
- for result in dom.xpath('//div[@class="g"]'):
+ for result in eval_xpath_list(dom, '//div[@class="g"]'):
- title = extract_text(result.xpath('.//h3'))
- url = result.xpath('.//div[@class="r"]/a/@href')[0]
- content = extract_text(result.xpath('.//span[@class="st"]'))
+ title = extract_text(eval_xpath(result, './/h3'))
+ url = eval_xpath_getindex(result, './/div[@class="r"]/a/@href', 0)
+ content = extract_text(eval_xpath(result, './/span[@class="st"]'))
# get thumbnails
script = str(dom.xpath('//script[contains(., "_setImagesSrc")]')[0].text)
diff --git a/searx/engines/ina.py b/searx/engines/ina.py
index ea50964..52c9394 100644
--- a/searx/engines/ina.py
+++ b/searx/engines/ina.py
@@ -12,15 +12,12 @@
# @todo embedded (needs some md5 from video page)
from json import loads
+from urllib.parse import urlencode
from lxml import html
from dateutil import parser
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
+from html.parser import HTMLParser
+from searx.utils import extract_text
-try:
- from HTMLParser import HTMLParser
-except:
- from html.parser import HTMLParser
# engine dependent config
categories = ['videos']
diff --git a/searx/engines/invidious.py b/searx/engines/invidious.py
index 8d81691..6ea9426 100644
--- a/searx/engines/invidious.py
+++ b/searx/engines/invidious.py
@@ -6,9 +6,9 @@
# @using-api yes
# @results JSON
# @stable yes
-# @parse url, title, content, publishedDate, thumbnail, embedded
+# @parse url, title, content, publishedDate, thumbnail, embedded, author, length
-from searx.url_utils import quote_plus
+from urllib.parse import quote_plus
from dateutil import parser
import time
@@ -84,13 +84,20 @@ def response(resp):
publishedDate = parser.parse(
time.ctime(result.get("published", 0))
)
+ length = time.gmtime(result.get("lengthSeconds"))
+ if length.tm_hour:
+ length = time.strftime("%H:%M:%S", length)
+ else:
+ length = time.strftime("%M:%S", length)
results.append(
{
"url": url,
"title": result.get("title", ""),
"content": result.get("description", ""),
+ 'length': length,
"template": "videos.html",
+ "author": result.get("author"),
"publishedDate": publishedDate,
"embedded": embedded,
"thumbnail": thumbnail,
diff --git a/searx/engines/json_engine.py b/searx/engines/json_engine.py
index 785b0c4..e2aa436 100644
--- a/searx/engines/json_engine.py
+++ b/searx/engines/json_engine.py
@@ -1,11 +1,8 @@
-from collections import Iterable
+from collections.abc import Iterable
from json import loads
-from sys import version_info
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from searx.utils import to_string
-if version_info[0] == 3:
- unicode = str
search_url = None
url_query = None
@@ -37,8 +34,6 @@ def iterate(iterable):
def is_iterable(obj):
if type(obj) == str:
return False
- if type(obj) == unicode:
- return False
return isinstance(obj, Iterable)
diff --git a/searx/engines/kickass.py b/searx/engines/kickass.py
index 5e897c9..90bd330 100644
--- a/searx/engines/kickass.py
+++ b/searx/engines/kickass.py
@@ -12,9 +12,8 @@
from lxml import html
from operator import itemgetter
-from searx.engines.xpath import extract_text
-from searx.utils import get_torrent_size, convert_str_to_int
-from searx.url_utils import quote, urljoin
+from urllib.parse import quote, urljoin
+from searx.utils import extract_text, get_torrent_size, convert_str_to_int
# engine dependent config
categories = ['videos', 'music', 'files']
diff --git a/searx/engines/mediawiki.py b/searx/engines/mediawiki.py
index 0607ac9..50ba74e 100644
--- a/searx/engines/mediawiki.py
+++ b/searx/engines/mediawiki.py
@@ -14,7 +14,7 @@
from json import loads
from string import Formatter
-from searx.url_utils import urlencode, quote
+from urllib.parse import urlencode, quote
# engine dependent config
categories = ['general']
@@ -79,7 +79,7 @@ def response(resp):
if result.get('snippet', '').startswith('#REDIRECT'):
continue
url = base_url.format(language=resp.search_params['language']) +\
- 'wiki/' + quote(result['title'].replace(' ', '_').encode('utf-8'))
+ 'wiki/' + quote(result['title'].replace(' ', '_').encode())
# append result
results.append({'url': url,
diff --git a/searx/engines/microsoft_academic.py b/searx/engines/microsoft_academic.py
index 9bac006..7426eef 100644
--- a/searx/engines/microsoft_academic.py
+++ b/searx/engines/microsoft_academic.py
@@ -12,8 +12,7 @@ Microsoft Academic (Science)
from datetime import datetime
from json import loads
from uuid import uuid4
-
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from searx.utils import html_to_text
categories = ['images']
diff --git a/searx/engines/mixcloud.py b/searx/engines/mixcloud.py
index 470c007..0606350 100644
--- a/searx/engines/mixcloud.py
+++ b/searx/engines/mixcloud.py
@@ -12,7 +12,7 @@
from json import loads
from dateutil import parser
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
# engine dependent config
categories = ['music']
diff --git a/searx/engines/not_evil.py b/searx/engines/not_evil.py
new file mode 100644
index 0000000..e84f153
--- /dev/null
+++ b/searx/engines/not_evil.py
@@ -0,0 +1,64 @@
+"""
+ not Evil (Onions)
+
+ @website http://hss3uro2hsxfogfq.onion
+ @provide-api yes (http://hss3uro2hsxfogfq.onion/api.htm)
+
+ @using-api no
+ @results HTML
+ @stable no
+ @parse url, title, content
+"""
+
+from urllib.parse import urlencode
+from lxml import html
+from searx.engines.xpath import extract_text
+
+# engine dependent config
+categories = ['onions']
+paging = True
+page_size = 20
+
+# search-url
+base_url = 'http://hss3uro2hsxfogfq.onion/'
+search_url = 'index.php?{query}&hostLimit=20&start={pageno}&numRows={page_size}'
+
+# specific xpath variables
+results_xpath = '//*[@id="content"]/div/p'
+url_xpath = './span[1]'
+title_xpath = './a[1]'
+content_xpath = './text()'
+
+
+# do search-request
+def request(query, params):
+ offset = (params['pageno'] - 1) * page_size
+
+ params['url'] = base_url + search_url.format(pageno=offset,
+ query=urlencode({'q': query}),
+ page_size=page_size)
+
+ return params
+
+
+# get response from search-request
+def response(resp):
+ results = []
+
+ # needed because otherwise requests guesses wrong encoding
+ resp.encoding = 'utf8'
+ dom = html.fromstring(resp.text)
+
+ # parse results
+ for result in dom.xpath(results_xpath):
+ url = extract_text(result.xpath(url_xpath)[0])
+ title = extract_text(result.xpath(title_xpath)[0])
+ content = extract_text(result.xpath(content_xpath))
+
+ # append result
+ results.append({'url': url,
+ 'title': title,
+ 'content': content,
+ 'is_onion': True})
+
+ return results
diff --git a/searx/engines/nyaa.py b/searx/engines/nyaa.py
index c57979a..e0a9149 100644
--- a/searx/engines/nyaa.py
+++ b/searx/engines/nyaa.py
@@ -10,9 +10,8 @@
"""
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
-from searx.utils import get_torrent_size, int_or_zero
+from urllib.parse import urlencode
+from searx.utils import extract_text, get_torrent_size, int_or_zero
# engine dependent config
categories = ['files', 'images', 'videos', 'music']
diff --git a/searx/engines/opensemantic.py b/searx/engines/opensemantic.py
new file mode 100644
index 0000000..9364bab
--- /dev/null
+++ b/searx/engines/opensemantic.py
@@ -0,0 +1,42 @@
+"""
+Open Semantic Search
+
+ @website https://www.opensemanticsearch.org/
+ @provide-api yes (https://www.opensemanticsearch.org/dev)
+
+ @using-api yes
+ @results JSON
+ @stable yes
+ @parse url, title, content, publishedDate
+"""
+from dateutil import parser
+from json import loads
+from urllib.parse import quote
+
+base_url = 'http://localhost:8983/solr/opensemanticsearch/'
+search_string = 'query?q={query}'
+
+
+def request(query, params):
+ search_path = search_string.format(
+ query=quote(query),
+ )
+ params['url'] = base_url + search_path
+ return params
+
+
+def response(resp):
+ results = []
+ data = loads(resp.text)
+ docs = data.get('response', {}).get('docs', [])
+
+ for current in docs:
+ item = {}
+ item['url'] = current['id']
+ item['title'] = current['title_txt_txt_en']
+ if current.get('content_txt'):
+ item['content'] = current['content_txt'][0]
+ item['publishedDate'] = parser.parse(current['file_modified_dt'])
+ results.append(item)
+
+ return results
diff --git a/searx/engines/openstreetmap.py b/searx/engines/openstreetmap.py
index 257b1a1..5475c7a 100644
--- a/searx/engines/openstreetmap.py
+++ b/searx/engines/openstreetmap.py
@@ -30,8 +30,8 @@ route_re = re.compile('(?:from )?(.+) to (.+)')
# do search-request
def request(query, params):
- params['url'] = base_url + search_string.format(query=query.decode('utf-8'))
- params['route'] = route_re.match(query.decode('utf-8'))
+ params['url'] = base_url + search_string.format(query=query)
+ params['route'] = route_re.match(query)
return params
@@ -52,7 +52,7 @@ def response(resp):
if 'display_name' not in r:
continue
- title = r['display_name'] or u''
+ title = r['display_name'] or ''
osm_type = r.get('osm_type', r.get('type'))
url = result_base_url.format(osm_type=osm_type,
osm_id=r['osm_id'])
@@ -64,7 +64,7 @@ def response(resp):
# if no geojson is found and osm_type is a node, add geojson Point
if not geojson and osm_type == 'node':
- geojson = {u'type': u'Point', u'coordinates': [r['lon'], r['lat']]}
+ geojson = {'type': 'Point', 'coordinates': [r['lon'], r['lat']]}
address_raw = r.get('address')
address = {}
diff --git a/searx/engines/peertube.py b/searx/engines/peertube.py
new file mode 100644
index 0000000..e43b2a6
--- /dev/null
+++ b/searx/engines/peertube.py
@@ -0,0 +1,94 @@
+"""
+ peertube (Videos)
+
+ @website https://www.peertube.live
+ @provide-api yes (https://docs.joinpeertube.org/api-rest-reference.html)
+
+ @using-api yes
+ @results JSON
+ @stable yes
+ @parse url, title, thumbnail, publishedDate, embedded
+
+ @todo implement time range support
+"""
+
+from json import loads
+from datetime import datetime
+from urllib.parse import urlencode
+from searx.utils import html_to_text
+
+# engine dependent config
+categories = ["videos"]
+paging = True
+language_support = True
+base_url = "https://peer.tube/"
+supported_languages_url = base_url + "api/v1/videos/languages"
+
+
+# do search-request
+def request(query, params):
+ pageno = (params["pageno"] - 1) * 15
+ search_url = base_url + "api/v1/search/videos/?pageno={pageno}&{query}"
+ query_dict = {"search": query}
+ language = params["language"].split("-")[0]
+ # pylint: disable=undefined-variable
+ if "all" != language and language in supported_languages:
+ query_dict["languageOneOf"] = language
+ params["url"] = search_url.format(
+ query=urlencode(query_dict), pageno=pageno
+ )
+ return params
+
+
+def _get_offset_from_pageno(pageno):
+ return (pageno - 1) * 15 + 1
+
+
+# get response from search-request
+def response(resp):
+ results = []
+
+ search_res = loads(resp.text)
+
+ embedded_url = (
+ '<iframe width="560" height="315" sandbox="allow-same-origin allow-scripts allow-popups" '
+ + 'src="'
+ + base_url
+ + '{embed_path}" frameborder="0" allowfullscreen></iframe>'
+ )
+ # return empty array if there are no results
+ if "data" not in search_res:
+ return []
+
+ # parse results
+ for res in search_res["data"]:
+ title = res["name"]
+ url = base_url + "/videos/watch/" + res["uuid"]
+ description = res["description"]
+ if description:
+ content = html_to_text(res["description"])
+ else:
+ content = None
+ thumbnail = base_url + res["thumbnailPath"]
+ publishedDate = datetime.strptime(res["publishedAt"], "%Y-%m-%dT%H:%M:%S.%fZ")
+ embedded = embedded_url.format(embed_path=res["embedPath"][1:])
+
+ results.append(
+ {
+ "template": "videos.html",
+ "url": url,
+ "title": title,
+ "content": content,
+ "publishedDate": publishedDate,
+ "embedded": embedded,
+ "thumbnail": thumbnail,
+ }
+ )
+
+ # return results
+ return results
+
+
+def _fetch_supported_languages(resp):
+ peertube_languages = list(loads(resp.text).keys())
+ return peertube_languages
diff --git a/searx/engines/photon.py b/searx/engines/photon.py
index 15236f6..7a6fc83 100644
--- a/searx/engines/photon.py
+++ b/searx/engines/photon.py
@@ -11,8 +11,8 @@
"""
from json import loads
+from urllib.parse import urlencode
from searx.utils import searx_useragent
-from searx.url_utils import urlencode
# engine dependent config
categories = ['map']
@@ -21,7 +21,7 @@ language_support = True
number_of_results = 10
# search-url
-base_url = 'https://photon.komoot.de/'
+base_url = 'https://photon.komoot.io/'
search_string = 'api/?{query}&limit={limit}'
result_base_url = 'https://openstreetmap.org/{osm_type}/{osm_id}'
diff --git a/searx/engines/piratebay.py b/searx/engines/piratebay.py
index 2f3f22a..828241e 100644
--- a/searx/engines/piratebay.py
+++ b/searx/engines/piratebay.py
@@ -1,44 +1,51 @@
# Piratebay (Videos, Music, Files)
#
-# @website https://thepiratebay.se
-# @provide-api no (nothing found)
+# @website https://thepiratebay.org
+# @provide-api yes (https://apibay.org/)
#
-# @using-api no
-# @results HTML (using search portal)
-# @stable yes (HTML can change)
-# @parse url, title, content, seed, leech, magnetlink
+# @using-api yes
+# @results JSON
+# @stable no (the API is not documented nor versioned)
+# @parse url, title, seed, leech, magnetlink, filesize, publishedDate
-from lxml import html
+from json import loads
+from datetime import datetime
from operator import itemgetter
-from searx.engines.xpath import extract_text
-from searx.url_utils import quote, urljoin
+
+from urllib.parse import quote
+from searx.utils import get_torrent_size
# engine dependent config
-categories = ['videos', 'music', 'files']
-paging = True
+categories = ["videos", "music", "files"]
# search-url
-url = 'https://thepiratebay.org/'
-search_url = url + 'search/{search_term}/{pageno}/99/{search_type}'
+url = "https://thepiratebay.org/"
+search_url = "https://apibay.org/q.php?q={search_term}&cat={search_type}"
+
+# default trackers provided by thepiratebay
+trackers = [
+ "udp://tracker.coppersurfer.tk:6969/announce",
+ "udp://9.rarbg.to:2920/announce",
+ "udp://tracker.opentrackr.org:1337",
+ "udp://tracker.internetwarriors.net:1337/announce",
+ "udp://tracker.leechers-paradise.org:6969/announce",
+ "udp://tracker.coppersurfer.tk:6969/announce",
+ "udp://tracker.pirateparty.gr:6969/announce",
+ "udp://tracker.cyberia.is:6969/announce",
+]
# piratebay specific type-definitions
-search_types = {'files': '0',
- 'music': '100',
- 'videos': '200'}
-
-# specific xpath variables
-magnet_xpath = './/a[@title="Download this torrent using magnet"]'
-torrent_xpath = './/a[@title="Download this torrent"]'
-content_xpath = './/font[@class="detDesc"]'
+search_types = {"files": "0",
+ "music": "100",
+ "videos": "200"}
# do search-request
def request(query, params):
- search_type = search_types.get(params['category'], '0')
+ search_type = search_types.get(params["category"], "0")
- params['url'] = search_url.format(search_term=quote(query),
- search_type=search_type,
- pageno=params['pageno'] - 1)
+ params["url"] = search_url.format(search_term=quote(query),
+ search_type=search_type)
return params
@@ -47,50 +54,43 @@ def request(query, params):
def response(resp):
results = []
- dom = html.fromstring(resp.text)
-
- search_res = dom.xpath('//table[@id="searchResult"]//tr')
+ search_res = loads(resp.text)
# return empty array if nothing is found
- if not search_res:
+ if search_res[0]["name"] == "No results returned":
return []
# parse results
- for result in search_res[1:]:
- link = result.xpath('.//div[@class="detName"]//a')[0]
- href = urljoin(url, link.attrib.get('href'))
- title = extract_text(link)
- content = extract_text(result.xpath(content_xpath))
- seed, leech = result.xpath('.//td[@align="right"]/text()')[:2]
-
- # convert seed to int if possible
- if seed.isdigit():
- seed = int(seed)
- else:
- seed = 0
-
- # convert leech to int if possible
- if leech.isdigit():
- leech = int(leech)
- else:
- leech = 0
-
- magnetlink = result.xpath(magnet_xpath)[0]
- torrentfile_links = result.xpath(torrent_xpath)
- if torrentfile_links:
- torrentfile_link = torrentfile_links[0].attrib.get('href')
- else:
- torrentfile_link = None
+ for result in search_res:
+ link = url + "description.php?id=" + result["id"]
+ magnetlink = "magnet:?xt=urn:btih:" + result["info_hash"] + "&dn=" + result["name"]\
+ + "&tr=" + "&tr=".join(trackers)
+
+ params = {
+ "url": link,
+ "title": result["name"],
+ "seed": result["seeders"],
+ "leech": result["leechers"],
+ "magnetlink": magnetlink,
+ "template": "torrent.html"
+ }
+
+ # extract and convert creation date
+ try:
+ date = datetime.fromtimestamp(float(result["added"]))
+ params['publishedDate'] = date
+ except:
+ pass
+
+ # let's try to calculate the torrent size
+ try:
+ filesize = get_torrent_size(result["size"], "B")
+ params['filesize'] = filesize
+ except:
+ pass
# append result
- results.append({'url': href,
- 'title': title,
- 'content': content,
- 'seed': seed,
- 'leech': leech,
- 'magnetlink': magnetlink.attrib.get('href'),
- 'torrentfile': torrentfile_link,
- 'template': 'torrent.html'})
+ results.append(params)
# return results sorted by seeder
- return sorted(results, key=itemgetter('seed'), reverse=True)
+ return sorted(results, key=itemgetter("seed"), reverse=True)
diff --git a/searx/engines/pubmed.py b/searx/engines/pubmed.py
index 055f092..07c4570 100644
--- a/searx/engines/pubmed.py
+++ b/searx/engines/pubmed.py
@@ -14,7 +14,7 @@
from flask_babel import gettext
from lxml import etree
from datetime import datetime
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
from searx.poolrequests import get
@@ -81,7 +81,7 @@ def response(resp):
pass
if len(content) > 300:
- content = content[0:300] + "..."
+ content = content[0:300] + "..."
# TODO: center snippet on query term
res_dict = {'url': url,
diff --git a/searx/engines/qwant.py b/searx/engines/qwant.py
index 54e9daf..b785719 100644
--- a/searx/engines/qwant.py
+++ b/searx/engines/qwant.py
@@ -12,20 +12,21 @@
from datetime import datetime
from json import loads
-from searx.utils import html_to_text
-from searx.url_utils import urlencode
-from searx.utils import match_language
+from urllib.parse import urlencode
+from searx.utils import html_to_text, match_language
+from searx.exceptions import SearxEngineAPIException, SearxEngineCaptchaException
+from searx.raise_for_httperror import raise_for_httperror
+
# engine dependent config
-categories = None
+categories = []
paging = True
language_support = True
supported_languages_url = 'https://qwant.com/region'
category_to_keyword = {'general': 'web',
'images': 'images',
- 'news': 'news',
- 'social media': 'social'}
+ 'news': 'news'}
# search-url
url = 'https://api.qwant.com/api/search/{keyword}?count=10&offset={offset}&f=&{query}&t={keyword}&uiv=4'
@@ -51,6 +52,7 @@ def request(query, params):
params['url'] += '&locale=' + language.replace('-', '_').lower()
params['headers']['User-Agent'] = 'Mozilla/5.0 (X11; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0'
+ params['raise_for_httperror'] = False
return params
@@ -58,8 +60,20 @@ def request(query, params):
def response(resp):
results = []
+ # According to https://www.qwant.com/js/app.js
+ if resp.status_code == 429:
+ raise SearxEngineCaptchaException()
+
+ # raise for other errors
+ raise_for_httperror(resp)
+
+ # load JSON result
search_results = loads(resp.text)
+ # check for an API error
+ if search_results.get('status') != 'success':
+ raise SearxEngineAPIException('API error ' + str(search_results.get('error', '')))
+
# return empty array if there are no results
if 'data' not in search_results:
return []
@@ -90,15 +104,6 @@ def response(resp):
'thumbnail_src': thumbnail_src,
'img_src': img_src})
- elif category_to_keyword.get(categories[0], '') == 'social':
- published_date = datetime.fromtimestamp(result['date'], None)
- img_src = result.get('img', None)
- results.append({'url': res_url,
- 'title': title,
- 'publishedDate': published_date,
- 'content': content,
- 'img_src': img_src})
-
elif category_to_keyword.get(categories[0], '') == 'news':
published_date = datetime.fromtimestamp(result['date'], None)
media = result.get('media', [])
@@ -124,11 +129,10 @@ def _fetch_supported_languages(resp):
regions_json = loads(response_text)
- supported_languages = []
+ supported_languages = {}
for lang in regions_json['languages'].values():
- if lang['code'] == 'nb':
- lang['code'] = 'no'
for country in lang['countries']:
- supported_languages.append(lang['code'] + '-' + country)
+ lang_code = "{lang}-{country}".format(lang=lang['code'], country=country)
+ supported_languages[lang_code] = {'name': lang['name']}
return supported_languages
diff --git a/searx/engines/recoll.py b/searx/engines/recoll.py
new file mode 100644
index 0000000..5a956b8
--- /dev/null
+++ b/searx/engines/recoll.py
@@ -0,0 +1,104 @@
+"""
+ Recoll (local search engine)
+
+ @using-api yes
+ @results JSON
+ @stable yes
+ @parse url, content, size, abstract, author, mtype, subtype, time, \
+ filename, label, type, embedded
+"""
+
+from datetime import date, timedelta
+from json import loads
+from urllib.parse import urlencode, quote
+
+# engine dependent config
+time_range_support = True
+
+# parameters from settings.yml
+base_url = None
+search_dir = ''
+mount_prefix = None
+dl_prefix = None
+
+# embedded
+embedded_url = '<{ttype} controls height="166px" ' +\
+ 'src="{url}" type="{mtype}"></{ttype}>'
+
+
+# helper functions
+def get_time_range(time_range):
+ sw = {
+ 'day': 1,
+ 'week': 7,
+ 'month': 30,
+ 'year': 365
+ }
+
+ offset = sw.get(time_range, 0)
+ if not offset:
+ return ''
+
+ return (date.today() - timedelta(days=offset)).isoformat()
+
+
+# do search-request
+def request(query, params):
+ search_after = get_time_range(params['time_range'])
+ search_url = base_url + 'json?{query}&highlight=0'
+ params['url'] = search_url.format(query=urlencode({
+ 'query': query,
+ 'after': search_after,
+ 'dir': search_dir}))
+
+ return params
+
+
+# get response from search-request
+def response(resp):
+ results = []
+
+ response_json = loads(resp.text)
+
+ if not response_json:
+ return []
+
+ for result in response_json.get('results', []):
+ title = result['label']
+ url = result['url'].replace('file://' + mount_prefix, dl_prefix)
+ content = '{}'.format(result['snippet'])
+
+ # append result
+ item = {'url': url,
+ 'title': title,
+ 'content': content,
+ 'template': 'files.html'}
+
+ if result['size']:
+ item['size'] = int(result['size'])
+
+ for parameter in ['filename', 'abstract', 'author', 'mtype', 'time']:
+ if result[parameter]:
+ item[parameter] = result[parameter]
+
+ # facilitate preview support for known mime types
+ if 'mtype' in result and '/' in result['mtype']:
+ (mtype, subtype) = result['mtype'].split('/')
+ item['mtype'] = mtype
+ item['subtype'] = subtype
+
+ if mtype in ['audio', 'video']:
+ item['embedded'] = embedded_url.format(
+ ttype=mtype,
+ url=quote(url.encode('utf8'), '/:'),
+ mtype=result['mtype'])
+
+ if mtype in ['image'] and subtype in ['bmp', 'gif', 'jpeg', 'png']:
+ item['img_src'] = url
+
+ results.append(item)
+
+ if 'nres' in response_json:
+ results.append({'number_of_results': response_json['nres']})
+
+ return results
diff --git a/searx/engines/reddit.py b/searx/engines/reddit.py
index d197249..e732875 100644
--- a/searx/engines/reddit.py
+++ b/searx/engines/reddit.py
@@ -12,7 +12,7 @@
import json
from datetime import datetime
-from searx.url_utils import urlencode, urljoin, urlparse
+from urllib.parse import urlencode, urljoin, urlparse
# engine dependent config
categories = ['general', 'images', 'news', 'social media']
diff --git a/searx/engines/scanr_structures.py b/searx/engines/scanr_structures.py
index 7208dcb..72fd2b3 100644
--- a/searx/engines/scanr_structures.py
+++ b/searx/engines/scanr_structures.py
@@ -29,7 +29,7 @@ def request(query, params):
params['url'] = search_url
params['method'] = 'POST'
params['headers']['Content-type'] = "application/json"
- params['data'] = dumps({"query": query.decode('utf-8'),
+ params['data'] = dumps({"query": query,
"searchField": "ALL",
"sortDirection": "ASC",
"sortOrder": "RELEVANCY",
diff --git a/searx/engines/searchcode_code.py b/searx/engines/searchcode_code.py
index 789e8e7..7062858 100644
--- a/searx/engines/searchcode_code.py
+++ b/searx/engines/searchcode_code.py
@@ -11,7 +11,7 @@
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
# engine dependent config
diff --git a/searx/engines/searchcode_doc.py b/searx/engines/searchcode_doc.py
deleted file mode 100644
index 4b8e9a8..0000000
--- a/searx/engines/searchcode_doc.py
+++ /dev/null
@@ -1,49 +0,0 @@
-"""
- Searchcode (It)
-
- @website https://searchcode.com/
- @provide-api yes (https://searchcode.com/api/)
-
- @using-api yes
- @results JSON
- @stable yes
- @parse url, title, content
-"""
-
-from json import loads
-from searx.url_utils import urlencode
-
-# engine dependent config
-categories = ['it']
-paging = True
-
-# search-url
-url = 'https://searchcode.com/'
-search_url = url + 'api/search_IV/?{query}&p={pageno}'
-
-
-# do search-request
-def request(query, params):
- params['url'] = search_url.format(query=urlencode({'q': query}), pageno=params['pageno'] - 1)
-
- return params
-
-
-# get response from search-request
-def response(resp):
- results = []
-
- search_results = loads(resp.text)
-
- # parse results
- for result in search_results.get('results', []):
- href = result['url']
- title = "[{}] {} {}".format(result['type'], result['namespace'], result['name'])
-
- # append result
- results.append({'url': href,
- 'title': title,
- 'content': result['description']})
-
- # return results
- return results
diff --git a/searx/engines/searx_engine.py b/searx/engines/searx_engine.py
index d4c85bd..87e5e05 100644
--- a/searx/engines/searx_engine.py
+++ b/searx/engines/searx_engine.py
@@ -1,8 +1,8 @@
"""
Searx (all)
- @website https://github.com/asciimoo/searx
- @provide-api yes (https://asciimoo.github.io/searx/dev/search_api.html)
+ @website https://github.com/searx/searx
+ @provide-api yes (https://searx.github.io/searx/dev/search_api.html)
@using-api yes
@results JSON
diff --git a/searx/engines/seedpeer.py b/searx/engines/seedpeer.py
deleted file mode 100644
index f9b1f99..0000000
--- a/searx/engines/seedpeer.py
+++ /dev/null
@@ -1,78 +0,0 @@
-# Seedpeer (Videos, Music, Files)
-#
-# @website https://seedpeer.me
-# @provide-api no (nothing found)
-#
-# @using-api no
-# @results HTML (using search portal)
-# @stable yes (HTML can change)
-# @parse url, title, content, seed, leech, magnetlink
-
-from lxml import html
-from json import loads
-from operator import itemgetter
-from searx.url_utils import quote, urljoin
-from searx.engines.xpath import extract_text
-
-
-url = 'https://seedpeer.me/'
-search_url = url + 'search/{search_term}?page={page_no}'
-torrent_file_url = url + 'torrent/{torrent_hash}'
-
-# specific xpath variables
-script_xpath = '//script[@type="text/javascript"][not(@src)]'
-torrent_xpath = '(//table)[2]/tbody/tr'
-link_xpath = '(./td)[1]/a/@href'
-age_xpath = '(./td)[2]'
-size_xpath = '(./td)[3]'
-
-
-# do search-request
-def request(query, params):
- params['url'] = search_url.format(search_term=quote(query),
- page_no=params['pageno'])
- return params
-
-
-# get response from search-request
-def response(resp):
- results = []
- dom = html.fromstring(resp.text)
- result_rows = dom.xpath(torrent_xpath)
-
- try:
- script_element = dom.xpath(script_xpath)[0]
- json_string = script_element.text[script_element.text.find('{'):]
- torrents_json = loads(json_string)
- except:
- return []
-
- # parse results
- for torrent_row, torrent_json in zip(result_rows, torrents_json['data']['list']):
- title = torrent_json['name']
- seed = int(torrent_json['seeds'])
- leech = int(torrent_json['peers'])
- size = int(torrent_json['size'])
- torrent_hash = torrent_json['hash']
-
- torrentfile = torrent_file_url.format(torrent_hash=torrent_hash)
- magnetlink = 'magnet:?xt=urn:btih:{}'.format(torrent_hash)
-
- age = extract_text(torrent_row.xpath(age_xpath))
- link = torrent_row.xpath(link_xpath)[0]
-
- href = urljoin(url, link)
-
- # append result
- results.append({'url': href,
- 'title': title,
- 'content': age,
- 'seed': seed,
- 'leech': leech,
- 'filesize': size,
- 'torrentfile': torrentfile,
- 'magnetlink': magnetlink,
- 'template': 'torrent.html'})
-
- # return results sorted by seeder
- return sorted(results, key=itemgetter('seed'), reverse=True)
diff --git a/searx/engines/sepiasearch.py b/searx/engines/sepiasearch.py
new file mode 100644
index 0000000..0b7c1ba
--- /dev/null
+++ b/searx/engines/sepiasearch.py
@@ -0,0 +1,97 @@
+# SepiaSearch (Videos)
+#
+# @website https://sepiasearch.org
+# @provide-api https://framagit.org/framasoft/peertube/search-index/-/tree/master/server/controllers/api
+# @using-api yes
+# @results JSON
+# @stable yes
+# @parse url, title, content, publishedDate, thumbnail
+
+from json import loads
+from dateutil import parser, relativedelta
+from urllib.parse import urlencode
+from datetime import datetime
+
+categories = ['videos']
+paging = True
+language_support = True
+time_range_support = True
+safesearch = True
+supported_languages = [
+ 'en', 'fr', 'ja', 'eu', 'ca', 'cs', 'eo', 'el',
+ 'de', 'it', 'nl', 'es', 'oc', 'gd', 'zh', 'pt',
+ 'sv', 'pl', 'fi', 'ru'
+]
+base_url = 'https://sepiasearch.org/api/v1/search/videos'
+
+safesearch_table = {
+ 0: 'both',
+ 1: 'false',
+ 2: 'false'
+}
+
+time_range_table = {
+ 'day': relativedelta.relativedelta(),
+ 'week': relativedelta.relativedelta(weeks=-1),
+ 'month': relativedelta.relativedelta(months=-1),
+ 'year': relativedelta.relativedelta(years=-1)
+}
+
+
+embedded_url = '<iframe width="540" height="304" src="{url}" frameborder="0" allowfullscreen></iframe>'
+
+
+def minute_to_hm(minute):
+ if isinstance(minute, int):
+ return "%d:%02d" % (divmod(minute, 60))
+ return None
+
+
+def request(query, params):
+ params['url'] = base_url + '?' + urlencode({
+ 'search': query,
+ 'start': (params['pageno'] - 1) * 10,
+ 'count': 10,
+ 'sort': '-match',
+ 'nsfw': safesearch_table[params['safesearch']]
+ })
+
+ language = params['language'].split('-')[0]
+ if language in supported_languages:
+ params['url'] += '&languageOneOf[]=' + language
+ if params['time_range'] in time_range_table:
+ time = datetime.now().date() + time_range_table[params['time_range']]
+ params['url'] += '&startDate=' + time.isoformat()
+
+ return params
+
+
+def response(resp):
+ results = []
+
+ search_results = loads(resp.text)
+
+ if 'data' not in search_results:
+ return []
+
+ for result in search_results['data']:
+ title = result['name']
+ content = result['description']
+ thumbnail = result['thumbnailUrl']
+ publishedDate = parser.parse(result['publishedAt'])
+ embedded = embedded_url.format(url=result.get('embedUrl'))
+ author = result.get('account', {}).get('displayName')
+ length = minute_to_hm(result.get('duration'))
+ url = result['url']
+
+ results.append({'url': url,
+ 'title': title,
+ 'content': content,
+ 'author': author,
+ 'length': length,
+ 'template': 'videos.html',
+ 'publishedDate': publishedDate,
+ 'embedded': embedded,
+ 'thumbnail': thumbnail})
+
+ return results
diff --git a/searx/engines/soundcloud.py b/searx/engines/soundcloud.py
index 284689b..84ff21a 100644
--- a/searx/engines/soundcloud.py
+++ b/searx/engines/soundcloud.py
@@ -14,14 +14,10 @@ import re
from json import loads
from lxml import html
from dateutil import parser
+from urllib.parse import quote_plus, urlencode
from searx import logger
from searx.poolrequests import get as http_get
-from searx.url_utils import quote_plus, urlencode
-try:
- from cStringIO import StringIO
-except:
- from io import StringIO
# engine dependent config
categories = ['music']
@@ -61,7 +57,7 @@ def get_client_id():
# gets app_js and searches for the clientid
response = http_get(app_js_url)
if response.ok:
- cids = cid_re.search(response.content.decode("utf-8"))
+ cids = cid_re.search(response.content.decode())
if cids is not None and len(cids.groups()):
return cids.groups()[0]
logger.warning("Unable to fetch guest client_id from SoundCloud, check parser!")
@@ -95,7 +91,7 @@ def response(resp):
for result in search_res.get('collection', []):
if result['kind'] in ('track', 'playlist'):
title = result['title']
- content = result['description']
+ content = result['description'] or ''
publishedDate = parser.parse(result['last_modified'])
uri = quote_plus(result['uri'])
embedded = embedded_url.format(uri=uri)
diff --git a/searx/engines/spotify.py b/searx/engines/spotify.py
index 00c3957..7494232 100644
--- a/searx/engines/spotify.py
+++ b/searx/engines/spotify.py
@@ -11,7 +11,7 @@
"""
from json import loads
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
import requests
import base64
@@ -39,8 +39,8 @@ def request(query, params):
'https://accounts.spotify.com/api/token',
data={'grant_type': 'client_credentials'},
headers={'Authorization': 'Basic ' + base64.b64encode(
- "{}:{}".format(api_client_id, api_client_secret).encode('utf-8')
- ).decode('utf-8')}
+ "{}:{}".format(api_client_id, api_client_secret).encode()
+ ).decode()}
)
j = loads(r.text)
params['headers'] = {'Authorization': 'Bearer {}'.format(j.get('access_token'))}
@@ -59,7 +59,7 @@ def response(resp):
if result['type'] == 'track':
title = result['name']
url = result['external_urls']['spotify']
- content = u'{} - {} - {}'.format(
+ content = '{} - {} - {}'.format(
result['artists'][0]['name'],
result['album']['name'],
result['name'])
diff --git a/searx/engines/stackoverflow.py b/searx/engines/stackoverflow.py
index 25875aa..f730264 100644
--- a/searx/engines/stackoverflow.py
+++ b/searx/engines/stackoverflow.py
@@ -10,9 +10,10 @@
@parse url, title, content
"""
+from urllib.parse import urlencode, urljoin, urlparse
from lxml import html
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode, urljoin
+from searx.utils import extract_text
+from searx.exceptions import SearxEngineCaptchaException
# engine dependent config
categories = ['it']
@@ -37,6 +38,10 @@ def request(query, params):
# get response from search-request
def response(resp):
+ resp_url = urlparse(resp.url)
+ if resp_url.path.startswith('/nocaptcha'):
+ raise SearxEngineCaptchaException()
+
results = []
dom = html.fromstring(resp.text)
diff --git a/searx/engines/startpage.py b/searx/engines/startpage.py
index 9537349..16e846a 100644
--- a/searx/engines/startpage.py
+++ b/searx/engines/startpage.py
@@ -14,9 +14,10 @@ from lxml import html
from dateutil import parser
from datetime import datetime, timedelta
import re
-from searx.engines.xpath import extract_text
-from searx.languages import language_codes
-from searx.utils import eval_xpath
+from unicodedata import normalize, combining
+from babel import Locale
+from babel.localedata import locale_identifiers
+from searx.utils import extract_text, eval_xpath, match_language
# engine dependent config
categories = ['general']
@@ -26,6 +27,7 @@ categories = ['general']
paging = True
language_support = True
+supported_languages_url = 'https://www.startpage.com/do/settings'
# search-url
base_url = 'https://startpage.com/'
@@ -34,8 +36,8 @@ search_url = base_url + 'do/search'
# specific xpath variables
# ads xpath //div[@id="results"]/div[@id="sponsored"]//div[@class="result"]
# not ads: div[@class="result"] are the direct childs of div[@id="results"]
-results_xpath = '//div[@class="w-gl__result"]'
-link_xpath = './/a[@class="w-gl__result-title"]'
+results_xpath = '//div[@class="w-gl__result__main"]'
+link_xpath = './/a[@class="w-gl__result-url result-link"]'
content_xpath = './/p[@class="w-gl__description"]'
@@ -54,12 +56,11 @@ def request(query, params):
# set language if specified
if params['language'] != 'all':
- language = 'english'
- for lc, _, _, lang in language_codes:
- if lc == params['language']:
- language = lang
- params['data']['language'] = language
- params['data']['lui'] = language
+ lang_code = match_language(params['language'], supported_languages, fallback=None)
+ if lang_code:
+ language_name = supported_languages[lang_code]['alias']
+ params['data']['language'] = language_name
+ params['data']['lui'] = language_name
return params
@@ -132,3 +133,55 @@ def response(resp):
# return results
return results
+
+
+# get supported languages from their site
+def _fetch_supported_languages(resp):
+ # startpage's language selector is a mess
+ # each option has a displayed name and a value, either of which may represent the language name
+ # in the native script, the language name in English, an English transliteration of the native name,
+ # the English name of the writing script used by the language, or occasionally something else entirely.
+
+ # this cases are so special they need to be hardcoded, a couple of them are mispellings
+ language_names = {
+ 'english_uk': 'en-GB',
+ 'fantizhengwen': ['zh-TW', 'zh-HK'],
+ 'hangul': 'ko',
+ 'malayam': 'ml',
+ 'norsk': 'nb',
+ 'sinhalese': 'si',
+ 'sudanese': 'su'
+ }
+
+ # get the English name of every language known by babel
+ language_names.update({name.lower(): lang_code for lang_code, name in Locale('en')._data['languages'].items()})
+
+ # get the native name of every language known by babel
+ for lang_code in filter(lambda lang_code: lang_code.find('_') == -1, locale_identifiers()):
+ native_name = Locale(lang_code).get_language_name().lower()
+ # add native name exactly as it is
+ language_names[native_name] = lang_code
+
+ # add "normalized" language name (i.e. français becomes francais and español becomes espanol)
+ unaccented_name = ''.join(filter(lambda c: not combining(c), normalize('NFKD', native_name)))
+ if len(unaccented_name) == len(unaccented_name.encode()):
+ # add only if result is ascii (otherwise "normalization" didn't work)
+ language_names[unaccented_name] = lang_code
+
+ dom = html.fromstring(resp.text)
+ sp_lang_names = []
+ for option in dom.xpath('//form[@id="settings-form"]//select[@name="language"]/option'):
+ sp_lang_names.append((option.get('value'), extract_text(option).lower()))
+
+ supported_languages = {}
+ for sp_option_value, sp_option_text in sp_lang_names:
+ lang_code = language_names.get(sp_option_value) or language_names.get(sp_option_text)
+ if isinstance(lang_code, str):
+ supported_languages[lang_code] = {'alias': sp_option_value}
+ elif isinstance(lang_code, list):
+ for lc in lang_code:
+ supported_languages[lc] = {'alias': sp_option_value}
+ else:
+ print('Unknown language option in Startpage: {} ({})'.format(sp_option_value, sp_option_text))
+
+ return supported_languages
diff --git a/searx/engines/tokyotoshokan.py b/searx/engines/tokyotoshokan.py
index 7732120..9fffba8 100644
--- a/searx/engines/tokyotoshokan.py
+++ b/searx/engines/tokyotoshokan.py
@@ -11,11 +11,10 @@
"""
import re
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text
from datetime import datetime
-from searx.url_utils import urlencode
-from searx.utils import get_torrent_size, int_or_zero
+from searx.utils import extract_text, get_torrent_size, int_or_zero
# engine dependent config
categories = ['files', 'videos', 'music']
diff --git a/searx/engines/torrentz.py b/searx/engines/torrentz.py
index fd4164a..4d3e6fd 100644
--- a/searx/engines/torrentz.py
+++ b/searx/engines/torrentz.py
@@ -1,30 +1,29 @@
"""
- Torrentz2.eu (BitTorrent meta-search engine)
+ Torrentz2.is (BitTorrent meta-search engine)
- @website https://torrentz2.eu/
+ @website https://torrentz2.is/
@provide-api no
@using-api no
@results HTML
@stable no (HTML can change, although unlikely,
- see https://torrentz.eu/torrentz.btsearch)
+ see https://torrentz.is/torrentz.btsearch)
@parse url, title, publishedDate, seed, leech, filesize, magnetlink
"""
import re
+from urllib.parse import urlencode
from lxml import html
from datetime import datetime
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode
-from searx.utils import get_torrent_size
+from searx.utils import extract_text, get_torrent_size
# engine dependent config
categories = ['files', 'videos', 'music']
paging = True
# search-url
-# https://torrentz2.eu/search?f=EXAMPLE&p=6
-base_url = 'https://torrentz2.eu/'
+# https://torrentz2.is/search?f=EXAMPLE&p=6
+base_url = 'https://torrentz2.is/'
search_url = base_url + 'search?{query}'
diff --git a/searx/engines/translated.py b/searx/engines/translated.py
index 5c7b170..75b8b5f 100644
--- a/searx/engines/translated.py
+++ b/searx/engines/translated.py
@@ -9,23 +9,20 @@
@parse url, title, content
"""
import re
-from sys import version_info
from searx.utils import is_valid_lang
-if version_info[0] == 3:
- unicode = str
-
categories = ['general']
-url = u'http://api.mymemory.translated.net/get?q={query}&langpair={from_lang}|{to_lang}{key}'
-web_url = u'http://mymemory.translated.net/en/{from_lang}/{to_lang}/{query}'
+url = 'https://api.mymemory.translated.net/get?q={query}&langpair={from_lang}|{to_lang}{key}'
+web_url = 'https://mymemory.translated.net/en/{from_lang}/{to_lang}/{query}'
weight = 100
+https_support = True
-parser_re = re.compile(u'.*?([a-z]+)-([a-z]+) (.{2,})$', re.I)
+parser_re = re.compile('.*?([a-z]+)-([a-z]+) (.{2,})$', re.I)
api_key = ''
def request(query, params):
- m = parser_re.match(unicode(query, 'utf8'))
+ m = parser_re.match(query)
if not m:
return params
diff --git a/searx/engines/twitter.py b/searx/engines/twitter.py
deleted file mode 100644
index d2a8d20..0000000
--- a/searx/engines/twitter.py
+++ /dev/null
@@ -1,87 +0,0 @@
-"""
- Twitter (Social media)
-
- @website https://twitter.com/
- @provide-api yes (https://dev.twitter.com/docs/using-search)
-
- @using-api no
- @results HTML (using search portal)
- @stable no (HTML can change)
- @parse url, title, content
-
- @todo publishedDate
-"""
-
-from lxml import html
-from datetime import datetime
-from searx.engines.xpath import extract_text
-from searx.url_utils import urlencode, urljoin
-
-# engine dependent config
-categories = ['social media']
-language_support = True
-
-# search-url
-base_url = 'https://twitter.com/'
-search_url = base_url + 'search?'
-
-# specific xpath variables
-results_xpath = '//li[@data-item-type="tweet"]'
-avatar_xpath = './/img[contains(@class, "avatar")]/@src'
-link_xpath = './/small[@class="time"]//a'
-title_xpath = './/span[contains(@class, "username")]'
-content_xpath = './/p[contains(@class, "tweet-text")]'
-timestamp_xpath = './/span[contains(@class,"_timestamp")]'
-
-
-# do search-request
-def request(query, params):
- params['url'] = search_url + urlencode({'q': query})
-
- # set language if specified
- if params['language'] != 'all':
- params['cookies']['lang'] = params['language'].split('-')[0]
- else:
- params['cookies']['lang'] = 'en'
-
- return params
-
-
-# get response from search-request
-def response(resp):
- results = []
-
- dom = html.fromstring(resp.text)
-
- # parse results
- for tweet in dom.xpath(results_xpath):
- try:
- link = tweet.xpath(link_xpath)[0]
- content = extract_text(tweet.xpath(content_xpath)[0])
- img_src = tweet.xpath(avatar_xpath)[0]
- img_src = img_src.replace('_bigger', '_normal')
- except Exception:
- continue
-
- url = urljoin(base_url, link.attrib.get('href'))
- title = extract_text(tweet.xpath(title_xpath))
-
- pubdate = tweet.xpath(timestamp_xpath)
- if len(pubdate) > 0:
- timestamp = float(pubdate[0].attrib.get('data-time'))
- publishedDate = datetime.fromtimestamp(timestamp, None)
- # append result
- results.append({'url': url,
- 'title': title,
- 'content': content,
- 'img_src': img_src,
- 'publishedDate': publishedDate})
- else:
- # append result
- results.append({'url': url,
- 'title': title,
- 'content': content,
- 'img_src': img_src})
-
- # return results
- return results
diff --git a/searx/engines/unsplash.py b/searx/engines/unsplash.py
index 2e8d6fd..45c6b30 100644
--- a/searx/engines/unsplash.py
+++ b/searx/engines/unsplash.py
@@ -10,7 +10,7 @@
@parse url, title, img_src, thumbnail_src
"""
-from searx.url_utils import urlencode, urlparse, urlunparse, parse_qsl
+from urllib.parse import urlencode, urlparse, urlunparse, parse_qsl
from json import loads
url = 'https://unsplash.com/'
diff --git a/searx/engines/vimeo.py b/searx/engines/vimeo.py
index a922710..fd3abc8 100644
--- a/searx/engines/vimeo.py
+++ b/searx/engines/vimeo.py
@@ -12,9 +12,9 @@
# @todo rewrite to api
# @todo set content-parameter with correct data
+from urllib.parse import urlencode
from json import loads
from dateutil import parser
-from searx.url_utils import urlencode
# engine dependent config
categories = ['videos']
diff --git a/searx/engines/wikidata.py b/searx/engines/wikidata.py
index 9d6238d..8d787ca 100644
--- a/searx/engines/wikidata.py
+++ b/searx/engines/wikidata.py
@@ -3,500 +3,690 @@
Wikidata
@website https://wikidata.org
- @provide-api yes (https://wikidata.org/w/api.php)
+ @provide-api yes (https://query.wikidata.org/)
- @using-api partially (most things require scraping)
- @results JSON, HTML
- @stable no (html can change)
+ @using-api yes
+ @results JSON
+ @stable yes
@parse url, infobox
"""
-from searx import logger
-from searx.poolrequests import get
-from searx.engines.xpath import extract_text
-from searx.engines.wikipedia import _fetch_supported_languages, supported_languages_url
-from searx.url_utils import urlencode
-from searx.utils import match_language, eval_xpath
+from urllib.parse import urlencode
from json import loads
-from lxml.html import fromstring
-from lxml import etree
+
+from dateutil.parser import isoparse
+from babel.dates import format_datetime, format_date, format_time, get_datetime_format
+
+from searx import logger
+from searx.data import WIKIDATA_UNITS
+from searx.poolrequests import post, get
+from searx.utils import match_language, searx_useragent, get_string_replaces_function
+from searx.external_urls import get_external_url, get_earth_coordinates_url, area_to_osm_zoom
+from searx.engines.wikipedia import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
logger = logger.getChild('wikidata')
-result_count = 1
-
-# urls
-wikidata_host = 'https://www.wikidata.org'
-url_search = wikidata_host \
- + '/w/index.php?{query}&ns0=1'
-
-wikidata_api = wikidata_host + '/w/api.php'
-url_detail = wikidata_api\
- + '?action=parse&format=json&{query}'\
- + '&redirects=1&prop=text%7Cdisplaytitle%7Cparsewarnings'\
- + '&disableeditsection=1&preview=1&sectionpreview=1&disabletoc=1&utf8=1&formatversion=2'
-
-url_map = 'https://www.openstreetmap.org/'\
- + '?lat={latitude}&lon={longitude}&zoom={zoom}&layers=M'
-url_image = 'https://commons.wikimedia.org/wiki/Special:FilePath/{filename}?width=500&height=400'
-
-# xpaths
-div_ids_xpath = '//div[@id]'
-wikidata_ids_xpath = '//ul[@class="mw-search-results"]/li//a/@href'
-title_xpath = '//*[contains(@class,"wikibase-title-label")]'
-description_xpath = '//div[contains(@class,"wikibase-entitytermsview-heading-description")]'
-label_xpath = './/div[contains(@class,"wikibase-statementgroupview-property-label")]/a'
-url_xpath = './/a[contains(@class,"external free") or contains(@class, "wb-external-id")]'
-wikilink_xpath = './/ul[contains(@class,"wikibase-sitelinklistview-listview")]'\
- + '/li[contains(@data-wb-siteid,"{wikiid}")]//a/@href'
-property_row_xpath = './/div[contains(@class,"wikibase-statementview")]'
-preferred_rank_xpath = './/span[contains(@class,"wikibase-rankselector-preferred")]'
-value_xpath = './/div[contains(@class,"wikibase-statementview-mainsnak")]'\
- + '/*/div[contains(@class,"wikibase-snakview-value")]'
-language_fallback_xpath = '//sup[contains(@class,"wb-language-fallback-indicator")]'
-calendar_name_xpath = './/sup[contains(@class,"wb-calendar-name")]'
-media_xpath = value_xpath + '//div[contains(@class,"commons-media-caption")]//a'
-
-
-def get_id_cache(result):
- id_cache = {}
- for e in eval_xpath(result, div_ids_xpath):
- id = e.get('id')
- if id.startswith('P'):
- id_cache[id] = e
- return id_cache
+
+# SPARQL
+SPARQL_ENDPOINT_URL = 'https://query.wikidata.org/sparql'
+SPARQL_EXPLAIN_URL = 'https://query.wikidata.org/bigdata/namespace/wdq/sparql?explain'
+WIKIDATA_PROPERTIES = {
+ 'P434': 'MusicBrainz',
+ 'P435': 'MusicBrainz',
+ 'P436': 'MusicBrainz',
+ 'P966': 'MusicBrainz',
+ 'P345': 'IMDb',
+ 'P2397': 'YouTube',
+ 'P1651': 'YouTube',
+ 'P2002': 'Twitter',
+ 'P2013': 'Facebook',
+ 'P2003': 'Instagram',
+}
+
+# SERVICE wikibase:mwapi : https://www.mediawiki.org/wiki/Wikidata_Query_Service/User_Manual/MWAPI
+# SERVICE wikibase:label: https://en.wikibooks.org/wiki/SPARQL/SERVICE_-_Label#Manual_Label_SERVICE
+# https://en.wikibooks.org/wiki/SPARQL/WIKIDATA_Precision,_Units_and_Coordinates
+# https://www.mediawiki.org/wiki/Wikibase/Indexing/RDF_Dump_Format#Data_model
+# optmization:
+# * https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/query_optimization
+# * https://github.com/blazegraph/database/wiki/QueryHints
+QUERY_TEMPLATE = """
+SELECT ?item ?itemLabel ?itemDescription ?lat ?long %SELECT%
+WHERE
+{
+ SERVICE wikibase:mwapi {
+ bd:serviceParam wikibase:endpoint "www.wikidata.org";
+ wikibase:api "EntitySearch";
+ wikibase:limit 1;
+ mwapi:search "%QUERY%";
+ mwapi:language "%LANGUAGE%".
+ ?item wikibase:apiOutputItem mwapi:item.
+ }
+
+ %WHERE%
+
+ SERVICE wikibase:label {
+ bd:serviceParam wikibase:language "%LANGUAGE%,en".
+ ?item rdfs:label ?itemLabel .
+ ?item schema:description ?itemDescription .
+ %WIKIBASE_LABELS%
+ }
+
+}
+GROUP BY ?item ?itemLabel ?itemDescription ?lat ?long %GROUP_BY%
+"""
+
+# Get the calendar names and the property names
+QUERY_PROPERTY_NAMES = """
+SELECT ?item ?name
+WHERE {
+ {
+ SELECT ?item
+ WHERE { ?item wdt:P279* wd:Q12132 }
+ } UNION {
+ VALUES ?item { %ATTRIBUTES% }
+ }
+ OPTIONAL { ?item rdfs:label ?name. }
+}
+"""
+
+
+# https://www.w3.org/TR/sparql11-query/#rSTRING_LITERAL1
+# https://lists.w3.org/Archives/Public/public-rdf-dawg/2011OctDec/0175.html
+sparql_string_escape = get_string_replaces_function({'\t': '\\\t',
+ '\n': '\\\n',
+ '\r': '\\\r',
+ '\b': '\\\b',
+ '\f': '\\\f',
+ '\"': '\\\"',
+ '\'': '\\\'',
+ '\\': '\\\\'})
+
+replace_http_by_https = get_string_replaces_function({'http:': 'https:'})
+
+
+def get_headers():
+ # user agent: https://www.mediawiki.org/wiki/Wikidata_Query_Service/User_Manual#Query_limits
+ return {
+ 'Accept': 'application/sparql-results+json',
+ 'User-Agent': searx_useragent()
+ }
+
+
+def get_label_for_entity(entity_id, language):
+ name = WIKIDATA_PROPERTIES.get(entity_id)
+ if name is None:
+ name = WIKIDATA_PROPERTIES.get((entity_id, language))
+ if name is None:
+ name = WIKIDATA_PROPERTIES.get((entity_id, language.split('-')[0]))
+ if name is None:
+ name = WIKIDATA_PROPERTIES.get((entity_id, 'en'))
+ if name is None:
+ name = entity_id
+ return name
+
+
+def send_wikidata_query(query, method='GET'):
+ if method == 'GET':
+ # query will be cached by wikidata
+ http_response = get(SPARQL_ENDPOINT_URL + '?' + urlencode({'query': query}), headers=get_headers())
+ else:
+ # query won't be cached by wikidata
+ http_response = post(SPARQL_ENDPOINT_URL, data={'query': query}, headers=get_headers())
+ if http_response.status_code != 200:
+ logger.debug('SPARQL endpoint error %s', http_response.content.decode())
+ logger.debug('request time %s', str(http_response.elapsed))
+ http_response.raise_for_status()
+ return loads(http_response.content.decode())
def request(query, params):
- params['url'] = url_search.format(
- query=urlencode({'search': query}))
+ language = params['language'].split('-')[0]
+ if language == 'all':
+ language = 'en'
+ else:
+ language = match_language(params['language'], supported_languages, language_aliases).split('-')[0]
+
+ query, attributes = get_query(query, language)
+
+ params['method'] = 'POST'
+ params['url'] = SPARQL_ENDPOINT_URL
+ params['data'] = {'query': query}
+ params['headers'] = get_headers()
+
+ params['language'] = language
+ params['attributes'] = attributes
return params
def response(resp):
results = []
- htmlparser = etree.HTMLParser()
- html = fromstring(resp.content.decode("utf-8"), parser=htmlparser)
- search_results = eval_xpath(html, wikidata_ids_xpath)
+ jsonresponse = loads(resp.content.decode())
- if resp.search_params['language'].split('-')[0] == 'all':
- language = 'en'
- else:
- language = match_language(resp.search_params['language'], supported_languages, language_aliases).split('-')[0]
+ language = resp.search_params['language'].lower()
+ attributes = resp.search_params['attributes']
+
+ seen_entities = set()
- # TODO: make requests asynchronous to avoid timeout when result_count > 1
- for search_result in search_results[:result_count]:
- wikidata_id = search_result.split('/')[-1]
- url = url_detail.format(query=urlencode({'page': wikidata_id, 'uselang': language}))
- htmlresponse = get(url)
- jsonresponse = loads(htmlresponse.content.decode("utf-8"))
- results += getDetail(jsonresponse, wikidata_id, language, resp.search_params['language'], htmlparser)
+ for result in jsonresponse.get('results', {}).get('bindings', []):
+ attribute_result = {key: value['value'] for key, value in result.items()}
+ entity_url = attribute_result['item']
+ if entity_url not in seen_entities:
+ seen_entities.add(entity_url)
+ results += get_results(attribute_result, attributes, language)
+ else:
+ logger.debug('The SPARQL request returns duplicate entities: %s', str(attribute_result))
return results
-def getDetail(jsonresponse, wikidata_id, language, locale, htmlparser):
+def get_results(attribute_result, attributes, language):
results = []
- urls = []
- attributes = []
+ infobox_title = attribute_result.get('itemLabel')
+ infobox_id = attribute_result['item']
+ infobox_id_lang = None
+ infobox_urls = []
+ infobox_attributes = []
+ infobox_content = attribute_result.get('itemDescription', [])
+ img_src = None
+ img_src_priority = 100
+
+ for attribute in attributes:
+ value = attribute.get_str(attribute_result, language)
+ if value is not None and value != '':
+ attribute_type = type(attribute)
+
+ if attribute_type in (WDURLAttribute, WDArticle):
+ # get_select() method : there is group_concat(distinct ...;separator=", ")
+ # split the value here
+ for url in value.split(', '):
+ infobox_urls.append({'title': attribute.get_label(language), 'url': url, **attribute.kwargs})
+ # "normal" results (not infobox) include official website and Wikipedia links.
+ if attribute.kwargs.get('official') or attribute_type == WDArticle:
+ results.append({'title': infobox_title, 'url': url})
+ # update the infobox_id with the wikipedia URL
+ # first the local wikipedia URL, and as fallback the english wikipedia URL
+ if attribute_type == WDArticle\
+ and ((attribute.language == 'en' and infobox_id_lang is None)
+ or attribute.language != 'en'):
+ infobox_id_lang = attribute.language
+ infobox_id = url
+ elif attribute_type == WDImageAttribute:
+ # this attribute is an image.
+ # replace the current image only the priority is lower
+ # (the infobox contain only one image).
+ if attribute.priority < img_src_priority:
+ img_src = value
+ img_src_priority = attribute.priority
+ elif attribute_type == WDGeoAttribute:
+ # geocoordinate link
+ # use the area to get the OSM zoom
+ # Note: ignre the unit (must be km² otherwise the calculation is wrong)
+ # Should use normalized value p:P2046/psn:P2046/wikibase:quantityAmount
+ area = attribute_result.get('P2046')
+ osm_zoom = area_to_osm_zoom(area) if area else 19
+ url = attribute.get_geo_url(attribute_result, osm_zoom=osm_zoom)
+ if url:
+ infobox_urls.append({'title': attribute.get_label(language),
+ 'url': url,
+ 'entity': attribute.name})
+ else:
+ infobox_attributes.append({'label': attribute.get_label(language),
+ 'value': value,
+ 'entity': attribute.name})
+
+ if infobox_id:
+ infobox_id = replace_http_by_https(infobox_id)
- title = jsonresponse.get('parse', {}).get('displaytitle', {})
- result = jsonresponse.get('parse', {}).get('text', {})
-
- if not title or not result:
- return results
-
- title = fromstring(title, parser=htmlparser)
- for elem in eval_xpath(title, language_fallback_xpath):
- elem.getparent().remove(elem)
- title = extract_text(eval_xpath(title, title_xpath))
-
- result = fromstring(result, parser=htmlparser)
- for elem in eval_xpath(result, language_fallback_xpath):
- elem.getparent().remove(elem)
-
- description = extract_text(eval_xpath(result, description_xpath))
-
- id_cache = get_id_cache(result)
-
- # URLS
-
- # official website
- add_url(urls, result, id_cache, 'P856', results=results)
-
- # wikipedia
- wikipedia_link_count = 0
- wikipedia_link = get_wikilink(result, language + 'wiki')
- if wikipedia_link:
- wikipedia_link_count += 1
- urls.append({'title': 'Wikipedia (' + language + ')',
- 'url': wikipedia_link})
-
- if language != 'en':
- wikipedia_en_link = get_wikilink(result, 'enwiki')
- if wikipedia_en_link:
- wikipedia_link_count += 1
- urls.append({'title': 'Wikipedia (en)',
- 'url': wikipedia_en_link})
-
- # TODO: get_wiki_firstlanguage
- # if wikipedia_link_count == 0:
-
- # more wikis
- add_url(urls, result, id_cache, default_label='Wikivoyage (' + language + ')', link_type=language + 'wikivoyage')
- add_url(urls, result, id_cache, default_label='Wikiquote (' + language + ')', link_type=language + 'wikiquote')
- add_url(urls, result, id_cache, default_label='Wikimedia Commons', link_type='commonswiki')
-
- add_url(urls, result, id_cache, 'P625', 'OpenStreetMap', link_type='geo')
-
- # musicbrainz
- add_url(urls, result, id_cache, 'P434', 'MusicBrainz', 'http://musicbrainz.org/artist/')
- add_url(urls, result, id_cache, 'P435', 'MusicBrainz', 'http://musicbrainz.org/work/')
- add_url(urls, result, id_cache, 'P436', 'MusicBrainz', 'http://musicbrainz.org/release-group/')
- add_url(urls, result, id_cache, 'P966', 'MusicBrainz', 'http://musicbrainz.org/label/')
-
- # IMDb
- add_url(urls, result, id_cache, 'P345', 'IMDb', 'https://www.imdb.com/', link_type='imdb')
- # source code repository
- add_url(urls, result, id_cache, 'P1324')
- # blog
- add_url(urls, result, id_cache, 'P1581')
- # social media links
- add_url(urls, result, id_cache, 'P2397', 'YouTube', 'https://www.youtube.com/channel/')
- add_url(urls, result, id_cache, 'P1651', 'YouTube', 'https://www.youtube.com/watch?v=')
- add_url(urls, result, id_cache, 'P2002', 'Twitter', 'https://twitter.com/')
- add_url(urls, result, id_cache, 'P2013', 'Facebook', 'https://facebook.com/')
- add_url(urls, result, id_cache, 'P2003', 'Instagram', 'https://instagram.com/')
-
- urls.append({'title': 'Wikidata',
- 'url': 'https://www.wikidata.org/wiki/'
- + wikidata_id + '?uselang=' + language})
-
- # INFOBOX ATTRIBUTES (ROWS)
-
- # DATES
- # inception date
- add_attribute(attributes, id_cache, 'P571', date=True)
- # dissolution date
- add_attribute(attributes, id_cache, 'P576', date=True)
- # start date
- add_attribute(attributes, id_cache, 'P580', date=True)
- # end date
- add_attribute(attributes, id_cache, 'P582', date=True)
- # date of birth
- add_attribute(attributes, id_cache, 'P569', date=True)
- # date of death
- add_attribute(attributes, id_cache, 'P570', date=True)
- # date of spacecraft launch
- add_attribute(attributes, id_cache, 'P619', date=True)
- # date of spacecraft landing
- add_attribute(attributes, id_cache, 'P620', date=True)
-
- # nationality
- add_attribute(attributes, id_cache, 'P27')
- # country of origin
- add_attribute(attributes, id_cache, 'P495')
- # country
- add_attribute(attributes, id_cache, 'P17')
- # headquarters
- add_attribute(attributes, id_cache, 'Q180')
-
- # PLACES
- # capital
- add_attribute(attributes, id_cache, 'P36', trim=True)
- # head of state
- add_attribute(attributes, id_cache, 'P35', trim=True)
- # head of government
- add_attribute(attributes, id_cache, 'P6', trim=True)
- # type of government
- add_attribute(attributes, id_cache, 'P122')
- # official language
- add_attribute(attributes, id_cache, 'P37')
- # population
- add_attribute(attributes, id_cache, 'P1082', trim=True)
- # area
- add_attribute(attributes, id_cache, 'P2046')
- # currency
- add_attribute(attributes, id_cache, 'P38', trim=True)
- # heigth (building)
- add_attribute(attributes, id_cache, 'P2048')
-
- # MEDIA
- # platform (videogames)
- add_attribute(attributes, id_cache, 'P400')
- # author
- add_attribute(attributes, id_cache, 'P50')
- # creator
- add_attribute(attributes, id_cache, 'P170')
- # director
- add_attribute(attributes, id_cache, 'P57')
- # performer
- add_attribute(attributes, id_cache, 'P175')
- # developer
- add_attribute(attributes, id_cache, 'P178')
- # producer
- add_attribute(attributes, id_cache, 'P162')
- # manufacturer
- add_attribute(attributes, id_cache, 'P176')
- # screenwriter
- add_attribute(attributes, id_cache, 'P58')
- # production company
- add_attribute(attributes, id_cache, 'P272')
- # record label
- add_attribute(attributes, id_cache, 'P264')
- # publisher
- add_attribute(attributes, id_cache, 'P123')
- # original network
- add_attribute(attributes, id_cache, 'P449')
- # distributor
- add_attribute(attributes, id_cache, 'P750')
- # composer
- add_attribute(attributes, id_cache, 'P86')
- # publication date
- add_attribute(attributes, id_cache, 'P577', date=True)
- # genre
- add_attribute(attributes, id_cache, 'P136')
- # original language
- add_attribute(attributes, id_cache, 'P364')
- # isbn
- add_attribute(attributes, id_cache, 'Q33057')
- # software license
- add_attribute(attributes, id_cache, 'P275')
- # programming language
- add_attribute(attributes, id_cache, 'P277')
- # version
- add_attribute(attributes, id_cache, 'P348', trim=True)
- # narrative location
- add_attribute(attributes, id_cache, 'P840')
-
- # LANGUAGES
- # number of speakers
- add_attribute(attributes, id_cache, 'P1098')
- # writing system
- add_attribute(attributes, id_cache, 'P282')
- # regulatory body
- add_attribute(attributes, id_cache, 'P1018')
- # language code
- add_attribute(attributes, id_cache, 'P218')
-
- # OTHER
- # ceo
- add_attribute(attributes, id_cache, 'P169', trim=True)
- # founder
- add_attribute(attributes, id_cache, 'P112')
- # legal form (company/organization)
- add_attribute(attributes, id_cache, 'P1454')
- # operator
- add_attribute(attributes, id_cache, 'P137')
- # crew members (tripulation)
- add_attribute(attributes, id_cache, 'P1029')
- # taxon
- add_attribute(attributes, id_cache, 'P225')
- # chemical formula
- add_attribute(attributes, id_cache, 'P274')
- # winner (sports/contests)
- add_attribute(attributes, id_cache, 'P1346')
- # number of deaths
- add_attribute(attributes, id_cache, 'P1120')
- # currency code
- add_attribute(attributes, id_cache, 'P498')
-
- image = add_image(id_cache)
-
- if len(attributes) == 0 and len(urls) == 2 and len(description) == 0:
+ # add the wikidata URL at the end
+ infobox_urls.append({'title': 'Wikidata', 'url': attribute_result['item']})
+
+ if img_src is None and len(infobox_attributes) == 0 and len(infobox_urls) == 1 and\
+ len(infobox_content) == 0:
results.append({
- 'url': urls[0]['url'],
- 'title': title,
- 'content': description
- })
+ 'url': infobox_urls[0]['url'],
+ 'title': infobox_title,
+ 'content': infobox_content
+ })
else:
results.append({
- 'infobox': title,
- 'id': wikipedia_link,
- 'content': description,
- 'img_src': image,
- 'attributes': attributes,
- 'urls': urls
- })
-
+ 'infobox': infobox_title,
+ 'id': infobox_id,
+ 'content': infobox_content,
+ 'img_src': img_src,
+ 'urls': infobox_urls,
+ 'attributes': infobox_attributes
+ })
return results
-# only returns first match
-def add_image(id_cache):
- # P15: route map, P242: locator map, P154: logo, P18: image, P242: map, P41: flag, P2716: collage, P2910: icon
- property_ids = ['P15', 'P242', 'P154', 'P18', 'P242', 'P41', 'P2716', 'P2910']
+def get_query(query, language):
+ attributes = get_attributes(language)
+ select = [a.get_select() for a in attributes]
+ where = list(filter(lambda s: len(s) > 0, [a.get_where() for a in attributes]))
+ wikibase_label = list(filter(lambda s: len(s) > 0, [a.get_wikibase_label() for a in attributes]))
+ group_by = list(filter(lambda s: len(s) > 0, [a.get_group_by() for a in attributes]))
+ query = QUERY_TEMPLATE\
+ .replace('%QUERY%', sparql_string_escape(query))\
+ .replace('%SELECT%', ' '.join(select))\
+ .replace('%WHERE%', '\n '.join(where))\
+ .replace('%WIKIBASE_LABELS%', '\n '.join(wikibase_label))\
+ .replace('%GROUP_BY%', ' '.join(group_by))\
+ .replace('%LANGUAGE%', language)
+ return query, attributes
- for property_id in property_ids:
- image = id_cache.get(property_id, None)
- if image is not None:
- image_name = eval_xpath(image, media_xpath)
- image_src = url_image.replace('{filename}', extract_text(image_name[0]))
- return image_src
+def get_attributes(language):
+ attributes = []
-# setting trim will only returned high ranked rows OR the first row
-def add_attribute(attributes, id_cache, property_id, default_label=None, date=False, trim=False):
- attribute = id_cache.get(property_id, None)
- if attribute is not None:
+ def add_value(name):
+ attributes.append(WDAttribute(name))
+
+ def add_amount(name):
+ attributes.append(WDAmountAttribute(name))
+
+ def add_label(name):
+ attributes.append(WDLabelAttribute(name))
+
+ def add_url(name, url_id=None, **kwargs):
+ attributes.append(WDURLAttribute(name, url_id, kwargs))
+
+ def add_image(name, url_id=None, priority=1):
+ attributes.append(WDImageAttribute(name, url_id, priority))
+
+ def add_date(name):
+ attributes.append(WDDateAttribute(name))
+
+ # Dates
+ for p in ['P571', # inception date
+ 'P576', # dissolution date
+ 'P580', # start date
+ 'P582', # end date
+ 'P569', # date of birth
+ 'P570', # date of death
+ 'P619', # date of spacecraft launch
+ 'P620']: # date of spacecraft landing
+ add_date(p)
+
+ for p in ['P27', # country of citizenship
+ 'P495', # country of origin
+ 'P17', # country
+ 'P159']: # headquarters location
+ add_label(p)
+
+ # Places
+ for p in ['P36', # capital
+ 'P35', # head of state
+ 'P6', # head of government
+ 'P122', # basic form of government
+ 'P37']: # official language
+ add_label(p)
+
+ add_value('P1082') # population
+ add_amount('P2046') # area
+ add_amount('P281') # postal code
+ add_label('P38') # currency
+ add_amount('P2048') # heigth (building)
+
+ # Media
+ for p in ['P400', # platform (videogames, computing)
+ 'P50', # author
+ 'P170', # creator
+ 'P57', # director
+ 'P175', # performer
+ 'P178', # developer
+ 'P162', # producer
+ 'P176', # manufacturer
+ 'P58', # screenwriter
+ 'P272', # production company
+ 'P264', # record label
+ 'P123', # publisher
+ 'P449', # original network
+ 'P750', # distributed by
+ 'P86']: # composer
+ add_label(p)
+
+ add_date('P577') # publication date
+ add_label('P136') # genre (music, film, artistic...)
+ add_label('P364') # original language
+ add_value('P212') # ISBN-13
+ add_value('P957') # ISBN-10
+ add_label('P275') # copyright license
+ add_label('P277') # programming language
+ add_value('P348') # version
+ add_label('P840') # narrative location
+
+ # Languages
+ add_value('P1098') # number of speakers
+ add_label('P282') # writing system
+ add_label('P1018') # language regulatory body
+ add_value('P218') # language code (ISO 639-1)
+
+ # Other
+ add_label('P169') # ceo
+ add_label('P112') # founded by
+ add_label('P1454') # legal form (company, organization)
+ add_label('P137') # operator (service, facility, ...)
+ add_label('P1029') # crew members (tripulation)
+ add_label('P225') # taxon name
+ add_value('P274') # chemical formula
+ add_label('P1346') # winner (sports, contests, ...)
+ add_value('P1120') # number of deaths
+ add_value('P498') # currency code (ISO 4217)
+
+ # URL
+ add_url('P856', official=True) # official website
+ attributes.append(WDArticle(language)) # wikipedia (user language)
+ if not language.startswith('en'):
+ attributes.append(WDArticle('en')) # wikipedia (english)
+
+ add_url('P1324') # source code repository
+ add_url('P1581') # blog
+ add_url('P434', url_id='musicbrainz_artist')
+ add_url('P435', url_id='musicbrainz_work')
+ add_url('P436', url_id='musicbrainz_release_group')
+ add_url('P966', url_id='musicbrainz_label')
+ add_url('P345', url_id='imdb_id')
+ add_url('P2397', url_id='youtube_channel')
+ add_url('P1651', url_id='youtube_video')
+ add_url('P2002', url_id='twitter_profile')
+ add_url('P2013', url_id='facebook_profile')
+ add_url('P2003', url_id='instagram_profile')
+
+ # Map
+ attributes.append(WDGeoAttribute('P625'))
+
+ # Image
+ add_image('P15', priority=1, url_id='wikimedia_image') # route map
+ add_image('P242', priority=2, url_id='wikimedia_image') # locator map
+ add_image('P154', priority=3, url_id='wikimedia_image') # logo
+ add_image('P18', priority=4, url_id='wikimedia_image') # image
+ add_image('P41', priority=5, url_id='wikimedia_image') # flag
+ add_image('P2716', priority=6, url_id='wikimedia_image') # collage
+ add_image('P2910', priority=7, url_id='wikimedia_image') # icon
+
+ return attributes
+
+
+class WDAttribute:
+
+ __slots__ = 'name',
+
+ def __init__(self, name):
+ self.name = name
+
+ def get_select(self):
+ return '(group_concat(distinct ?{name};separator=", ") as ?{name}s)'.replace('{name}', self.name)
+
+ def get_label(self, language):
+ return get_label_for_entity(self.name, language)
+
+ def get_where(self):
+ return "OPTIONAL { ?item wdt:{name} ?{name} . }".replace('{name}', self.name)
+
+ def get_wikibase_label(self):
+ return ""
+
+ def get_group_by(self):
+ return ""
+
+ def get_str(self, result, language):
+ return result.get(self.name + 's')
- if default_label:
- label = default_label
- else:
- label = extract_text(eval_xpath(attribute, label_xpath))
- label = label[0].upper() + label[1:]
-
- if date:
- trim = True
- # remove calendar name
- calendar_name = eval_xpath(attribute, calendar_name_xpath)
- for calendar in calendar_name:
- calendar.getparent().remove(calendar)
-
- concat_values = ""
- values = []
- first_value = None
- for row in eval_xpath(attribute, property_row_xpath):
- if not first_value or not trim or eval_xpath(row, preferred_rank_xpath):
- value = eval_xpath(row, value_xpath)
- if not value:
- continue
- value = extract_text(value)
-
- # save first value in case no ranked row is found
- if trim and not first_value:
- first_value = value
- else:
- # to avoid duplicate values
- if value not in values:
- concat_values += value + ", "
- values.append(value)
-
- if trim and not values:
- attributes.append({'label': label,
- 'value': first_value})
- else:
- attributes.append({'label': label,
- 'value': concat_values[:-2]})
+ def __repr__(self):
+ return '<' + str(type(self).__name__) + ':' + self.name + '>'
-# requires property_id unless it's a wiki link (defined in link_type)
-def add_url(urls, result, id_cache, property_id=None, default_label=None, url_prefix=None, results=None,
- link_type=None):
- links = []
+class WDAmountAttribute(WDAttribute):
- # wiki links don't have property in wikidata page
- if link_type and 'wiki' in link_type:
- links.append(get_wikilink(result, link_type))
- else:
- dom_element = id_cache.get(property_id, None)
- if dom_element is not None:
- if not default_label:
- label = extract_text(eval_xpath(dom_element, label_xpath))
- label = label[0].upper() + label[1:]
+ def get_select(self):
+ return '?{name} ?{name}Unit'.replace('{name}', self.name)
- if link_type == 'geo':
- links.append(get_geolink(dom_element))
+ def get_where(self):
+ return """ OPTIONAL { ?item p:{name} ?{name}Node .
+ ?{name}Node rdf:type wikibase:BestRank ; ps:{name} ?{name} .
+ OPTIONAL { ?{name}Node psv:{name}/wikibase:quantityUnit ?{name}Unit. } }""".replace('{name}', self.name)
- elif link_type == 'imdb':
- links.append(get_imdblink(dom_element, url_prefix))
+ def get_group_by(self):
+ return self.get_select()
- else:
- url_results = eval_xpath(dom_element, url_xpath)
- for link in url_results:
- if link is not None:
- if url_prefix:
- link = url_prefix + extract_text(link)
- else:
- link = extract_text(link)
- links.append(link)
-
- # append urls
- for url in links:
- if url is not None:
- u = {'title': default_label or label, 'url': url}
- if property_id == 'P856':
- u['official'] = True
- u['domain'] = url.split('/')[2]
- urls.append(u)
- if results is not None:
- results.append(u)
-
-
-def get_imdblink(result, url_prefix):
- imdb_id = eval_xpath(result, value_xpath)
- if imdb_id:
- imdb_id = extract_text(imdb_id)
- id_prefix = imdb_id[:2]
- if id_prefix == 'tt':
- url = url_prefix + 'title/' + imdb_id
- elif id_prefix == 'nm':
- url = url_prefix + 'name/' + imdb_id
- elif id_prefix == 'ch':
- url = url_prefix + 'character/' + imdb_id
- elif id_prefix == 'co':
- url = url_prefix + 'company/' + imdb_id
- elif id_prefix == 'ev':
- url = url_prefix + 'event/' + imdb_id
- else:
- url = None
- return url
+ def get_str(self, result, language):
+ value = result.get(self.name)
+ unit = result.get(self.name + "Unit")
+ if unit is not None:
+ unit = unit.replace('http://www.wikidata.org/entity/', '')
+ return value + " " + get_label_for_entity(unit, language)
+ return value
-def get_geolink(result):
- coordinates = eval_xpath(result, value_xpath)
- if not coordinates:
- return None
- coordinates = extract_text(coordinates[0])
- latitude, longitude = coordinates.split(',')
-
- # convert to decimal
- lat = int(latitude[:latitude.find(u'°')])
- if latitude.find('\'') >= 0:
- lat += int(latitude[latitude.find(u'°') + 1:latitude.find('\'')] or 0) / 60.0
- if latitude.find('"') >= 0:
- lat += float(latitude[latitude.find('\'') + 1:latitude.find('"')] or 0) / 3600.0
- if latitude.find('S') >= 0:
- lat *= -1
- lon = int(longitude[:longitude.find(u'°')])
- if longitude.find('\'') >= 0:
- lon += int(longitude[longitude.find(u'°') + 1:longitude.find('\'')] or 0) / 60.0
- if longitude.find('"') >= 0:
- lon += float(longitude[longitude.find('\'') + 1:longitude.find('"')] or 0) / 3600.0
- if longitude.find('W') >= 0:
- lon *= -1
-
- # TODO: get precision
- precision = 0.0002
- # there is no zoom information, deduce from precision (error prone)
- # samples :
- # 13 --> 5
- # 1 --> 6
- # 0.016666666666667 --> 9
- # 0.00027777777777778 --> 19
- # wolframalpha :
- # quadratic fit { {13, 5}, {1, 6}, {0.0166666, 9}, {0.0002777777,19}}
- # 14.1186-8.8322 x+0.625447 x^2
- if precision < 0.0003:
- zoom = 19
- else:
- zoom = int(15 - precision * 8.8322 + precision * precision * 0.625447)
+class WDArticle(WDAttribute):
+
+ __slots__ = 'language', 'kwargs'
+
+ def __init__(self, language, kwargs=None):
+ super().__init__('wikipedia')
+ self.language = language
+ self.kwargs = kwargs or {}
+
+ def get_label(self, language):
+ # language parameter is ignored
+ return "Wikipedia ({language})".replace('{language}', self.language)
+
+ def get_select(self):
+ return "?article{language} ?articleName{language}".replace('{language}', self.language)
+
+ def get_where(self):
+ return """OPTIONAL { ?article{language} schema:about ?item ;
+ schema:inLanguage "{language}" ;
+ schema:isPartOf <https://{language}.wikipedia.org/> ;
+ schema:name ?articleName{language} . }""".replace('{language}', self.language)
+
+ def get_group_by(self):
+ return self.get_select()
+
+ def get_str(self, result, language):
+ key = 'article{language}'.replace('{language}', self.language)
+ return result.get(key)
+
+
+class WDLabelAttribute(WDAttribute):
+
+ def get_select(self):
+ return '(group_concat(distinct ?{name}Label;separator=", ") as ?{name}Labels)'.replace('{name}', self.name)
+
+ def get_where(self):
+ return "OPTIONAL { ?item wdt:{name} ?{name} . }".replace('{name}', self.name)
+
+ def get_wikibase_label(self):
+ return "?{name} rdfs:label ?{name}Label .".replace('{name}', self.name)
- url = url_map\
- .replace('{latitude}', str(lat))\
- .replace('{longitude}', str(lon))\
- .replace('{zoom}', str(zoom))
+ def get_str(self, result, language):
+ return result.get(self.name + 'Labels')
- return url
+class WDURLAttribute(WDAttribute):
-def get_wikilink(result, wikiid):
- url = eval_xpath(result, wikilink_xpath.replace('{wikiid}', wikiid))
- if not url:
+ HTTP_WIKIMEDIA_IMAGE = 'http://commons.wikimedia.org/wiki/Special:FilePath/'
+
+ __slots__ = 'url_id', 'kwargs'
+
+ def __init__(self, name, url_id=None, kwargs=None):
+ super().__init__(name)
+ self.url_id = url_id
+ self.kwargs = kwargs
+
+ def get_str(self, result, language):
+ value = result.get(self.name + 's')
+ if self.url_id and value is not None and value != '':
+ value = value.split(',')[0]
+ url_id = self.url_id
+ if value.startswith(WDURLAttribute.HTTP_WIKIMEDIA_IMAGE):
+ value = value[len(WDURLAttribute.HTTP_WIKIMEDIA_IMAGE):]
+ url_id = 'wikimedia_image'
+ return get_external_url(url_id, value)
+ return value
+
+
+class WDGeoAttribute(WDAttribute):
+
+ def get_label(self, language):
+ return "OpenStreetMap"
+
+ def get_select(self):
+ return "?{name}Lat ?{name}Long".replace('{name}', self.name)
+
+ def get_where(self):
+ return """OPTIONAL { ?item p:{name}/psv:{name} [
+ wikibase:geoLatitude ?{name}Lat ;
+ wikibase:geoLongitude ?{name}Long ] }""".replace('{name}', self.name)
+
+ def get_group_by(self):
+ return self.get_select()
+
+ def get_str(self, result, language):
+ latitude = result.get(self.name + 'Lat')
+ longitude = result.get(self.name + 'Long')
+ if latitude and longitude:
+ return latitude + ' ' + longitude
+ return None
+
+ def get_geo_url(self, result, osm_zoom=19):
+ latitude = result.get(self.name + 'Lat')
+ longitude = result.get(self.name + 'Long')
+ if latitude and longitude:
+ return get_earth_coordinates_url(latitude, longitude, osm_zoom)
return None
- url = url[0]
- if url.startswith('http://'):
- url = url.replace('http://', 'https://')
- elif url.startswith('//'):
- url = 'https:' + url
- return url
+
+
+class WDImageAttribute(WDURLAttribute):
+
+ __slots__ = 'priority',
+
+ def __init__(self, name, url_id=None, priority=100):
+ super().__init__(name, url_id)
+ self.priority = priority
+
+
+class WDDateAttribute(WDAttribute):
+
+ def get_select(self):
+ return '?{name} ?{name}timePrecision ?{name}timeZone ?{name}timeCalendar'.replace('{name}', self.name)
+
+ def get_where(self):
+ # To remove duplicate, add
+ # FILTER NOT EXISTS { ?item p:{name}/psv:{name}/wikibase:timeValue ?{name}bis FILTER (?{name}bis < ?{name}) }
+ # this filter is too slow, so the response function ignore duplicate results
+ # (see the seen_entities variable)
+ return """OPTIONAL { ?item p:{name}/psv:{name} [
+ wikibase:timeValue ?{name} ;
+ wikibase:timePrecision ?{name}timePrecision ;
+ wikibase:timeTimezone ?{name}timeZone ;
+ wikibase:timeCalendarModel ?{name}timeCalendar ] . }
+ hint:Prior hint:rangeSafe true;""".replace('{name}', self.name)
+
+ def get_group_by(self):
+ return self.get_select()
+
+ def format_8(self, value, locale):
+ # precision: less than a year
+ return value
+
+ def format_9(self, value, locale):
+ year = int(value)
+ # precision: year
+ if year < 1584:
+ if year < 0:
+ return str(year - 1)
+ return str(year)
+ timestamp = isoparse(value)
+ return format_date(timestamp, format='yyyy', locale=locale)
+
+ def format_10(self, value, locale):
+ # precision: month
+ timestamp = isoparse(value)
+ return format_date(timestamp, format='MMMM y', locale=locale)
+
+ def format_11(self, value, locale):
+ # precision: day
+ timestamp = isoparse(value)
+ return format_date(timestamp, format='full', locale=locale)
+
+ def format_13(self, value, locale):
+ timestamp = isoparse(value)
+ # precision: minute
+ return get_datetime_format(format, locale=locale) \
+ .replace("'", "") \
+ .replace('{0}', format_time(timestamp, 'full', tzinfo=None,
+ locale=locale)) \
+ .replace('{1}', format_date(timestamp, 'short', locale=locale))
+
+ def format_14(self, value, locale):
+ # precision: second.
+ return format_datetime(isoparse(value), format='full', locale=locale)
+
+ DATE_FORMAT = {
+ '0': ('format_8', 1000000000),
+ '1': ('format_8', 100000000),
+ '2': ('format_8', 10000000),
+ '3': ('format_8', 1000000),
+ '4': ('format_8', 100000),
+ '5': ('format_8', 10000),
+ '6': ('format_8', 1000),
+ '7': ('format_8', 100),
+ '8': ('format_8', 10),
+ '9': ('format_9', 1), # year
+ '10': ('format_10', 1), # month
+ '11': ('format_11', 0), # day
+ '12': ('format_13', 0), # hour (not supported by babel, display minute)
+ '13': ('format_13', 0), # minute
+ '14': ('format_14', 0) # second
+ }
+
+ def get_str(self, result, language):
+ value = result.get(self.name)
+ if value == '' or value is None:
+ return None
+ precision = result.get(self.name + 'timePrecision')
+ date_format = WDDateAttribute.DATE_FORMAT.get(precision)
+ if date_format is not None:
+ format_method = getattr(self, date_format[0])
+ precision = date_format[1]
+ try:
+ if precision >= 1:
+ t = value.split('-')
+ if value.startswith('-'):
+ value = '-' + t[1]
+ else:
+ value = t[0]
+ return format_method(value, language)
+ except Exception:
+ return value
+ return value
+
+
+def debug_explain_wikidata_query(query, method='GET'):
+ if method == 'GET':
+ http_response = get(SPARQL_EXPLAIN_URL + '&' + urlencode({'query': query}), headers=get_headers())
+ else:
+ http_response = post(SPARQL_EXPLAIN_URL, data={'query': query}, headers=get_headers())
+ http_response.raise_for_status()
+ return http_response.content
+
+
+def init(engine_settings=None):
+ # WIKIDATA_PROPERTIES : add unit symbols
+ WIKIDATA_PROPERTIES.update(WIKIDATA_UNITS)
+
+ # WIKIDATA_PROPERTIES : add property labels
+ wikidata_property_names = []
+ for attribute in get_attributes('en'):
+ if type(attribute) in (WDAttribute, WDAmountAttribute, WDURLAttribute, WDDateAttribute, WDLabelAttribute):
+ if attribute.name not in WIKIDATA_PROPERTIES:
+ wikidata_property_names.append("wd:" + attribute.name)
+ query = QUERY_PROPERTY_NAMES.replace('%ATTRIBUTES%', " ".join(wikidata_property_names))
+ jsonresponse = send_wikidata_query(query)
+ for result in jsonresponse.get('results', {}).get('bindings', {}):
+ name = result['name']['value']
+ lang = result['name']['xml:lang']
+ entity_id = result['item']['value'].replace('http://www.wikidata.org/entity/', '')
+ WIKIDATA_PROPERTIES[(entity_id, lang)] = name.capitalize()
diff --git a/searx/engines/wikipedia.py b/searx/engines/wikipedia.py
index a216ba8..54d7510 100644
--- a/searx/engines/wikipedia.py
+++ b/searx/engines/wikipedia.py
@@ -1,7 +1,7 @@
"""
Wikipedia (Web)
- @website https://{language}.wikipedia.org
+ @website https://en.wikipedia.org/api/rest_v1/
@provide-api yes
@using-api yes
@@ -10,23 +10,14 @@
@parse url, infobox
"""
+from urllib.parse import quote
from json import loads
from lxml.html import fromstring
-from searx.url_utils import quote, urlencode
-from searx.utils import match_language
+from searx.utils import match_language, searx_useragent
+from searx.raise_for_httperror import raise_for_httperror
# search-url
-base_url = u'https://{language}.wikipedia.org/'
-search_url = base_url + u'w/api.php?'\
- 'action=query'\
- '&format=json'\
- '&{query}'\
- '&prop=extracts|pageimages|pageprops'\
- '&ppprop=disambiguation'\
- '&exintro'\
- '&explaintext'\
- '&pithumbsize=300'\
- '&redirects'
+search_url = 'https://{language}.wikipedia.org/api/rest_v1/page/summary/{title}'
supported_languages_url = 'https://meta.wikimedia.org/wiki/List_of_Wikipedias'
@@ -41,77 +32,40 @@ def url_lang(lang):
# do search-request
def request(query, params):
if query.islower():
- query = u'{0}|{1}'.format(query.decode('utf-8'), query.decode('utf-8').title()).encode('utf-8')
+ query = query.title()
- params['url'] = search_url.format(query=urlencode({'titles': query}),
+ params['url'] = search_url.format(title=quote(query),
language=url_lang(params['language']))
- return params
-
-
-# get first meaningful paragraph
-# this should filter out disambiguation pages and notes above first paragraph
-# "magic numbers" were obtained by fine tuning
-def extract_first_paragraph(content, title, image):
- first_paragraph = None
-
- failed_attempts = 0
- for paragraph in content.split('\n'):
-
- starts_with_title = paragraph.lower().find(title.lower(), 0, len(title) + 35)
- length = len(paragraph)
+ params['headers']['User-Agent'] = searx_useragent()
+ params['raise_for_httperror'] = False
+ params['soft_max_redirects'] = 2
- if length >= 200 or (starts_with_title >= 0 and (image or length >= 150)):
- first_paragraph = paragraph
- break
-
- failed_attempts += 1
- if failed_attempts > 3:
- return None
-
- return first_paragraph
+ return params
# get response from search-request
def response(resp):
- results = []
-
- search_result = loads(resp.text)
-
- # wikipedia article's unique id
- # first valid id is assumed to be the requested article
- if 'pages' not in search_result['query']:
- return results
-
- for article_id in search_result['query']['pages']:
- page = search_result['query']['pages'][article_id]
- if int(article_id) > 0:
- break
-
- if int(article_id) < 0 or 'disambiguation' in page.get('pageprops', {}):
+ if resp.status_code == 404:
return []
+ raise_for_httperror(resp)
- title = page.get('title')
-
- image = page.get('thumbnail')
- if image:
- image = image.get('source')
-
- extract = page.get('extract')
+ results = []
+ api_result = loads(resp.text)
- summary = extract_first_paragraph(extract, title, image)
- summary = summary.replace('() ', '')
+ # skip disambiguation pages
+ if api_result.get('type') != 'standard':
+ return []
- # link to wikipedia article
- wikipedia_link = base_url.format(language=url_lang(resp.search_params['language'])) \
- + 'wiki/' + quote(title.replace(' ', '_').encode('utf8'))
+ title = api_result['title']
+ wikipedia_link = api_result['content_urls']['desktop']['page']
results.append({'url': wikipedia_link, 'title': title})
results.append({'infobox': title,
'id': wikipedia_link,
- 'content': summary,
- 'img_src': image,
+ 'content': api_result.get('extract', ''),
+ 'img_src': api_result.get('thumbnail', {}).get('source'),
'urls': [{'title': 'Wikipedia', 'url': wikipedia_link}]})
return results
diff --git a/searx/engines/wolframalpha_api.py b/searx/engines/wolframalpha_api.py
index 1c58c4a..520eaa2 100644
--- a/searx/engines/wolframalpha_api.py
+++ b/searx/engines/wolframalpha_api.py
@@ -9,7 +9,7 @@
# @parse url, infobox
from lxml import etree
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
# search-url
search_url = 'https://api.wolframalpha.com/v2/query?appid={api_key}&{query}'
@@ -45,15 +45,15 @@ def request(query, params):
# replace private user area characters to make text legible
def replace_pua_chars(text):
- pua_chars = {u'\uf522': u'\u2192', # rigth arrow
- u'\uf7b1': u'\u2115', # set of natural numbers
- u'\uf7b4': u'\u211a', # set of rational numbers
- u'\uf7b5': u'\u211d', # set of real numbers
- u'\uf7bd': u'\u2124', # set of integer numbers
- u'\uf74c': 'd', # differential
- u'\uf74d': u'\u212f', # euler's number
- u'\uf74e': 'i', # imaginary number
- u'\uf7d9': '='} # equals sign
+ pua_chars = {'\uf522': '\u2192', # rigth arrow
+ '\uf7b1': '\u2115', # set of natural numbers
+ '\uf7b4': '\u211a', # set of rational numbers
+ '\uf7b5': '\u211d', # set of real numbers
+ '\uf7bd': '\u2124', # set of integer numbers
+ '\uf74c': 'd', # differential
+ '\uf74d': '\u212f', # euler's number
+ '\uf74e': 'i', # imaginary number
+ '\uf7d9': '='} # equals sign
for k, v in pua_chars.items():
text = text.replace(k, v)
diff --git a/searx/engines/wolframalpha_noapi.py b/searx/engines/wolframalpha_noapi.py
index 387c9fa..943d4f3 100644
--- a/searx/engines/wolframalpha_noapi.py
+++ b/searx/engines/wolframalpha_noapi.py
@@ -10,9 +10,9 @@
from json import loads
from time import time
+from urllib.parse import urlencode
from searx.poolrequests import get as http_get
-from searx.url_utils import urlencode
# search-url
url = 'https://www.wolframalpha.com/'
diff --git a/searx/engines/www1x.py b/searx/engines/www1x.py
index f1154b1..b8f111a 100644
--- a/searx/engines/www1x.py
+++ b/searx/engines/www1x.py
@@ -7,12 +7,12 @@
@using-api no
@results HTML
@stable no (HTML can change)
- @parse url, title, thumbnail, img_src, content
+ @parse url, title, thumbnail
"""
-from lxml import html
-from searx.url_utils import urlencode, urljoin
-from searx.engines.xpath import extract_text
+from lxml import html, etree
+from urllib.parse import urlencode, urljoin
+from searx.utils import extract_text, eval_xpath_list, eval_xpath_getindex
# engine dependent config
categories = ['images']
@@ -21,6 +21,7 @@ paging = False
# search-url
base_url = 'https://1x.com'
search_url = base_url + '/backend/search.php?{query}'
+gallery_url = 'https://gallery.1x.com/'
# do search-request
@@ -33,23 +34,18 @@ def request(query, params):
# get response from search-request
def response(resp):
results = []
-
- dom = html.fromstring(resp.text)
- for res in dom.xpath('//div[@class="List-item MainListing"]'):
- # processed start and end of link
- link = res.xpath('//a')[0]
-
+ xmldom = etree.fromstring(resp.content)
+ xmlsearchresult = eval_xpath_getindex(xmldom, '//searchresult', 0)
+ dom = html.fragment_fromstring(xmlsearchresult.text, create_parent='div')
+ for link in eval_xpath_list(dom, '/div/table/tr/td/div[2]//a'):
url = urljoin(base_url, link.attrib.get('href'))
title = extract_text(link)
-
- thumbnail_src = urljoin(base_url, res.xpath('.//img')[0].attrib['src'])
- # TODO: get image with higher resolution
- img_src = thumbnail_src
+ thumbnail_src = urljoin(gallery_url, eval_xpath_getindex(link, './/img', 0).attrib['src'])
# append result
results.append({'url': url,
'title': title,
- 'img_src': img_src,
+ 'img_src': thumbnail_src,
'content': '',
'thumbnail_src': thumbnail_src,
'template': 'images.html'})
diff --git a/searx/engines/xpath.py b/searx/engines/xpath.py
index b75896c..1507176 100644
--- a/searx/engines/xpath.py
+++ b/searx/engines/xpath.py
@@ -1,7 +1,6 @@
from lxml import html
-from lxml.etree import _ElementStringResult, _ElementUnicodeResult
-from searx.utils import html_to_text, eval_xpath
-from searx.url_utils import unquote, urlencode, urljoin, urlparse
+from urllib.parse import urlencode
+from searx.utils import extract_text, extract_url, eval_xpath, eval_xpath_list
search_url = None
url_xpath = None
@@ -11,6 +10,8 @@ thumbnail_xpath = False
paging = False
suggestion_xpath = ''
results_xpath = ''
+cached_xpath = ''
+cached_url = ''
# parameters for engines with paging support
#
@@ -21,72 +22,6 @@ page_size = 1
first_page_num = 1
-'''
-if xpath_results is list, extract the text from each result and concat the list
-if xpath_results is a xml element, extract all the text node from it
- ( text_content() method from lxml )
-if xpath_results is a string element, then it's already done
-'''
-
-
-def extract_text(xpath_results):
- if type(xpath_results) == list:
- # it's list of result : concat everything using recursive call
- result = ''
- for e in xpath_results:
- result = result + extract_text(e)
- return result.strip()
- elif type(xpath_results) in [_ElementStringResult, _ElementUnicodeResult]:
- # it's a string
- return ''.join(xpath_results)
- else:
- # it's a element
- text = html.tostring(
- xpath_results, encoding='unicode', method='text', with_tail=False
- )
- text = text.strip().replace('\n', ' ')
- return ' '.join(text.split())
-
-
-def extract_url(xpath_results, search_url):
- if xpath_results == []:
- raise Exception('Empty url resultset')
- url = extract_text(xpath_results)
-
- if url.startswith('//'):
- # add http or https to this kind of url //example.com/
- parsed_search_url = urlparse(search_url)
- url = u'{0}:{1}'.format(parsed_search_url.scheme or 'http', url)
- elif url.startswith('/'):
- # fix relative url to the search engine
- url = urljoin(search_url, url)
-
- # normalize url
- url = normalize_url(url)
-
- return url
-
-
-def normalize_url(url):
- parsed_url = urlparse(url)
-
- # add a / at this end of the url if there is no path
- if not parsed_url.netloc:
- raise Exception('Cannot parse url')
- if not parsed_url.path:
- url += '/'
-
- # FIXME : hack for yahoo
- if parsed_url.hostname == 'search.yahoo.com'\
- and parsed_url.path.startswith('/r'):
- p = parsed_url.path
- mark = p.find('/**')
- if mark != -1:
- return unquote(p[mark + 3:]).decode('utf-8')
-
- return url
-
-
def request(query, params):
query = urlencode({'q': query})[2:]
@@ -103,28 +38,49 @@ def request(query, params):
def response(resp):
results = []
dom = html.fromstring(resp.text)
+ is_onion = True if 'onions' in categories else False # pylint: disable=undefined-variable
+
if results_xpath:
- for result in eval_xpath(dom, results_xpath):
- url = extract_url(eval_xpath(result, url_xpath), search_url)
- title = extract_text(eval_xpath(result, title_xpath))
- content = extract_text(eval_xpath(result, content_xpath))
+ for result in eval_xpath_list(dom, results_xpath):
+ url = extract_url(eval_xpath_list(result, url_xpath, min_len=1), search_url)
+ title = extract_text(eval_xpath_list(result, title_xpath, min_len=1))
+ content = extract_text(eval_xpath_list(result, content_xpath, min_len=1))
tmp_result = {'url': url, 'title': title, 'content': content}
# add thumbnail if available
if thumbnail_xpath:
- thumbnail_xpath_result = eval_xpath(result, thumbnail_xpath)
+ thumbnail_xpath_result = eval_xpath_list(result, thumbnail_xpath)
if len(thumbnail_xpath_result) > 0:
tmp_result['img_src'] = extract_url(thumbnail_xpath_result, search_url)
+ # add alternative cached url if available
+ if cached_xpath:
+ tmp_result['cached_url'] = cached_url\
+ + extract_text(eval_xpath_list(result, cached_xpath, min_len=1))
+
+ if is_onion:
+ tmp_result['is_onion'] = True
+
results.append(tmp_result)
else:
- for url, title, content in zip(
- (extract_url(x, search_url) for
- x in eval_xpath(dom, url_xpath)),
- map(extract_text, eval_xpath(dom, title_xpath)),
- map(extract_text, eval_xpath(dom, content_xpath))
- ):
- results.append({'url': url, 'title': title, 'content': content})
+ if cached_xpath:
+ for url, title, content, cached in zip(
+ (extract_url(x, search_url) for
+ x in eval_xpath_list(dom, url_xpath)),
+ map(extract_text, eval_xpath_list(dom, title_xpath)),
+ map(extract_text, eval_xpath_list(dom, content_xpath)),
+ map(extract_text, eval_xpath_list(dom, cached_xpath))
+ ):
+ results.append({'url': url, 'title': title, 'content': content,
+ 'cached_url': cached_url + cached, 'is_onion': is_onion})
+ else:
+ for url, title, content in zip(
+ (extract_url(x, search_url) for
+ x in eval_xpath_list(dom, url_xpath)),
+ map(extract_text, eval_xpath_list(dom, title_xpath)),
+ map(extract_text, eval_xpath_list(dom, content_xpath))
+ ):
+ results.append({'url': url, 'title': title, 'content': content, 'is_onion': is_onion})
if not suggestion_xpath:
return results
diff --git a/searx/engines/yacy.py b/searx/engines/yacy.py
index f1d4c6a..6f7ab75 100644
--- a/searx/engines/yacy.py
+++ b/searx/engines/yacy.py
@@ -14,7 +14,9 @@
from json import loads
from dateutil import parser
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
+
+from requests.auth import HTTPDigestAuth
from searx.utils import html_to_text
@@ -23,6 +25,8 @@ categories = ['general', 'images'] # TODO , 'music', 'videos', 'files'
paging = True
language_support = True
number_of_results = 5
+http_digest_auth_user = ""
+http_digest_auth_pass = ""
# search-url
base_url = 'http://localhost:8090'
@@ -51,6 +55,9 @@ def request(query, params):
limit=number_of_results,
search_type=search_type)
+ if http_digest_auth_user and http_digest_auth_pass:
+ params['auth'] = HTTPDigestAuth(http_digest_auth_user, http_digest_auth_pass)
+
# add language tag if specified
if params['language'] != 'all':
params['url'] += '&lr=lang_' + params['language'].split('-')[0]
@@ -75,7 +82,7 @@ def response(resp):
for result in search_results[0].get('items', []):
# parse image results
- if result.get('image') and result.get('width') and result.get('height'):
+ if resp.search_params.get('category') == 'images':
result_url = ''
if 'url' in result:
@@ -104,5 +111,4 @@ def response(resp):
# TODO parse video, audio and file results
- # return results
return results
diff --git a/searx/engines/yahoo.py b/searx/engines/yahoo.py
index a6b4aeb..3420aa6 100644
--- a/searx/engines/yahoo.py
+++ b/searx/engines/yahoo.py
@@ -11,10 +11,9 @@
@parse url, title, content, suggestion
"""
+from urllib.parse import unquote, urlencode
from lxml import html
-from searx.engines.xpath import extract_text, extract_url
-from searx.url_utils import unquote, urlencode
-from searx.utils import match_language, eval_xpath
+from searx.utils import extract_text, extract_url, match_language, eval_xpath
# engine dependent config
categories = ['general']
diff --git a/searx/engines/yahoo_news.py b/searx/engines/yahoo_news.py
index 9f6a415..793d110 100644
--- a/searx/engines/yahoo_news.py
+++ b/searx/engines/yahoo_news.py
@@ -11,14 +11,12 @@
import re
from datetime import datetime, timedelta
+from urllib.parse import urlencode
from lxml import html
-from searx.engines.xpath import extract_text, extract_url
-from searx.engines.yahoo import (
- parse_url, _fetch_supported_languages, supported_languages_url, language_aliases
-)
+from searx.engines.yahoo import parse_url, language_aliases
+from searx.engines.yahoo import _fetch_supported_languages, supported_languages_url # NOQA # pylint: disable=unused-import
from dateutil import parser
-from searx.url_utils import urlencode
-from searx.utils import match_language
+from searx.utils import extract_text, extract_url, match_language
# engine dependent config
categories = ['news']
@@ -58,7 +56,7 @@ def request(query, params):
def sanitize_url(url):
if ".yahoo.com/" in url:
- return re.sub(u"\\;\\_ylt\\=.+$", "", url)
+ return re.sub("\\;\\_ylt\\=.+$", "", url)
else:
return url
diff --git a/searx/engines/yandex.py b/searx/engines/yandex.py
index 1c789f6..b4a6a54 100644
--- a/searx/engines/yandex.py
+++ b/searx/engines/yandex.py
@@ -9,9 +9,10 @@
@parse url, title, content
"""
+from urllib.parse import urlencode, urlparse
from lxml import html
from searx import logger
-from searx.url_utils import urlencode
+from searx.exceptions import SearxEngineCaptchaException
logger = logger.getChild('yandex engine')
@@ -47,6 +48,10 @@ def request(query, params):
# get response from search-request
def response(resp):
+ resp_url = urlparse(resp.url)
+ if resp_url.path.startswith('/showcaptcha'):
+ raise SearxEngineCaptchaException()
+
dom = html.fromstring(resp.text)
results = []
diff --git a/searx/engines/yggtorrent.py b/searx/engines/yggtorrent.py
new file mode 100644
index 0000000..ec84d2c
--- /dev/null
+++ b/searx/engines/yggtorrent.py
@@ -0,0 +1,123 @@
+# Yggtorrent (Videos, Music, Files)
+#
+# @website https://www2.yggtorrent.si
+# @provide-api no (nothing found)
+#
+# @using-api no
+# @results HTML (using search portal)
+# @stable no (HTML can change)
+# @parse url, title, seed, leech, publishedDate, filesize
+
+from lxml import html
+from operator import itemgetter
+from datetime import datetime
+from urllib.parse import quote
+from searx.utils import extract_text, get_torrent_size
+from searx.poolrequests import get as http_get
+
+# engine dependent config
+categories = ['videos', 'music', 'files']
+paging = True
+
+# search-url
+url = 'https://www2.yggtorrent.si/'
+search_url = url + 'engine/search?name={search_term}&do=search&page={pageno}&category={search_type}'
+
+# yggtorrent specific type-definitions
+search_types = {'files': 'all',
+ 'music': '2139',
+ 'videos': '2145'}
+
+cookies = dict()
+
+
+def init(engine_settings=None):
+ global cookies
+ # initial cookies
+ resp = http_get(url, allow_redirects=False)
+ if resp.ok:
+ for r in resp.history:
+ cookies.update(r.cookies)
+ cookies.update(resp.cookies)
+
+
+# do search-request
+def request(query, params):
+ search_type = search_types.get(params['category'], 'all')
+ pageno = (params['pageno'] - 1) * 50
+
+ params['url'] = search_url.format(search_term=quote(query),
+ search_type=search_type,
+ pageno=pageno)
+
+ params['cookies'] = cookies
+
+ return params
+
+
+# get response from search-request
+def response(resp):
+ results = []
+ dom = html.fromstring(resp.text)
+
+ search_res = dom.xpath('//section[@id="#torrents"]/div/table/tbody/tr')
+
+ # return empty array if nothing is found
+ if not search_res:
+ return []
+
+ # parse results
+ for result in search_res:
+ link = result.xpath('.//a[@id="torrent_name"]')[0]
+ href = link.attrib.get('href')
+ title = extract_text(link)
+ seed = result.xpath('.//td[8]/text()')[0]
+ leech = result.xpath('.//td[9]/text()')[0]
+
+ # convert seed to int if possible
+ if seed.isdigit():
+ seed = int(seed)
+ else:
+ seed = 0
+
+ # convert leech to int if possible
+ if leech.isdigit():
+ leech = int(leech)
+ else:
+ leech = 0
+
+ params = {'url': href,
+ 'title': title,
+ 'seed': seed,
+ 'leech': leech,
+ 'template': 'torrent.html'}
+
+ # let's try to calculate the torrent size
+ try:
+ filesize_info = result.xpath('.//td[6]/text()')[0]
+ filesize = filesize_info[:-2]
+ filesize_multiplier = filesize_info[-2:].lower()
+ multiplier_french_to_english = {
+ 'to': 'TiB',
+ 'go': 'GiB',
+ 'mo': 'MiB',
+ 'ko': 'KiB'
+ }
+ filesize = get_torrent_size(filesize, multiplier_french_to_english[filesize_multiplier])
+ params['filesize'] = filesize
+ except:
+ pass
+
+ # extract and convert creation date
+ try:
+ date_ts = result.xpath('.//td[5]/div/text()')[0]
+ date = datetime.fromtimestamp(float(date_ts))
+ params['publishedDate'] = date
+ except:
+ pass
+
+ # append result
+ results.append(params)
+
+ # return results sorted by seeder
+ return sorted(results, key=itemgetter('seed'), reverse=True)
diff --git a/searx/engines/youtube_api.py b/searx/engines/youtube_api.py
index bc4c0d5..8c12ac4 100644
--- a/searx/engines/youtube_api.py
+++ b/searx/engines/youtube_api.py
@@ -10,7 +10,8 @@
from json import loads
from dateutil import parser
-from searx.url_utils import urlencode
+from urllib.parse import urlencode
+from searx.exceptions import SearxEngineAPIException
# engine dependent config
categories = ['videos', 'music']
@@ -47,6 +48,9 @@ def response(resp):
search_results = loads(resp.text)
+ if 'error' in search_results and 'message' in search_results['error']:
+ raise SearxEngineAPIException(search_results['error']['message'])
+
# return empty array if there are no results
if 'items' not in search_results:
return []
diff --git a/searx/engines/youtube_noapi.py b/searx/engines/youtube_noapi.py
index 68a3739..36fc72e 100644
--- a/searx/engines/youtube_noapi.py
+++ b/searx/engines/youtube_noapi.py
@@ -10,9 +10,7 @@
from functools import reduce
from json import loads
-from searx.engines.xpath import extract_text
-from searx.utils import list_get
-from searx.url_utils import quote_plus
+from urllib.parse import quote_plus
# engine dependent config
categories = ['videos', 'music']
@@ -51,7 +49,7 @@ def response(resp):
results = []
results_data = resp.text[resp.text.find('ytInitialData'):]
- results_data = results_data[results_data.find('{'):results_data.find(';\n')]
+ results_data = results_data[results_data.find('{'):results_data.find(';</script>')]
results_json = loads(results_data) if results_data else {}
sections = results_json.get('contents', {})\
diff --git a/searx/exceptions.py b/searx/exceptions.py
index 0175acf..67a282d 100644
--- a/searx/exceptions.py
+++ b/searx/exceptions.py
@@ -27,7 +27,77 @@ class SearxParameterException(SearxException):
message = 'Empty ' + name + ' parameter'
else:
message = 'Invalid value "' + value + '" for parameter ' + name
- super(SearxParameterException, self).__init__(message)
+ super().__init__(message)
self.message = message
self.parameter_name = name
self.parameter_value = value
+
+
+class SearxSettingsException(SearxException):
+ """Error while loading the settings"""
+
+ def __init__(self, message, filename):
+ super().__init__(message)
+ self.message = message
+ self.filename = filename
+
+
+class SearxEngineException(SearxException):
+ """Error inside an engine"""
+
+
+class SearxXPathSyntaxException(SearxEngineException):
+ """Syntax error in a XPATH"""
+
+ def __init__(self, xpath_spec, message):
+ super().__init__(str(xpath_spec) + " " + message)
+ self.message = message
+ # str(xpath_spec) to deal with str and XPath instance
+ self.xpath_str = str(xpath_spec)
+
+
+class SearxEngineResponseException(SearxEngineException):
+ """Impossible to parse the result of an engine"""
+
+
+class SearxEngineAPIException(SearxEngineResponseException):
+ """The website has returned an application error"""
+
+
+class SearxEngineAccessDeniedException(SearxEngineResponseException):
+ """The website is blocking the access"""
+
+ def __init__(self, suspended_time=24 * 3600, message='Access denied'):
+ super().__init__(message + ', suspended_time=' + str(suspended_time))
+ self.suspended_time = suspended_time
+ self.message = message
+
+
+class SearxEngineCaptchaException(SearxEngineAccessDeniedException):
+ """The website has returned a CAPTCHA
+
+ By default, searx stops sending requests to this engine for 1 day.
+ """
+
+ def __init__(self, suspended_time=24 * 3600, message='CAPTCHA'):
+ super().__init__(message=message, suspended_time=suspended_time)
+
+
+class SearxEngineTooManyRequestsException(SearxEngineAccessDeniedException):
+ """The website has returned a Too Many Request status code
+
+ By default, searx stops sending requests to this engine for 1 hour.
+ """
+
+ def __init__(self, suspended_time=3600, message='Too many request'):
+ super().__init__(message=message, suspended_time=suspended_time)
+
+
+class SearxEngineXPathException(SearxEngineResponseException):
+ """Error while getting the result of an XPath expression"""
+
+ def __init__(self, xpath_spec, message):
+ super().__init__(str(xpath_spec) + " " + message)
+ self.message = message
+ # str(xpath_spec) to deal with str and XPath instance
+ self.xpath_str = str(xpath_spec)
diff --git a/searx/external_bang.py b/searx/external_bang.py
index f8b9c44..104f859 100644
--- a/searx/external_bang.py
+++ b/searx/external_bang.py
@@ -1,7 +1,4 @@
-import json
-from os.path import join
-
-from searx import searx_dir
+from searx.data import bangs_loader
# bangs data coming from the following url convert to json with
# https://raw.githubusercontent.com/jivesearch/jivesearch/master/bangs/bangs.toml
@@ -9,10 +6,9 @@ from searx import searx_dir
# NOTE only use the get_bang_url
bangs_data = {}
-with open(join(searx_dir, 'data/bangs.json')) as json_file:
- for bang in json.load(json_file)['bang']:
- for trigger in bang["triggers"]:
- bangs_data[trigger] = {x: y for x, y in bang.items() if x != "triggers"}
+for bang in bangs_loader()['bang']:
+ for trigger in bang["triggers"]:
+ bangs_data[trigger] = {x: y for x, y in bang.items() if x != "triggers"}
def get_bang_url(search_query):
@@ -23,7 +19,7 @@ def get_bang_url(search_query):
"""
if search_query.external_bang:
- query = search_query.query.decode('utf-8', 'ignore')
+ query = search_query.query
bang = _get_bang(search_query.external_bang)
if bang and query:
diff --git a/searx/external_urls.py b/searx/external_urls.py
new file mode 100644
index 0000000..da58b8f
--- /dev/null
+++ b/searx/external_urls.py
@@ -0,0 +1,77 @@
+import math
+
+from searx.data import EXTERNAL_URLS
+
+
+IMDB_PREFIX_TO_URL_ID = {
+ 'tt': 'imdb_title',
+ 'mn': 'imdb_name',
+ 'ch': 'imdb_character',
+ 'co': 'imdb_company',
+ 'ev': 'imdb_event'
+}
+
+
+def get_imdb_url_id(imdb_item_id):
+ id_prefix = imdb_item_id[:2]
+ return IMDB_PREFIX_TO_URL_ID.get(id_prefix)
+
+
+def get_external_url(url_id, item_id, alternative="default"):
+ """Return an external URL or None if url_id is not found.
+
+ url_id can take value from data/external_urls.json
+ The "imdb_id" value is automaticaly converted according to the item_id value.
+
+ If item_id is None, the raw URL with the $1 is returned.
+ """
+ if url_id == 'imdb_id' and item_id is not None:
+ url_id = get_imdb_url_id(item_id)
+
+ url_description = EXTERNAL_URLS.get(url_id)
+ if url_description:
+ url_template = url_description["urls"].get(alternative)
+ if url_template is not None:
+ if item_id is not None:
+ return url_template.replace('$1', item_id)
+ else:
+ return url_template
+ return None
+
+
+def get_earth_coordinates_url(latitude, longitude, osm_zoom, alternative='default'):
+ url = get_external_url('map', None, alternative)\
+ .replace('${latitude}', str(latitude))\
+ .replace('${longitude}', str(longitude))\
+ .replace('${zoom}', str(osm_zoom))
+ return url
+
+
+def area_to_osm_zoom(area):
+ """Convert an area in km² into an OSM zoom. Less reliable if the shape is not round.
+
+ logarithm regression using these data:
+ * 9596961 -> 4 (China)
+ * 3287263 -> 5 (India)
+ * 643801 -> 6 (France)
+ * 6028 -> 9
+ * 1214 -> 10
+ * 891 -> 12
+ * 12 -> 13
+
+ In WolframAlpha:
+ >>> log fit {9596961,15},{3287263, 14},{643801,13},{6028,10},{1214,9},{891,7},{12,6}
+
+ with 15 = 19-4 (China); 14 = 19-5 (India) and so on
+
+ Args:
+ area (int,float,str): area in km²
+
+ Returns:
+ int: OSM zoom or 19 in area is not a number
+ """
+ try:
+ amount = float(area)
+ return max(0, min(19, round(19 - 0.688297 * math.log(226.878 * amount))))
+ except ValueError:
+ return 19
diff --git a/searx/languages.py b/searx/languages.py
index 72e1a73..20f72cf 100644
--- a/searx/languages.py
+++ b/searx/languages.py
@@ -1,75 +1,73 @@
# -*- coding: utf-8 -*-
# list of language codes
-# this file is generated automatically by utils/update_search_languages.py
-
-language_codes = (
- (u"af-NA", u"Afrikaans", u"", u"Afrikaans"),
- (u"ar-SA", u"العربية", u"", u"Arabic"),
- (u"be-BY", u"Беларуская", u"", u"Belarusian"),
- (u"bg-BG", u"Български", u"", u"Bulgarian"),
- (u"ca-AD", u"Català", u"", u"Catalan"),
- (u"cs-CZ", u"Čeština", u"", u"Czech"),
- (u"da-DK", u"Dansk", u"", u"Danish"),
- (u"de", u"Deutsch", u"", u"German"),
- (u"de-AT", u"Deutsch", u"Österreich", u"German"),
- (u"de-CH", u"Deutsch", u"Schweiz", u"German"),
- (u"de-DE", u"Deutsch", u"Deutschland", u"German"),
- (u"el-GR", u"Ελληνικά", u"", u"Greek"),
- (u"en", u"English", u"", u"English"),
- (u"en-AU", u"English", u"Australia", u"English"),
- (u"en-CA", u"English", u"Canada", u"English"),
- (u"en-GB", u"English", u"United Kingdom", u"English"),
- (u"en-IE", u"English", u"Ireland", u"English"),
- (u"en-IN", u"English", u"India", u"English"),
- (u"en-NZ", u"English", u"New Zealand", u"English"),
- (u"en-PH", u"English", u"Philippines", u"English"),
- (u"en-SG", u"English", u"Singapore", u"English"),
- (u"en-US", u"English", u"United States", u"English"),
- (u"es", u"Español", u"", u"Spanish"),
- (u"es-AR", u"Español", u"Argentina", u"Spanish"),
- (u"es-CL", u"Español", u"Chile", u"Spanish"),
- (u"es-ES", u"Español", u"España", u"Spanish"),
- (u"es-MX", u"Español", u"México", u"Spanish"),
- (u"et-EE", u"Eesti", u"", u"Estonian"),
- (u"fa-IR", u"فارسی", u"", u"Persian"),
- (u"fi-FI", u"Suomi", u"", u"Finnish"),
- (u"fr", u"Français", u"", u"French"),
- (u"fr-BE", u"Français", u"Belgique", u"French"),
- (u"fr-CA", u"Français", u"Canada", u"French"),
- (u"fr-CH", u"Français", u"Suisse", u"French"),
- (u"fr-FR", u"Français", u"France", u"French"),
- (u"he-IL", u"עברית", u"", u"Hebrew"),
- (u"hr-HR", u"Hrvatski", u"", u"Croatian"),
- (u"hu-HU", u"Magyar", u"", u"Hungarian"),
- (u"hy-AM", u"Հայերեն", u"", u"Armenian"),
- (u"id-ID", u"Indonesia", u"", u"Indonesian"),
- (u"is-IS", u"Íslenska", u"", u"Icelandic"),
- (u"it-IT", u"Italiano", u"", u"Italian"),
- (u"ja-JP", u"日本語", u"", u"Japanese"),
- (u"ko-KR", u"한국어", u"", u"Korean"),
- (u"lt-LT", u"Lietuvių", u"", u"Lithuanian"),
- (u"lv-LV", u"Latviešu", u"", u"Latvian"),
- (u"ms-MY", u"Melayu", u"", u"Malay"),
- (u"nb-NO", u"Norsk Bokmål", u"", u"Norwegian Bokmål"),
- (u"nl", u"Nederlands", u"", u"Dutch"),
- (u"nl-BE", u"Nederlands", u"België", u"Dutch"),
- (u"nl-NL", u"Nederlands", u"Nederland", u"Dutch"),
- (u"pl-PL", u"Polski", u"", u"Polish"),
- (u"pt", u"Português", u"", u"Portuguese"),
- (u"pt-BR", u"Português", u"Brasil", u"Portuguese"),
- (u"pt-PT", u"Português", u"Portugal", u"Portuguese"),
- (u"ro-RO", u"Română", u"", u"Romanian"),
- (u"ru-RU", u"Русский", u"", u"Russian"),
- (u"sk-SK", u"Slovenčina", u"", u"Slovak"),
- (u"sl-SI", u"Slovenščina", u"", u"Slovenian"),
- (u"sr-RS", u"Srpski", u"", u"Serbian"),
- (u"sv-SE", u"Svenska", u"", u"Swedish"),
- (u"sw-KE", u"Kiswahili", u"", u"Swahili"),
- (u"th-TH", u"ไทย", u"", u"Thai"),
- (u"tr-TR", u"Türkçe", u"", u"Turkish"),
- (u"uk-UA", u"Українська", u"", u"Ukrainian"),
- (u"vi-VN", u"Tiếng Việt", u"", u"Vietnamese"),
- (u"zh", u"中文", u"", u"Chinese"),
- (u"zh-CN", u"中文", u"中国", u"Chinese"),
- (u"zh-TW", u"中文", u"台灣", u"Chinese")
-)
+# this file is generated automatically by utils/fetch_languages.py
+language_codes = \
+( ('af-ZA', 'Afrikaans', '', 'Afrikaans'),
+ ('ar-EG', 'العربية', '', 'Arabic'),
+ ('be-BY', 'Беларуская', '', 'Belarusian'),
+ ('bg-BG', 'Български', '', 'Bulgarian'),
+ ('ca-ES', 'Català', '', 'Catalan'),
+ ('cs-CZ', 'Čeština', '', 'Czech'),
+ ('da-DK', 'Dansk', '', 'Danish'),
+ ('de', 'Deutsch', '', 'German'),
+ ('de-AT', 'Deutsch', 'Österreich', 'German'),
+ ('de-CH', 'Deutsch', 'Schweiz', 'German'),
+ ('de-DE', 'Deutsch', 'Deutschland', 'German'),
+ ('el-GR', 'Ελληνικά', '', 'Greek'),
+ ('en', 'English', '', 'English'),
+ ('en-AU', 'English', 'Australia', 'English'),
+ ('en-CA', 'English', 'Canada', 'English'),
+ ('en-GB', 'English', 'United Kingdom', 'English'),
+ ('en-IE', 'English', 'Ireland', 'English'),
+ ('en-IN', 'English', 'India', 'English'),
+ ('en-NZ', 'English', 'New Zealand', 'English'),
+ ('en-PH', 'English', 'Philippines', 'English'),
+ ('en-SG', 'English', 'Singapore', 'English'),
+ ('en-US', 'English', 'United States', 'English'),
+ ('es', 'Español', '', 'Spanish'),
+ ('es-AR', 'Español', 'Argentina', 'Spanish'),
+ ('es-CL', 'Español', 'Chile', 'Spanish'),
+ ('es-ES', 'Español', 'España', 'Spanish'),
+ ('es-MX', 'Español', 'México', 'Spanish'),
+ ('et-EE', 'Eesti', '', 'Estonian'),
+ ('fa-IR', 'فارسی', '', 'Persian'),
+ ('fi-FI', 'Suomi', '', 'Finnish'),
+ ('fr', 'Français', '', 'French'),
+ ('fr-BE', 'Français', 'Belgique', 'French'),
+ ('fr-CA', 'Français', 'Canada', 'French'),
+ ('fr-CH', 'Français', 'Suisse', 'French'),
+ ('fr-FR', 'Français', 'France', 'French'),
+ ('he-IL', 'עברית', '', 'Hebrew'),
+ ('hr-HR', 'Hrvatski', '', 'Croatian'),
+ ('hu-HU', 'Magyar', '', 'Hungarian'),
+ ('hy-AM', 'Հայերեն', '', 'Armenian'),
+ ('id-ID', 'Indonesia', '', 'Indonesian'),
+ ('is-IS', 'Íslenska', '', 'Icelandic'),
+ ('it-IT', 'Italiano', '', 'Italian'),
+ ('ja-JP', '日本語', '', 'Japanese'),
+ ('ko-KR', '한국어', '', 'Korean'),
+ ('lt-LT', 'Lietuvių', '', 'Lithuanian'),
+ ('lv-LV', 'Latviešu', '', 'Latvian'),
+ ('ms-MY', 'Melayu', '', 'Malay'),
+ ('nb-NO', 'Norsk Bokmål', '', 'Norwegian Bokmål'),
+ ('nl', 'Nederlands', '', 'Dutch'),
+ ('nl-BE', 'Nederlands', 'België', 'Dutch'),
+ ('nl-NL', 'Nederlands', 'Nederland', 'Dutch'),
+ ('pl-PL', 'Polski', '', 'Polish'),
+ ('pt', 'Português', '', 'Portuguese'),
+ ('pt-BR', 'Português', 'Brasil', 'Portuguese'),
+ ('pt-PT', 'Português', 'Portugal', 'Portuguese'),
+ ('ro-RO', 'Română', '', 'Romanian'),
+ ('ru-RU', 'Русский', '', 'Russian'),
+ ('sk-SK', 'Slovenčina', '', 'Slovak'),
+ ('sl-SI', 'Slovenščina', '', 'Slovenian'),
+ ('sr-RS', 'Srpski', '', 'Serbian'),
+ ('sv-SE', 'Svenska', '', 'Swedish'),
+ ('sw-TZ', 'Kiswahili', '', 'Swahili'),
+ ('th-TH', 'ไทย', '', 'Thai'),
+ ('tr-TR', 'Türkçe', '', 'Turkish'),
+ ('uk-UA', 'Українська', '', 'Ukrainian'),
+ ('vi-VN', 'Tiếng Việt', '', 'Vietnamese'),
+ ('zh', '中文', '', 'Chinese'),
+ ('zh-CN', '中文', '中国', 'Chinese'),
+ ('zh-TW', '中文', '台灣', 'Chinese')) \ No newline at end of file
diff --git a/searx/metrology/__init__.py b/searx/metrology/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/searx/metrology/__init__.py
diff --git a/searx/metrology/error_recorder.py b/searx/metrology/error_recorder.py
new file mode 100644
index 0000000..fee1ef7
--- /dev/null
+++ b/searx/metrology/error_recorder.py
@@ -0,0 +1,147 @@
+import typing
+import inspect
+import logging
+from json import JSONDecodeError
+from urllib.parse import urlparse
+from requests.exceptions import RequestException
+from searx.exceptions import (SearxXPathSyntaxException, SearxEngineXPathException, SearxEngineAPIException,
+ SearxEngineAccessDeniedException)
+from searx import logger
+
+
+logging.basicConfig(level=logging.INFO)
+
+errors_per_engines = {}
+
+
+class ErrorContext:
+
+ __slots__ = 'filename', 'function', 'line_no', 'code', 'exception_classname', 'log_message', 'log_parameters'
+
+ def __init__(self, filename, function, line_no, code, exception_classname, log_message, log_parameters):
+ self.filename = filename
+ self.function = function
+ self.line_no = line_no
+ self.code = code
+ self.exception_classname = exception_classname
+ self.log_message = log_message
+ self.log_parameters = log_parameters
+
+ def __eq__(self, o) -> bool:
+ if not isinstance(o, ErrorContext):
+ return False
+ return self.filename == o.filename and self.function == o.function and self.line_no == o.line_no\
+ and self.code == o.code and self.exception_classname == o.exception_classname\
+ and self.log_message == o.log_message and self.log_parameters == o.log_parameters
+
+ def __hash__(self):
+ return hash((self.filename, self.function, self.line_no, self.code, self.exception_classname, self.log_message,
+ self.log_parameters))
+
+ def __repr__(self):
+ return "ErrorContext({!r}, {!r}, {!r}, {!r}, {!r}, {!r})".\
+ format(self.filename, self.line_no, self.code, self.exception_classname, self.log_message,
+ self.log_parameters)
+
+
+def add_error_context(engine_name: str, error_context: ErrorContext) -> None:
+ errors_for_engine = errors_per_engines.setdefault(engine_name, {})
+ errors_for_engine[error_context] = errors_for_engine.get(error_context, 0) + 1
+ logger.debug('⚠️ %s: %s', engine_name, str(error_context))
+
+
+def get_trace(traces):
+ previous_trace = traces[-1]
+ for trace in reversed(traces):
+ if trace.filename.endswith('searx/search.py'):
+ if previous_trace.filename.endswith('searx/poolrequests.py'):
+ return trace
+ if previous_trace.filename.endswith('requests/models.py'):
+ return trace
+ return previous_trace
+ previous_trace = trace
+ return traces[-1]
+
+
+def get_hostname(exc: RequestException) -> typing.Optional[None]:
+ url = exc.request.url
+ if url is None and exc.response is not None:
+ url = exc.response.url
+ return urlparse(url).netloc
+
+
+def get_request_exception_messages(exc: RequestException)\
+ -> typing.Tuple[typing.Optional[str], typing.Optional[str], typing.Optional[str]]:
+ url = None
+ status_code = None
+ reason = None
+ hostname = None
+ if exc.request is not None:
+ url = exc.request.url
+ if url is None and exc.response is not None:
+ url = exc.response.url
+ if url is not None:
+ hostname = str(urlparse(url).netloc)
+ if exc.response is not None:
+ status_code = str(exc.response.status_code)
+ reason = exc.response.reason
+ return (status_code, reason, hostname)
+
+
+def get_messages(exc, filename) -> typing.Tuple:
+ if isinstance(exc, JSONDecodeError):
+ return (exc.msg, )
+ if isinstance(exc, TypeError):
+ return (str(exc), )
+ if isinstance(exc, ValueError) and 'lxml' in filename:
+ return (str(exc), )
+ if isinstance(exc, RequestException):
+ return get_request_exception_messages(exc)
+ if isinstance(exc, SearxXPathSyntaxException):
+ return (exc.xpath_str, exc.message)
+ if isinstance(exc, SearxEngineXPathException):
+ return (exc.xpath_str, exc.message)
+ if isinstance(exc, SearxEngineAPIException):
+ return (str(exc.args[0]), )
+ if isinstance(exc, SearxEngineAccessDeniedException):
+ return (exc.message, )
+ return ()
+
+
+def get_exception_classname(exc: Exception) -> str:
+ exc_class = exc.__class__
+ exc_name = exc_class.__qualname__
+ exc_module = exc_class.__module__
+ if exc_module is None or exc_module == str.__class__.__module__:
+ return exc_name
+ return exc_module + '.' + exc_name
+
+
+def get_error_context(framerecords, exception_classname, log_message, log_parameters) -> ErrorContext:
+ searx_frame = get_trace(framerecords)
+ filename = searx_frame.filename
+ function = searx_frame.function
+ line_no = searx_frame.lineno
+ code = searx_frame.code_context[0].strip()
+ del framerecords
+ return ErrorContext(filename, function, line_no, code, exception_classname, log_message, log_parameters)
+
+
+def record_exception(engine_name: str, exc: Exception) -> None:
+ framerecords = inspect.trace()
+ try:
+ exception_classname = get_exception_classname(exc)
+ log_parameters = get_messages(exc, framerecords[-1][1])
+ error_context = get_error_context(framerecords, exception_classname, None, log_parameters)
+ add_error_context(engine_name, error_context)
+ finally:
+ del framerecords
+
+
+def record_error(engine_name: str, log_message: str, log_parameters: typing.Optional[typing.Tuple] = None) -> None:
+ framerecords = list(reversed(inspect.stack()[1:]))
+ try:
+ error_context = get_error_context(framerecords, None, log_message, log_parameters or ())
+ add_error_context(engine_name, error_context)
+ finally:
+ del framerecords
diff --git a/searx/plugins/__init__.py b/searx/plugins/__init__.py
index 4dbcbbd..661b4f6 100644
--- a/searx/plugins/__init__.py
+++ b/searx/plugins/__init__.py
@@ -14,25 +14,30 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2015 by Adam Tauber, <asciimoo@gmail.com>
'''
-from sys import exit, version_info
-from searx import logger
-if version_info[0] == 3:
- unicode = str
+from hashlib import sha256
+from importlib import import_module
+from os import listdir, makedirs, remove, stat, utime
+from os.path import abspath, basename, dirname, exists, join
+from shutil import copyfile
+
+from searx import logger, settings, static_path
+
logger = logger.getChild('plugins')
from searx.plugins import (oa_doi_rewrite,
+ ahmia_filter,
+ hash_plugin,
https_rewrite,
infinite_scroll,
- open_results_on_new_tab,
self_info,
search_on_category_select,
tracker_url_remover,
vim_hotkeys)
-required_attrs = (('name', (str, unicode)),
- ('description', (str, unicode)),
+required_attrs = (('name', str),
+ ('description', str),
('default_on', bool))
optional_attrs = (('js_dependencies', tuple),
@@ -54,7 +59,9 @@ class PluginStore():
for plugin in self.plugins:
yield plugin
- def register(self, *plugins):
+ def register(self, *plugins, external=False):
+ if external:
+ plugins = load_external_plugins(plugins)
for plugin in plugins:
for plugin_attr, plugin_attr_type in required_attrs:
if not hasattr(plugin, plugin_attr) or not isinstance(getattr(plugin, plugin_attr), plugin_attr_type):
@@ -77,12 +84,104 @@ class PluginStore():
return ret
+def load_external_plugins(plugin_names):
+ plugins = []
+ for name in plugin_names:
+ logger.debug('loading plugin: {0}'.format(name))
+ try:
+ pkg = import_module(name)
+ except Exception as e:
+ logger.critical('failed to load plugin module {0}: {1}'.format(name, e))
+ exit(3)
+
+ pkg.__base_path = dirname(abspath(pkg.__file__))
+
+ prepare_package_resources(pkg, name)
+
+ plugins.append(pkg)
+ logger.debug('plugin "{0}" loaded'.format(name))
+ return plugins
+
+
+def sync_resource(base_path, resource_path, name, target_dir, plugin_dir):
+ dep_path = join(base_path, resource_path)
+ file_name = basename(dep_path)
+ resource_path = join(target_dir, file_name)
+ if not exists(resource_path) or sha_sum(dep_path) != sha_sum(resource_path):
+ try:
+ copyfile(dep_path, resource_path)
+ # copy atime_ns and mtime_ns, so the weak ETags (generated by
+ # the HTTP server) do not change
+ dep_stat = stat(dep_path)
+ utime(resource_path, ns=(dep_stat.st_atime_ns, dep_stat.st_mtime_ns))
+ except:
+ logger.critical('failed to copy plugin resource {0} for plugin {1}'.format(file_name, name))
+ exit(3)
+
+ # returning with the web path of the resource
+ return join('plugins/external_plugins', plugin_dir, file_name)
+
+
+def prepare_package_resources(pkg, name):
+ plugin_dir = 'plugin_' + name
+ target_dir = join(static_path, 'plugins/external_plugins', plugin_dir)
+ try:
+ makedirs(target_dir, exist_ok=True)
+ except:
+ logger.critical('failed to create resource directory {0} for plugin {1}'.format(target_dir, name))
+ exit(3)
+
+ resources = []
+
+ if hasattr(pkg, 'js_dependencies'):
+ resources.extend(map(basename, pkg.js_dependencies))
+ pkg.js_dependencies = tuple([
+ sync_resource(pkg.__base_path, x, name, target_dir, plugin_dir)
+ for x in pkg.js_dependencies
+ ])
+ if hasattr(pkg, 'css_dependencies'):
+ resources.extend(map(basename, pkg.css_dependencies))
+ pkg.css_dependencies = tuple([
+ sync_resource(pkg.__base_path, x, name, target_dir, plugin_dir)
+ for x in pkg.css_dependencies
+ ])
+
+ for f in listdir(target_dir):
+ if basename(f) not in resources:
+ resource_path = join(target_dir, basename(f))
+ try:
+ remove(resource_path)
+ except:
+ logger.critical('failed to remove unused resource file {0} for plugin {1}'.format(resource_path, name))
+ exit(3)
+
+
+def sha_sum(filename):
+ with open(filename, "rb") as f:
+ file_content_bytes = f.read()
+ return sha256(file_content_bytes).hexdigest()
+
+
plugins = PluginStore()
plugins.register(oa_doi_rewrite)
+plugins.register(hash_plugin)
plugins.register(https_rewrite)
plugins.register(infinite_scroll)
-plugins.register(open_results_on_new_tab)
plugins.register(self_info)
plugins.register(search_on_category_select)
plugins.register(tracker_url_remover)
plugins.register(vim_hotkeys)
+# load external plugins
+if 'plugins' in settings:
+ plugins.register(*settings['plugins'], external=True)
+
+if 'enabled_plugins' in settings:
+ for plugin in plugins:
+ if plugin.name in settings['enabled_plugins']:
+ plugin.default_on = True
+ else:
+ plugin.default_on = False
+
+# load tor specific plugins
+if settings['outgoing'].get('using_tor_proxy'):
+ plugins.register(ahmia_filter)
diff --git a/searx/plugins/ahmia_filter.py b/searx/plugins/ahmia_filter.py
new file mode 100644
index 0000000..83b05e4
--- /dev/null
+++ b/searx/plugins/ahmia_filter.py
@@ -0,0 +1,33 @@
+'''
+ SPDX-License-Identifier: AGPL-3.0-or-later
+'''
+
+from hashlib import md5
+from searx.data import ahmia_blacklist_loader
+
+name = "Ahmia blacklist"
+description = "Filter out onion results that appear in Ahmia's blacklist. (See https://ahmia.fi/blacklist)"
+default_on = True
+preference_section = 'onions'
+
+ahmia_blacklist = None
+
+
+def get_ahmia_blacklist():
+ global ahmia_blacklist
+ if not ahmia_blacklist:
+ ahmia_blacklist = ahmia_blacklist_loader()
+ return ahmia_blacklist
+
+
+def not_blacklisted(result):
+ if not result.get('is_onion') or not result.get('parsed_url'):
+ return True
+ result_hash = md5(result['parsed_url'].hostname.encode()).hexdigest()
+ return result_hash not in get_ahmia_blacklist()
+
+
+def post_search(request, search):
+ filtered_results = list(filter(not_blacklisted, search.result_container._merged_results))
+ search.result_container._merged_results = filtered_results
+ return True
diff --git a/searx/plugins/hash_plugin.py b/searx/plugins/hash_plugin.py
new file mode 100644
index 0000000..1d3baae
--- /dev/null
+++ b/searx/plugins/hash_plugin.py
@@ -0,0 +1,54 @@
+'''
+searx is free software: you can redistribute it and/or modify
+it under the terms of the GNU Affero General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+searx is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Affero General Public License for more details.
+
+You should have received a copy of the GNU Affero General Public License
+along with searx. If not, see < http://www.gnu.org/licenses/ >.
+
+(C) 2015 by Adam Tauber, <asciimoo@gmail.com>
+(C) 2018, 2020 by Vaclav Zouzalik
+'''
+
+from flask_babel import gettext
+import hashlib
+import re
+
+name = "Hash plugin"
+description = gettext("Converts strings to different hash digests.")
+default_on = True
+
+parser_re = re.compile('(md5|sha1|sha224|sha256|sha384|sha512) (.*)', re.I)
+
+
+def post_search(request, search):
+ # process only on first page
+ if search.search_query.pageno > 1:
+ return True
+ m = parser_re.match(search.search_query.query)
+ if not m:
+ # wrong query
+ return True
+
+ function, string = m.groups()
+ if string.strip().__len__() == 0:
+ # end if the string is empty
+ return True
+
+ # select hash function
+ f = hashlib.new(function.lower())
+
+ # make digest from the given string
+ f.update(string.encode('utf-8').strip())
+ answer = function + " " + gettext('hash digest') + ": " + f.hexdigest()
+
+ # print result
+ search.result_container.answers.clear()
+ search.result_container.answers['hash'] = {'answer': answer}
+ return True
diff --git a/searx/plugins/https_rewrite.py b/searx/plugins/https_rewrite.py
index 8255601..aeb4249 100644
--- a/searx/plugins/https_rewrite.py
+++ b/searx/plugins/https_rewrite.py
@@ -16,17 +16,14 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
'''
import re
-import sys
+from urllib.parse import urlparse
from lxml import etree
from os import listdir, environ
from os.path import isfile, isdir, join
from searx.plugins import logger
from flask_babel import gettext
from searx import searx_dir
-from searx.url_utils import urlparse
-if sys.version_info[0] == 3:
- unicode = str
name = "HTTPS rewrite"
description = gettext('Rewrite HTTP links to HTTPS if possible')
diff --git a/searx/plugins/oa_doi_rewrite.py b/searx/plugins/oa_doi_rewrite.py
index be80beb..eef29f1 100644
--- a/searx/plugins/oa_doi_rewrite.py
+++ b/searx/plugins/oa_doi_rewrite.py
@@ -1,6 +1,6 @@
+from urllib.parse import urlparse, parse_qsl
from flask_babel import gettext
import re
-from searx.url_utils import urlparse, parse_qsl
from searx import settings
diff --git a/searx/plugins/open_results_on_new_tab.py b/searx/plugins/open_results_on_new_tab.py
deleted file mode 100644
index 0f06f5a..0000000
--- a/searx/plugins/open_results_on_new_tab.py
+++ /dev/null
@@ -1,25 +0,0 @@
-'''
-searx is free software: you can redistribute it and/or modify
-it under the terms of the GNU Affero General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-searx is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Affero General Public License for more details.
-
-You should have received a copy of the GNU Affero General Public License
-along with searx. If not, see < http://www.gnu.org/licenses/ >.
-
-(C) 2016 by Adam Tauber, <asciimoo@gmail.com>
-'''
-from flask_babel import gettext
-name = gettext('Open result links on new browser tabs')
-description = gettext('Results are opened in the same window by default. '
- 'This plugin overwrites the default behaviour to open links on new tabs/windows. '
- '(JavaScript required)')
-default_on = False
-preference_section = 'ui'
-
-js_dependencies = ('plugins/js/open_results_on_new_tab.js',)
diff --git a/searx/plugins/self_info.py b/searx/plugins/self_info.py
index 67e5e0e..4fdfb42 100644
--- a/searx/plugins/self_info.py
+++ b/searx/plugins/self_info.py
@@ -16,13 +16,13 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
'''
from flask_babel import gettext
import re
-name = "Self Informations"
+name = gettext('Self Informations')
description = gettext('Displays your IP if the query is "ip" and your user agent if the query contains "user agent".')
default_on = True
# Self User Agent regex
-p = re.compile(b'.*user[ -]agent.*', re.IGNORECASE)
+p = re.compile('.*user[ -]agent.*', re.IGNORECASE)
# attach callback to the post search hook
@@ -31,7 +31,7 @@ p = re.compile(b'.*user[ -]agent.*', re.IGNORECASE)
def post_search(request, search):
if search.search_query.pageno > 1:
return True
- if search.search_query.query == b'ip':
+ if search.search_query.query == 'ip':
x_forwarded_for = request.headers.getlist("X-Forwarded-For")
if x_forwarded_for:
ip = x_forwarded_for[0]
diff --git a/searx/plugins/tracker_url_remover.py b/searx/plugins/tracker_url_remover.py
index 33dd621..742f390 100644
--- a/searx/plugins/tracker_url_remover.py
+++ b/searx/plugins/tracker_url_remover.py
@@ -17,7 +17,7 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
from flask_babel import gettext
import re
-from searx.url_utils import urlunparse, parse_qsl, urlencode
+from urllib.parse import urlunparse, parse_qsl, urlencode
regexes = {re.compile(r'utm_[^&]+'),
re.compile(r'(wkey|wemail)[^&]*'),
diff --git a/searx/poolrequests.py b/searx/poolrequests.py
index f9a9d77..25a6bae 100644
--- a/searx/poolrequests.py
+++ b/searx/poolrequests.py
@@ -1,9 +1,34 @@
-import requests
-
+import sys
+from time import time
from itertools import cycle
from threading import RLock, local
+
+import requests
+
from searx import settings
-from time import time
+from searx import logger
+from searx.raise_for_httperror import raise_for_httperror
+
+
+logger = logger.getChild('poolrequests')
+
+
+try:
+ import ssl
+ if ssl.OPENSSL_VERSION_INFO[0:3] < (1, 0, 2):
+ # https://github.com/certifi/python-certifi#1024-bit-root-certificates
+ logger.critical('You are using an old openssl version({0}), please upgrade above 1.0.2!'
+ .format(ssl.OPENSSL_VERSION))
+ sys.exit(1)
+except ImportError:
+ ssl = None
+if not getattr(ssl, "HAS_SNI", False):
+ try:
+ import OpenSSL # pylint: disable=unused-import
+ except ImportError:
+ logger.critical("ssl doesn't support SNI and the pyopenssl module is not installed.\n"
+ "Some HTTPS connections will fail")
+ sys.exit(1)
class HTTPAdapterWithConnParams(requests.adapters.HTTPAdapter):
@@ -20,7 +45,7 @@ class HTTPAdapterWithConnParams(requests.adapters.HTTPAdapter):
self.config = {}
self.proxy_manager = {}
- super(requests.adapters.HTTPAdapter, self).__init__()
+ super().__init__()
self._pool_connections = pool_connections
self._pool_maxsize = pool_maxsize
@@ -60,7 +85,7 @@ else:
class SessionSinglePool(requests.Session):
def __init__(self):
- super(SessionSinglePool, self).__init__()
+ super().__init__()
# reuse the same adapters
with RLock():
@@ -71,7 +96,7 @@ class SessionSinglePool(requests.Session):
def close(self):
"""Call super, but clear adapters since there are managed globaly"""
self.adapters.clear()
- super(SessionSinglePool, self).close()
+ super().close()
def set_timeout_for_thread(timeout, start_time=None):
@@ -87,6 +112,32 @@ def get_time_for_thread():
return threadLocal.total_time
+def get_proxy_cycles(proxy_settings):
+ if not proxy_settings:
+ return None
+ # Backwards compatibility for single proxy in settings.yml
+ for protocol, proxy in proxy_settings.items():
+ if isinstance(proxy, str):
+ proxy_settings[protocol] = [proxy]
+
+ for protocol in proxy_settings:
+ proxy_settings[protocol] = cycle(proxy_settings[protocol])
+ return proxy_settings
+
+
+GLOBAL_PROXY_CYCLES = get_proxy_cycles(settings['outgoing'].get('proxies'))
+
+
+def get_proxies(proxy_cycles):
+ if proxy_cycles:
+ return {protocol: next(proxy_cycle) for protocol, proxy_cycle in proxy_cycles.items()}
+ return None
+
+
+def get_global_proxies():
+ return get_proxies(GLOBAL_PROXY_CYCLES)
+
+
def request(method, url, **kwargs):
"""same as requests/requests/api.py request(...)"""
time_before_request = time()
@@ -95,7 +146,8 @@ def request(method, url, **kwargs):
session = SessionSinglePool()
# proxies
- kwargs['proxies'] = settings['outgoing'].get('proxies') or None
+ if not kwargs.get('proxies'):
+ kwargs['proxies'] = get_global_proxies()
# timeout
if 'timeout' in kwargs:
@@ -105,6 +157,12 @@ def request(method, url, **kwargs):
if timeout is not None:
kwargs['timeout'] = timeout
+ # raise_for_error
+ check_for_httperror = True
+ if 'raise_for_httperror' in kwargs:
+ check_for_httperror = kwargs['raise_for_httperror']
+ del kwargs['raise_for_httperror']
+
# do request
response = session.request(method=method, url=url, **kwargs)
@@ -125,6 +183,10 @@ def request(method, url, **kwargs):
if hasattr(threadLocal, 'total_time'):
threadLocal.total_time += time_after_request - time_before_request
+ # raise an exception
+ if check_for_httperror:
+ raise_for_httperror(response)
+
return response
diff --git a/searx/preferences.py b/searx/preferences.py
index f70aee3..a9f16ff 100644
--- a/searx/preferences.py
+++ b/searx/preferences.py
@@ -6,16 +6,11 @@
from base64 import urlsafe_b64encode, urlsafe_b64decode
from zlib import compress, decompress
-from sys import version
+from urllib.parse import parse_qs, urlencode
from searx import settings, autocomplete
from searx.languages import language_codes as languages
-from searx.utils import match_language
-from searx.url_utils import parse_qs, urlencode
-
-if version[0] == '3':
- # pylint: disable=invalid-name
- unicode = str
+from searx.webutils import VALID_LANGUAGE_CODE
COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5 # 5 years
@@ -37,12 +32,13 @@ class ValidationException(Exception):
"""
-class Setting(object):
+class Setting:
"""Base class of user settings"""
- def __init__(self, default_value, **kwargs):
- super(Setting, self).__init__()
+ def __init__(self, default_value, locked=False, **kwargs):
+ super().__init__()
self.value = default_value
+ self.locked = locked
for key, value in kwargs.items():
setattr(self, key, value)
@@ -120,6 +116,9 @@ class MultipleChoiceSetting(EnumStringSetting):
self.value = elements
def parse_form(self, data): # pylint: disable=missing-function-docstring
+ if self.locked:
+ return
+
self.value = []
for choice in data:
if choice in self.choices and choice not in self.value: # pylint: disable=no-member
@@ -154,6 +153,9 @@ class SetSetting(Setting):
self.values.add(element)
def parse_form(self, data): # pylint: disable=missing-function-docstring
+ if self.locked:
+ return
+
elements = data.split(',')
self.values = set(elements) # pylint: disable=attribute-defined-outside-init
@@ -167,9 +169,7 @@ class SearchLanguageSetting(EnumStringSetting):
"""Available choices may change, so user's value may not be in choices anymore"""
def _validate_selection(self, selection):
- if selection != "" and not match_language(
- # pylint: disable=no-member
- selection, self.choices, fallback=None):
+ if selection != '' and not VALID_LANGUAGE_CODE.match(selection):
raise ValidationException('Invalid language code: "{0}"'.format(selection))
def parse(self, data):
@@ -186,6 +186,7 @@ class SearchLanguageSetting(EnumStringSetting):
data = lang
else:
data = self.value
+ self._validate_selection(data)
self.value = data
@@ -239,6 +240,9 @@ class SwitchableSetting(Setting):
self.enabled = set(data[ENABLED].split(','))
def parse_form(self, items): # pylint: disable=missing-function-docstring
+ if self.locked:
+ return
+
items = self.transform_form_items(items)
self.disabled = set() # pylint: disable=attribute-defined-outside-init
self.enabled = set() # pylint: disable=attribute-defined-outside-init
@@ -275,7 +279,7 @@ class EnginesSetting(SwitchableSetting):
"""Engine settings"""
def _post_init(self):
- super(EnginesSetting, self)._post_init()
+ super()._post_init()
transformed_choices = []
for engine_name, engine in self.choices.items(): # pylint: disable=no-member,access-member-before-definition
for category in engine.categories:
@@ -302,7 +306,7 @@ class PluginsSetting(SwitchableSetting):
"""Plugin settings"""
def _post_init(self):
- super(PluginsSetting, self)._post_init()
+ super()._post_init()
transformed_choices = []
for plugin in self.choices: # pylint: disable=access-member-before-definition
transformed_choice = dict()
@@ -315,30 +319,36 @@ class PluginsSetting(SwitchableSetting):
return [item[len('plugin_'):] for item in items]
-class Preferences(object):
+class Preferences:
"""Validates and saves preferences to cookies"""
def __init__(self, themes, categories, engines, plugins):
- super(Preferences, self).__init__()
+ super().__init__()
self.key_value_settings = {
'categories': MultipleChoiceSetting(
- ['general'], choices=categories + ['none']
+ ['general'],
+ is_locked('categories'),
+ choices=categories + ['none']
),
'language': SearchLanguageSetting(
settings['search'].get('default_lang', ''),
+ is_locked('language'),
choices=list(LANGUAGE_CODES) + ['']
),
'locale': EnumStringSetting(
settings['ui'].get('default_locale', ''),
+ is_locked('locale'),
choices=list(settings['locales'].keys()) + ['']
),
'autocomplete': EnumStringSetting(
settings['search'].get('autocomplete', ''),
+ is_locked('autocomplete'),
choices=list(autocomplete.backends.keys()) + ['']
),
'image_proxy': MapSetting(
settings['server'].get('image_proxy', False),
+ is_locked('image_proxy'),
map={
'': settings['server'].get('image_proxy', 0),
'0': False,
@@ -348,11 +358,13 @@ class Preferences(object):
}
),
'method': EnumStringSetting(
- 'POST',
+ settings['server'].get('method', 'POST'),
+ is_locked('method'),
choices=('GET', 'POST')
),
'safesearch': MapSetting(
settings['search'].get('safe_search', 0),
+ is_locked('safesearch'),
map={
'0': 0,
'1': 1,
@@ -361,10 +373,12 @@ class Preferences(object):
),
'theme': EnumStringSetting(
settings['ui'].get('default_theme', 'oscar'),
+ is_locked('theme'),
choices=themes
),
'results_on_new_tab': MapSetting(
- False,
+ settings['ui'].get('results_on_new_tab', False),
+ is_locked('results_on_new_tab'),
map={
'0': False,
'1': True,
@@ -373,11 +387,25 @@ class Preferences(object):
}
),
'doi_resolver': MultipleChoiceSetting(
- ['oadoi.org'], choices=DOI_RESOLVERS
+ ['oadoi.org'],
+ is_locked('doi_resolver'),
+ choices=DOI_RESOLVERS
),
'oscar-style': EnumStringSetting(
settings['ui'].get('theme_args', {}).get('oscar_style', 'logicodev'),
+ is_locked('oscar-style'),
choices=['', 'logicodev', 'logicodev-dark', 'pointhi']),
+ 'advanced_search': MapSetting(
+ settings['ui'].get('advanced_search', False),
+ is_locked('advanced_search'),
+ map={
+ '0': False,
+ '1': True,
+ 'False': False,
+ 'True': True,
+ 'on': True,
+ }
+ ),
}
self.engines = EnginesSetting('engines', choices=engines)
@@ -389,6 +417,8 @@ class Preferences(object):
"""Return preferences as URL parameters"""
settings_kv = {}
for k, v in self.key_value_settings.items():
+ if v.locked:
+ continue
if isinstance(v, MultipleChoiceSetting):
settings_kv[k] = ','.join(v.get_value())
else:
@@ -402,20 +432,22 @@ class Preferences(object):
settings_kv['tokens'] = ','.join(self.tokens.values)
- return urlsafe_b64encode(compress(urlencode(settings_kv).encode('utf-8'))).decode('utf-8')
+ return urlsafe_b64encode(compress(urlencode(settings_kv).encode())).decode()
def parse_encoded_data(self, input_data):
"""parse (base64) preferences from request (``flask.request.form['preferences']``)"""
- decoded_data = decompress(urlsafe_b64decode(input_data.encode('utf-8')))
+ decoded_data = decompress(urlsafe_b64decode(input_data.encode()))
dict_data = {}
for x, y in parse_qs(decoded_data).items():
- dict_data[x.decode('utf8')] = y[0].decode('utf8')
+ dict_data[x.decode()] = y[0].decode()
self.parse_dict(dict_data)
def parse_dict(self, input_data):
"""parse preferences from request (``flask.request.form``)"""
for user_setting_name, user_setting in input_data.items():
if user_setting_name in self.key_value_settings:
+ if self.key_value_settings[user_setting_name].locked:
+ continue
self.key_value_settings[user_setting_name].parse(user_setting)
elif user_setting_name == 'disabled_engines':
self.engines.parse_cookie((input_data.get('disabled_engines', ''),
@@ -470,6 +502,8 @@ class Preferences(object):
"""Save cookie in the HTTP reponse obect
"""
for user_setting_name, user_setting in self.key_value_settings.items():
+ if self.key_value_settings[user_setting_name].locked:
+ continue
user_setting.save(user_setting_name, resp)
self.engines.save(resp)
self.plugins.save(resp)
@@ -488,3 +522,13 @@ class Preferences(object):
break
return valid
+
+
+def is_locked(setting_name):
+ """Checks if a given setting name is locked by settings.yml
+ """
+ if 'preferences' not in settings:
+ return False
+ if 'lock' not in settings['preferences']:
+ return False
+ return setting_name in settings['preferences']['lock']
diff --git a/searx/query.py b/searx/query.py
index e8b57d4..422cd57 100644
--- a/searx/query.py
+++ b/searx/query.py
@@ -17,23 +17,19 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2014 by Thomas Pointhuber, <thomas.pointhuber@gmx.at>
'''
-from searx.languages import language_codes
-from searx.engines import (
- categories, engines, engine_shortcuts
-)
import re
-import sys
-
-if sys.version_info[0] == 3:
- unicode = str
-VALID_LANGUAGE_CODE = re.compile(r'^[a-z]{2,3}(-[a-zA-Z]{2})?$')
+from searx.languages import language_codes
+from searx.engines import categories, engines, engine_shortcuts
+from searx.search import EngineRef
+from searx.webutils import VALID_LANGUAGE_CODE
-class RawTextQuery(object):
+class RawTextQuery:
"""parse raw text query (the value from the html input)"""
def __init__(self, query, disabled_engines):
+ assert isinstance(query, str)
self.query = query
self.disabled_engines = []
@@ -41,34 +37,28 @@ class RawTextQuery(object):
self.disabled_engines = disabled_engines
self.query_parts = []
- self.engines = []
+ self.user_query_parts = []
+ self.enginerefs = []
self.languages = []
self.timeout_limit = None
self.external_bang = None
self.specific = False
+ self._parse_query()
# parse query, if tags are set, which
# change the search engine or search-language
- def parse_query(self):
+ def _parse_query(self):
self.query_parts = []
# split query, including whitespaces
- raw_query_parts = re.split(r'(\s+)' if isinstance(self.query, str) else b'(\s+)', self.query)
-
- parse_next = True
+ raw_query_parts = re.split(r'(\s+)', self.query)
for query_part in raw_query_parts:
- if not parse_next:
- self.query_parts[-1] += query_part
- continue
-
- parse_next = False
+ searx_query_part = False
# part does only contain spaces, skip
if query_part.isspace()\
or query_part == '':
- parse_next = True
- self.query_parts.append(query_part)
continue
# this force the timeout
@@ -81,7 +71,7 @@ class RawTextQuery(object):
else:
# 100 or above, the unit is the millisecond ( <850 = 850 milliseconds timeout )
self.timeout_limit = raw_timeout_limit / 1000.0
- parse_next = True
+ searx_query_part = True
except ValueError:
# error not reported to the user
pass
@@ -93,7 +83,7 @@ class RawTextQuery(object):
# check if any language-code is equal with
# declared language-codes
for lc in language_codes:
- lang_id, lang_name, country, english_name = map(unicode.lower, lc)
+ lang_id, lang_name, country, english_name = map(str.lower, lc)
# if correct language-code is found
# set it as new search-language
@@ -102,15 +92,15 @@ class RawTextQuery(object):
or lang == english_name
or lang.replace('-', ' ') == country)\
and lang not in self.languages:
- parse_next = True
- lang_parts = lang_id.split('-')
- if len(lang_parts) == 2:
- self.languages.append(lang_parts[0] + '-' + lang_parts[1].upper())
- else:
- self.languages.append(lang_id)
- # to ensure best match (first match is not necessarily the best one)
- if lang == lang_id:
- break
+ searx_query_part = True
+ lang_parts = lang_id.split('-')
+ if len(lang_parts) == 2:
+ self.languages.append(lang_parts[0] + '-' + lang_parts[1].upper())
+ else:
+ self.languages.append(lang_id)
+ # to ensure best match (first match is not necessarily the best one)
+ if lang == lang_id:
+ break
# user may set a valid, yet not selectable language
if VALID_LANGUAGE_CODE.match(lang):
@@ -119,12 +109,12 @@ class RawTextQuery(object):
lang = lang_parts[0].lower() + '-' + lang_parts[1].upper()
if lang not in self.languages:
self.languages.append(lang)
- parse_next = True
+ searx_query_part = True
# external bang
if query_part[0:2] == "!!":
self.external_bang = query_part[2:]
- parse_next = True
+ searx_query_part = True
continue
# this force a engine or category
if query_part[0] == '!' or query_part[0] == '?':
@@ -132,69 +122,41 @@ class RawTextQuery(object):
# check if prefix is equal with engine shortcut
if prefix in engine_shortcuts:
- parse_next = True
+ searx_query_part = True
engine_name = engine_shortcuts[prefix]
if engine_name in engines:
- self.engines.append({'category': 'none',
- 'name': engine_name,
- 'from_bang': True})
+ self.enginerefs.append(EngineRef(engine_name, 'none', True))
# check if prefix is equal with engine name
elif prefix in engines:
- parse_next = True
- self.engines.append({'category': 'none',
- 'name': prefix,
- 'from_bang': True})
+ searx_query_part = True
+ self.enginerefs.append(EngineRef(prefix, 'none', True))
# check if prefix is equal with categorie name
elif prefix in categories:
# using all engines for that search, which
# are declared under that categorie name
- parse_next = True
- self.engines.extend({'category': prefix,
- 'name': engine.name}
- for engine in categories[prefix]
- if (engine.name, prefix) not in self.disabled_engines)
+ searx_query_part = True
+ self.enginerefs.extend(EngineRef(engine.name, prefix)
+ for engine in categories[prefix]
+ if (engine.name, prefix) not in self.disabled_engines)
if query_part[0] == '!':
self.specific = True
# append query part to query_part list
- self.query_parts.append(query_part)
+ if searx_query_part:
+ self.query_parts.append(query_part)
+ else:
+ self.user_query_parts.append(query_part)
- def changeSearchQuery(self, search_query):
- if len(self.query_parts):
- self.query_parts[-1] = search_query
- else:
- self.query_parts.append(search_query)
+ def changeQuery(self, query):
+ self.user_query_parts = query.strip().split()
return self
- def getSearchQuery(self):
- if len(self.query_parts):
- return self.query_parts[-1]
- else:
- return ''
+ def getQuery(self):
+ return ' '.join(self.user_query_parts)
def getFullQuery(self):
# get full querry including whitespaces
- return u''.join(self.query_parts)
-
-
-class SearchQuery(object):
- """container for all the search parameters (query, language, etc...)"""
-
- def __init__(self, query, engines, categories, lang, safesearch, pageno, time_range,
- timeout_limit=None, preferences=None, external_bang=None):
- self.query = query.encode('utf-8')
- self.engines = engines
- self.categories = categories
- self.lang = lang
- self.safesearch = safesearch
- self.pageno = pageno
- self.time_range = None if time_range in ('', 'None', None) else time_range
- self.timeout_limit = timeout_limit
- self.preferences = preferences
- self.external_bang = external_bang
-
- def __str__(self):
- return str(self.query) + ";" + str(self.engines)
+ return '{0} {1}'.format(''.join(self.query_parts), self.getQuery()).strip()
diff --git a/searx/raise_for_httperror.py b/searx/raise_for_httperror.py
new file mode 100644
index 0000000..bd12df9
--- /dev/null
+++ b/searx/raise_for_httperror.py
@@ -0,0 +1,66 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+"""
+Raise exception for an HTTP response is an error.
+"""
+from searx.exceptions import (SearxEngineCaptchaException, SearxEngineTooManyRequestsException,
+ SearxEngineAccessDeniedException)
+
+
+def is_cloudflare_challenge(resp):
+ if resp.status_code in [429, 503]:
+ if ('__cf_chl_jschl_tk__=' in resp.text)\
+ or ('/cdn-cgi/challenge-platform/' in resp.text
+ and 'orchestrate/jsch/v1' in resp.text
+ and 'window._cf_chl_enter(' in resp.text):
+ return True
+ if resp.status_code == 403 and '__cf_chl_captcha_tk__=' in resp.text:
+ return True
+ return False
+
+
+def is_cloudflare_firewall(resp):
+ return resp.status_code == 403 and '<span class="cf-error-code">1020</span>' in resp.text
+
+
+def raise_for_cloudflare_captcha(resp):
+ if resp.headers.get('Server', '').startswith('cloudflare'):
+ if is_cloudflare_challenge(resp):
+ # https://support.cloudflare.com/hc/en-us/articles/200170136-Understanding-Cloudflare-Challenge-Passage-Captcha-
+ # suspend for 2 weeks
+ raise SearxEngineCaptchaException(message='Cloudflare CAPTCHA', suspended_time=3600 * 24 * 15)
+
+ if is_cloudflare_firewall(resp):
+ raise SearxEngineAccessDeniedException(message='Cloudflare Firewall', suspended_time=3600 * 24)
+
+
+def raise_for_recaptcha(resp):
+ if resp.status_code == 503 \
+ and '"https://www.google.com/recaptcha/' in resp.text:
+ raise SearxEngineCaptchaException(message='ReCAPTCHA', suspended_time=3600 * 24 * 7)
+
+
+def raise_for_captcha(resp):
+ raise_for_cloudflare_captcha(resp)
+ raise_for_recaptcha(resp)
+
+
+def raise_for_httperror(resp):
+ """Raise exception for an HTTP response is an error.
+
+ Args:
+ resp (requests.Response): Response to check
+
+ Raises:
+ requests.HTTPError: raise by resp.raise_for_status()
+ searx.exceptions.SearxEngineAccessDeniedException: raise when the HTTP status code is 402 or 403.
+ searx.exceptions.SearxEngineTooManyRequestsException: raise when the HTTP status code is 429.
+ searx.exceptions.SearxEngineCaptchaException: raise when if CATPCHA challenge is detected.
+ """
+ if resp.status_code and resp.status_code >= 400:
+ raise_for_captcha(resp)
+ if resp.status_code in (402, 403):
+ raise SearxEngineAccessDeniedException(message='HTTP error ' + str(resp.status_code),
+ suspended_time=3600 * 24)
+ if resp.status_code == 429:
+ raise SearxEngineTooManyRequestsException()
+ resp.raise_for_status()
diff --git a/searx/results.py b/searx/results.py
index 4fed58e..fb7e816 100644
--- a/searx/results.py
+++ b/searx/results.py
@@ -1,13 +1,11 @@
import re
-import sys
-from collections import defaultdict
from operator import itemgetter
from threading import RLock
+from urllib.parse import urlparse, unquote
+from searx import logger
from searx.engines import engines
-from searx.url_utils import urlparse, unquote
+from searx.metrology.error_recorder import record_error
-if sys.version_info[0] == 3:
- basestring = str
CONTENT_LEN_IGNORED_CHARS_REGEX = re.compile(r'[,;:!?\./\\\\ ()-_]', re.M | re.U)
WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U)
@@ -15,13 +13,25 @@ WHITESPACE_REGEX = re.compile('( |\t|\n)+', re.M | re.U)
# return the meaningful length of the content for a result
def result_content_len(content):
- if isinstance(content, basestring):
+ if isinstance(content, str):
return len(CONTENT_LEN_IGNORED_CHARS_REGEX.sub('', content))
else:
return 0
def compare_urls(url_a, url_b):
+ """Lazy compare between two URL.
+ "www.example.com" and "example.com" are equals.
+ "www.example.com/path/" and "www.example.com/path" are equals.
+ "https://www.example.com/" and "http://www.example.com/" are equals.
+
+ Args:
+ url_a (ParseResult): first URL
+ url_b (ParseResult): second URL
+
+ Returns:
+ bool: True if url_a and url_b are equals
+ """
# ignore www. in comparison
if url_a.netloc.startswith('www.'):
host_a = url_a.netloc.replace('www.', '', 1)
@@ -60,6 +70,8 @@ def merge_two_infoboxes(infobox1, infobox2):
if weight2 > weight1:
infobox1['engine'] = infobox2['engine']
+ infobox1['engines'] |= infobox2['engines']
+
if 'urls' in infobox2:
urls1 = infobox1.get('urls', None)
if urls1 is None:
@@ -68,8 +80,10 @@ def merge_two_infoboxes(infobox1, infobox2):
for url2 in infobox2.get('urls', []):
unique_url = True
parsed_url2 = urlparse(url2.get('url', ''))
+ entity_url2 = url2.get('entity')
for url1 in urls1:
- if compare_urls(urlparse(url1.get('url', '')), parsed_url2):
+ if (entity_url2 is not None and url1.get('entity') == entity_url2)\
+ or compare_urls(urlparse(url1.get('url', '')), parsed_url2):
unique_url = False
break
if unique_url:
@@ -86,18 +100,22 @@ def merge_two_infoboxes(infobox1, infobox2):
infobox1['img_src'] = img2
if 'attributes' in infobox2:
- attributes1 = infobox1.get('attributes', None)
+ attributes1 = infobox1.get('attributes')
if attributes1 is None:
- attributes1 = []
- infobox1['attributes'] = attributes1
+ infobox1['attributes'] = attributes1 = []
attributeSet = set()
- for attribute in infobox1.get('attributes', []):
- if attribute.get('label', None) not in attributeSet:
- attributeSet.add(attribute.get('label', None))
+ for attribute in attributes1:
+ label = attribute.get('label')
+ if label not in attributeSet:
+ attributeSet.add(label)
+ entity = attribute.get('entity')
+ if entity not in attributeSet:
+ attributeSet.add(entity)
for attribute in infobox2.get('attributes', []):
- if attribute.get('label', None) not in attributeSet:
+ if attribute.get('label') not in attributeSet\
+ and attribute.get('entity') not in attributeSet:
attributes1.append(attribute)
if 'content' in infobox2:
@@ -122,12 +140,14 @@ def result_score(result):
return sum((occurences * weight) / position for position in result['positions'])
-class ResultContainer(object):
+class ResultContainer:
"""docstring for ResultContainer"""
+ __slots__ = '_merged_results', 'infoboxes', 'suggestions', 'answers', 'corrections', '_number_of_results',\
+ '_ordered', 'paging', 'unresponsive_engines', 'timings', 'redirect_url'
+
def __init__(self):
- super(ResultContainer, self).__init__()
- self.results = defaultdict(list)
+ super().__init__()
self._merged_results = []
self.infoboxes = []
self.suggestions = set()
@@ -141,54 +161,52 @@ class ResultContainer(object):
self.redirect_url = None
def extend(self, engine_name, results):
+ standard_result_count = 0
+ error_msgs = set()
for result in list(results):
result['engine'] = engine_name
if 'suggestion' in result:
self.suggestions.add(result['suggestion'])
- results.remove(result)
elif 'answer' in result:
self.answers[result['answer']] = result
- results.remove(result)
elif 'correction' in result:
self.corrections.add(result['correction'])
- results.remove(result)
elif 'infobox' in result:
self._merge_infobox(result)
- results.remove(result)
elif 'number_of_results' in result:
self._number_of_results.append(result['number_of_results'])
- results.remove(result)
+ else:
+ # standard result (url, title, content)
+ if 'url' in result and not isinstance(result['url'], str):
+ logger.debug('result: invalid URL: %s', str(result))
+ error_msgs.add('invalid URL')
+ elif 'title' in result and not isinstance(result['title'], str):
+ logger.debug('result: invalid title: %s', str(result))
+ error_msgs.add('invalid title')
+ elif 'content' in result and not isinstance(result['content'], str):
+ logger.debug('result: invalid content: %s', str(result))
+ error_msgs.add('invalid content')
+ else:
+ self._merge_result(result, standard_result_count + 1)
+ standard_result_count += 1
+
+ if len(error_msgs) > 0:
+ for msg in error_msgs:
+ record_error(engine_name, 'some results are invalids: ' + msg)
if engine_name in engines:
with RLock():
engines[engine_name].stats['search_count'] += 1
- engines[engine_name].stats['result_count'] += len(results)
-
- if not results:
- return
-
- self.results[engine_name].extend(results)
+ engines[engine_name].stats['result_count'] += standard_result_count
- if not self.paging and engine_name in engines and engines[engine_name].paging:
+ if not self.paging and standard_result_count > 0 and engine_name in engines\
+ and engines[engine_name].paging:
self.paging = True
- for i, result in enumerate(results):
- if 'url' in result and not isinstance(result['url'], basestring):
- continue
- try:
- result['url'] = result['url'].decode('utf-8')
- except:
- pass
- if 'title' in result and not isinstance(result['title'], basestring):
- continue
- if 'content' in result and not isinstance(result['content'], basestring):
- continue
- position = i + 1
- self._merge_result(result, position)
-
def _merge_infobox(self, infobox):
add_infobox = True
infobox_id = infobox.get('id', None)
+ infobox['engines'] = set([infobox['engine']])
if infobox_id is not None:
parsed_url_infobox_id = urlparse(infobox_id)
for existingIndex in self.infoboxes:
@@ -289,12 +307,13 @@ class ResultContainer(object):
gresults = []
categoryPositions = {}
- for i, res in enumerate(results):
+ for res in results:
# FIXME : handle more than one category per engine
- res['category'] = engines[res['engine']].categories[0]
+ engine = engines[res['engine']]
+ res['category'] = engine.categories[0] if len(engine.categories) > 0 else ''
# FIXME : handle more than one category per engine
- category = engines[res['engine']].categories[0]\
+ category = res['category']\
+ ':' + res.get('template', '')\
+ ':' + ('img_src' if 'img_src' in res or 'thumbnail' in res else '')
diff --git a/searx/search.py b/searx/search.py
index 2469508..2209508 100644
--- a/searx/search.py
+++ b/searx/search.py
@@ -15,39 +15,30 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2013- by Adam Tauber, <asciimoo@gmail.com>
'''
+import typing
import gc
-import sys
import threading
from time import time
from uuid import uuid4
+from urllib.parse import urlparse
+from _thread import start_new_thread
-import six
-from flask_babel import gettext
import requests.exceptions
import searx.poolrequests as requests_lib
-from searx.engines import (
- categories, engines, settings
-)
+from searx.engines import engines, settings
from searx.answerers import ask
from searx.external_bang import get_bang_url
from searx.utils import gen_useragent
-from searx.query import RawTextQuery, SearchQuery, VALID_LANGUAGE_CODE
from searx.results import ResultContainer
from searx import logger
from searx.plugins import plugins
-from searx.exceptions import SearxParameterException
+from searx.exceptions import (SearxEngineAccessDeniedException, SearxEngineCaptchaException,
+ SearxEngineTooManyRequestsException,)
+from searx.metrology.error_recorder import record_exception, record_error
-try:
- from thread import start_new_thread
-except:
- from _thread import start_new_thread
-
-if sys.version_info[0] == 3:
- unicode = str
logger = logger.getChild('search')
-number_of_searches = 0
max_request_timeout = settings.get('outgoing', {}).get('max_request_timeout' or None)
if max_request_timeout is None:
logger.info('max_request_timeout={0}'.format(max_request_timeout))
@@ -56,9 +47,67 @@ else:
logger.info('max_request_timeout={0} second(s)'.format(max_request_timeout))
else:
logger.critical('outgoing.max_request_timeout if defined has to be float')
- from sys import exit
-
- exit(1)
+ import sys
+ sys.exit(1)
+
+
+class EngineRef:
+
+ __slots__ = 'name', 'category', 'from_bang'
+
+ def __init__(self, name: str, category: str, from_bang: bool=False):
+ self.name = name
+ self.category = category
+ self.from_bang = from_bang
+
+ def __repr__(self):
+ return "EngineRef({!r}, {!r}, {!r})".format(self.name, self.category, self.from_bang)
+
+ def __eq__(self, other):
+ return self.name == other.name and self.category == other.category and self.from_bang == other.from_bang
+
+
+class SearchQuery:
+ """container for all the search parameters (query, language, etc...)"""
+
+ __slots__ = 'query', 'engineref_list', 'categories', 'lang', 'safesearch', 'pageno', 'time_range',\
+ 'timeout_limit', 'external_bang'
+
+ def __init__(self,
+ query: str,
+ engineref_list: typing.List[EngineRef],
+ categories: typing.List[str],
+ lang: str,
+ safesearch: int,
+ pageno: int,
+ time_range: typing.Optional[str],
+ timeout_limit: typing.Optional[float]=None,
+ external_bang: typing.Optional[str]=None):
+ self.query = query
+ self.engineref_list = engineref_list
+ self.categories = categories
+ self.lang = lang
+ self.safesearch = safesearch
+ self.pageno = pageno
+ self.time_range = time_range
+ self.timeout_limit = timeout_limit
+ self.external_bang = external_bang
+
+ def __repr__(self):
+ return "SearchQuery({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})".\
+ format(self.query, self.engineref_list, self.categories, self.lang, self.safesearch,
+ self.pageno, self.time_range, self.timeout_limit, self.external_bang)
+
+ def __eq__(self, other):
+ return self.query == other.query\
+ and self.engineref_list == other.engineref_list\
+ and self.categories == self.categories\
+ and self.lang == other.lang\
+ and self.safesearch == other.safesearch\
+ and self.pageno == other.pageno\
+ and self.time_range == other.time_range\
+ and self.timeout_limit == other.timeout_limit\
+ and self.external_bang == other.external_bang
def send_http_request(engine, request_params):
@@ -67,18 +116,48 @@ def send_http_request(engine, request_params):
request_args = dict(
headers=request_params['headers'],
cookies=request_params['cookies'],
- verify=request_params['verify']
+ verify=request_params['verify'],
+ auth=request_params['auth']
)
+ # setting engine based proxies
+ if hasattr(engine, 'proxies'):
+ request_args['proxies'] = requests_lib.get_proxies(engine.proxies)
+
+ # max_redirects
+ max_redirects = request_params.get('max_redirects')
+ if max_redirects:
+ request_args['max_redirects'] = max_redirects
+
+ # soft_max_redirects
+ soft_max_redirects = request_params.get('soft_max_redirects', max_redirects or 0)
+
+ # raise_for_status
+ request_args['raise_for_httperror'] = request_params.get('raise_for_httperror', False)
+
# specific type of request (GET or POST)
if request_params['method'] == 'GET':
req = requests_lib.get
else:
req = requests_lib.post
- request_args['data'] = request_params['data']
+
+ request_args['data'] = request_params['data']
# send the request
- return req(request_params['url'], **request_args)
+ response = req(request_params['url'], **request_args)
+
+ # check soft limit of the redirect count
+ if len(response.history) > soft_max_redirects:
+ # unexpected redirect : record an error
+ # but the engine might still return valid results.
+ status_code = str(response.status_code or '')
+ reason = response.reason or ''
+ hostname = str(urlparse(response.url or '').netloc)
+ record_error(engine.name,
+ '{} redirects, maximum: {}'.format(len(response.history), soft_max_redirects),
+ (status_code, reason, hostname))
+
+ return response
def search_one_http_request(engine, query, request_params):
@@ -101,48 +180,6 @@ def search_one_http_request(engine, query, request_params):
return engine.response(response)
-def search_one_offline_request(engine, query, request_params):
- return engine.search(query, request_params)
-
-
-def search_one_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
- if engines[engine_name].offline:
- return search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit) # noqa
- return search_one_http_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit)
-
-
-def search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
- engine = engines[engine_name]
-
- try:
- search_results = search_one_offline_request(engine, query, request_params)
-
- if search_results:
- result_container.extend(engine_name, search_results)
-
- engine_time = time() - start_time
- result_container.add_timing(engine_name, engine_time, engine_time)
- with threading.RLock():
- engine.stats['engine_time'] += engine_time
- engine.stats['engine_time_count'] += 1
-
- except ValueError as e:
- record_offline_engine_stats_on_error(engine, result_container, start_time)
- logger.exception('engine {0} : invalid input : {1}'.format(engine_name, e))
- except Exception as e:
- record_offline_engine_stats_on_error(engine, result_container, start_time)
- result_container.add_unresponsive_engine(engine_name, 'unexpected crash', str(e))
- logger.exception('engine {0} : exception : {1}'.format(engine_name, e))
-
-
-def record_offline_engine_stats_on_error(engine, result_container, start_time):
- engine_time = time() - start_time
- result_container.add_timing(engine.name, engine_time, engine_time)
-
- with threading.RLock():
- engine.stats['errors'] += 1
-
-
def search_one_http_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
# set timeout for all HTTP requests
requests_lib.set_timeout_for_thread(timeout_limit, start_time=start_time)
@@ -154,6 +191,7 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
# suppose everything will be alright
requests_exception = False
+ suspended_time = None
try:
# send requests and parse the results
@@ -174,8 +212,9 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
# update stats with the total HTTP time
engine.stats['page_load_time'] += page_load_time
engine.stats['page_load_count'] += 1
-
except Exception as e:
+ record_exception(engine_name, e)
+
# Timing
engine_time = time() - start_time
page_load_time = requests_lib.get_time_for_thread()
@@ -186,38 +225,102 @@ def search_one_http_request_safe(engine_name, query, request_params, result_cont
engine.stats['errors'] += 1
if (issubclass(e.__class__, requests.exceptions.Timeout)):
- result_container.add_unresponsive_engine(engine_name, 'timeout')
+ result_container.add_unresponsive_engine(engine_name, 'HTTP timeout')
# requests timeout (connect or read)
logger.error("engine {0} : HTTP requests timeout"
"(search duration : {1} s, timeout: {2} s) : {3}"
.format(engine_name, engine_time, timeout_limit, e.__class__.__name__))
requests_exception = True
elif (issubclass(e.__class__, requests.exceptions.RequestException)):
- result_container.add_unresponsive_engine(engine_name, 'request exception')
+ result_container.add_unresponsive_engine(engine_name, 'HTTP error')
# other requests exception
logger.exception("engine {0} : requests exception"
"(search duration : {1} s, timeout: {2} s) : {3}"
.format(engine_name, engine_time, timeout_limit, e))
requests_exception = True
+ elif (issubclass(e.__class__, SearxEngineCaptchaException)):
+ result_container.add_unresponsive_engine(engine_name, 'CAPTCHA required')
+ logger.exception('engine {0} : CAPTCHA')
+ suspended_time = e.suspended_time # pylint: disable=no-member
+ elif (issubclass(e.__class__, SearxEngineTooManyRequestsException)):
+ result_container.add_unresponsive_engine(engine_name, 'too many requests')
+ logger.exception('engine {0} : Too many requests')
+ suspended_time = e.suspended_time # pylint: disable=no-member
+ elif (issubclass(e.__class__, SearxEngineAccessDeniedException)):
+ result_container.add_unresponsive_engine(engine_name, 'blocked')
+ logger.exception('engine {0} : Searx is blocked')
+ suspended_time = e.suspended_time # pylint: disable=no-member
else:
- result_container.add_unresponsive_engine(engine_name, 'unexpected crash', str(e))
+ result_container.add_unresponsive_engine(engine_name, 'unexpected crash')
# others errors
logger.exception('engine {0} : exception : {1}'.format(engine_name, e))
+ else:
+ if getattr(threading.current_thread(), '_timeout', False):
+ record_error(engine_name, 'Timeout')
- # suspend or not the engine if there are HTTP errors
+ # suspend the engine if there is an HTTP error
+ # or suspended_time is defined
with threading.RLock():
- if requests_exception:
+ if requests_exception or suspended_time:
# update continuous_errors / suspend_end_time
engine.continuous_errors += 1
- engine.suspend_end_time = time() + min(settings['search']['max_ban_time_on_fail'],
- engine.continuous_errors * settings['search']['ban_time_on_fail'])
+ if suspended_time is None:
+ suspended_time = min(settings['search']['max_ban_time_on_fail'],
+ engine.continuous_errors * settings['search']['ban_time_on_fail'])
+ engine.suspend_end_time = time() + suspended_time
else:
- # no HTTP error (perhaps an engine error)
- # anyway, reset the suspend variables
+ # reset the suspend variables
engine.continuous_errors = 0
engine.suspend_end_time = 0
+def record_offline_engine_stats_on_error(engine, result_container, start_time):
+ engine_time = time() - start_time
+ result_container.add_timing(engine.name, engine_time, engine_time)
+
+ with threading.RLock():
+ engine.stats['errors'] += 1
+
+
+def search_one_offline_request(engine, query, request_params):
+ return engine.search(query, request_params)
+
+
+def search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
+ engine = engines[engine_name]
+
+ try:
+ search_results = search_one_offline_request(engine, query, request_params)
+
+ if search_results:
+ result_container.extend(engine_name, search_results)
+
+ engine_time = time() - start_time
+ result_container.add_timing(engine_name, engine_time, engine_time)
+ with threading.RLock():
+ engine.stats['engine_time'] += engine_time
+ engine.stats['engine_time_count'] += 1
+
+ except ValueError as e:
+ record_exception(engine_name, e)
+ record_offline_engine_stats_on_error(engine, result_container, start_time)
+ logger.exception('engine {0} : invalid input : {1}'.format(engine_name, e))
+ except Exception as e:
+ record_exception(engine_name, e)
+ record_offline_engine_stats_on_error(engine, result_container, start_time)
+ result_container.add_unresponsive_engine(engine_name, 'unexpected crash', str(e))
+ logger.exception('engine {0} : exception : {1}'.format(engine_name, e))
+ else:
+ if getattr(threading.current_thread(), '_timeout', False):
+ record_error(engine_name, 'Timeout')
+
+
+def search_one_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit):
+ if engines[engine_name].offline:
+ return search_one_offline_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit) # noqa
+ return search_one_http_request_safe(engine_name, query, request_params, result_container, start_time, timeout_limit)
+
+
def search_multiple_requests(requests, result_container, start_time, timeout_limit):
search_id = uuid4().__str__()
@@ -227,6 +330,7 @@ def search_multiple_requests(requests, result_container, start_time, timeout_lim
args=(engine_name, query, request_params, result_container, start_time, timeout_limit),
name=search_id,
)
+ th._timeout = False
th._engine_name = engine_name
th.start()
@@ -234,7 +338,8 @@ def search_multiple_requests(requests, result_container, start_time, timeout_lim
if th.name == search_id:
remaining_time = max(0.0, timeout_limit - (time() - start_time))
th.join(remaining_time)
- if th.isAlive():
+ if th.is_alive():
+ th._timeout = True
result_container.add_unresponsive_engine(th._engine_name, 'timeout')
logger.warning('engine timeout: {0}'.format(th._engine_name))
@@ -247,265 +352,126 @@ def default_request_params():
'data': {},
'url': '',
'cookies': {},
- 'verify': True
+ 'verify': True,
+ 'auth': None,
+ 'raise_for_httperror': True
}
-# remove duplicate queries.
-# FIXME: does not fix "!music !soundcloud", because the categories are 'none' and 'music'
-def deduplicate_query_engines(query_engines):
- uniq_query_engines = {q["category"] + '|' + q["name"]: q for q in query_engines}
- return uniq_query_engines.values()
-
-
-def get_search_query_from_webapp(preferences, form):
- # no text for the query ?
- if not form.get('q'):
- raise SearxParameterException('q', '')
-
- # set blocked engines
- disabled_engines = preferences.engines.get_disabled()
-
- # parse query, if tags are set, which change
- # the serch engine or search-language
- raw_text_query = RawTextQuery(form['q'], disabled_engines)
- raw_text_query.parse_query()
-
- # set query
- query = raw_text_query.getSearchQuery()
-
- # get and check page number
- pageno_param = form.get('pageno', '1')
- if not pageno_param.isdigit() or int(pageno_param) < 1:
- raise SearxParameterException('pageno', pageno_param)
- query_pageno = int(pageno_param)
-
- # get language
- # set specific language if set on request, query or preferences
- # TODO support search with multible languages
- if len(raw_text_query.languages):
- query_lang = raw_text_query.languages[-1]
- elif 'language' in form:
- query_lang = form.get('language')
- else:
- query_lang = preferences.get_value('language')
-
- # check language
- if not VALID_LANGUAGE_CODE.match(query_lang):
- raise SearxParameterException('language', query_lang)
-
- # get safesearch
- if 'safesearch' in form:
- query_safesearch = form.get('safesearch')
- # first check safesearch
- if not query_safesearch.isdigit():
- raise SearxParameterException('safesearch', query_safesearch)
- query_safesearch = int(query_safesearch)
- else:
- query_safesearch = preferences.get_value('safesearch')
-
- # safesearch : second check
- if query_safesearch < 0 or query_safesearch > 2:
- raise SearxParameterException('safesearch', query_safesearch)
-
- # get time_range
- query_time_range = form.get('time_range')
-
- # check time_range
- if query_time_range not in ('None', None, '', 'day', 'week', 'month', 'year'):
- raise SearxParameterException('time_range', query_time_range)
-
- # query_engines
- query_engines = raw_text_query.engines
-
- # timeout_limit
- query_timeout = raw_text_query.timeout_limit
- if query_timeout is None and 'timeout_limit' in form:
- raw_time_limit = form.get('timeout_limit')
- if raw_time_limit in ['None', '']:
- raw_time_limit = None
- else:
- try:
- query_timeout = float(raw_time_limit)
- except ValueError:
- raise SearxParameterException('timeout_limit', raw_time_limit)
-
- # query_categories
- query_categories = []
-
- # if engines are calculated from query,
- # set categories by using that informations
- if query_engines and raw_text_query.specific:
- additional_categories = set()
- for engine in query_engines:
- if 'from_bang' in engine and engine['from_bang']:
- additional_categories.add('none')
- else:
- additional_categories.add(engine['category'])
- query_categories = list(additional_categories)
-
- # otherwise, using defined categories to
- # calculate which engines should be used
- else:
- # set categories/engines
- load_default_categories = True
- for pd_name, pd in form.items():
- if pd_name == 'categories':
- query_categories.extend(categ for categ in map(unicode.strip, pd.split(',')) if categ in categories)
- elif pd_name == 'engines':
- pd_engines = [{'category': engines[engine].categories[0],
- 'name': engine}
- for engine in map(unicode.strip, pd.split(',')) if engine in engines]
- if pd_engines:
- query_engines.extend(pd_engines)
- load_default_categories = False
- elif pd_name.startswith('category_'):
- category = pd_name[9:]
-
- # if category is not found in list, skip
- if category not in categories:
- continue
-
- if pd != 'off':
- # add category to list
- query_categories.append(category)
- elif category in query_categories:
- # remove category from list if property is set to 'off'
- query_categories.remove(category)
-
- if not load_default_categories:
- if not query_categories:
- query_categories = list(set(engine['category']
- for engine in query_engines))
- else:
- # if no category is specified for this search,
- # using user-defined default-configuration which
- # (is stored in cookie)
- if not query_categories:
- cookie_categories = preferences.get_value('categories')
- for ccateg in cookie_categories:
- if ccateg in categories:
- query_categories.append(ccateg)
-
- # if still no category is specified, using general
- # as default-category
- if not query_categories:
- query_categories = ['general']
-
- # using all engines for that search, which are
- # declared under the specific categories
- for categ in query_categories:
- query_engines.extend({'category': categ,
- 'name': engine.name}
- for engine in categories[categ]
- if (engine.name, categ) not in disabled_engines)
-
- query_engines = deduplicate_query_engines(query_engines)
- external_bang = raw_text_query.external_bang
-
- return (SearchQuery(query, query_engines, query_categories,
- query_lang, query_safesearch, query_pageno,
- query_time_range, query_timeout, preferences,
- external_bang=external_bang),
- raw_text_query)
-
-
-class Search(object):
+class Search:
"""Search information container"""
+ __slots__ = "search_query", "result_container", "start_time", "actual_timeout"
+
def __init__(self, search_query):
# init vars
- super(Search, self).__init__()
+ super().__init__()
self.search_query = search_query
self.result_container = ResultContainer()
+ self.start_time = None
self.actual_timeout = None
- # do search-request
- def search(self):
- global number_of_searches
-
- # Check if there is a external bang. After that we can stop because the search will terminate.
+ def search_external_bang(self):
+ """
+ Check if there is a external bang.
+ If yes, update self.result_container and return True
+ """
if self.search_query.external_bang:
self.result_container.redirect_url = get_bang_url(self.search_query)
# This means there was a valid bang and the
# rest of the search does not need to be continued
- if isinstance(self.result_container.redirect_url, six.string_types):
- return self.result_container
- # start time
- start_time = time()
-
- # answeres ?
+ if isinstance(self.result_container.redirect_url, str):
+ return True
+ return False
+
+ def search_answerers(self):
+ """
+ Check if an answer return a result.
+ If yes, update self.result_container and return True
+ """
answerers_results = ask(self.search_query)
if answerers_results:
for results in answerers_results:
self.result_container.extend('answer', results)
- return self.result_container
+ return True
+ return False
- # init vars
- requests = []
+ def _is_accepted(self, engine_name, engine):
+ # skip suspended engines
+ if engine.suspend_end_time >= time():
+ logger.debug('Engine currently suspended: %s', engine_name)
+ return False
- # increase number of searches
- number_of_searches += 1
+ # if paging is not supported, skip
+ if self.search_query.pageno > 1 and not engine.paging:
+ return False
- # set default useragent
- # user_agent = request.headers.get('User-Agent', '')
- user_agent = gen_useragent()
+ # if time_range is not supported, skip
+ if self.search_query.time_range and not engine.time_range_support:
+ return False
- search_query = self.search_query
+ return True
- # max of all selected engine timeout
- default_timeout = 0
+ def _get_params(self, engineref, user_agent):
+ if engineref.name not in engines:
+ return None, None
- # start search-reqest for all selected engines
- for selected_engine in search_query.engines:
- if selected_engine['name'] not in engines:
- continue
+ engine = engines[engineref.name]
- engine = engines[selected_engine['name']]
+ if not self._is_accepted(engineref.name, engine):
+ return None, None
- if not search_query.preferences.validate_token(engine):
- continue
+ # set default request parameters
+ request_params = {}
+ if not engine.offline:
+ request_params = default_request_params()
+ request_params['headers']['User-Agent'] = user_agent
- # skip suspended engines
- if engine.suspend_end_time >= time():
- logger.debug('Engine currently suspended: %s', selected_engine['name'])
- continue
+ if hasattr(engine, 'language') and engine.language:
+ request_params['language'] = engine.language
+ else:
+ request_params['language'] = self.search_query.lang
- # if paging is not supported, skip
- if search_query.pageno > 1 and not engine.paging:
- continue
+ request_params['safesearch'] = self.search_query.safesearch
+ request_params['time_range'] = self.search_query.time_range
- # if time_range is not supported, skip
- if search_query.time_range and not engine.time_range_support:
- continue
+ request_params['category'] = engineref.category
+ request_params['pageno'] = self.search_query.pageno
- # set default request parameters
- request_params = {}
- if not engine.offline:
- request_params = default_request_params()
- request_params['headers']['User-Agent'] = user_agent
+ with threading.RLock():
+ engine.stats['sent_search_count'] += 1
- if hasattr(engine, 'language') and engine.language:
- request_params['language'] = engine.language
- else:
- request_params['language'] = search_query.lang
+ return request_params, engine.timeout
- request_params['safesearch'] = search_query.safesearch
- request_params['time_range'] = search_query.time_range
+ # do search-request
+ def _get_requests(self):
+ # init vars
+ requests = []
+
+ # set default useragent
+ # user_agent = request.headers.get('User-Agent', '')
+ user_agent = gen_useragent()
- request_params['category'] = selected_engine['category']
- request_params['pageno'] = search_query.pageno
+ # max of all selected engine timeout
+ default_timeout = 0
+
+ # start search-reqest for all selected engines
+ for engineref in self.search_query.engineref_list:
+ # set default request parameters
+ request_params, engine_timeout = self._get_params(engineref, user_agent)
+ if request_params is None:
+ continue
# append request to list
- requests.append((selected_engine['name'], search_query.query, request_params))
+ requests.append((engineref.name, self.search_query.query, request_params))
# update default_timeout
- default_timeout = max(default_timeout, engine.timeout)
+ default_timeout = max(default_timeout, engine_timeout)
# adjust timeout
- self.actual_timeout = default_timeout
+ actual_timeout = default_timeout
query_timeout = self.search_query.timeout_limit
if max_request_timeout is None and query_timeout is None:
@@ -513,37 +479,57 @@ class Search(object):
pass
elif max_request_timeout is None and query_timeout is not None:
# No max, but user query: From user query except if above default
- self.actual_timeout = min(default_timeout, query_timeout)
+ actual_timeout = min(default_timeout, query_timeout)
elif max_request_timeout is not None and query_timeout is None:
# Max, no user query: Default except if above max
- self.actual_timeout = min(default_timeout, max_request_timeout)
+ actual_timeout = min(default_timeout, max_request_timeout)
elif max_request_timeout is not None and query_timeout is not None:
# Max & user query: From user query except if above max
- self.actual_timeout = min(query_timeout, max_request_timeout)
+ actual_timeout = min(query_timeout, max_request_timeout)
logger.debug("actual_timeout={0} (default_timeout={1}, ?timeout_limit={2}, max_request_timeout={3})"
- .format(self.actual_timeout, default_timeout, query_timeout, max_request_timeout))
+ .format(actual_timeout, default_timeout, query_timeout, max_request_timeout))
+
+ return requests, actual_timeout
+
+ def search_standard(self):
+ """
+ Update self.result_container, self.actual_timeout
+ """
+ requests, self.actual_timeout = self._get_requests()
# send all search-request
if requests:
- search_multiple_requests(requests, self.result_container, start_time, self.actual_timeout)
+ search_multiple_requests(requests, self.result_container, self.start_time, self.actual_timeout)
start_new_thread(gc.collect, tuple())
# return results, suggestions, answers and infoboxes
+ return True
+
+ # do search-request
+ def search(self):
+ self.start_time = time()
+
+ if not self.search_external_bang():
+ if not self.search_answerers():
+ self.search_standard()
+
return self.result_container
class SearchWithPlugins(Search):
"""Similar to the Search class but call the plugins."""
+ __slots__ = 'ordered_plugin_list', 'request'
+
def __init__(self, search_query, ordered_plugin_list, request):
- super(SearchWithPlugins, self).__init__(search_query)
+ super().__init__(search_query)
self.ordered_plugin_list = ordered_plugin_list
self.request = request
def search(self):
if plugins.call(self.ordered_plugin_list, 'pre_search', self.request, self):
- super(SearchWithPlugins, self).search()
+ super().search()
plugins.call(self.ordered_plugin_list, 'post_search', self.request, self)
diff --git a/searx/settings.yml b/searx/settings.yml
index 8df151b..e263e3a 100644
--- a/searx/settings.yml
+++ b/searx/settings.yml
@@ -16,6 +16,13 @@ server:
base_url : False # Set custom base_url. Possible values: False or "https://your.custom.host/location/"
image_proxy : False # Proxying image results through searx
http_protocol_version : "1.0" # 1.0 and 1.1 are supported
+ method: "POST" # POST queries are more secure as they don't show up in history but may cause problems when using Firefox containers
+ default_http_headers:
+ X-Content-Type-Options : nosniff
+ X-XSS-Protection : 1; mode=block
+ X-Download-Options : noopen
+ X-Robots-Tag : noindex, nofollow
+ Referrer-Policy : no-referrer
ui:
static_path : "" # Custom static path - leave it blank if you didn't change
@@ -24,6 +31,7 @@ ui:
default_locale : "" # Default interface locale - leave blank to detect from browser information or use codes from the 'locales' config section
theme_args :
oscar_style : logicodev # default style of oscar
+# results_on_new_tab: False # Open result links in a new tab by default
# categories_order :
# - general
# - files
@@ -31,6 +39,15 @@ ui:
# - it
# - science
+# Lock arbitrary settings on the preferences page.
+# To find the ID of the user setting you want to lock, check
+# the ID of the form on the page "preferences".
+#preferences:
+# lock:
+# - language
+# - autocomplete
+# - method
+
# searx supports result proxification using an external service: https://github.com/asciimoo/morty
# uncomment below section if you have running morty proxy
# the key is base64 encoded (keep the !!binary notation)
@@ -46,17 +63,35 @@ outgoing: # communication with search engines
pool_connections : 100 # Number of different hosts
pool_maxsize : 10 # Number of simultaneous requests by host
# uncomment below section if you want to use a proxy
-# see http://docs.python-requests.org/en/latest/user/advanced/#proxies
-# SOCKS proxies are also supported: see http://requests.readthedocs.io/en/master/user/advanced/#socks
-# proxies :
-# http : http://127.0.0.1:8080
-# https: http://127.0.0.1:8080
+# see https://2.python-requests.org/en/latest/user/advanced/#proxies
+# SOCKS proxies are also supported: see https://2.python-requests.org/en/latest/user/advanced/#socks
+# proxies:
+# http:
+# - http://proxy1:8080
+# - http://proxy2:8080
+# https:
+# - http://proxy1:8080
+# - http://proxy2:8080
# uncomment below section only if you have more than one network interface
# which can be the source of outgoing search requests
# source_ips:
# - 1.1.1.1
# - 1.1.1.2
+# External plugin configuration
+# See http://searx.github.io/searx/dev/plugins.html for more details
+#
+# plugins:
+# - plugin1
+# - plugin2
+# - ...
+
+# uncomment below section if you want to configure which plugin is enabled by default
+#
+# enabled_plugins:
+# - "HTTPS rewrite"
+# - ...
+
engines:
- name: apk mirror
engine: apkmirror
@@ -64,6 +99,12 @@ engines:
shortcut: apkm
disabled: True
+# Requires Tor
+ - name : ahmia
+ engine : ahmia
+ categories : onions
+ shortcut : ah
+
- name : arch linux wiki
engine : archlinux
shortcut : al
@@ -160,7 +201,7 @@ engines:
- name : deviantart
engine : deviantart
shortcut : da
- timeout: 3.0
+ timeout : 3.0
- name : ddg definitions
engine : duckduckgo_definitions
@@ -192,6 +233,20 @@ engines:
shortcut : ew
disabled : True
+# - name : elasticsearch
+# shortcut : es
+# engine : elasticsearch
+# base_url : http://localhost:9200
+# username : elastic
+# password : changeme
+# index : my-index
+# # available options: match, simple_query_string, term, terms, custom
+# query_type : match
+# # if query_type is set to custom, provide your query here
+# #custom_query_json: {"query":{"match_all": {}}}
+# #show_metadata: False
+# disabled : True
+
- name : wikidata
engine : wikidata
shortcut : wd
@@ -225,9 +280,16 @@ engines:
shortcut : et
disabled : True
+# - name : ebay
+# engine : ebay
+# shortcut : eb
+# disabled : True
+# timeout: 5
+
- name : 1x
engine : www1x
shortcut : 1x
+ timeout : 3.0
disabled : True
- name : fdroid
@@ -293,6 +355,19 @@ engines:
engine : github
shortcut : gh
+ # This a Gitea service. If you would like to use a different instance,
+ # change codeberg.org to URL of the desired Gitea host. Or you can create
+ # a new engine by copying this and changing the name, shortcut and search_url.
+ - name : codeberg
+ engine : json_engine
+ search_url : https://codeberg.org/api/v1/repos/search?q={query}&limit=10
+ url_query : html_url
+ title_query : name
+ content_query : description
+ categories : it
+ shortcut : cb
+ disabled : True
+
- name : google
engine : google
shortcut : go
@@ -406,6 +481,7 @@ engines:
base_url : 'https://invidio.us/'
shortcut: iv
timeout : 5.0
+ disabled : True
- name: kickass
engine : kickass
@@ -415,7 +491,7 @@ engines:
- name : library genesis
engine : xpath
- search_url : https://libgen.is/search.php?req={query}
+ search_url : http://libgen.rs/search.php?req={query}
url_xpath : //a[contains(@href,"bookfi.net")]/@href
title_xpath : //a[contains(@href,"book/")]/text()[1]
content_xpath : //td/a[1][contains(@href,"=author")]/text()
@@ -428,11 +504,24 @@ engines:
engine : xpath
search_url : https://lobste.rs/search?utf8=%E2%9C%93&q={query}&what=stories&order=relevance
results_xpath : //li[contains(@class, "story")]
- url_xpath : .//span[@class="link"]/a/@href
- title_xpath : .//span[@class="link"]/a
+ url_xpath : .//a[@class="u-url"]/@href
+ title_xpath : .//a[@class="u-url"]
content_xpath : .//a[@class="domain"]
categories : it
shortcut : lo
+ timeout : 3.0
+ disabled: True
+
+ - name : metager
+ engine : xpath
+ paging : False
+ search_url : https://metager.org/meta/meta.ger3?eingabe={query}
+ url_xpath : //div[@class="result-subheadline"]/a/@href
+ title_xpath : //div[@class="result-headline"]/h2/@title
+ content_xpath : //div[@class="result-description"]/text()
+ categories : general
+ shortcut : mg
+ disabled : True
- name : microsoft academic
engine : microsoft_academic
@@ -457,6 +546,11 @@ engines:
timeout: 5.0
shortcut : npm
+# Requires Tor
+ - name : not evil
+ engine : not_evil
+ shortcut : ne
+
- name : nyaa
engine : nyaa
shortcut : nt
@@ -492,6 +586,11 @@ engines:
shortcut : oap
timeout: 5.0
+# - name : opensemanticsearch
+# engine : opensemantic
+# shortcut : oss
+# base_url : 'http://localhost:8983/solr/opensemanticsearch/'
+
- name : openstreetmap
engine : openstreetmap
shortcut : osm
@@ -522,7 +621,8 @@ engines:
- name : piratebay
engine : piratebay
shortcut : tpb
- url: https://pirateproxy.red/
+ # You may need to change this URL to a proxy if piratebay is blocked in your country
+ url: https://thepiratebay.org/
timeout : 3.0
- name : pubmed
@@ -547,10 +647,27 @@ engines:
shortcut : qwn
categories : news
- - name : qwant social
- engine : qwant
- shortcut : qws
- categories : social media
+# - name: library
+# engine: recoll
+# shortcut: lib
+# base_url: 'https://recoll.example.org/'
+# search_dir: ''
+# mount_prefix: /export
+# dl_prefix: 'https://download.example.org'
+# timeout: 30.0
+# categories: files
+# disabled: True
+
+# - name: recoll library reference
+# engine: recoll
+# base_url: 'https://recoll.example.org/'
+# search_dir: reference
+# mount_prefix: /export
+# dl_prefix: 'https://download.example.org'
+# shortcut: libr
+# timeout: 30.0
+# categories: files
+# disabled: True
- name : reddit
engine : reddit
@@ -565,6 +682,10 @@ engines:
# engine : scanr_structures
# disabled : True
+ - name: sepiasearch
+ engine: sepiasearch
+ shortcut: sep
+
- name : soundcloud
engine : soundcloud
shortcut : sc
@@ -573,10 +694,6 @@ engines:
engine : stackoverflow
shortcut : st
- - name : searchcode doc
- engine : searchcode_doc
- shortcut : scd
-
- name : searchcode code
engine : searchcode_code
shortcut : scc
@@ -631,9 +748,17 @@ engines:
url: https://torrentz2.eu/
timeout : 3.0
- - name : twitter
- engine : twitter
- shortcut : tw
+# Requires Tor
+ - name : torch
+ engine : xpath
+ paging : True
+ search_url : http://xmh57jrknzkhv6y3ls3ubitzfqnkrwxhopf5aygthi7d6rplyvk3noyd.onion/cgi-bin/omega/omega?P={query}&DEFAULTOP=and
+ results_xpath : //table//tr
+ url_xpath : ./td[2]/a
+ title_xpath : ./td[2]/b
+ content_xpath : ./td[2]/small
+ categories : onions
+ shortcut : tch
# maybe in a fun category
# - name : uncyclopedia
@@ -679,6 +804,14 @@ engines:
# Or you can use the html non-stable engine, activated by default
engine : youtube_noapi
+ # tmp suspended: Cloudflare CAPTCHA
+ #- name : yggtorrent
+ # engine : yggtorrent
+ # shortcut : ygg
+ # url: https://www2.yggtorrent.si/
+ # disabled : True
+ # timeout : 4.0
+
- name : dailymotion
engine : dailymotion
shortcut : dm
@@ -822,10 +955,19 @@ engines:
page_size : 10
disabled : True
- - name : seedpeer
- shortcut : speu
- engine : seedpeer
- categories: files, music, videos
+ - name : naver
+ shortcut: nvr
+ engine: xpath
+ paging : True
+ search_url : https://search.naver.com/search.naver?where=webkr&sm=osp_hty&ie=UTF-8&query={query}&start={pageno}
+ results_xpath: /html/body//ul[@id="elThumbnailResultArea"]/li
+ url_xpath : ./dl/dt/a[@class="title_link"]/@href
+ title_xpath : ./dl/dt/a[@class="title_link"]
+ content_xpath : ./dl/dd[@class="sh_web_passage"]
+ suggestion_xpath : /html/body//div[@class="sp_keyword section"]//a
+ first_page_num : 1
+ page_size : 10
+ disabled : True
- name : rubygems
shortcut: rbg
@@ -841,6 +983,14 @@ engines:
categories: it
disabled : True
+ - name : peertube
+ engine: peertube
+ shortcut: ptb
+ paging : True
+ base_url : https://peer.tube/
+ categories: videos
+ disabled : True
+
# - name : yacy
# engine : yacy
# shortcut : ya
@@ -855,6 +1005,77 @@ engines:
# shortcut : uw
# base_url : 'http://doc.ubuntu-fr.org'
+# Be careful when enabling this engine if you are
+# running a public instance. Do not expose any sensitive
+# information. You can restrict access by configuring a list
+# of access tokens under tokens.
+# - name: git grep
+# engine: command
+# command: ['git', 'grep', '{{QUERY}}']
+# shortcut: gg
+# tokens: []
+# disabled: True
+# delimiter:
+# chars: ':'
+# keys: ['filepath', 'code']
+
+# Be careful when enabling this engine if you are
+# running a public instance. Do not expose any sensitive
+# information. You can restrict access by configuring a list
+# of access tokens under tokens.
+# - name: locate
+# engine: command
+# command: ['locate', '{{QUERY}}']
+# shortcut: loc
+# tokens: []
+# disabled: True
+# delimiter:
+# chars: ' '
+# keys: ['line']
+
+# Be careful when enabling this engine if you are
+# running a public instance. Do not expose any sensitive
+# information. You can restrict access by configuring a list
+# of access tokens under tokens.
+# - name: find
+# engine: command
+# command: ['find', '.', '-name', '{{QUERY}}']
+# query_type: path
+# shortcut: fnd
+# tokens: []
+# disabled: True
+# delimiter:
+# chars: ' '
+# keys: ['line']
+
+# Be careful when enabling this engine if you are
+# running a public instance. Do not expose any sensitive
+# information. You can restrict access by configuring a list
+# of access tokens under tokens.
+# - name: pattern search in files
+# engine: command
+# command: ['fgrep', '{{QUERY}}']
+# shortcut: fgr
+# tokens: []
+# disabled: True
+# delimiter:
+# chars: ' '
+# keys: ['line']
+
+# Be careful when enabling this engine if you are
+# running a public instance. Do not expose any sensitive
+# information. You can restrict access by configuring a list
+# of access tokens under tokens.
+# - name: regex search in files
+# engine: command
+# command: ['grep', '{{QUERY}}']
+# shortcut: gr
+# tokens: []
+# disabled: True
+# delimiter:
+# chars: ' '
+# keys: ['line']
+
locales:
en : English
ar : العَرَبِيَّة (Arabic)
@@ -905,7 +1126,7 @@ locales:
doi_resolvers :
oadoi.org : 'https://oadoi.org/'
doi.org : 'https://doi.org/'
- doai.io : 'https://doai.io/'
+ doai.io : 'https://dissem.in/'
sci-hub.tw : 'https://sci-hub.tw/'
-default_doi_resolver : 'oadoi.org'
+default_doi_resolver : 'sci-hub.tw'
diff --git a/searx/settings_loader.py b/searx/settings_loader.py
new file mode 100644
index 0000000..5dbeb4a
--- /dev/null
+++ b/searx/settings_loader.py
@@ -0,0 +1,132 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+
+from os import environ
+from os.path import dirname, join, abspath, isfile
+from collections.abc import Mapping
+from itertools import filterfalse
+
+import yaml
+
+from searx.exceptions import SearxSettingsException
+
+
+searx_dir = abspath(dirname(__file__))
+
+
+def check_settings_yml(file_name):
+ if isfile(file_name):
+ return file_name
+ return None
+
+
+def load_yaml(file_name):
+ try:
+ with open(file_name, 'r', encoding='utf-8') as settings_yaml:
+ return yaml.safe_load(settings_yaml)
+ except IOError as e:
+ raise SearxSettingsException(e, file_name)
+ except yaml.YAMLError as e:
+ raise SearxSettingsException(e, file_name)
+
+
+def get_default_settings_path():
+ return check_settings_yml(join(searx_dir, 'settings.yml'))
+
+
+def get_user_settings_path():
+ # find location of settings.yml
+ if 'SEARX_SETTINGS_PATH' in environ:
+ # if possible set path to settings using the
+ # enviroment variable SEARX_SETTINGS_PATH
+ return check_settings_yml(environ['SEARX_SETTINGS_PATH'])
+
+ # if not, get it from searx code base or last solution from /etc/searx
+ return check_settings_yml('/etc/searx/settings.yml')
+
+
+def update_dict(default_dict, user_dict):
+ for k, v in user_dict.items():
+ if isinstance(v, Mapping):
+ default_dict[k] = update_dict(default_dict.get(k, {}), v)
+ else:
+ default_dict[k] = v
+ return default_dict
+
+
+def update_settings(default_settings, user_settings):
+ # merge everything except the engines
+ for k, v in user_settings.items():
+ if k not in ('use_default_settings', 'engines'):
+ if k in default_settings:
+ update_dict(default_settings[k], v)
+ else:
+ default_settings[k] = v
+
+ # parse the engines
+ remove_engines = None
+ keep_only_engines = None
+ use_default_settings = user_settings.get('use_default_settings')
+ if isinstance(use_default_settings, dict):
+ remove_engines = use_default_settings.get('engines', {}).get('remove')
+ keep_only_engines = use_default_settings.get('engines', {}).get('keep_only')
+
+ if 'engines' in user_settings or remove_engines is not None or keep_only_engines is not None:
+ engines = default_settings['engines']
+
+ # parse "use_default_settings.engines.remove"
+ if remove_engines is not None:
+ engines = list(filterfalse(lambda engine: (engine.get('name')) in remove_engines, engines))
+
+ # parse "use_default_settings.engines.keep_only"
+ if keep_only_engines is not None:
+ engines = list(filter(lambda engine: (engine.get('name')) in keep_only_engines, engines))
+
+ # parse "engines"
+ user_engines = user_settings.get('engines')
+ if user_engines:
+ engines_dict = dict((definition['name'], definition) for definition in engines)
+ for user_engine in user_engines:
+ default_engine = engines_dict.get(user_engine['name'])
+ if default_engine:
+ update_dict(default_engine, user_engine)
+ else:
+ engines.append(user_engine)
+
+ # store the result
+ default_settings['engines'] = engines
+
+ return default_settings
+
+
+def is_use_default_settings(user_settings):
+ use_default_settings = user_settings.get('use_default_settings')
+ if use_default_settings is True:
+ return True
+ if isinstance(use_default_settings, dict):
+ return True
+ if use_default_settings is False or use_default_settings is None:
+ return False
+ raise ValueError('Invalid value for use_default_settings')
+
+
+def load_settings(load_user_setttings=True):
+ default_settings_path = get_default_settings_path()
+ user_settings_path = get_user_settings_path()
+ if user_settings_path is None or not load_user_setttings:
+ # no user settings
+ return (load_yaml(default_settings_path),
+ 'load the default settings from {}'.format(default_settings_path))
+
+ # user settings
+ user_settings = load_yaml(user_settings_path)
+ if is_use_default_settings(user_settings):
+ # the user settings are merged with the default configuration
+ default_settings = load_yaml(default_settings_path)
+ update_settings(default_settings, user_settings)
+ return (default_settings,
+ 'merge the default settings ( {} ) and the user setttings ( {} )'
+ .format(default_settings_path, user_settings_path))
+
+ # the user settings, fully replace the default configuration
+ return (user_settings,
+ 'load the user settings from {}'.format(user_settings_path))
diff --git a/searx/settings_robot.yml b/searx/settings_robot.yml
index 33e7626..05c8eeb 100644
--- a/searx/settings_robot.yml
+++ b/searx/settings_robot.yml
@@ -8,7 +8,7 @@ search:
server:
port : 11111
bind_address : 127.0.0.1
- secret_key : "ultrasecretkey" # change this!
+ secret_key : "changedultrasecretkey"
base_url : False
http_protocol_version : "1.0"
@@ -17,6 +17,9 @@ ui:
templates_path : ""
default_theme : oscar
+preferences:
+ lock: []
+
outgoing:
request_timeout : 1.0 # seconds
useragent_suffix : ""
@@ -39,7 +42,7 @@ locales:
doi_resolvers :
oadoi.org : 'https://oadoi.org/'
doi.org : 'https://doi.org/'
- doai.io : 'https://doai.io/'
+ doai.io : 'https://dissem.in/'
sci-hub.tw : 'https://sci-hub.tw/'
-default_doi_resolver : 'oadoi.org'
+default_doi_resolver : 'sci-hub.tw'
diff --git a/searx/static/plugins/external_plugins/.gitignore b/searx/static/plugins/external_plugins/.gitignore
new file mode 100644
index 0000000..94548af
--- /dev/null
+++ b/searx/static/plugins/external_plugins/.gitignore
@@ -0,0 +1,3 @@
+*
+*/
+!.gitignore
diff --git a/searx/static/plugins/js/infinite_scroll.js b/searx/static/plugins/js/infinite_scroll.js
index 9930880..cd80965 100644
--- a/searx/static/plugins/js/infinite_scroll.js
+++ b/searx/static/plugins/js/infinite_scroll.js
@@ -9,7 +9,7 @@ function loadNextPage() {
$('#pagination').html('<div class="loading-spinner"></div>');
$.ajax({
type: "POST",
- url: './',
+ url: $('#search_form').prop('action'),
data: formData,
dataType: 'html',
success: function(data) {
diff --git a/searx/static/plugins/js/open_results_on_new_tab.js b/searx/static/plugins/js/open_results_on_new_tab.js
deleted file mode 100644
index 99ef382..0000000
--- a/searx/static/plugins/js/open_results_on_new_tab.js
+++ /dev/null
@@ -1,3 +0,0 @@
-$(document).ready(function() {
- $('.result_header > a').attr('target', '_blank');
-});
diff --git a/searx/static/themes/oscar/gruntfile.js b/searx/static/themes/oscar/gruntfile.js
index 606b6bc..b18c0bc 100644
--- a/searx/static/themes/oscar/gruntfile.js
+++ b/searx/static/themes/oscar/gruntfile.js
@@ -13,6 +13,7 @@ module.exports = function(grunt) {
},
uglify: {
options: {
+ sourceMap: true,
banner: '/*! oscar/searx.min.js | <%= grunt.template.today("dd-mm-yyyy") %> | <%= process.env.GIT_URL %> */\n'
},
dist: {
diff --git a/searx/static/themes/oscar/js/searx.js b/searx/static/themes/oscar/js/searx.js
index 040d57b..8208ce4 100644
--- a/searx/static/themes/oscar/js/searx.js
+++ b/searx/static/themes/oscar/js/searx.js
@@ -124,6 +124,13 @@ $(document).ready(function(){
$('#q.autofocus').focus();
/**
+ * Empty search bar when click on reset button
+ */
+ $("#clear_search").click(function () {
+ document.getElementById("q").value = "";
+ });
+
+ /**
* select full content on click if class="select-all-on-click"
*/
$(".select-all-on-click").click(function () {
@@ -204,6 +211,17 @@ $(document).ready(function(){
$(a.target).parent().attr("aria-selected", "true");
});
});
+;window.addEventListener('load', function() {
+ // Hide infobox toggle if shrunk size already fits all content.
+ $('.infobox').each(function() {
+ var infobox_body = $(this).find('.infobox_body');
+ var total_height = infobox_body.prop('scrollHeight') + infobox_body.find('img.infobox_part').height();
+ var max_height = infobox_body.css('max-height').replace('px', '');
+ if (total_height <= max_height) {
+ $(this).find('.infobox_toggle').hide();
+ }
+ });
+});
;/**
* searx is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
diff --git a/searx/static/themes/oscar/js/searx.min.js.map b/searx/static/themes/oscar/js/searx.min.js.map
new file mode 100644
index 0000000..4dd22d6
--- /dev/null
+++ b/searx/static/themes/oscar/js/searx.min.js.map
@@ -0,0 +1 @@
+{"version":3,"sources":["searx.js"],"names":["requirejs","config","baseUrl","paths","app","window","searx","d","script","currentScript","scripts","getElementsByTagName","length","autocompleter","getAttribute","method","document","searchResults","Bloodhound","datumTokenizer","tokenizers","obj","whitespace","queryTokenizer","remote","initialize","$","ready","original_search_value","on","e","which","val","typeahead","name","displayKey","result","source","ttAdapter","bind","ev","suggestion","submit","focus","click","getElementById","value","this","select","btnTextCollapsed","data","btnTextNotCollapsed","hasClass","new_html","html","replace","btnClass","btnLabelDefault","btnLabelToggled","toggleClass","target","iframe_load","srctest","attr","undefined","dblclick","prop","addClass","removeClass","removeAttr","checked","a","parents","children","parent","addEventListener","each","infobox_body","find","height","css","hide","event","overpass_url","query_start","query_end","osm_id","osm_type","result_table","result_table_loadicon","osm_ignore_tags","query","ajax","done","elements","element","newHtml","row","tags","indexOf","substring","fail","could_not_load","off","leaflet_target","map_lon","map_lat","map_zoom","map_boundingbox","map_geojson","require","leaflet","southWest","L","latLng","northEast","map_bounds","latLngBounds","Icon","Default","imagePath","map","osmMapnikUrl","osmMapnikAttrib","osmMapnik","TileLayer","minZoom","maxZoom","attribution","osmWikimediaUrl","osmWikimediaAttrib","setTimeout","fitBounds","setView","LatLng","addLayer","baseLayers","OSM Mapnik","control","layers","addTo","geoJson"],"mappings":";;AAiBAA,UAAUC,QACNC,QAAS,2BACTC,OACIC,IAAK,YAmBbC,OAAOC,MAAQ,SAAUC,GACrB,YAGA,IAAIC,GAASD,EAAEE,eAAkB,WAC7B,GAAIC,GAAUH,EAAEI,qBAAqB,SACrC,OAAOD,GAAQA,EAAQE,OAAS,KAGpC,QACIC,cAA6D,SAA9CL,EAAOM,aAAa,sBACnCC,OAAQP,EAAOM,aAAa,iBAEjCE,UAkBAV,MAAMO,gBACLP,MAAMW,cAAgB,GAAIC,aACtBC,eAAgBD,WAAWE,WAAWC,IAAIC,WAAW,SACrDC,eAAgBL,WAAWE,WAAWE,WACtCE,OAAQ,6BAEZlB,MAAMW,cAAcQ,cAGxBC,EAAEV,UAAUW,MAAM,WACd,GAAIC,GAAwB,EACzBtB,OAAMO,gBACXa,EAAE,MAAMG,GAAG,UAAW,SAASC,GAChB,IAAXA,EAAEC,QACQH,EAAwBF,EAAE,MAAMM,SAGxCN,EAAE,MAAMO,UAAU,MACdC,KAAM,iBACNC,WAAY,SAASC,GACjB,MAAOA,IAEXC,OAAQ/B,MAAMW,cAAcqB,cAEhCZ,EAAE,MAAMa,KAAK,qBAAsB,SAASC,EAAIC,GACzCb,GACCF,EAAE,MAAMM,IAAIJ,GAEhBF,EAAE,gBAAgBgB,cAqB9BhB,EAAEV,UAAUW,MAAM,WAIdD,EAAE,gBAAgBiB,QAKlBjB,EAAE,iBAAiBkB,MAAM,WAC5B5B,SAAS6B,eAAe,KAAKC,MAAQ,KAMlCpB,EAAE,wBAAwBkB,MAAM,WAC5BlB,EAAEqB,MAAMC,WAMZtB,EAAE,iBAAiBkB,MAAM,WACrB,GAAIK,GAAmBvB,EAAEqB,MAAMG,KAAK,sBAChCC,EAAsBzB,EAAEqB,MAAMG,KAAK,yBAEf,MAArBD,GAAmD,KAAxBE,IACvBzB,EAAEqB,MAAMK,SAAS,aAChBC,SAAW3B,EAAEqB,MAAMO,OAAOC,QAAQN,EAAkBE,GAEpDE,SAAW3B,EAAEqB,MAAMO,OAAOC,QAAQJ,EAAqBF,GAE3DvB,EAAEqB,MAAMO,KAAKD,aAOrB3B,EAAE,oBAAoBkB,MAAM,WACxB,GAAIY,GAAW,OAAS9B,EAAEqB,MAAMG,KAAK,aACjCO,EAAkB/B,EAAEqB,MAAMG,KAAK,qBAC/BQ,EAAkBhC,EAAEqB,MAAMG,KAAK,oBACZ,MAApBQ,IACIhC,EAAEqB,MAAMK,SAAS,eAChBC,SAAW3B,EAAEqB,MAAMO,OAAOC,QAAQE,EAAiBC,GAEnDL,SAAW3B,EAAEqB,MAAMO,OAAOC,QAAQG,EAAiBD,GAEvD/B,EAAEqB,MAAMO,KAAKD,WAEjB3B,EAAEqB,MAAMY,YAAYH,GACpB9B,EAAEqB,MAAMY,YAAY,iBAMxBjC,EAAE,iBAAiBkB,MAAM,WACrB,GAAIgB,GAASlC,EAAEqB,MAAMG,KAAK,UACtBW,EAAcnC,EAAEkC,EAAS,aACzBE,EAAUD,EAAYE,KAAK,WAChBC,KAAZF,IAAqC,IAAZA,GACxBD,EAAYE,KAAK,MAAOF,EAAYX,KAAK,UAOjDxB,EAAE,WAAWuC,SAAS,WACtB,GAAIT,GAAW,OAAS9B,EAAEqB,MAAMG,KAAK,YAC9BxB,GAAEqB,MAAMK,SAAS,gBAChB1B,EAAE,mBAAmBqC,KAAK,UAAW,WACrCrC,EAAE,mBAAmBwC,KAAK,WAAW,GACrCxC,EAAE,WAAWyC,SAASX,GACtB9B,EAAE,WAAWyC,SAAS,UACtBzC,EAAE,WAAW0C,YAAY,iBAEzB1C,EAAE,mBAAmBqC,KAAK,UAAW,IACrCrC,EAAE,mBAAmB2C,WAAW,WAChC3C,EAAE,mBAAmB4C,SAAU,EAC/B5C,EAAE,WAAW0C,YAAYZ,GACzB9B,EAAE,WAAW0C,YAAY,UACzB1C,EAAE,WAAWyC,SAAS,kBAG9BzC,EAAE,aAAakB,MAAM,SAAS2B,GACf7C,EAAE6C,EAAEX,QAAQY,QAAQ,MAC1BC,WAAWV,KAAK,gBAAiB,SACtCrC,EAAE6C,EAAEX,QAAQc,SAASX,KAAK,gBAAiB,YAGlD1D,OAAOsE,iBAAiB,OAAQ,WAE7BjD,EAAE,YAAYkD,KAAK,WACf,GAAIC,GAAenD,EAAEqB,MAAM+B,KAAK,gBACbD,GAAaX,KAAK,gBAAkBW,EAAaC,KAAK,oBAAoBC,UAC5EF,EAAaG,IAAI,cAAczB,QAAQ,KAAM,KAE1D7B,EAAEqB,MAAM+B,KAAK,mBAAmBG,WAqB5CvD,EAAEV,UAAUW,MAAM,WACdD,EAAE,2BAA2BG,GAAI,QAAS,SAAUqD,GAChD,GAAIC,GAAe,gDACfC,EAAcD,EAAe,2BAC7BE,EAAY,cAEZC,EAAS5D,EAAEqB,MAAMG,KAAK,UACtBqC,EAAW7D,EAAEqB,MAAMG,KAAK,YACxBsC,EAAe9D,EAAEqB,MAAMG,KAAK,gBAC5BuC,EAAwB,IAAM/D,EAAEqB,MAAMG,KAAK,yBAG3CwC,GAAoB,YAAa,eAAgB,mBAAoB,gBAAiB,cAE1F,IAAGJ,GAAUC,GAAYC,EAAc,CACnCA,EAAe,IAAMA,CACrB,IAAIG,GAAQ,IACZ,QAAOJ,GACH,IAAK,OACDI,EAAQP,EAAc,QAAUE,EAAS,KAAOD,CAChD,MACJ,KAAK,MACDM,EAAQP,EAAc,OAASE,EAAS,KAAOD,CAC/C,MACJ,KAAK,WACDM,EAAQP,EAAc,YAAcE,EAAS,KAAOD,EAK5D,GAAGM,EAEC,CAAkBjE,EAAEkE,KAAMD,GACzBE,KAAK,SAAUvC,GACZ,GAAGA,GAAQA,EAAKwC,UAAYxC,EAAKwC,SAAS,GAAI,CAC1C,GAAIC,GAAUzC,EAAKwC,SAAS,GACxBE,EAAUtE,EAAE8D,GAAclC,MAC9B,KAAK,GAAI2C,KAAOF,GAAQG,KACpB,GAAyB,OAAtBH,EAAQG,KAAKhE,OAAkD,GAAjCwD,EAAgBS,QAAQF,GAAY,CAEjE,OADAD,GAAW,WAAaC,EAAM,YACvBA,GACH,IAAK,QACL,IAAK,MACDD,GAAW,gBAAmBD,EAAQG,KAAKD,GAAK1C,QAAQ,KAAK,IAAM,KAAQwC,EAAQG,KAAKD,GAAO,MAC/F,MACJ,KAAK,QACDD,GAAW,mBAAsBD,EAAQG,KAAKD,GAAO,KAAQF,EAAQG,KAAKD,GAAO,MACjF,MACJ,KAAK,UACL,IAAK,MACDD,GAAW,YAAeD,EAAQG,KAAKD,GAAO,KAAQF,EAAQG,KAAKD,GAAO,MAC1E,MACJ,KAAK,WACDD,GAAW,0CAA6CD,EAAQG,KAAKD,GAAO,KAAQF,EAAQG,KAAKD,GAAO,MACxG,MACJ,KAAK,YACD,IAAsC,GAAnCF,EAAQG,KAAKD,GAAKE,QAAQ,KAAY,CACrCH,GAAW,oBAAuBD,EAAQG,KAAKD,GAAKG,UAAU,EAAEL,EAAQG,KAAKD,GAAKE,QAAQ,MAAQ,uBAAyBJ,EAAQG,KAAKD,GAAKG,UAAUL,EAAQG,KAAKD,GAAKE,QAAQ,KAAK,GAAK,KAAQJ,EAAQG,KAAKD,GAAO,MACvN,OAGR,QAEID,GAAWD,EAAQG,KAAKD,GAGhCD,GAAW,aAGnBtE,EAAE8D,GAAclC,KAAK0C,GACrBtE,EAAE8D,GAAcpB,YAAY,UAC5B1C,EAAE+D,GAAuBtB,SAAS,aAGzCkC,KAAK,WACF3E,EAAE+D,GAAuBnC,KAAK5B,EAAE+D,GAAuBnC,OAAS,yBAA2BgD,eAAe,WAMtH5E,EAAGqB,MAAOwD,IAAKrB,KAGnBxD,EAAE,mBAAmBG,GAAI,QAAS,SAAUqD,GACxC,GAAIsB,GAAiB9E,EAAEqB,MAAMG,KAAK,kBAC9BuD,EAAU/E,EAAEqB,MAAMG,KAAK,WACvBwD,EAAUhF,EAAEqB,MAAMG,KAAK,WACvByD,EAAWjF,EAAEqB,MAAMG,KAAK,YACxB0D,EAAkBlF,EAAEqB,MAAMG,KAAK,mBAC/B2D,EAAcnF,EAAEqB,MAAMG,KAAK,cAE/B4D,UAAS,qBAAsB,SAASC,GACjCH,IACCI,UAAYC,EAAEC,OAAON,EAAgB,GAAIA,EAAgB,IACzDO,UAAYF,EAAEC,OAAON,EAAgB,GAAIA,EAAgB,IACzDQ,WAAaH,EAAEI,aAAaL,UAAWG,YAK3CF,EAAEK,KAAKC,QAAQC,UAAa,+BAG5B,IAAIC,GAAMR,EAAEQ,IAAIjB,GAGZkB,EAAa,qDACbC,EAAgB,gFAChBC,EAAY,GAAIX,GAAEY,UAAUH,GAAeI,QAAS,EAAGC,QAAS,GAAIC,YAAaL,IAEjFM,EAAgB,sDAChBC,EAAqB,sGACN,IAAIjB,GAAEY,UAAUI,GAAkBH,QAAS,EAAGC,QAAS,GAAIC,YAAaE,GAGxFd,YAECe,WAAW,WACPV,EAAIW,UAAUhB,YACVW,QAAQ,MAEb,GACItB,GAAWC,IACfC,EACCc,EAAIY,QAAQ,GAAIpB,GAAEqB,OAAO5B,EAASD,GAASE,GAE3Cc,EAAIY,QAAQ,GAAIpB,GAAEqB,OAAO5B,EAASD,GAAS,IAG/CgB,EAAIc,SAASX,EAEb,IAAIY,IACPC,aAAcb,EAIfX,GAAEyB,QAAQC,OAAOH,GAAYI,MAAMnB,GAGhCZ,GACCI,EAAE4B,QAAQhC,GAAa+B,MAAMnB,KAMrC/F,EAAGqB,MAAOwD,IAAKrB,OAGtBxD,EAAEV,UAAUW,MAAM,WACfD,EAAE,sBAAsBkB,MAAM,WAC1BlB,EAAE,yBAAyBkD,KAAK,WAAa7B,KAAKuB,SAAU,MAGhE5C,EAAE,wBAAwBkB,MAAM,WAC5BlB,EAAE,yBAAyBkD,KAAK,WAAa7B,KAAKuB,SAAU","file":"searx.min.js"} \ No newline at end of file
diff --git a/searx/static/themes/oscar/js/searx_src/element_modifiers.js b/searx/static/themes/oscar/js/searx_src/element_modifiers.js
index 31fe760..a113df9 100644
--- a/searx/static/themes/oscar/js/searx_src/element_modifiers.js
+++ b/searx/static/themes/oscar/js/searx_src/element_modifiers.js
@@ -22,6 +22,13 @@ $(document).ready(function(){
$('#q.autofocus').focus();
/**
+ * Empty search bar when click on reset button
+ */
+ $("#clear_search").click(function () {
+ document.getElementById("q").value = "";
+ });
+
+ /**
* select full content on click if class="select-all-on-click"
*/
$(".select-all-on-click").click(function () {
diff --git a/searx/static/themes/oscar/js/searx_src/infobox.js b/searx/static/themes/oscar/js/searx_src/infobox.js
new file mode 100644
index 0000000..cb7f1ee
--- /dev/null
+++ b/searx/static/themes/oscar/js/searx_src/infobox.js
@@ -0,0 +1,11 @@
+window.addEventListener('load', function() {
+ // Hide infobox toggle if shrunk size already fits all content.
+ $('.infobox').each(function() {
+ var infobox_body = $(this).find('.infobox_body');
+ var total_height = infobox_body.prop('scrollHeight') + infobox_body.find('img.infobox_part').height();
+ var max_height = infobox_body.css('max-height').replace('px', '');
+ if (total_height <= max_height) {
+ $(this).find('.infobox_toggle').hide();
+ }
+ });
+});
diff --git a/searx/static/themes/oscar/less/logicodev/infobox.less b/searx/static/themes/oscar/less/logicodev/infobox.less
index 86b8afb..e3582df 100644
--- a/searx/static/themes/oscar/less/logicodev/infobox.less
+++ b/searx/static/themes/oscar/less/logicodev/infobox.less
@@ -8,12 +8,23 @@
}
}
+ .header_url {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: block;
+ }
+
p{
font-family: "DejaVu Serif", Georgia, Cambria, "Times New Roman", Times, serif !important;
font-style: italic;
}
+ img{
+ max-height: "250px";
+ }
+
.btn{
background-color: @dark-blue;
border: none;
@@ -34,4 +45,43 @@
.infobox_part:last-child {
margin-bottom: 0;
}
+
+ .infobox_toggle {
+ width: 100%;
+ text-align: center;
+ margin-bottom: 0px;
+ }
+
+ // Shrink infobox size when toggle is off
+ .infobox_checkbox ~ .infobox_body {
+ max-height: 300px;
+ overflow: hidden;
+ }
+ .infobox_checkbox:checked ~ .infobox_body {
+ max-height: none;
+ }
+
+ // Show toggle button as down when infobox is shrunk
+ .infobox_checkbox ~ .infobox_toggle .infobox_label_down {
+ display: block;
+ }
+ .infobox_checkbox ~ .infobox_toggle .infobox_label_up {
+ display: none;
+ }
+
+ // Show toggle button as up when infobox is expanded
+ .infobox_checkbox:checked ~ .infobox_toggle .infobox_label_up {
+ display: block;
+ }
+ .infobox_checkbox:checked ~ .infobox_toggle .infobox_label_down {
+ display: none;
+ }
+
+ // Hide main image when toggle is off
+ .infobox_checkbox ~ .infobox_body img.infobox_part {
+ display: none;
+ }
+ .infobox_checkbox:checked ~ .infobox_body img.infobox_part {
+ display: block;
+ }
}
diff --git a/searx/static/themes/oscar/less/logicodev/results.less b/searx/static/themes/oscar/less/logicodev/results.less
index 9926d6e..33965fb 100644
--- a/searx/static/themes/oscar/less/logicodev/results.less
+++ b/searx/static/themes/oscar/less/logicodev/results.less
@@ -51,6 +51,11 @@
float: right;
}
+.result-abstract {
+ margin-top: 0.5em;
+ margin-bottom: 0.8em;
+}
+
.external-link {
color: @dark-green;
font-size: 12px;
@@ -124,6 +129,20 @@
}
}
+.result-metadata {
+ clear: both;
+ margin: 1em;
+
+ td {
+ padding-right: 1em;
+ color: @gray;
+ }
+
+ td:first-of-type {
+ color: @dark-gray;
+ }
+}
+
// map formating of results
.result-map {
clear: both;
diff --git a/searx/static/themes/oscar/less/logicodev/search.less b/searx/static/themes/oscar/less/logicodev/search.less
index a0cbe4d..0142287 100644
--- a/searx/static/themes/oscar/less/logicodev/search.less
+++ b/searx/static/themes/oscar/less/logicodev/search.less
@@ -56,7 +56,7 @@
color: white;
}
-.custom-select {
+.custom-select, .custom-select-rtl {
appearance: none;
-webkit-appearance: none;
-moz-appearance: none;
@@ -75,6 +75,10 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
7jwaAAAAAElFTkSuQmCC) 96% no-repeat;
}
+.custom-select-rtl {
+ background-position-x: 4%;
+}
+
.search-margin {
margin-bottom: 0.6em;
}
diff --git a/searx/static/themes/oscar/less/pointhi/infobox.less b/searx/static/themes/oscar/less/pointhi/infobox.less
index df51b00..e6a55e9 100644
--- a/searx/static/themes/oscar/less/pointhi/infobox.less
+++ b/searx/static/themes/oscar/less/pointhi/infobox.less
@@ -1,4 +1,9 @@
.infobox {
+
+ img {
+ max-height: 250px;
+ }
+
.infobox_part {
margin-bottom: 20px;
word-wrap: break-word;
@@ -8,4 +13,50 @@
.infobox_part:last-child {
margin-bottom: 0;
}
+
+ .header_url {
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ display: block;
+ }
+
+ .infobox_toggle {
+ width: 100%;
+ text-align: center;
+ margin-bottom: 0px;
+ }
+
+ // Shrink infobox size when toggle is off
+ .infobox_checkbox ~ .infobox_body {
+ max-height: 300px;
+ overflow: hidden;
+ }
+ .infobox_checkbox:checked ~ .infobox_body {
+ max-height: none;
+ }
+
+ // Show toggle button as down when infobox is shrunk
+ .infobox_checkbox ~ .infobox_toggle .infobox_label_down {
+ display: block;
+ }
+ .infobox_checkbox ~ .infobox_toggle .infobox_label_up {
+ display: none;
+ }
+
+ // Show toggle button as up when infobox is expanded
+ .infobox_checkbox:checked ~ .infobox_toggle .infobox_label_up {
+ display: block;
+ }
+ .infobox_checkbox:checked ~ .infobox_toggle .infobox_label_down {
+ display: none;
+ }
+
+ // Hide main image when toggle is off
+ .infobox_checkbox ~ .infobox_body img.infobox_part {
+ display: none;
+ }
+ .infobox_checkbox:checked ~ .infobox_body img.infobox_part {
+ display: block;
+ }
}
diff --git a/searx/static/themes/oscar/less/pointhi/search.less b/searx/static/themes/oscar/less/pointhi/search.less
index 5ff7336..ac0a7a0 100644
--- a/searx/static/themes/oscar/less/pointhi/search.less
+++ b/searx/static/themes/oscar/less/pointhi/search.less
@@ -31,3 +31,13 @@
background-color: #EEE;
}
}
+
+.visually-hidden {
+ position: absolute !important;
+ height: 1px;
+ width: 1px;
+ overflow: hidden;
+ clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
+ clip: rect(1px, 1px, 1px, 1px);
+ white-space: nowrap; /* added line */
+}
diff --git a/searx/static/themes/simple/js/searx_src/searx_search.js b/searx/static/themes/simple/js/searx_src/searx_search.js
index 580d98d..7b652fa 100644
--- a/searx/static/themes/simple/js/searx_src/searx_search.js
+++ b/searx/static/themes/simple/js/searx_src/searx_search.js
@@ -75,6 +75,10 @@
Url: "./autocompleter",
EmptyMessage: searx.no_item_found,
HttpMethod: searx.method,
+ HttpHeaders: {
+ "Content-type": "application/x-www-form-urlencoded",
+ "X-Requested-With": "XMLHttpRequest"
+ },
MinChars: 4,
Delay: 300,
}, "#" + qinput_id);
diff --git a/searx/templates/__common__/about.html b/searx/templates/__common__/about.html
index 9741b51..649e661 100644
--- a/searx/templates/__common__/about.html
+++ b/searx/templates/__common__/about.html
@@ -7,10 +7,10 @@
while not storing information about its users.
</p>
- <p>More about searx ...</p>
+ <p>More about searx...</p>
<ul>
- <li><a href="https://github.com/asciimoo/searx">github</a></li>
+ <li><a href="https://github.com/searx/searx">github</a></li>
<li><a href="https://twitter.com/Searx_engine">twitter</a></li>
<li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
<li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
@@ -31,7 +31,7 @@
</li>
<li>
Searx is free software, the code is 100% open and you can help to make it
- better. See more on <a href="https://github.com/asciimoo/searx">github</a>.
+ better. See more on <a href="https://github.com/searx/searx">github</a>.
</li>
</ul>
@@ -49,10 +49,11 @@
It provides basic privacy by mixing your queries with searches on other
platforms without storing search data. Queries are made using a POST request
- on every browser (except chrome*). Therefore they show up in neither our
- logs, nor your url history. In case of Chrome* users there is an exception,
- searx uses the search bar to perform GET requests.
-
+ on every browser (except Chromium-based browsers*). Therefore they show up
+ in neither our logs, nor your url history. In the case of Chromium-based
+ browser users there is an exception: searx uses the search bar to perform GET
+ requests.
+
Searx can be added to your browser's search bar; moreover, it can be set as
the default search engine.
</p>
@@ -66,8 +67,8 @@
<ul>
<li><a href="https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox">Firefox</a></li>
- <li><a href="https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine" >Microsoft Egde</a></li>
- <li>Chrome based browsers <a href="https://www.chromium.org/tab-to-search">only add websites that the user navigates to without a path.</a>
+ <li><a href="https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine">Microsoft Edge</a></li>
+ <li>Chromium-based browsers <a href="https://www.chromium.org/tab-to-search">only add websites that the user navigates to without a path.</a>
</ul>
<h2>Where to find anonymous usage statistics of this instance ?</h2>
@@ -80,13 +81,13 @@
<p>
Searx appreciates your concern regarding logs, so take the
- code from the <a href="https://github.com/asciimoo/searx">original searx project</a> and
+ code from the <a href="https://github.com/searx/searx">original searx project</a> and
run it yourself!
</p>
<p>
Add your searx instance to this <a href="{{ brand.PUBLIC_INSTANCES }}"> list
of public searx instances</a> to help other people reclaim their privacy and
- make the Internet freer! The more decentralized the Internet is, the more
+ make the Internet freer! The more decentralized the Internet is, the more
freedom we have!
</p>
diff --git a/searx/templates/__common__/opensearch.xml b/searx/templates/__common__/opensearch.xml
index 2763424..2476258 100644
--- a/searx/templates/__common__/opensearch.xml
+++ b/searx/templates/__common__/opensearch.xml
@@ -6,13 +6,17 @@
<Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image>
<LongName>searx metasearch</LongName>
{% if opensearch_method == 'get' %}
- <Url rel="results" type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
+ <Url rel="results" type="text/html" method="get" template="{{ url_for('search', _external=True) }}?q={searchTerms}"/>
{% else %}
- <Url rel="results" type="text/html" method="post" template="{{ host }}">
+ <Url rel="results" type="text/html" method="post" template="{{ url_for('search', _external=True) }}">
<Param name="q" value="{searchTerms}" />
</Url>
{% endif %}
{% if autocomplete %}
- <Url rel="suggestions" type="application/json" template="{{ host }}autocompleter"/>
+ <Url rel="suggestions" type="application/x-suggestions+json" template="{{ host }}autocompleter?q={searchTerms}"/>
{% endif %}
+
+ <Url type="application/opensearchdescription+xml"
+ rel="self"
+ template="{{ opensearch_url }}" />
</OpenSearchDescription>
diff --git a/searx/templates/__common__/opensearch_response_rss.xml b/searx/templates/__common__/opensearch_response_rss.xml
index 3781dd8..82d3f7c 100644
--- a/searx/templates/__common__/opensearch_response_rss.xml
+++ b/searx/templates/__common__/opensearch_response_rss.xml
@@ -4,12 +4,12 @@
xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Searx search: {{ q|e }}</title>
- <link>{{ base_url }}?q={{ q|e }}</link>
+ <link>{{ url_for('search', _external=True) }}?q={{ q|e }}</link>
<description>Search results for "{{ q|e }}" - searx</description>
<opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults>
<opensearch:startIndex>1</opensearch:startIndex>
<opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
- <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/>
+ <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ opensearch_url }}"/>
<opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
{% if error_message %}
<item>
diff --git a/searx/templates/courgette/404.html b/searx/templates/courgette/404.html
index 9e3b8ac..7a317f0 100644
--- a/searx/templates/courgette/404.html
+++ b/searx/templates/courgette/404.html
@@ -3,7 +3,7 @@
<div class="center">
<h1>{{ _('Page not found') }}</h1>
{% autoescape false %}
- <p>{{ _('Go to %(search_page)s.', search_page=unicode('<a href="{}">{}</a>').format(url_for('index'), _('search page'))) }}</p>
+ <p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.format(url_for('index'), _('search page'))) }}</p>
{% endautoescape %}
</div>
{% endblock %}
diff --git a/searx/templates/courgette/base.html b/searx/templates/courgette/base.html
index f4c61da..468b817 100644
--- a/searx/templates/courgette/base.html
+++ b/searx/templates/courgette/base.html
@@ -22,7 +22,7 @@
{% endblock %}
{% block meta %}{% endblock %}
{% block head %}
- <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
+ <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"/>
{% endblock %}
<script type="text/javascript">
searx = {};
diff --git a/searx/templates/courgette/github_ribbon.html b/searx/templates/courgette/github_ribbon.html
index bdd9cf1..fb38a20 100644
--- a/searx/templates/courgette/github_ribbon.html
+++ b/searx/templates/courgette/github_ribbon.html
@@ -1,3 +1,3 @@
-<a href="https://github.com/asciimoo/searx" class="github">
+<a href="https://github.com/searx/searx" class="github">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="{{ url_for('static', filename='img/github_ribbon.png') }}" alt="Fork me on GitHub" class="github"/>
</a>
diff --git a/searx/templates/courgette/preferences.html b/searx/templates/courgette/preferences.html
index c67f766..6480694 100644
--- a/searx/templates/courgette/preferences.html
+++ b/searx/templates/courgette/preferences.html
@@ -5,10 +5,13 @@
<h2>{{ _('Preferences') }}</h2>
<form method="post" action="{{ url_for('preferences') }}" id="search_form">
+ {% if 'categories' not in locked_preferences %}
<fieldset>
<legend>{{ _('Default categories') }}</legend>
{% include 'courgette/categories.html' %}
</fieldset>
+ {% endif %}
+ {% if 'language' not in locked_preferences %}
<fieldset>
<legend>{{ _('Search language') }}</legend>
<p>
@@ -20,6 +23,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'locale' not in locked_preferences %}
<fieldset>
<legend>{{ _('Interface language') }}</legend>
<p>
@@ -30,6 +35,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'autocomplete' not in locked_preferences %}
<fieldset>
<legend>{{ _('Autocomplete') }}</legend>
<p>
@@ -41,6 +48,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'image_proxy' not in locked_preferences %}
<fieldset>
<legend>{{ _('Image proxy') }}</legend>
<p>
@@ -50,6 +59,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'method' not in locked_preferences %}
<fieldset>
<legend>{{ _('Method') }}</legend>
<p>
@@ -59,6 +70,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'safesearch' not in locked_preferences %}
<fieldset>
<legend>{{ _('SafeSearch') }}</legend>
<p>
@@ -69,6 +82,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'theme' not in locked_preferences %}
<fieldset>
<legend>{{ _('Themes') }}</legend>
<p>
@@ -92,6 +107,7 @@
</select>
</p>
</fieldset>
+ {% endif %}
<fieldset>
<legend>{{ _('Currently used search engines') }}</legend>
diff --git a/searx/templates/courgette/results.html b/searx/templates/courgette/results.html
index aa983e6..716ea4d 100644
--- a/searx/templates/courgette/results.html
+++ b/searx/templates/courgette/results.html
@@ -1,6 +1,6 @@
{% extends "courgette/base.html" %}
{% block title %}{{ q|e }} - {% endblock %}
-{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('index') }}?q={{ q|urlencode }}&amp;format=rss&amp;{% for category in selected_categories %}category_{{ category }}=1&amp;{% endfor %}pageno={{ pageno }}">{% endblock %}
+{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;format=rss&amp;{% for category in selected_categories %}category_{{ category }}=1&amp;{% endfor %}pageno={{ pageno }}">{% endblock %}
{% block content %}
<div class="right"><a href="{{ url_for('preferences') }}" id="preferences"><span>{{ _('preferences') }}</span></a></div>
<div class="small search center">
@@ -10,12 +10,12 @@
<div id="sidebar">
<div id="search_url">
{{ _('Search URL') }}:
- <input type="text" value="{{ base_url }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}" readonly />
+ <input type="text" value="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}" readonly />
</div>
<div id="apis">
{{ _('Download results') }}<br />
{% for output_type in ('csv', 'json', 'rss') %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="left">
<input type="hidden" name="q" value="{{ q|e }}" />
<input type="hidden" name="format" value="{{ output_type }}" />
@@ -41,7 +41,7 @@
{% if suggestions %}
<div id="suggestions"><span>{{ _('Suggestions') }}</span>
{% for suggestion in suggestions %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion.url }}">
<input type="submit" value="{{ suggestion.title }}" />
</form>
@@ -60,7 +60,7 @@
{% if paging %}
<div id="pagination">
{% if pageno > 1 %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="left">
<input type="hidden" name="q" value="{{ q|e }}" />
{% for category in selected_categories %}
@@ -71,7 +71,7 @@
</div>
</form>
{% endif %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="left">
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1"/>
diff --git a/searx/templates/courgette/search.html b/searx/templates/courgette/search.html
index fe70fde..89daead 100644
--- a/searx/templates/courgette/search.html
+++ b/searx/templates/courgette/search.html
@@ -1,7 +1,7 @@
-<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form">
+<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" id="search_form">
<div id="search_wrapper">
<input type="text" autofocus placeholder="{{ _('Search for...') }}" id="q" class="q" name="q" tabindex="1" autocomplete="off" {% if q %}value="{{ q }}"{% endif %}/>
<input type="submit" value="search" id="search_submit" />
</div>
{% include 'courgette/categories.html' %}
-</form> \ No newline at end of file
+</form>
diff --git a/searx/templates/legacy/404.html b/searx/templates/legacy/404.html
index 3e889dd..c0fa62b 100644
--- a/searx/templates/legacy/404.html
+++ b/searx/templates/legacy/404.html
@@ -3,7 +3,7 @@
<div class="center">
<h1>{{ _('Page not found') }}</h1>
{% autoescape false %}
- <p>{{ _('Go to %(search_page)s.', search_page=unicode('<a href="{}">{}</a>').format(url_for('index'), _('search page'))) }}</p>
+ <p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.format(url_for('index'), _('search page'))) }}</p>
{% endautoescape %}
</div>
{% endblock %}
diff --git a/searx/templates/legacy/base.html b/searx/templates/legacy/base.html
index 21fe42e..1e52322 100644
--- a/searx/templates/legacy/base.html
+++ b/searx/templates/legacy/base.html
@@ -2,7 +2,7 @@
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"{% if rtl %} dir="rtl"{% endif %}>
<head>
<meta charset="UTF-8" />
- <meta name="description" content="searx - a privacy-respecting, hackable metasearch engine" />
+ <meta name="description" content="searx — a privacy-respecting, hackable metasearch engine" />
<meta name="keywords" content="searx, search, search engine, metasearch, meta search" />
<meta name="generator" content="searx/{{ searx_version }}">
<meta name="referrer" content="no-referrer">
@@ -17,7 +17,7 @@
{% endblock %}
{% block meta %}{% endblock %}
{% block head %}
- <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
+ <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"/>
{% endblock %}
</head>
<body class="{{ endpoint }}_endpoint" >
diff --git a/searx/templates/legacy/github_ribbon.html b/searx/templates/legacy/github_ribbon.html
index bdd9cf1..fb38a20 100644
--- a/searx/templates/legacy/github_ribbon.html
+++ b/searx/templates/legacy/github_ribbon.html
@@ -1,3 +1,3 @@
-<a href="https://github.com/asciimoo/searx" class="github">
+<a href="https://github.com/searx/searx" class="github">
<img style="position: absolute; top: 0; right: 0; border: 0;" src="{{ url_for('static', filename='img/github_ribbon.png') }}" alt="Fork me on GitHub" class="github"/>
</a>
diff --git a/searx/templates/legacy/infobox.html b/searx/templates/legacy/infobox.html
index 4dd25fa..70f3b12 100644
--- a/searx/templates/legacy/infobox.html
+++ b/searx/templates/legacy/infobox.html
@@ -36,7 +36,7 @@
<div>
<h3><bdi>{{ topic.name }}</bdi></h3>
{% for suggestion in topic.suggestions %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion }}">
<input type="submit" value="{{ suggestion }}" />
</form>
diff --git a/searx/templates/legacy/preferences.html b/searx/templates/legacy/preferences.html
index 414b3f6..23b3875 100644
--- a/searx/templates/legacy/preferences.html
+++ b/searx/templates/legacy/preferences.html
@@ -10,6 +10,7 @@
{% set display_tooltip = false %}
{% include 'legacy/categories.html' %}
</fieldset>
+ {% if 'language' not in locked_preferences %}
<fieldset>
<legend>{{ _('Search language') }}</legend>
<p>
@@ -21,6 +22,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'locale' not in locked_preferences %}
<fieldset>
<legend>{{ _('Interface language') }}</legend>
<p>
@@ -31,6 +34,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'autocomplete' not in locked_preferences %}
<fieldset>
<legend>{{ _('Autocomplete') }}</legend>
<p>
@@ -42,6 +47,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'image_proxy' not in locked_preferences %}
<fieldset>
<legend>{{ _('Image proxy') }}</legend>
<p>
@@ -51,6 +58,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'method' not in locked_preferences %}
<fieldset>
<legend>{{ _('Method') }}</legend>
<p>
@@ -60,6 +69,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'safesearch' not in locked_preferences %}
<fieldset>
<legend>{{ _('SafeSearch') }}</legend>
<p>
@@ -70,6 +81,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'theme' not in locked_preferences %}
<fieldset>
<legend>{{ _('Themes') }}</legend>
<p>
@@ -80,6 +93,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'results_on_new_tab' not in locked_preferences %}
<fieldset>
<legend>{{ _('Results on new tabs') }}</legend>
<p>
@@ -89,6 +104,7 @@
</select>
</p>
</fieldset>
+ {% endif %}
<fieldset>
<legend>{{ _('Currently used search engines') }}</legend>
diff --git a/searx/templates/legacy/result_templates/default.html b/searx/templates/legacy/result_templates/default.html
index 13e2d29..78bf031 100644
--- a/searx/templates/legacy/result_templates/default.html
+++ b/searx/templates/legacy/result_templates/default.html
@@ -1,6 +1,11 @@
<div class="result {{ result.class }}{% for e in result.engines %} {{ e }}{% endfor %}">
<h3 class="result_title">{% if "icon_"~result.engine~".ico" in favicons %}<img width="14" height="14" class="favicon" src="{{ url_for('static', filename='img/icons/icon_'+result.engine+'.ico') }}" alt="{{result.engine}}" />{% endif %}<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ result.title|safe }}</a></h3>
- <p class="url">{{ result.pretty_url }}&lrm; <a class="cache_link" href="https://web.archive.org/web/{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('cached') }}</a>
+ <p class="url">{{ result.pretty_url }}&lrm;
+ {% if result.cached_url %}
+ <a class="cache_link" href="{{ result.cached_url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('cached') }}</a>
+ {% elif not result.is_onion %}
+ <a class="cache_link" href="https://web.archive.org/web/{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}>{{ _('cached') }}</a>
+ {% endif %}
{% if result.publishedDate %}<span class="published_date">{{ result.publishedDate }}</span>{% endif %}</p>
<p class="content">{% if result.img_src %}<img src="{{ image_proxify(result.img_src) }}" class="image" />{% endif %}{% if result.content %}{{ result.content|safe }}<br class="last"/>{% endif %}</p>
</div>
diff --git a/searx/templates/legacy/results.html b/searx/templates/legacy/results.html
index fd95657..efff066 100644
--- a/searx/templates/legacy/results.html
+++ b/searx/templates/legacy/results.html
@@ -1,6 +1,6 @@
{% extends "legacy/base.html" %}
{% block title %}{{ q|e }} - {% endblock %}
-{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('index') }}?q={{ q|urlencode }}&amp;format=rss&amp;{% for category in selected_categories %}category_{{ category }}=1&amp;{% endfor %}pageno={{ pageno }}">{% endblock %}
+{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;format=rss&amp;{% for category in selected_categories %}category_{{ category }}=1&amp;{% endfor %}pageno={{ pageno }}">{% endblock %}
{% block content %}
<div class="preferences_container right"><a href="{{ url_for('preferences') }}" id="preferences"><span>preferences</span></a></div>
<div class="small search center">
@@ -11,12 +11,12 @@
<div id="search_url">
{{ _('Search URL') }}:
- <input type="text" value="{{ base_url }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}" readonly />
+ <input type="text" value="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}" readonly />
</div>
<div id="apis">
{{ _('Download results') }}
{% for output_type in ('csv', 'json', 'rss') %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="left">
<input type="hidden" name="q" value="{{ q|e }}" />
<input type="hidden" name="format" value="{{ output_type }}" />
@@ -47,7 +47,7 @@
<div id="suggestions"><span id="suggestions-title">{{ _('Suggestions') }} : </span>
{% set first = true %}
{% for suggestion in suggestions %}
- {% if not first %} &bull; {% endif %}<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ {% if not first %} &bull; {% endif %}<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion.url }}">
<input type="submit" class="suggestion" value="{{ suggestion.title }}" />
</form>
@@ -75,7 +75,7 @@
{% if paging %}
<div id="pagination">
{% if pageno > 1 %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="{% if rtl %}right{% else %}left{% endif %}">
<input type="hidden" name="q" value="{{ q|e }}" />
{% for category in selected_categories %}
@@ -86,7 +86,7 @@
</div>
</form>
{% endif %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="{% if rtl %}left{% else %}right{% endif %}">
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1"/>
diff --git a/searx/templates/legacy/search.html b/searx/templates/legacy/search.html
index fcd08d6..88cf3d3 100644
--- a/searx/templates/legacy/search.html
+++ b/searx/templates/legacy/search.html
@@ -1,4 +1,4 @@
-<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form">
+<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" id="search_form">
<div id="search_wrapper">
<input type="text" autofocus placeholder="{{ _('Search for...') }}" id="q" class="q" name="q" tabindex="1" autocomplete="off" size="100" {% if q %}value="{{ q }}"{% endif %}/>
<input type="submit" value="search" id="search_submit" />
diff --git a/searx/templates/oscar/404.html b/searx/templates/oscar/404.html
index 5a50880..cdb31db 100644
--- a/searx/templates/oscar/404.html
+++ b/searx/templates/oscar/404.html
@@ -3,7 +3,7 @@
<div class="text-center">
<h1>{{ _('Page not found') }}</h1>
{% autoescape false %}
- <p>{{ _('Go to %(search_page)s.', search_page=unicode('<a href="{}">{}</a>').format(url_for('index'), _('search page'))) }}</p>
+ <p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.format(url_for('index'), _('search page'))) }}</p>
{% endautoescape %}
</div>
{% endblock %}
diff --git a/searx/templates/oscar/base.html b/searx/templates/oscar/base.html
index a3bfa52..7b3d33f 100644
--- a/searx/templates/oscar/base.html
+++ b/searx/templates/oscar/base.html
@@ -37,7 +37,7 @@
{% block head %}
{% endblock %}
- <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
+ <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"/>
<noscript>
<style type="text/css">
.tab-content > .active_if_nojs, .active_if_nojs {display: block !important; visibility: visible !important;}
diff --git a/searx/templates/oscar/infobox.html b/searx/templates/oscar/infobox.html
index 6ae7965..8a12b80 100644
--- a/searx/templates/oscar/infobox.html
+++ b/searx/templates/oscar/infobox.html
@@ -1,10 +1,18 @@
{% from 'oscar/macros.html' import result_link with context %}
<div class="panel panel-default infobox">
<div class="panel-heading">{{- "" -}}
- <h4 class="panel-title infobox_part"><bdi>{{ infobox.infobox }}</bdi></h4>{{- "" -}}
- {% for u in infobox.urls %}{% if u.official %} <a href="{{ u.url }}">{{ u.domain }}</a>{% endif %}{% endfor %}
+ <div class="infobox_part">
+ <div class="{% if not rtl %}pull-right{% endif %}">
+ {% for engine in infobox.engines %}
+ <span class="label label-default">{{ engine }}</span>
+ {% endfor %}
+ </div>
+ <h4 class="panel-title"><bdi>{{ infobox.infobox }}</bdi></h4>{{- "" -}}
+ {% for u in infobox.urls %}{% if u.official %} <a class="header_url" href="{{ u.url }}">{{ u.url }}</a>{% endif %}{% endfor %}
+ </div>
</div>
- <div class="panel-body">
+ <input type="checkbox" class="infobox_checkbox" id="expand_infobox_{{ infobox.engine }}" hidden>
+ <div class="panel-body infobox_body">
{% if infobox.img_src %}<img class="img-responsive center-block infobox_part" src="{{ image_proxify(infobox.img_src) }}" />{% endif %}
{% if infobox.content %}<bdi><p class="infobox_part">{{ infobox.content | safe }}</p></bdi>{% endif %}
@@ -17,11 +25,7 @@
{%- if attribute.image -%}
<td><img class="img-responsive" src="{{ image_proxify(attribute.image.src) }}" alt="{{ attribute.image.alt }}" /></td>
{%- else -%}
- {% if attribute.label == 'Instance of' %}
- <td><bdi><a href="https://wikidata.org/wiki/{{ attribute.value.id }}">{{ attribute.value.id }}</a></bdi></td>
- {% else %}
- <td><bdi>{{ attribute.value }}</bdi></td>
- {%- endif -%}
+ <td><bdi>{{ attribute.value }}</bdi></td>
{%- endif -%}
</tr>
{% endfor -%}
@@ -38,4 +42,8 @@
</div>
{% endif %}
</div>
+ <label for="expand_infobox_{{ infobox.engine }}" class="infobox_toggle panel-footer">
+ <span class="infobox_label_down glyphicon glyphicon-chevron-down"></span>
+ <span class="infobox_label_up glyphicon glyphicon-chevron-up"></span>
+ </label>
</div>
diff --git a/searx/templates/oscar/languages.html b/searx/templates/oscar/languages.html
index 9c00c9c..0846caa 100644
--- a/searx/templates/oscar/languages.html
+++ b/searx/templates/oscar/languages.html
@@ -1,5 +1,6 @@
+{% from 'oscar/macros.html' import custom_select_class %}
<label class="visually-hidden" for="language">{{ _('Language') }}</label>
-<select class="language custom-select form-control" id="language" name="language" accesskey="l">
+<select class="language form-control {{ custom_select_class(rtl) }}" id="language" name="language" accesskey="l">
<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }}</option>
{%- for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) -%}
<option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>
diff --git a/searx/templates/oscar/macros.html b/searx/templates/oscar/macros.html
index 58f9669..f40eebd 100644
--- a/searx/templates/oscar/macros.html
+++ b/searx/templates/oscar/macros.html
@@ -1,6 +1,6 @@
<!-- Draw glyphicon icon from bootstrap-theme -->
-{% macro icon(action) -%}
- <span class="glyphicon glyphicon-{{ action }}"></span>
+{% macro icon(action, alt) -%}
+ <span title="{{ alt }}" class="glyphicon glyphicon-{{ action }}"></span>
{%- endmacro %}
<!-- Draw favicon -->
@@ -32,7 +32,11 @@
<span class="label label-default">{{ engine }}</span>
{%- endfor -%}
{%- if result.url -%}
- <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% if result.cached_url %}
+ <small>{{ result_link(result.cached_url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% elif not result.is_onion %}
+ <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% endif %}
{%- endif -%}
{%- if proxify -%}
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info", id) }}</small>
@@ -43,6 +47,20 @@
{%- endif -%}
{%- endmacro %}
+<!-- Draw result footer without cache link -->
+{% macro result_footer_nocache(result) -%}
+ <div class="clearfix"></div>
+ <div class="pull-right">
+ {% for engine in result.engines %}
+ <span class="label label-default">{{ engine }}</span>
+ {% endfor %}
+ {% if proxify %}
+ <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
+ {% endif %}
+</div>
+<div class="external-link">{{ result.pretty_url }}</div>
+{%- endmacro %}
+
<!-- Draw result footer -->
{% macro result_footer_rtl(result, id) -%}
<div class="clearfix"></div>{{- "" -}}
@@ -50,7 +68,11 @@
<span class="label label-default">{{ engine }}</span>
{%- endfor %}
{%- if result.url -%}
- <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% if result.cached_url %}
+ <small>{{ result_link(result.cached_url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% elif not result.is_onion %}
+ <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info", id) }}</small>
+ {% endif %}
{%- endif -%}
{% if proxify -%}
<small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info", id) }}</small>
@@ -60,6 +82,18 @@
{%- endif %}
{%- endmacro %}
+<!-- Draw result footer without cache link -->
+{% macro result_footer_nocache_rtl(result) -%}
+ <div class="clearfix"></div>
+ {% for engine in result.engines %}
+ <span class="label label-default">{{ engine }}</span>
+ {% endfor %}
+ {% if proxify %}
+ <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
+ {% endif %}
+ <div class="external-link">{{ result.pretty_url }}</div>
+{%- endmacro %}
+
{% macro preferences_item_header(info, label, rtl, id) -%}
{% if rtl %}
<div class="row form-group">
@@ -84,6 +118,10 @@
{% endif %}
{%- endmacro %}
+{% macro custom_select_class(rtl) -%}
+custom-select{% if rtl %}-rtl{% endif %}
+{%- endmacro %}
+
{% macro checkbox_toggle(id, blocked) -%}
<div class="onoffswitch">
<input type="checkbox" id="{{ id }}" name="{{ id }}"{% if blocked %} checked="checked"{% endif %} class="onoffswitch-checkbox">
diff --git a/searx/templates/oscar/preferences.html b/searx/templates/oscar/preferences.html
index ab71b06..fc20b8c 100644
--- a/searx/templates/oscar/preferences.html
+++ b/searx/templates/oscar/preferences.html
@@ -1,4 +1,4 @@
-{% from 'oscar/macros.html' import preferences_item_header, preferences_item_header_rtl, preferences_item_footer, preferences_item_footer_rtl, checkbox_toggle, support_toggle %}
+{% from 'oscar/macros.html' import preferences_item_header, preferences_item_header_rtl, preferences_item_footer, preferences_item_footer_rtl, checkbox_toggle, support_toggle, custom_select_class %}
{% extends "oscar/base.html" %}
{% block title %}{{ _('preferences') }} - {% endblock %}
{% block content %}
@@ -25,6 +25,7 @@
<div class="tab-pane active" id="tab_general">
<fieldset>
<div class="container-fluid">
+ {% if 'categories' not in locked_preferences %}
<div class="row form-group">
{% if rtl %}
<div class="col-sm-11 col-md-10">
@@ -38,92 +39,121 @@
</div>
{% endif %}
</div>
+ {% endif %}
+ {% if 'language' not in locked_preferences %}
{% set language_label = _('Search language') %}
{% set language_info = _('What language do you prefer for search?') %}
{{ preferences_item_header(language_info, language_label, rtl, 'language') }}
{% include 'oscar/languages.html' %}
{{ preferences_item_footer(language_info, language_label, rtl) }}
+ {% endif %}
+ {% if 'locale' not in locked_preferences %}
{% set locale_label = _('Interface language') %}
{% set locale_info = _('Change the language of the layout') %}
{{ preferences_item_header(locale_info, locale_label, rtl, 'locale') }}
- <select class="form-control" name="locale" id="locale">
+ <select class="form-control {{ custom_select_class(rtl)}}" name="locale" id="locale">
{% for locale_id,locale_name in locales.items() | sort %}
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
{% endfor %}
</select>
{{ preferences_item_footer(locale_info, locale_label, rtl) }}
+ {% endif %}
+ {% if 'autocomplete' not in locked_preferences %}
{% set autocomplete_label = _('Autocomplete') %}
{% set autocomplete_info = _('Find stuff as you type') %}
{{ preferences_item_header(autocomplete_info, autocomplete_label, rtl, 'autocomplete') }}
- <select class="form-control" name="autocomplete" id="autocomplete">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="autocomplete" id="autocomplete">
<option value=""> - </option>
{% for backend in autocomplete_backends %}
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
{% endfor %}
</select>
{{ preferences_item_footer(autocomplete_info, autocomplete_label, rtl) }}
+ {% endif %}
+ {% if 'image_proxy' not in locked_preferences %}
{% set image_proxy_label = _('Image proxy') %}
{% set image_proxy_info = _('Proxying image results through searx') %}
{{ preferences_item_header(image_proxy_info, image_proxy_label, rtl, 'image_proxy') }}
- <select class="form-control" name="image_proxy" id="image_proxy">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="image_proxy" id="image_proxy">
<option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
<option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled')}}</option>
</select>
{{ preferences_item_footer(image_proxy_info, image_proxy_label, rtl) }}
+ {% endif %}
+ {% if 'method' not in locked_preferences %}
{% set method_label = _('Method') %}
{% set method_info = _('Change how forms are submited, <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods" rel="external">learn more about request methods</a>') %}
{{ preferences_item_header(method_info, method_label, rtl, 'method') }}
- <select class="form-control" name="method" id="method">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="method" id="method">
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
</select>
{{ preferences_item_footer(method_info, method_label, rtl) }}
+ {% endif %}
+ {% if 'safesearch' not in locked_preferences %}
{% set safesearch_label = _('SafeSearch') %}
{% set safesearch_info = _('Filter content') %}
{{ preferences_item_header(safesearch_info, safesearch_label, rtl, 'safesearch') }}
- <select class="form-control" name="safesearch" id="safesearch">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="safesearch" id="safesearch">
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option>
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option>
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option>
</select>
{{ preferences_item_footer(safesearch_info, safesearch_label, rtl) }}
+ {% endif %}
+ {% if 'theme' not in locked_preferences %}
{% set theme_label = _('Themes') %}
{% set theme_info = _('Change searx layout') %}
{{ preferences_item_header(theme_info, theme_label, rtl, 'theme') }}
- <select class="form-control" name="theme" id="theme">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="theme" id="theme">
{% for name in themes %}
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
{% endfor %}
</select>
{{ preferences_item_footer(theme_info, theme_label, rtl) }}
+ {% endif %}
+ {% if 'oscar-style' not in locked_preferences %}
{{ preferences_item_header(_('Choose style for this theme'), _('Style'), rtl, 'oscar_style') }}
- <select class="form-control" name="oscar-style" id="oscar_style">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="oscar-style" id="oscar_style">
<option value="logicodev" >Logicodev</option>
<option value="pointhi" {% if preferences.get_value('oscar-style') == 'pointhi' %}selected="selected"{% endif %}>Pointhi</option>
<option value="logicodev-dark" {% if preferences.get_value('oscar-style') == 'logicodev-dark' %}selected="selected"{% endif %}>Logicodev dark</option>
</select>
{{ preferences_item_footer(_('Choose style for this theme'), _('Style'), rtl) }}
+ {% endif %}
+ {% if 'results_on_new_tab' not in locked_preferences %}
{% set label = _('Results on new tabs') %}
{% set info = _('Open result links on new browser tabs') %}
{{ preferences_item_header(info, label, rtl, 'results_on_new_tab') }}
- <select class="form-control" name="results_on_new_tab" id="results_on_new_tab">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="results_on_new_tab" id="results_on_new_tab">
<option value="1" {% if results_on_new_tab %}selected="selected"{% endif %}>{{ _('On') }}</option>
<option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>
</select>
{{ preferences_item_footer(info, label, rtl) }}
+ {% endif %}
+ {% set label = _('Show advanced settings') %}
+ {% set info = _('Show advanced settings panel in the home page by default') %}
+ {{ preferences_item_header(info, label, rtl, 'advanced_search') }}
+ <select class="form-control {{ custom_select_class(rtl) }}" name="advanced_search" id="advanced_search">
+ <option value="1" {% if preferences.get_value('advanced_search')%}selected="selected"{% endif %}>{{ _('On') }}</option>
+ <option value="0" {% if not preferences.get_value('advanced_search')%}selected="selected"{% endif %}>{{ _('Off')}}</option>
+ </select>
+ {{ preferences_item_footer(info, label, rtl) }}
+
+ {% if 'doi_resolver' not in locked_preferences %}
{% set label = _('Open Access DOI resolver') %}
{% set info = _('Redirect to open-access versions of publications when available (plugin required)') %}
{{ preferences_item_header(info, label, rtl, 'doi_resolver') }}
- <select class="form-control" name="doi_resolver" id="doi_resolver">
+ <select class="form-control {{ custom_select_class(rtl) }}" name="doi_resolver" id="doi_resolver">
{% for doi_resolver_name,doi_resolver_url in doi_resolvers.items() %}
<option value="{{ doi_resolver_name }}" {% if doi_resolver_name == current_doi_resolver %}selected="selected"{% endif %}>
{{ doi_resolver_name }} - {{ doi_resolver_url }}
@@ -131,6 +161,7 @@
{% endfor %}
</select>
{{ preferences_item_footer(info, label, rtl) }}
+ {% endif %}
{% set label = _('Engine tokens') %}
{% set info = _('Access tokens for private engines') %}
@@ -199,8 +230,8 @@
<td class="onoff-checkbox">
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
</td>
- <th scope="row">{{ search_engine.name }}</th>
- <td class="name">{{ shortcuts[search_engine.name] }}</td>
+ <th scope="row">{% if not search_engine.https_support %}{{ icon('exclamation-sign', 'No HTTPS') }}{% endif %} {{ search_engine.name }}</td></th>
+ <td class="name">{{ shortcuts[search_engine.name] }}
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
@@ -236,6 +267,7 @@
<fieldset>
<div class="container-fluid">
{% for plugin in plugins %}
+ {% if plugin.preference_section != 'onions' %}
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">{{ _(plugin.name) }}</h3>
@@ -249,6 +281,7 @@
</div>
</div>
</div>
+ {% endif %}
{% endfor %}
</div>
</fieldset>
@@ -321,7 +354,7 @@
</p>
<div class="tab-pane">
- <input readonly="" class="form-control select-all-on-click cursor-text" type="url" value="{{ url_for('index', _external=True) }}?preferences={{ preferences_url_params|e }}{% raw %}&amp;q=%s{% endraw %}">
+ <input readonly="" class="form-control select-all-on-click cursor-text" type="url" value="{{ base_url }}?preferences={{ preferences_url_params|e }}{% raw %}&amp;q=%s{% endraw %}">
<input type="submit" class="btn btn-primary" value="{{ _('save') }}" />
<a href="{{ url_for('index') }}"><div class="btn btn-default">{{ _('back') }}</div></a>
<a href="{{ url_for('clear_cookies') }}"><div class="btn btn-default">{{ _('Reset defaults') }}</div></a>
diff --git a/searx/templates/oscar/result_templates/files.html b/searx/templates/oscar/result_templates/files.html
new file mode 100644
index 0000000..5e3894e
--- /dev/null
+++ b/searx/templates/oscar/result_templates/files.html
@@ -0,0 +1,55 @@
+{% from 'oscar/macros.html' import result_header, result_sub_header, result_footer_nocache, result_footer_nocache_rtl, icon with context %}
+
+{{ result_header(result, favicons) }}
+{{ result_sub_header(result) }}
+
+{% if result.embedded %}
+ <small> &bull; <a class="text-info btn-collapse collapsed cursor-pointer media-loader disabled_if_nojs" data-toggle="collapse" data-target="#result-media-{{ index }}" data-btn-text-collapsed="{{ _('show media') }}" data-btn-text-not-collapsed="{{ _('hide media') }}">
+ {% if result.mtype == 'audio' %}{{ icon('music') }}
+ {% elif result.mtype == 'video' %} {{ icon('film') }}
+ {% endif %} {{ _('show media') }}</a></small>
+{% endif %}
+
+{% if result.embedded %}
+<div id="result-media-{{ index }}" class="collapse">
+ {{ result.embedded|safe }}
+</div>
+{% endif %}
+
+{% if result.abstract %}<p class="result-content result-abstract">{{ result.abstract|safe }}</p>{% endif %}
+
+{% if result.img_src %}
+<div class="container-fluid">
+ <div class="row">
+<img src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" style="width: auto; max-height: 60px; min-height: 60px;" class="col-xs-2 col-sm-4 col-md-4 result-content">
+{% if result.content %}<p class="result-content col-xs-8 col-sm-8 col-md-8">{{ result.content|safe }}</p>{% endif %}
+ </div>
+</div>
+{% else %}
+{% if result.content %}<p class="result-content">{{ result.content|safe }}</p>{% endif %}
+{% endif %}
+
+<table class="result-metadata result-content">
+{% if result.author %}<tr><td>{{ _('Author') }}</td><td>{{ result.author|safe }}</td></tr>{% endif %}
+
+{% if result.filename %}<tr><td>{{ _('Filename') }}</td><td>{{ result.filename|safe }}</td></tr>{% endif %}
+
+{% if result.size %}<tr><td>{{ _('Filesize') }}</td><td>
+ {% if result.size < 1024 %}{{ result.size }} {{ _('Bytes') }}
+ {% elif result.size < 1024*1024 %}{{ '{0:0.2f}'.format(result.size/1024) }} {{ _('kiB') }}
+ {% elif result.size < 1024*1024*1024 %}{{ '{0:0.2f}'.format(result.size/1024/1024) }} {{ _('MiB') }}
+ {% elif result.size < 1024*1024*1024*1024 %}{{ '{0:0.2f}'.format(result.size/1024/1024/1024) }} {{ _('GiB') }}
+ {% else %}{{ '{0:0.2f}'.format(result.size/1024/1024/1024/1024) }} {{ _('TiB') }}{% endif %}
+ </td></tr>
+{% endif %}
+
+{% if result.time %}<tr><td>{{ _('Date') }}</td><td>{{ result.time|safe }}</td></tr>{% endif %}
+
+{% if result.mtype %}<tr><td>{{ _('Type') }}</td><td>{{ result.mtype|safe }}/{{ result.subtype|safe }}</td></tr>{% endif %}
+</table>
+
+{% if rtl %}
+{{ result_footer_nocache_rtl(result) }}
+{% else %}
+{{ result_footer_nocache(result) }}
+{% endif %}
diff --git a/searx/templates/oscar/result_templates/key-value.html b/searx/templates/oscar/result_templates/key-value.html
index 67c748e..d5c56a1 100644
--- a/searx/templates/oscar/result_templates/key-value.html
+++ b/searx/templates/oscar/result_templates/key-value.html
@@ -6,7 +6,7 @@
{% continue %}
{% endif %}
<tr>
- <td><b>{{ key|upper }}</b>: {{ value }}</td>
+ <td><b>{{ key|upper }}</b>: {{ value|truncate }}</td>
</tr>
{% endfor %}
</table>
diff --git a/searx/templates/oscar/result_templates/products.html b/searx/templates/oscar/result_templates/products.html
new file mode 100644
index 0000000..590db0e
--- /dev/null
+++ b/searx/templates/oscar/result_templates/products.html
@@ -0,0 +1,22 @@
+{% from 'oscar/macros.html' import draw_favicon, result_header, result_sub_header, result_footer_rtl, result_footer %}
+
+{{ result_header(result, favicons) }}
+{{ result_sub_header(result) }}
+
+<div class="container-fluid">
+ <div class="row">
+ <a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="thumbnail col-xs-6 col-sm-3 col-md-3 result-content" src="{{ image_proxify(result.thumbnail) }}" alt="{{ result.title|striptags }} {{ result.engine }}" /></a>
+ <p class="col-xs-12 col-sm-9 col-md-9 result-content">
+ {% if result.price %}<big>{{ result.price|safe }}</big></br>{% endif %}
+ {% if result.shipping %}<small>{{ result.shipping|safe }}</small></br>{% endif %}
+ {% if result.source_country %}<small>{{ result.source_country|safe }}</small></br>{% endif %}
+ {% if result.content %}{{ result.content|safe }}{% endif %}
+ </p>
+ </div>
+</div>
+
+{% if rtl %}
+{{ result_footer_rtl(result) }}
+{% else %}
+{{ result_footer(result) }}
+{% endif %}
diff --git a/searx/templates/oscar/results.html b/searx/templates/oscar/results.html
index 7a444d1..7f60713 100644
--- a/searx/templates/oscar/results.html
+++ b/searx/templates/oscar/results.html
@@ -7,7 +7,7 @@
<input type="hidden" name="language" value="{{ current_language }}" />{{- "" -}}
{% if timeout_limit %}<input type="hidden" name="timeout_limit" value="{{ timeout_limit|e }}" />{% endif -%}
{%- endmacro %}
-{%- macro search_url() %}{{ base_url }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}{% if time_range %}&amp;time_range={{ time_range }}{% endif %}{% if current_language != 'all' %}&amp;language={{ current_language }}{% endif %}{% endmacro -%}
+{%- macro search_url() %}{{ url_for('search', _external=True) }}?q={{ q|urlencode }}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}{% if time_range %}&amp;time_range={{ time_range }}{% endif %}{% if current_language != 'all' %}&amp;language={{ current_language }}{% endif %}{% endmacro -%}
{% block title %}{{ q|e }} - {% endblock %}
{% block meta %}{{" "}}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ search_url() }}&amp;format=rss">{% endblock %}
@@ -42,7 +42,13 @@
</div>
<div class="panel-body">
{% for suggestion in suggestions %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" role="navigation" class="form-inline pull-{% if rtl %}right{% else %}left{% endif %} suggestion_item">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="navigation" class="form-inline pull-{% if rtl %}right{% else %}left{% endif %} suggestion_item">
+ {% if current_language != 'all' %}
+ <input type="hidden" name="language" value="{{ current_language }}">
+ {% endif %}
+ {% if time_range %}
+ <input type="hidden" name="time_range" value="{{ time_range }}">
+ {% endif %}
<input type="hidden" name="q" value="{{ suggestion.url }}">
<button type="submit" class="btn btn-default btn-xs">{{ suggestion.title }}</button>
</form>
@@ -65,7 +71,7 @@
<label>{{ _('Download results') }}</label>
<div class="clearfix"></div>
{% for output_type in ('csv', 'json', 'rss') %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" class="form-inline pull-{% if rtl %}right{% else %}left{% endif %} result_download">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="form-inline pull-{% if rtl %}right{% else %}left{% endif %} result_download">
{{- search_form_attrs(pageno) -}}
<input type="hidden" name="format" value="{{ output_type }}">{{- "" -}}
<button type="submit" class="btn btn-default">{{ output_type }}</button>{{- "" -}}
@@ -83,13 +89,21 @@
{% if corrections -%}
<div class="result">
- <span class="result_header text-muted form-inline pull-left suggestion_item">{{ _('Try searching for:') }}</span>
- {% for correction in corrections -%}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" role="navigation" class="form-inline pull-left suggestion_item">{{- "" -}}
- <input type="hidden" name="q" value="{{ correction.url }}">{{- "" -}}
- <button type="submit" class="btn btn-default btn-xs">{{ correction.title }}</button>{{- "" -}}
- </form>
- {% endfor %}
+ <div class="clearfix">
+ <span class="result_header text-muted form-inline pull-left suggestion_item">{{ _('Try searching for:') }}</span>
+ {% for correction in corrections -%}
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="navigation" class="form-inline pull-left suggestion_item">{{- "" -}}
+ {% if current_language != 'all' %}
+ <input type="hidden" name="language" value="{{ current_language }}">
+ {% endif %}
+ {% if time_range %}
+ <input type="hidden" name="time_range" value="{{ time_range }}">
+ {% endif %}
+ <input type="hidden" name="q" value="{{ correction.url }}">{{- "" -}}
+ <button type="submit" class="btn btn-default btn-xs">{{ correction.title }}</button>{{- "" -}}
+ </form>
+ {% endfor %}
+ </div>
</div>
{%- endif %}
@@ -126,13 +140,13 @@
{% if rtl %}
<div id="pagination">
<div class="pull-left">{{- "" -}}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" class="pull-left">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="pull-left">
{{- search_form_attrs(pageno+1) -}}
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-backward"></span> {{ _('next page') }}</button>{{- "" -}}
</form>{{- "" -}}
</div>
<div class="pull-right">{{- "" -}}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" class="pull-left">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="pull-left">
{{- search_form_attrs(pageno-1) -}}
<button type="submit" class="btn btn-default" {% if pageno == 1 %}disabled{% endif %}><span class="glyphicon glyphicon-forward"></span> {{ _('previous page') }}</button>{{- "" -}}
</form>{{- "" -}}
@@ -142,13 +156,13 @@
{% else %}
<div id="pagination">
<div class="pull-left">{{- "" -}}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" class="pull-left">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="pull-left">
{{- search_form_attrs(pageno-1) -}}
<button type="submit" class="btn btn-default" {% if pageno == 1 %}disabled{% endif %}><span class="glyphicon glyphicon-backward"></span> {{ _('previous page') }}</button>{{- "" -}}
</form>{{- "" -}}
</div>
<div class="pull-right">{{- "" -}}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" class="pull-left">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" class="pull-left">
{{- search_form_attrs(pageno+1) -}}
<button type="submit" class="btn btn-default"><span class="glyphicon glyphicon-forward"></span> {{ _('next page') }}</button>{{- "" -}}
</form>{{- "" -}}
diff --git a/searx/templates/oscar/search.html b/searx/templates/oscar/search.html
index 666a4df..2b3758e 100644
--- a/searx/templates/oscar/search.html
+++ b/searx/templates/oscar/search.html
@@ -1,12 +1,12 @@
{% from 'oscar/macros.html' import icon %}
-<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form" role="search">
+<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" id="search_form" role="search">
<div class="row">
<div class="col-xs-12 col-md-8">
<div class="input-group search-margin">
<input type="search" autofocus name="q" class="form-control" id="q" placeholder="{{ _('Search for...') }}" aria-label="{{ _('Search for...') }}" autocomplete="off" value="{{ q }}" accesskey="s">
<span class="input-group-btn">
<button type="submit" class="btn btn-default" aria-label="{{ _('Start search') }}"><span class="hide_if_nojs">{{ icon('search') }}</span><span class="hidden active_if_nojs">{{ _('Start search') }}</span></button>
- <button type="reset" class="btn btn-default" aria-label="{{ _('Clear search') }}"><span class="hide_if_nojs">{{ icon('remove') }}</span><span class="hidden active_if_nojs">{{ _('Clear') }}</span></button>
+ <button type="button" id="clear_search" class="btn btn-default hide_if_nojs" aria-label="{{ _('Clear search') }}">{{ icon('remove') }}</button>
</span>
</div>
</div>
diff --git a/searx/templates/oscar/search_full.html b/searx/templates/oscar/search_full.html
index 1f1c50e..d398230 100644
--- a/searx/templates/oscar/search_full.html
+++ b/searx/templates/oscar/search_full.html
@@ -1,6 +1,6 @@
{% from 'oscar/macros.html' import icon %}
-<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form" role="search">
+<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" id="search_form" role="search">
{% if rtl %}
<div class="input-group">
{% else %}
diff --git a/searx/templates/oscar/time-range.html b/searx/templates/oscar/time-range.html
index 181b576..6087dd4 100644
--- a/searx/templates/oscar/time-range.html
+++ b/searx/templates/oscar/time-range.html
@@ -1,5 +1,6 @@
+{% from 'oscar/macros.html' import custom_select_class %}
<label class="visually-hidden" for="time-range">{{ _('Time range') }}</label>
-<select name="time_range" id="time-range" class="custom-select form-control" accesskey="t">{{- "" -}}
+<select name="time_range" id="time-range" class="{{ custom_select_class(rtl) }} form-control" accesskey="t">{{- "" -}}
<option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range else ""}}>
{{- _('Anytime') -}}
</option>{{- "" -}}
diff --git a/searx/templates/pix-art/preferences.html b/searx/templates/pix-art/preferences.html
index 05876de..ee41543 100644
--- a/searx/templates/pix-art/preferences.html
+++ b/searx/templates/pix-art/preferences.html
@@ -5,6 +5,7 @@
<h2>{{ _('Preferences') }}</h2>
<form method="post" action="{{ url_for('preferences') }}" id="search_form">
+ {% if 'language' not in locked_preferences %}
<fieldset>
<legend>{{ _('Search language') }}</legend>
<p>
@@ -16,6 +17,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'locale' not in locked_preferences %}
<fieldset>
<legend>{{ _('Interface language') }}</legend>
<p>
@@ -26,6 +29,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'method' not in locked_preferences %}
<fieldset>
<legend>{{ _('Method') }}</legend>
<p>
@@ -35,6 +40,8 @@
</select>
</p>
</fieldset>
+ {% endif %}
+ {% if 'theme' not in locked_preferences %}
<fieldset>
<legend>{{ _('Themes') }}</legend>
<p>
@@ -45,6 +52,7 @@
</select>
</p>
</fieldset>
+ {% endif %}
<fieldset>
<legend>{{ _('Currently used search engines') }}</legend>
diff --git a/searx/templates/pix-art/search.html b/searx/templates/pix-art/search.html
index bb40559..210913e 100644
--- a/searx/templates/pix-art/search.html
+++ b/searx/templates/pix-art/search.html
@@ -1,4 +1,4 @@
-<form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" id="search_form">
+<form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" id="search_form">
<div id="search_wrapper">
<input type="text" autofocus placeholder="{{ _('Search for...') }}" id="q" class="q" name="q" tabindex="1" size="100" {% if q %}value="{{ q }}"{% endif %}/>
<input type="submit" value="" id="search_submit" />
diff --git a/searx/templates/simple/404.html b/searx/templates/simple/404.html
index 11d6043..1a10514 100644
--- a/searx/templates/simple/404.html
+++ b/searx/templates/simple/404.html
@@ -3,7 +3,7 @@
<div class="center">
<h1>{{ _('Page not found') }}</h1>
{% autoescape false %}
- <p>{{ _('Go to %(search_page)s.', search_page=unicode('<a href="{}">{}</a>').format(url_for('index'), _('search page'))) }}</p>
+ <p>{{ _('Go to %(search_page)s.', search_page='<a href="{}">{}</a>'.format(url_for('index'), _('search page'))) }}</p>
{% endautoescape %}
</div>
{% endblock %}
diff --git a/searx/templates/simple/base.html b/searx/templates/simple/base.html
index 5cb1e17..10fb424 100644
--- a/searx/templates/simple/base.html
+++ b/searx/templates/simple/base.html
@@ -2,7 +2,7 @@
<html class="no-js" lang="en" {% if rtl %} dir="rtl"{% endif %}>
<head>
<meta charset="UTF-8" />
- <meta name="description" content="searx - a privacy-respecting, hackable metasearch engine">
+ <meta name="description" content="searx — a privacy-respecting, hackable metasearch engine">
<meta name="keywords" content="searx, search, search engine, metasearch, meta search">
<meta name="generator" content="searx/{{ searx_version }}">
<meta name="referrer" content="no-referrer">
@@ -29,7 +29,7 @@
data-no-item-found="{{ _('No item found') }}"></script>
<!--<![endif]-->
{% block head %}
- <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
+ <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ opensearch_url }}"/>
{% endblock %}
<link rel="shortcut icon" href="{{ url_for('static', filename='img/favicon.png') }}" />
</head>
@@ -51,7 +51,7 @@
</main>
<footer>
<p>
- {{ _('Powered by') }} <a href="{{ url_for('about') }}">searx</a> - {{ searx_version }} - {{ _('a privacy-respecting, hackable metasearch engine') }}<br/>
+ {{ _('Powered by') }} <a href="{{ url_for('about') }}">searx</a> - {{ searx_version }} — {{ _('a privacy-respecting, hackable metasearch engine') }}<br/>
<a href="{{ brand.GIT_URL }}">{{ _('Source code') }}</a> |
<a href="{{ brand.ISSUE_URL }}">{{ _('Issue tracker') }}</a> |
<a href="{{ brand.PUBLIC_INSTANCES }}">{{ _('Public instances') }}</a>
diff --git a/searx/templates/simple/infobox.html b/searx/templates/simple/infobox.html
index 50b5689..56c51af 100644
--- a/searx/templates/simple/infobox.html
+++ b/searx/templates/simple/infobox.html
@@ -1,7 +1,6 @@
<aside class="infobox">
<h2><bdi>{{ infobox.infobox }}</bdi></h2>
{% if infobox.img_src %}<img src="{{ image_proxify(infobox.img_src) }}" title="{{ infobox.infobox|striptags }}" alt="{{ infobox.infobox|striptags }}" />{% endif %}
- <p><bdi>{{ infobox.entity }}</bdi></p>
<p><bdi>{{ infobox.content | safe }}</bdi></p>
{% if infobox.attributes %}
<div class="attributes">
@@ -34,7 +33,7 @@
<div>
<h3><bdi>{{ topic.name }}</bdi></h3>
{% for suggestion in topic.suggestions %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="language" value="{{ current_language }}">
diff --git a/searx/templates/simple/macros.html b/searx/templates/simple/macros.html
index cacbbec..1eb4266 100644
--- a/searx/templates/simple/macros.html
+++ b/searx/templates/simple/macros.html
@@ -1,6 +1,6 @@
<!-- Draw glyphicon icon from bootstrap-theme -->
-{% macro icon(action) -%}
- <span class="ion-icon-big ion-{{ action }}"></span>
+{% macro icon(action, alt) -%}
+ <span title="{{ alt }}" class="ion-icon-big ion-{{ action }}"></span>
{%- endmacro %}
{% macro icon_small(action) -%}
diff --git a/searx/templates/simple/preferences.html b/searx/templates/simple/preferences.html
index 7437ed4..f091a97 100644
--- a/searx/templates/simple/preferences.html
+++ b/searx/templates/simple/preferences.html
@@ -1,4 +1,4 @@
-{% from 'simple/macros.html' import tabs_open, tabs_close, tab_header, tab_footer, checkbox_onoff, checkbox %}
+{% from 'simple/macros.html' import icon, tabs_open, tabs_close, tab_header, tab_footer, checkbox_onoff, checkbox %}
{% extends "simple/base.html" %}
@@ -30,11 +30,14 @@
{{ tabs_open() }}
{{ tab_header('maintab', 'general', _('General')) }}
+ {% if 'categories' not in locked_preferences %}
<fieldset>
<legend>{{ _('Default categories') }}</legend>
{% set display_tooltip = false %}
{% include 'simple/categories.html' %}
</fieldset>
+ {% endif %}
+ {% if 'language' not in locked_preferences %}
<fieldset>
<legend>{{ _('Search language') }}</legend>
<p class="value">{{- '' -}}
@@ -47,6 +50,8 @@
</p>
<div class="description">{{ _('What language do you prefer for search?') }}</div>
</fieldset>
+ {% endif %}
+ {% if 'autocomplete' not in locked_preferences %}
<fieldset>
<legend>{{ _('Autocomplete') }}</legend>
<p class="value">
@@ -59,6 +64,8 @@
</p>
<div class="description">{{ _('Find stuff as you type') }}</div>
</fieldset>
+ {% endif %}
+ {% if 'safesearch' not in locked_preferences %}
<fieldset>
<legend>{{ _('SafeSearch') }}</legend>
<p class="value">
@@ -70,7 +77,9 @@
</p>
<p class="description">{{ _('Filter content') }}</p>
</fieldset>
+ {% endif %}
{{ plugin_preferences('general') }}
+ {% if 'doi_resolver' not in locked_preferences %}
<fieldset>
<legend>{{ _('Open Access DOI resolver') }}</legend>
<p class="value">
@@ -84,6 +93,7 @@
</p>
<div class="description"><!-- {{ _('Redirect to open-access versions of publications when available (plugin required)') }} --></div>
</fieldset>
+ {% endif %}
{{ tab_footer() }}
{{ tab_header('maintab', 'engines', _('Engines')) }}
@@ -111,7 +121,7 @@
{% set engine_id = 'engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_') %}
<tr>
<td class="engine_checkbox">{{ checkbox_onoff(engine_id, (search_engine.name, categ) in disabled_engines) }}</td>
- <th class="name">{{ search_engine.name }}</th>
+ <th class="name">{% if not search_engine.https_support %}{{ icon('warning', 'No HTTPS') }}{% endif %} {{ search_engine.name }}</th>
<td class="shortcut">{{ shortcuts[search_engine.name] }}</td>
<td>{{ checkbox(engine_id + '_supported_languages', current_language == 'all' or current_language in search_engine.supported_languages or current_language.split('-')[0] in search_engine.supported_languages, true, true) }}</td>
<td>{{ checkbox(engine_id + '_safesearch', search_engine.safesearch==True, true, true) }}</td>
@@ -129,6 +139,7 @@
{{ tab_footer() }}
{{ tab_header('maintab', 'ui', _('User interface')) }}
+ {% if 'locale' not in locked_preferences %}
<fieldset>
<legend>{{ _('Interface language') }}</legend>
<p class="value">
@@ -140,6 +151,8 @@
</p>
<div class="description">{{ _('Change the language of the layout') }}</div>
</fieldset>
+ {% endif %}
+ {% if 'theme' not in locked_preferences %}
<fieldset>
<legend>{{ _('Themes') }}</legend>
<p class="value">
@@ -151,6 +164,8 @@
</p>
<div class="description">{{ _('Change searx layout') }}</div>
</fieldset>
+ {% endif %}
+ {% if 'results_on_new_tab' not in locked_preferences %}
<fieldset>
<legend>{{ _('Results on new tabs') }}</legend>
<p class="value">
@@ -161,6 +176,7 @@
</p>
<div class="description">{{_('Open result links on new browser tabs') }}</div>
</fieldset>
+ {% endif %}
{{ plugin_preferences('ui') }}
{{ tab_footer() }}
@@ -197,6 +213,7 @@
{{ tab_footer() }}
{{ tab_header('maintab', 'privacy', _('Privacy')) }}
+ {% if 'method' not in locked_preferences %}
<fieldset>
<legend>{{ _('Method') }}</legend>
<p class="value">
@@ -207,6 +224,8 @@
</p>
<div class="description">{{ _('Search language') }}</div>
</fieldset>
+ {% endif %}
+ {% if 'image_proxy' not in locked_preferences %}
<fieldset>
<legend>{{ _('Image proxy') }}</legend>
<p class="value">
@@ -217,6 +236,7 @@
</p>
<div class="description">{{ _('Proxying image results through searx') }}</div>
</fieldset>
+ {% endif %}
{{ plugin_preferences('privacy') }}
{{ tab_footer() }}
diff --git a/searx/templates/simple/results.html b/searx/templates/simple/results.html
index 2e39319..936de88 100644
--- a/searx/templates/simple/results.html
+++ b/searx/templates/simple/results.html
@@ -1,7 +1,7 @@
{% extends "simple/base.html" %}
{% from 'simple/macros.html' import icon, icon_small %}
{% block title %}{% if method == 'GET' %}{{- q|e -}} -{% endif %}{% endblock %}
-{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('index') }}?q={{ q|urlencode }}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}&amp;pageno={{ pageno }}&amp;time_range={{ time_range }}&amp;language={{ current_language }}&amp;safesearch={{ safesearch }}&amp;format=rss">{% endblock %}
+{% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q|e }}" href="{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}&amp;pageno={{ pageno }}&amp;time_range={{ time_range }}&amp;language={{ current_language }}&amp;safesearch={{ safesearch }}&amp;format=rss">{% endblock %}
{% block content %}
<nav id="linkto_preferences"><a href="{{ url_for('preferences') }}">{{ icon('navicon-round') }}</a></nav>
{% include 'simple/search.html' %}
@@ -55,7 +55,7 @@
<h4 class="title">{{ _('Suggestions') }} : </h4>
<div class="wrapper">
{% for suggestion in suggestions %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ suggestion.url }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="language" value="{{ current_language }}">
@@ -71,13 +71,13 @@
<div id="search_url">
<h4 class="title">{{ _('Search URL') }} :</h4>
- <div class="selectable_url"><pre>{{ base_url }}?q={{ q|urlencode }}&amp;language={{ current_language }}&amp;time_range={{ time_range }}&amp;safesearch={{ safesearch }}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if timeout_limit %}&amp;timeout_limit={{ timeout_limit|urlencode }}{% endif %}</pre></div>
+ <div class="selectable_url"><pre>{{ url_for('search', _external=True) }}?q={{ q|urlencode }}&amp;language={{ current_language }}&amp;time_range={{ time_range }}&amp;safesearch={{ safesearch }}{% if pageno > 1 %}&amp;pageno={{ pageno }}{% endif %}{% if selected_categories %}&amp;categories={{ selected_categories|join(",") | replace(' ','+') }}{% endif %}{% if timeout_limit %}&amp;timeout_limit={{ timeout_limit|urlencode }}{% endif %}</pre></div>
</div>
<div id="apis">
<h4 class="title">{{ _('Download results') }}</h4>
{% for output_type in ('csv', 'json', 'rss') %}
<div class="left">
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<input type="hidden" name="q" value="{{ q|e }}">
{% for category in selected_categories %}
<input type="hidden" name="category_{{ category }}" value="1">
@@ -100,7 +100,7 @@
<h4>{{ _('Try searching for:') }}</h4>
{% for correction in corrections %}
<div class="left">
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}" role="navigation">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}" role="navigation">
<input type="hidden" name="q" value="{{ correction.url }}">
<input type="hidden" name="time_range" value="{{ time_range }}">
<input type="hidden" name="language" value="{{ current_language }}">
@@ -133,7 +133,7 @@
{% if paging %}
<nav id="pagination">
{% if pageno > 1 %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="{% if rtl %}right{% else %}left{% endif %}">
<input type="hidden" name="q" value="{{ q|e }}" >
{% for category in selected_categories %}
@@ -149,7 +149,7 @@
</div>
</form>
{% endif %}
- <form method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+ <form method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div class="{% if rtl %}left{% else %}right{% endif %}">
<input type="hidden" name="q" value="{{ q|e }}" >
{% for category in selected_categories %}
diff --git a/searx/templates/simple/search.html b/searx/templates/simple/search.html
index 61d52db..176e790 100644
--- a/searx/templates/simple/search.html
+++ b/searx/templates/simple/search.html
@@ -1,4 +1,4 @@
-<form id="search" method="{{ method or 'POST' }}" action="{{ url_for('index') }}">
+<form id="search" method="{{ method or 'POST' }}" action="{{ url_for('search') }}">
<div id="search_wrapper">
<div class="search_box">
<input id="q" autofocus name="q" type="text" placeholder="{{ _('Search for...') }}" tabindex="1" autocomplete="off" spellcheck="false" dir="auto" {% if q %}value="{{ q }}"{% endif %} >
diff --git a/searx/testing.py b/searx/testing.py
index f0e303e..c529749 100644
--- a/searx/testing.py
+++ b/searx/testing.py
@@ -17,7 +17,7 @@ from unittest2 import TestCase
class SearxTestLayer:
"""Base layer for non-robot tests."""
- __name__ = u'SearxTestLayer'
+ __name__ = 'SearxTestLayer'
@classmethod
def setUp(cls):
@@ -66,7 +66,7 @@ class SearxRobotLayer():
stderr=subprocess.STDOUT
)
if hasattr(self.server.stdout, 'read1'):
- print(self.server.stdout.read1(1024).decode('utf-8'))
+ print(self.server.stdout.read1(1024).decode())
def tearDown(self):
os.kill(self.server.pid, 9)
diff --git a/searx/url_utils.py b/searx/url_utils.py
deleted file mode 100644
index dcafc3b..0000000
--- a/searx/url_utils.py
+++ /dev/null
@@ -1,30 +0,0 @@
-from sys import version_info
-
-if version_info[0] == 2:
- from urllib import quote, quote_plus, unquote, urlencode
- from urlparse import parse_qs, parse_qsl, urljoin, urlparse, urlunparse, ParseResult
-else:
- from urllib.parse import (
- parse_qs,
- parse_qsl,
- quote,
- quote_plus,
- unquote,
- urlencode,
- urljoin,
- urlparse,
- urlunparse,
- ParseResult
- )
-
-
-__export__ = (parse_qs,
- parse_qsl,
- quote,
- quote_plus,
- unquote,
- urlencode,
- urljoin,
- urlparse,
- urlunparse,
- ParseResult)
diff --git a/searx/utils.py b/searx/utils.py
index 5ea9dc8..057e9d0 100644
--- a/searx/utils.py
+++ b/searx/utils.py
@@ -1,45 +1,26 @@
# -*- coding: utf-8 -*-
-import csv
-import hashlib
-import hmac
-import os
+import sys
import re
+import importlib
-from babel.core import get_global
-from babel.dates import format_date
-from codecs import getincrementalencoder
-from imp import load_source
from numbers import Number
from os.path import splitext, join
-from io import open
from random import choice
-from lxml.etree import XPath
-import sys
-import json
+from html.parser import HTMLParser
+from urllib.parse import urljoin, urlparse
+
+from lxml import html
+from lxml.etree import ElementBase, XPath, XPathError, XPathSyntaxError, _ElementStringResult, _ElementUnicodeResult
+from babel.core import get_global
+
from searx import settings
+from searx.data import USER_AGENTS
from searx.version import VERSION_STRING
from searx.languages import language_codes
-from searx import settings
+from searx.exceptions import SearxXPathSyntaxException, SearxEngineXPathException
from searx import logger
-try:
- from cStringIO import StringIO
-except:
- from io import StringIO
-
-try:
- from HTMLParser import HTMLParser
-except:
- from html.parser import HTMLParser
-
-if sys.version_info[0] == 3:
- unichr = chr
- unicode = str
- IS_PY2 = False
- basestring = str
-else:
- IS_PY2 = True
logger = logger.getChild('utils')
@@ -49,52 +30,37 @@ blocked_tags = ('script',
ecma_unescape4_re = re.compile(r'%u([0-9a-fA-F]{4})', re.UNICODE)
ecma_unescape2_re = re.compile(r'%([0-9a-fA-F]{2})', re.UNICODE)
-useragents = json.loads(open(os.path.dirname(os.path.realpath(__file__))
- + "/data/useragents.json", 'r', encoding='utf-8').read())
-
xpath_cache = dict()
lang_to_lc_cache = dict()
+class NotSetClass:
+ pass
+
+
+NOTSET = NotSetClass()
+
+
def searx_useragent():
+ """Return the searx User Agent"""
return 'searx/{searx_version} {suffix}'.format(
searx_version=VERSION_STRING,
suffix=settings['outgoing'].get('useragent_suffix', ''))
def gen_useragent(os=None):
- return str(useragents['ua'].format(os=os or choice(useragents['os']), version=choice(useragents['versions'])))
-
+ """Return a random browser User Agent
-def highlight_content(content, query):
+ See searx/data/useragents.json
+ """
+ return str(USER_AGENTS['ua'].format(os=os or choice(USER_AGENTS['os']), version=choice(USER_AGENTS['versions'])))
- if not content:
- return None
- # ignoring html contents
- # TODO better html content detection
- if content.find('<') != -1:
- return content
-
- query = query.decode('utf-8')
- if content.lower().find(query.lower()) > -1:
- query_regex = u'({0})'.format(re.escape(query))
- content = re.sub(query_regex, '<span class="highlight">\\1</span>',
- content, flags=re.I | re.U)
- else:
- regex_parts = []
- for chunk in query.split():
- if len(chunk) == 1:
- regex_parts.append(u'\\W+{0}\\W+'.format(re.escape(chunk)))
- else:
- regex_parts.append(u'{0}'.format(re.escape(chunk)))
- query_regex = u'({0})'.format('|'.join(regex_parts))
- content = re.sub(query_regex, '<span class="highlight">\\1</span>',
- content, flags=re.I | re.U)
- return content
+class HTMLTextExtractorException(Exception):
+ pass
-class HTMLTextExtractor(HTMLParser):
+class HTMLTextExtractor(HTMLParser): # pylint: disable=W0223 # (see https://bugs.python.org/issue31844)
def __init__(self):
HTMLParser.__init__(self)
@@ -109,140 +75,193 @@ class HTMLTextExtractor(HTMLParser):
return
if tag != self.tags[-1]:
- raise Exception("invalid html")
+ raise HTMLTextExtractorException()
self.tags.pop()
def is_valid_tag(self):
return not self.tags or self.tags[-1] not in blocked_tags
- def handle_data(self, d):
+ def handle_data(self, data):
if not self.is_valid_tag():
return
- self.result.append(d)
+ self.result.append(data)
- def handle_charref(self, number):
+ def handle_charref(self, name):
if not self.is_valid_tag():
return
- if number[0] in (u'x', u'X'):
- codepoint = int(number[1:], 16)
+ if name[0] in ('x', 'X'):
+ codepoint = int(name[1:], 16)
else:
- codepoint = int(number)
- self.result.append(unichr(codepoint))
+ codepoint = int(name)
+ self.result.append(chr(codepoint))
def handle_entityref(self, name):
if not self.is_valid_tag():
return
# codepoint = htmlentitydefs.name2codepoint[name]
- # self.result.append(unichr(codepoint))
+ # self.result.append(chr(codepoint))
self.result.append(name)
def get_text(self):
- return u''.join(self.result).strip()
+ return ''.join(self.result).strip()
-def html_to_text(html):
- html = html.replace('\n', ' ')
- html = ' '.join(html.split())
- s = HTMLTextExtractor()
- s.feed(html)
- return s.get_text()
+def html_to_text(html_str):
+ """Extract text from a HTML string
+ Args:
+ * html_str (str): string HTML
-class UnicodeWriter:
- """
- A CSV writer which will write rows to CSV file "f",
- which is encoded in the given encoding.
- """
-
- def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
- # Redirect output to a queue
- self.queue = StringIO()
- self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
- self.stream = f
- self.encoder = getincrementalencoder(encoding)()
-
- def writerow(self, row):
- if IS_PY2:
- row = [s.encode("utf-8") if hasattr(s, 'encode') else s for s in row]
- self.writer.writerow(row)
- # Fetch UTF-8 output from the queue ...
- data = self.queue.getvalue()
- if IS_PY2:
- data = data.decode("utf-8")
- else:
- data = data.strip('\x00')
- # ... and reencode it into the target encoding
- data = self.encoder.encode(data)
- # write to the target stream
- if IS_PY2:
- self.stream.write(data)
- else:
- self.stream.write(data.decode("utf-8"))
- # empty queue
- self.queue.truncate(0)
-
- def writerows(self, rows):
- for row in rows:
- self.writerow(row)
-
-
-def get_resources_directory(searx_directory, subdirectory, resources_directory):
- if not resources_directory:
- resources_directory = os.path.join(searx_directory, subdirectory)
- if not os.path.isdir(resources_directory):
- raise Exception(resources_directory + " is not a directory")
- return resources_directory
-
-
-def get_themes(templates_path):
- """Returns available themes list."""
- themes = os.listdir(templates_path)
- if '__common__' in themes:
- themes.remove('__common__')
- return themes
-
-
-def get_static_files(static_path):
- static_files = set()
- static_path_length = len(static_path) + 1
- for directory, _, files in os.walk(static_path):
- for filename in files:
- f = os.path.join(directory[static_path_length:], filename)
- static_files.add(f)
- return static_files
-
-
-def get_result_templates(templates_path):
- result_templates = set()
- templates_path_length = len(templates_path) + 1
- for directory, _, files in os.walk(templates_path):
- if directory.endswith('result_templates'):
- for filename in files:
- f = os.path.join(directory[templates_path_length:], filename)
- result_templates.add(f)
- return result_templates
+ Returns:
+ * str: extracted text
+ Examples:
+ >>> html_to_text('Example <span id="42">#2</span>')
+ 'Example #2'
-def format_date_by_locale(date, locale_string):
- # strftime works only on dates after 1900
+ >>> html_to_text('<style>.span { color: red; }</style><span>Example</span>')
+ 'Example'
+ """
+ html_str = html_str.replace('\n', ' ')
+ html_str = ' '.join(html_str.split())
+ s = HTMLTextExtractor()
+ try:
+ s.feed(html_str)
+ except HTMLTextExtractorException:
+ logger.debug("HTMLTextExtractor: invalid HTML\n%s", html_str)
+ return s.get_text()
- if date.year <= 1900:
- return date.isoformat().split('T')[0]
- if locale_string == 'all':
- locale_string = settings['ui']['default_locale'] or 'en_US'
+def extract_text(xpath_results, allow_none=False):
+ """Extract text from a lxml result
- # to avoid crashing if locale is not supported by babel
- try:
- formatted_date = format_date(date, locale=locale_string)
- except:
- formatted_date = format_date(date, "YYYY-MM-dd")
+ * if xpath_results is list, extract the text from each result and concat the list
+ * if xpath_results is a xml element, extract all the text node from it
+ ( text_content() method from lxml )
+ * if xpath_results is a string element, then it's already done
+ """
+ if isinstance(xpath_results, list):
+ # it's list of result : concat everything using recursive call
+ result = ''
+ for e in xpath_results:
+ result = result + extract_text(e)
+ return result.strip()
+ elif isinstance(xpath_results, ElementBase):
+ # it's a element
+ text = html.tostring(
+ xpath_results, encoding='unicode', method='text', with_tail=False
+ )
+ text = text.strip().replace('\n', ' ')
+ return ' '.join(text.split())
+ elif isinstance(xpath_results, (_ElementStringResult, _ElementUnicodeResult, str, Number, bool)):
+ return str(xpath_results)
+ elif xpath_results is None and allow_none:
+ return None
+ elif xpath_results is None and not allow_none:
+ raise ValueError('extract_text(None, allow_none=False)')
+ else:
+ raise ValueError('unsupported type')
+
+
+def normalize_url(url, base_url):
+ """Normalize URL: add protocol, join URL with base_url, add trailing slash if there is no path
+
+ Args:
+ * url (str): Relative URL
+ * base_url (str): Base URL, it must be an absolute URL.
+
+ Example:
+ >>> normalize_url('https://example.com', 'http://example.com/')
+ 'https://example.com/'
+ >>> normalize_url('//example.com', 'http://example.com/')
+ 'http://example.com/'
+ >>> normalize_url('//example.com', 'https://example.com/')
+ 'https://example.com/'
+ >>> normalize_url('/path?a=1', 'https://example.com')
+ 'https://example.com/path?a=1'
+ >>> normalize_url('', 'https://example.com')
+ 'https://example.com/'
+ >>> normalize_url('/test', '/path')
+ raise ValueError
+
+ Raises:
+ * lxml.etree.ParserError
+
+ Returns:
+ * str: normalized URL
+ """
+ if url.startswith('//'):
+ # add http or https to this kind of url //example.com/
+ parsed_search_url = urlparse(base_url)
+ url = '{0}:{1}'.format(parsed_search_url.scheme or 'http', url)
+ elif url.startswith('/'):
+ # fix relative url to the search engine
+ url = urljoin(base_url, url)
+
+ # fix relative urls that fall through the crack
+ if '://' not in url:
+ url = urljoin(base_url, url)
+
+ parsed_url = urlparse(url)
+
+ # add a / at this end of the url if there is no path
+ if not parsed_url.netloc:
+ raise ValueError('Cannot parse url')
+ if not parsed_url.path:
+ url += '/'
+
+ return url
+
+
+def extract_url(xpath_results, base_url):
+ """Extract and normalize URL from lxml Element
+
+ Args:
+ * xpath_results (Union[List[html.HtmlElement], html.HtmlElement]): lxml Element(s)
+ * base_url (str): Base URL
+
+ Example:
+ >>> def f(s, search_url):
+ >>> return searx.utils.extract_url(html.fromstring(s), search_url)
+ >>> f('<span id="42">https://example.com</span>', 'http://example.com/')
+ 'https://example.com/'
+ >>> f('https://example.com', 'http://example.com/')
+ 'https://example.com/'
+ >>> f('//example.com', 'http://example.com/')
+ 'http://example.com/'
+ >>> f('//example.com', 'https://example.com/')
+ 'https://example.com/'
+ >>> f('/path?a=1', 'https://example.com')
+ 'https://example.com/path?a=1'
+ >>> f('', 'https://example.com')
+ raise lxml.etree.ParserError
+ >>> searx.utils.extract_url([], 'https://example.com')
+ raise ValueError
+
+ Raises:
+ * ValueError
+ * lxml.etree.ParserError
+
+ Returns:
+ * str: normalized URL
+ """
+ if xpath_results == []:
+ raise ValueError('Empty url resultset')
- return formatted_date
+ url = extract_text(xpath_results)
+ return normalize_url(url, base_url)
def dict_subset(d, properties):
+ """Extract a subset of a dict
+
+ Examples:
+ >>> dict_subset({'A': 'a', 'B': 'b', 'C': 'c'}, ['A', 'C'])
+ {'A': 'a', 'C': 'c'}
+ >>> >> dict_subset({'A': 'a', 'B': 'b', 'C': 'c'}, ['A', 'D'])
+ {'A': 'a'}
+ """
result = {}
for k in properties:
if k in d:
@@ -250,23 +269,22 @@ def dict_subset(d, properties):
return result
-def prettify_url(url, max_length=74):
- if len(url) > max_length:
- chunk_len = int(max_length / 2 + 1)
- return u'{0}[...]{1}'.format(url[:chunk_len], url[-chunk_len:])
- else:
- return url
-
+def get_torrent_size(filesize, filesize_multiplier):
+ """
-# get element in list or default value
-def list_get(a_list, index, default=None):
- if len(a_list) > index:
- return a_list[index]
- else:
- return default
+ Args:
+ * filesize (str): size
+ * filesize_multiplier (str): TB, GB, .... TiB, GiB...
+ Returns:
+ * int: number of bytes
-def get_torrent_size(filesize, filesize_multiplier):
+ Example:
+ >>> get_torrent_size('5', 'GB')
+ 5368709120
+ >>> get_torrent_size('3.14', 'MiB')
+ 3140000
+ """
try:
filesize = float(filesize)
@@ -286,21 +304,25 @@ def get_torrent_size(filesize, filesize_multiplier):
filesize = int(filesize * 1000 * 1000)
elif filesize_multiplier == 'KiB':
filesize = int(filesize * 1000)
- except:
+ except ValueError:
filesize = None
return filesize
def convert_str_to_int(number_str):
+ """Convert number_str to int or 0 if number_str is not a number."""
if number_str.isdigit():
return int(number_str)
else:
return 0
-# convert a variable to integer or return 0 if it's not a number
def int_or_zero(num):
+ """Convert num to int or 0. num can be either a str or a list.
+ If num is a list, the first element is converted to int (or return 0 if the list is empty).
+ If num is a str, see convert_str_to_int
+ """
if isinstance(num, list):
if len(num) < 1:
return 0
@@ -309,8 +331,26 @@ def int_or_zero(num):
def is_valid_lang(lang):
+ """Return language code and name if lang describe a language.
+
+ Examples:
+ >>> is_valid_lang('zz')
+ False
+ >>> is_valid_lang('uk')
+ (True, 'uk', 'ukrainian')
+ >>> is_valid_lang(b'uk')
+ (True, 'uk', 'ukrainian')
+ >>> is_valid_lang('en')
+ (True, 'en', 'english')
+ >>> searx.utils.is_valid_lang('Español')
+ (True, 'es', 'spanish')
+ >>> searx.utils.is_valid_lang('Spanish')
+ (True, 'es', 'spanish')
+ """
+ if isinstance(lang, bytes):
+ lang = lang.decode()
is_abbr = (len(lang) == 2)
- lang = lang.lower().decode('utf-8')
+ lang = lang.lower()
if is_abbr:
for l in language_codes:
if l[0][:2] == lang:
@@ -334,8 +374,8 @@ def _get_lang_to_lc_dict(lang_list):
return value
-# auxiliary function to match lang_code in lang_list
-def _match_language(lang_code, lang_list=[], custom_aliases={}):
+def _match_language(lang_code, lang_list=[], custom_aliases={}): # pylint: disable=W0102
+ """auxiliary function to match lang_code in lang_list"""
# replace language code with a custom alias if necessary
if lang_code in custom_aliases:
lang_code = custom_aliases[lang_code]
@@ -357,8 +397,8 @@ def _match_language(lang_code, lang_list=[], custom_aliases={}):
return _get_lang_to_lc_dict(lang_list).get(lang_code, None)
-# get the language code from lang_list that best matches locale_code
-def match_language(locale_code, lang_list=[], custom_aliases={}, fallback='en-US'):
+def match_language(locale_code, lang_list=[], custom_aliases={}, fallback='en-US'): # pylint: disable=W0102
+ """get the language code from lang_list that best matches locale_code"""
# try to get language from given locale_code
language = _match_language(locale_code, lang_list, custom_aliases)
if language:
@@ -394,30 +434,20 @@ def load_module(filename, module_dir):
if modname in sys.modules:
del sys.modules[modname]
filepath = join(module_dir, filename)
- module = load_source(modname, filepath)
- module.name = modname
+ # and https://docs.python.org/3/library/importlib.html#importing-a-source-file-directly
+ spec = importlib.util.spec_from_file_location(modname, filepath)
+ module = importlib.util.module_from_spec(spec)
+ sys.modules[modname] = module
+ spec.loader.exec_module(module)
return module
-def new_hmac(secret_key, url):
- try:
- secret_key_bytes = bytes(secret_key, 'utf-8')
- except TypeError as err:
- if isinstance(secret_key, bytes):
- secret_key_bytes = secret_key
- else:
- raise err
- if sys.version_info[0] == 2:
- return hmac.new(bytes(secret_key), url, hashlib.sha256).hexdigest()
- else:
- return hmac.new(secret_key_bytes, url, hashlib.sha256).hexdigest()
-
-
def to_string(obj):
- if isinstance(obj, basestring):
+ """Convert obj to its string representation."""
+ if isinstance(obj, str):
return obj
if isinstance(obj, Number):
- return unicode(obj)
+ return str(obj)
if hasattr(obj, '__str__'):
return obj.__str__()
if hasattr(obj, '__repr__'):
@@ -425,20 +455,36 @@ def to_string(obj):
def ecma_unescape(s):
- """
- python implementation of the unescape javascript function
+ """Python implementation of the unescape javascript function
https://www.ecma-international.org/ecma-262/6.0/#sec-unescape-string
https://developer.mozilla.org/fr/docs/Web/JavaScript/Reference/Objets_globaux/unescape
+
+ Examples:
+ >>> ecma_unescape('%u5409')
+ '吉'
+ >>> ecma_unescape('%20')
+ ' '
+ >>> ecma_unescape('%F3')
+ 'ó'
"""
- # s = unicode(s)
# "%u5409" becomes "吉"
- s = ecma_unescape4_re.sub(lambda e: unichr(int(e.group(1), 16)), s)
+ s = ecma_unescape4_re.sub(lambda e: chr(int(e.group(1), 16)), s)
# "%20" becomes " ", "%F3" becomes "ó"
- s = ecma_unescape2_re.sub(lambda e: unichr(int(e.group(1), 16)), s)
+ s = ecma_unescape2_re.sub(lambda e: chr(int(e.group(1), 16)), s)
return s
+def get_string_replaces_function(replaces):
+ rep = {re.escape(k): v for k, v in replaces.items()}
+ pattern = re.compile("|".join(rep.keys()))
+
+ def f(text):
+ return pattern.sub(lambda m: rep[re.escape(m.group(0))], text)
+
+ return f
+
+
def get_engine_from_settings(name):
"""Return engine configuration from settings.yml of a given engine name"""
@@ -454,14 +500,110 @@ def get_engine_from_settings(name):
return {}
-def get_xpath(xpath_str):
- result = xpath_cache.get(xpath_str, None)
- if result is None:
- result = XPath(xpath_str)
- xpath_cache[xpath_str] = result
+def get_xpath(xpath_spec):
+ """Return cached compiled XPath
+
+ There is no thread lock.
+ Worst case scenario, xpath_str is compiled more than one time.
+
+ Args:
+ * xpath_spec (str|lxml.etree.XPath): XPath as a str or lxml.etree.XPath
+
+ Returns:
+ * result (bool, float, list, str): Results.
+
+ Raises:
+ * TypeError: Raise when xpath_spec is neither a str nor a lxml.etree.XPath
+ * SearxXPathSyntaxException: Raise when there is a syntax error in the XPath
+ """
+ if isinstance(xpath_spec, str):
+ result = xpath_cache.get(xpath_spec, None)
+ if result is None:
+ try:
+ result = XPath(xpath_spec)
+ except XPathSyntaxError as e:
+ raise SearxXPathSyntaxException(xpath_spec, str(e.msg))
+ xpath_cache[xpath_spec] = result
+ return result
+
+ if isinstance(xpath_spec, XPath):
+ return xpath_spec
+
+ raise TypeError('xpath_spec must be either a str or a lxml.etree.XPath')
+
+
+def eval_xpath(element, xpath_spec):
+ """Equivalent of element.xpath(xpath_str) but compile xpath_str once for all.
+ See https://lxml.de/xpathxslt.html#xpath-return-values
+
+ Args:
+ * element (ElementBase): [description]
+ * xpath_spec (str|lxml.etree.XPath): XPath as a str or lxml.etree.XPath
+
+ Returns:
+ * result (bool, float, list, str): Results.
+
+ Raises:
+ * TypeError: Raise when xpath_spec is neither a str nor a lxml.etree.XPath
+ * SearxXPathSyntaxException: Raise when there is a syntax error in the XPath
+ * SearxEngineXPathException: Raise when the XPath can't be evaluated.
+ """
+ xpath = get_xpath(xpath_spec)
+ try:
+ return xpath(element)
+ except XPathError as e:
+ arg = ' '.join([str(i) for i in e.args])
+ raise SearxEngineXPathException(xpath_spec, arg)
+
+
+def eval_xpath_list(element, xpath_spec, min_len=None):
+ """Same as eval_xpath, check if the result is a list
+
+ Args:
+ * element (ElementBase): [description]
+ * xpath_spec (str|lxml.etree.XPath): XPath as a str or lxml.etree.XPath
+ * min_len (int, optional): [description]. Defaults to None.
+
+ Raises:
+ * TypeError: Raise when xpath_spec is neither a str nor a lxml.etree.XPath
+ * SearxXPathSyntaxException: Raise when there is a syntax error in the XPath
+ * SearxEngineXPathException: raise if the result is not a list
+
+ Returns:
+ * result (bool, float, list, str): Results.
+ """
+ result = eval_xpath(element, xpath_spec)
+ if not isinstance(result, list):
+ raise SearxEngineXPathException(xpath_spec, 'the result is not a list')
+ if min_len is not None and min_len > len(result):
+ raise SearxEngineXPathException(xpath_spec, 'len(xpath_str) < ' + str(min_len))
return result
-def eval_xpath(element, xpath_str):
- xpath = get_xpath(xpath_str)
- return xpath(element)
+def eval_xpath_getindex(elements, xpath_spec, index, default=NOTSET):
+ """Call eval_xpath_list then get one element using the index parameter.
+ If the index does not exist, either aise an exception is default is not set,
+ other return the default value (can be None).
+
+ Args:
+ * elements (ElementBase): lxml element to apply the xpath.
+ * xpath_spec (str|lxml.etree.XPath): XPath as a str or lxml.etree.XPath.
+ * index (int): index to get
+ * default (Object, optional): Defaults if index doesn't exist.
+
+ Raises:
+ * TypeError: Raise when xpath_spec is neither a str nor a lxml.etree.XPath
+ * SearxXPathSyntaxException: Raise when there is a syntax error in the XPath
+ * SearxEngineXPathException: if the index is not found. Also see eval_xpath.
+
+ Returns:
+ * result (bool, float, list, str): Results.
+ """
+ result = eval_xpath_list(elements, xpath_spec)
+ if index >= -len(result) and index < len(result):
+ return result[index]
+ if default == NOTSET:
+ # raise an SearxEngineXPathException instead of IndexError
+ # to record xpath_spec
+ raise SearxEngineXPathException(xpath_spec, 'index ' + str(index) + ' not found')
+ return default
diff --git a/searx/version.py b/searx/version.py
index 75bb3c4..d9bf907 100644
--- a/searx/version.py
+++ b/searx/version.py
@@ -18,7 +18,7 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
# version of searx
VERSION_MAJOR = 0
-VERSION_MINOR = 17
+VERSION_MINOR = 18
VERSION_BUILD = 0
VERSION_STRING = "{0}.{1}.{2}".format(VERSION_MAJOR,
diff --git a/searx/webadapter.py b/searx/webadapter.py
new file mode 100644
index 0000000..7c71b72
--- /dev/null
+++ b/searx/webadapter.py
@@ -0,0 +1,255 @@
+from typing import Dict, List, Optional, Tuple
+from searx.exceptions import SearxParameterException
+from searx.webutils import VALID_LANGUAGE_CODE
+from searx.query import RawTextQuery
+from searx.engines import categories, engines
+from searx.search import SearchQuery, EngineRef
+from searx.preferences import Preferences, is_locked
+
+
+# remove duplicate queries.
+# FIXME: does not fix "!music !soundcloud", because the categories are 'none' and 'music'
+def deduplicate_engineref_list(engineref_list: List[EngineRef]) -> List[EngineRef]:
+ engineref_dict = {q.category + '|' + q.name: q for q in engineref_list}
+ return list(engineref_dict.values())
+
+
+def validate_engineref_list(engineref_list: List[EngineRef], preferences: Preferences)\
+ -> Tuple[List[EngineRef], List[EngineRef], List[EngineRef]]:
+ """Validate query_engines according to the preferences
+
+ Returns:
+ List[EngineRef]: list of existing engines with a validated token
+ List[EngineRef]: list of unknown engine
+ List[EngineRef]: list of engine with invalid token according to the preferences
+ """
+ valid = []
+ unknown = []
+ no_token = []
+ for engineref in engineref_list:
+ if engineref.name not in engines:
+ unknown.append(engineref)
+ continue
+
+ engine = engines[engineref.name]
+ if not preferences.validate_token(engine):
+ no_token.append(engineref)
+ continue
+
+ valid.append(engineref)
+ return valid, unknown, no_token
+
+
+def parse_pageno(form: Dict[str, str]) -> int:
+ pageno_param = form.get('pageno', '1')
+ if not pageno_param.isdigit() or int(pageno_param) < 1:
+ raise SearxParameterException('pageno', pageno_param)
+ return int(pageno_param)
+
+
+def parse_lang(preferences: Preferences, form: Dict[str, str], raw_text_query: RawTextQuery) -> str:
+ if is_locked('language'):
+ return preferences.get_value('langueage')
+ # get language
+ # set specific language if set on request, query or preferences
+ # TODO support search with multible languages
+ if len(raw_text_query.languages):
+ query_lang = raw_text_query.languages[-1]
+ elif 'language' in form:
+ query_lang = form.get('language')
+ else:
+ query_lang = preferences.get_value('language')
+
+ # check language
+ if not VALID_LANGUAGE_CODE.match(query_lang):
+ raise SearxParameterException('language', query_lang)
+
+ return query_lang
+
+
+def parse_safesearch(preferences: Preferences, form: Dict[str, str]) -> int:
+ if is_locked('safesearch'):
+ return preferences.get_value('safesearch')
+
+ if 'safesearch' in form:
+ query_safesearch = form.get('safesearch')
+ # first check safesearch
+ if not query_safesearch.isdigit():
+ raise SearxParameterException('safesearch', query_safesearch)
+ query_safesearch = int(query_safesearch)
+ else:
+ query_safesearch = preferences.get_value('safesearch')
+
+ # safesearch : second check
+ if query_safesearch < 0 or query_safesearch > 2:
+ raise SearxParameterException('safesearch', query_safesearch)
+
+ return query_safesearch
+
+
+def parse_time_range(form: Dict[str, str]) -> Optional[str]:
+ query_time_range = form.get('time_range')
+ # check time_range
+ query_time_range = None if query_time_range in ('', 'None') else query_time_range
+ if query_time_range not in (None, 'day', 'week', 'month', 'year'):
+ raise SearxParameterException('time_range', query_time_range)
+ return query_time_range
+
+
+def parse_timeout(form: Dict[str, str], raw_text_query: RawTextQuery) -> Optional[float]:
+ timeout_limit = raw_text_query.timeout_limit
+ if timeout_limit is None:
+ timeout_limit = form.get('timeout_limit')
+
+ if timeout_limit is None or timeout_limit in ['None', '']:
+ return None
+ try:
+ return float(timeout_limit)
+ except ValueError:
+ raise SearxParameterException('timeout_limit', timeout_limit)
+
+
+def parse_specific(raw_text_query: RawTextQuery) -> Tuple[List[EngineRef], List[str]]:
+ query_engineref_list = raw_text_query.enginerefs
+ additional_categories = set()
+ for engineref in raw_text_query.enginerefs:
+ if engineref.from_bang:
+ additional_categories.add('none')
+ else:
+ additional_categories.add(engineref.category)
+ query_categories = list(additional_categories)
+ return query_engineref_list, query_categories
+
+
+def parse_category_form(query_categories: List[str], name: str, value: str) -> None:
+ if name == 'categories':
+ query_categories.extend(categ for categ in map(str.strip, value.split(',')) if categ in categories)
+ elif name.startswith('category_'):
+ category = name[9:]
+
+ # if category is not found in list, skip
+ if category not in categories:
+ return
+
+ if value != 'off':
+ # add category to list
+ query_categories.append(category)
+ elif category in query_categories:
+ # remove category from list if property is set to 'off'
+ query_categories.remove(category)
+
+
+def get_selected_categories(preferences: Preferences, form: Optional[Dict[str, str]]) -> List[str]:
+ selected_categories = []
+
+ if not is_locked('categories') and form is not None:
+ for name, value in form.items():
+ parse_category_form(selected_categories, name, value)
+
+ # if no category is specified for this search,
+ # using user-defined default-configuration which
+ # (is stored in cookie)
+ if not selected_categories:
+ cookie_categories = preferences.get_value('categories')
+ for ccateg in cookie_categories:
+ selected_categories.append(ccateg)
+
+ # if still no category is specified, using general
+ # as default-category
+ if not selected_categories:
+ selected_categories = ['general']
+
+ return selected_categories
+
+
+def get_engineref_from_category_list(category_list: List[str], disabled_engines: List[str]) -> List[EngineRef]:
+ result = []
+ for categ in category_list:
+ result.extend(EngineRef(engine.name, categ)
+ for engine in categories[categ]
+ if (engine.name, categ) not in disabled_engines)
+ return result
+
+
+def parse_generic(preferences: Preferences, form: Dict[str, str], disabled_engines: List[str])\
+ -> Tuple[List[EngineRef], List[str]]:
+ query_engineref_list = []
+ query_categories = []
+
+ # set categories/engines
+ explicit_engine_list = False
+ if not is_locked('categories'):
+ # parse the form only if the categories are not locked
+ for pd_name, pd in form.items():
+ if pd_name == 'engines':
+ pd_engines = [EngineRef(engine_name, engines[engine_name].categories[0])
+ for engine_name in map(str.strip, pd.split(',')) if engine_name in engines]
+ if pd_engines:
+ query_engineref_list.extend(pd_engines)
+ explicit_engine_list = True
+ else:
+ parse_category_form(query_categories, pd_name, pd)
+
+ if explicit_engine_list:
+ # explicit list of engines with the "engines" parameter in the form
+ if query_categories:
+ # add engines from referenced by the "categories" parameter and the "category_*"" parameters
+ query_engineref_list.extend(get_engineref_from_category_list(query_categories, disabled_engines))
+ # get categories from the query_engineref_list
+ query_categories = list(set(engine.category for engine in query_engineref_list))
+ else:
+ # no "engines" parameters in the form
+ if not query_categories:
+ # and neither "categories" parameter nor "category_*"" parameters in the form
+ # -> get the categories from the preferences (the cookies or the settings)
+ query_categories = get_selected_categories(preferences, None)
+
+ # using all engines for that search, which are
+ # declared under the specific categories
+ query_engineref_list.extend(get_engineref_from_category_list(query_categories, disabled_engines))
+
+ return query_engineref_list, query_categories
+
+
+def get_search_query_from_webapp(preferences: Preferences, form: Dict[str, str])\
+ -> Tuple[SearchQuery, RawTextQuery, List[EngineRef], List[EngineRef]]:
+ # no text for the query ?
+ if not form.get('q'):
+ raise SearxParameterException('q', '')
+
+ # set blocked engines
+ disabled_engines = preferences.engines.get_disabled()
+
+ # parse query, if tags are set, which change
+ # the serch engine or search-language
+ raw_text_query = RawTextQuery(form['q'], disabled_engines)
+
+ # set query
+ query = raw_text_query.getQuery()
+ query_pageno = parse_pageno(form)
+ query_lang = parse_lang(preferences, form, raw_text_query)
+ query_safesearch = parse_safesearch(preferences, form)
+ query_time_range = parse_time_range(form)
+ query_timeout = parse_timeout(form, raw_text_query)
+ external_bang = raw_text_query.external_bang
+
+ if not is_locked('categories') and raw_text_query.enginerefs and raw_text_query.specific:
+ # if engines are calculated from query,
+ # set categories by using that informations
+ query_engineref_list, query_categories = parse_specific(raw_text_query)
+ else:
+ # otherwise, using defined categories to
+ # calculate which engines should be used
+ query_engineref_list, query_categories = parse_generic(preferences, form, disabled_engines)
+
+ query_engineref_list = deduplicate_engineref_list(query_engineref_list)
+ query_engineref_list, query_engineref_list_unknown, query_engineref_list_notoken =\
+ validate_engineref_list(query_engineref_list, preferences)
+
+ return (SearchQuery(query, query_engineref_list, query_categories,
+ query_lang, query_safesearch, query_pageno,
+ query_time_range, query_timeout,
+ external_bang=external_bang),
+ raw_text_query,
+ query_engineref_list_unknown,
+ query_engineref_list_notoken)
diff --git a/searx/webapp.py b/searx/webapp.py
index 4b52c0c..ace5a12 100755
--- a/searx/webapp.py
+++ b/searx/webapp.py
@@ -17,37 +17,35 @@ along with searx. If not, see < http://www.gnu.org/licenses/ >.
(C) 2013- by Adam Tauber, <asciimoo@gmail.com>
'''
+import sys
+if sys.version_info[0] < 3:
+ print('\033[1;31m Python2 is no longer supported\033[0m')
+ exit(1)
+
if __name__ == '__main__':
- from sys import path
from os.path import realpath, dirname
- path.append(realpath(dirname(realpath(__file__)) + '/../'))
+ sys.path.append(realpath(dirname(realpath(__file__)) + '/../'))
import hashlib
import hmac
import json
import os
-import sys
import requests
from searx import logger
logger = logger.getChild('webapp')
-try:
- from pygments import highlight
- from pygments.lexers import get_lexer_by_name
- from pygments.formatters import HtmlFormatter
-except:
- logger.critical("cannot import dependency: pygments")
- from sys import exit
- exit(1)
-try:
- from cgi import escape
-except:
- from html import escape
-from six import next
from datetime import datetime, timedelta
from time import time
+from html import escape
+from io import StringIO
+from urllib.parse import urlencode, urljoin, urlparse
+
+from pygments import highlight
+from pygments.lexers import get_lexer_by_name
+from pygments.formatters import HtmlFormatter # pylint: disable=no-name-in-module
+
from werkzeug.middleware.proxy_fix import ProxyFix
from flask import (
Flask, request, render_template, url_for, Response, make_response,
@@ -58,49 +56,31 @@ import flask_babel
from flask_babel import Babel, gettext, format_date, format_decimal
from flask.ctx import has_request_context
from flask.json import jsonify
-from searx import brand
+from searx import brand, static_path
from searx import settings, searx_dir, searx_debug
from searx.exceptions import SearxParameterException
from searx.engines import (
categories, engines, engine_shortcuts, get_engines_stats, initialize_engines
)
-from searx.utils import (
- UnicodeWriter, highlight_content, html_to_text, get_resources_directory,
- get_static_files, get_result_templates, get_themes, gen_useragent,
- dict_subset, prettify_url, match_language
+from searx.webutils import (
+ UnicodeWriter, highlight_content, get_resources_directory,
+ get_static_files, get_result_templates, get_themes,
+ prettify_url, new_hmac, is_flask_run_cmdline
)
+from searx.webadapter import get_search_query_from_webapp, get_selected_categories
+from searx.utils import html_to_text, gen_useragent, dict_subset, match_language
from searx.version import VERSION_STRING
from searx.languages import language_codes as languages
-from searx.search import SearchWithPlugins, get_search_query_from_webapp
+from searx.search import SearchWithPlugins
from searx.query import RawTextQuery
from searx.autocomplete import searx_bang, backends as autocomplete_backends
from searx.plugins import plugins
from searx.plugins.oa_doi_rewrite import get_doi_resolver
from searx.preferences import Preferences, ValidationException, LANGUAGE_CODES
from searx.answerers import answerers
-from searx.url_utils import urlencode, urlparse, urljoin
-from searx.utils import new_hmac
-
-# check if the pyopenssl package is installed.
-# It is needed for SSL connection without trouble, see #298
-try:
- import OpenSSL.SSL # NOQA
-except ImportError:
- logger.critical("The pyopenssl package has to be installed.\n"
- "Some HTTPS connections will fail")
-
-try:
- from cStringIO import StringIO
-except:
- from io import StringIO
-
-
-if sys.version_info[0] == 3:
- unicode = str
- PY3 = True
-else:
- logger.warning('\033[1;31m Python2 is no longer supported\033[0m')
- exit(1)
+from searx.poolrequests import get_global_proxies
+from searx.metrology.error_recorder import errors_per_engines
+
# serve pages with HTTP/1.1
from werkzeug.serving import WSGIRequestHandler
@@ -133,12 +113,24 @@ app = Flask(
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
-app.jinja_env.add_extension('jinja2.ext.loopcontrols')
+app.jinja_env.add_extension('jinja2.ext.loopcontrols') # pylint: disable=no-member
app.secret_key = settings['server']['secret_key']
-if not searx_debug \
- or os.environ.get("WERKZEUG_RUN_MAIN") == "true" \
- or os.environ.get('UWSGI_ORIGINAL_PROC_NAME') is not None:
+# see https://flask.palletsprojects.com/en/1.1.x/cli/
+# True if "FLASK_APP=searx/webapp.py FLASK_ENV=development flask run"
+flask_run_development = \
+ os.environ.get("FLASK_APP") is not None\
+ and os.environ.get("FLASK_ENV") == 'development'\
+ and is_flask_run_cmdline()
+
+# True if reload feature is activated of werkzeug, False otherwise (including uwsgi, etc..)
+# __name__ != "__main__" if searx.webapp is imported (make test, make docs, uwsgi...)
+# see run() at the end of this file : searx_debug activates the reload feature.
+werkzeug_reloader = flask_run_development or (searx_debug and __name__ == "__main__")
+
+# initialize the engines except on the first run of the werkzeug server.
+if not werkzeug_reloader\
+ or (werkzeug_reloader and os.environ.get("WERKZEUG_RUN_MAIN") == "true"):
initialize_engines(settings['engines'])
babel = Babel(app)
@@ -156,10 +148,9 @@ _category_names = (gettext('files'),
gettext('it'),
gettext('news'),
gettext('map'),
+ gettext('onions'),
gettext('science'))
-outgoing_proxies = settings['outgoing'].get('proxies') or None
-
_flask_babel_get_translations = flask_babel.get_translations
@@ -175,7 +166,7 @@ def _get_translations():
flask_babel.get_translations = _get_translations
-def _get_browser_language(request, lang_list):
+def _get_browser_or_settings_language(request, lang_list):
for lang in request.headers.get("Accept-Language", "en").split(","):
if ';' in lang:
lang = lang.split(';')[0]
@@ -187,26 +178,31 @@ def _get_browser_language(request, lang_list):
@babel.localeselector
def get_locale():
- locale = _get_browser_language(request, settings['locales'].keys())
-
- logger.debug("default locale from browser info is `%s`", locale)
-
- if request.preferences.get_value('locale') != '':
- locale = request.preferences.get_value('locale')
-
if 'locale' in request.form\
and request.form['locale'] in settings['locales']:
+ # use locale from the form
locale = request.form['locale']
+ locale_source = 'form'
+ elif request.preferences.get_value('locale') != '':
+ # use locale from the preferences
+ locale = request.preferences.get_value('locale')
+ locale_source = 'preferences'
+ else:
+ # use local from the browser
+ locale = _get_browser_or_settings_language(request, settings['locales'].keys())
+ locale_source = 'browser'
+ #
if locale == 'zh_TW':
locale = 'zh_Hant_TW'
+ # see _get_translations function
+ # and https://github.com/searx/searx/pull/1863
if locale == 'oc':
request.form['use-translation'] = 'oc'
locale = 'fr_FR'
- logger.debug("selected locale is `%s`", locale)
-
+ logger.debug("%s uses locale `%s` from %s", request.url, locale, locale_source)
return locale
@@ -305,7 +301,12 @@ def url_for_theme(endpoint, override_theme=None, **values):
filename_with_theme = "themes/{}/{}".format(theme_name, values['filename'])
if filename_with_theme in static_files:
values['filename'] = filename_with_theme
- return url_for(endpoint, **values)
+ url = url_for(endpoint, **values)
+ if settings['server']['base_url']:
+ if url.startswith('/'):
+ url = url[1:]
+ url = urljoin(settings['server']['base_url'], url)
+ return url
def proxify(url):
@@ -315,11 +316,11 @@ def proxify(url):
if not settings.get('result_proxy'):
return url
- url_params = dict(mortyurl=url.encode('utf-8'))
+ url_params = dict(mortyurl=url.encode())
if settings['result_proxy'].get('key'):
url_params['mortyhash'] = hmac.new(settings['result_proxy']['key'],
- url.encode('utf-8'),
+ url.encode(),
hashlib.sha256).hexdigest()
return '{0}?{1}'.format(settings['result_proxy']['url'],
@@ -347,10 +348,10 @@ def image_proxify(url):
if settings.get('result_proxy'):
return proxify(url)
- h = new_hmac(settings['server']['secret_key'], url.encode('utf-8'))
+ h = new_hmac(settings['server']['secret_key'], url.encode())
return '{0}?{1}'.format(url_for('image_proxy'),
- urlencode(dict(url=url.encode('utf-8'), h=h)))
+ urlencode(dict(url=url.encode(), h=h)))
def render(template_name, override_theme=None, **kwargs):
@@ -365,25 +366,6 @@ def render(template_name, override_theme=None, **kwargs):
_get_ordered_categories()
if x in enabled_categories]
- if 'all_categories' not in kwargs:
- kwargs['all_categories'] = _get_ordered_categories()
-
- if 'selected_categories' not in kwargs:
- kwargs['selected_categories'] = []
- for arg in request.args:
- if arg.startswith('category_'):
- c = arg.split('_', 1)[1]
- if c in categories:
- kwargs['selected_categories'].append(c)
-
- if not kwargs['selected_categories']:
- cookie_categories = request.preferences.get_value('categories')
- for ccateg in cookie_categories:
- kwargs['selected_categories'].append(ccateg)
-
- if not kwargs['selected_categories']:
- kwargs['selected_categories'] = ['general']
-
if 'autocomplete' not in kwargs:
kwargs['autocomplete'] = request.preferences.get_value('autocomplete')
@@ -410,6 +392,9 @@ def render(template_name, override_theme=None, **kwargs):
kwargs['proxify'] = proxify if settings.get('result_proxy', {}).get('url') else None
+ kwargs['opensearch_url'] = url_for('opensearch') + '?' \
+ + urlencode({'method': kwargs['method'], 'autocomplete': kwargs['autocomplete']})
+
kwargs['get_result_template'] = get_result_template
kwargs['theme'] = get_current_theme_name(override=override_theme)
@@ -424,8 +409,6 @@ def render(template_name, override_theme=None, **kwargs):
kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
- kwargs['unicode'] = unicode
-
kwargs['preferences'] = request.preferences
kwargs['brand'] = brand
@@ -463,6 +446,9 @@ def pre_request():
request.errors = []
preferences = Preferences(themes, list(categories.keys()), engines, plugins)
+ user_agent = request.headers.get('User-Agent', '').lower()
+ if 'webkit' in user_agent and 'android' in user_agent:
+ preferences.key_value_settings['method'].value = 'GET'
request.preferences = preferences
try:
preferences.parse_dict(request.cookies)
@@ -481,13 +467,13 @@ def pre_request():
else:
try:
preferences.parse_dict(request.form)
- except Exception as e:
+ except Exception:
logger.exception('invalid settings')
request.errors.append(gettext('Invalid settings'))
# init search language and locale
if not preferences.get_value("language"):
- preferences.parse_dict({"language": _get_browser_language(request, LANGUAGE_CODES)})
+ preferences.parse_dict({"language": _get_browser_or_settings_language(request, LANGUAGE_CODES)})
if not preferences.get_value("locale"):
preferences.parse_dict({"locale": get_locale()})
@@ -502,6 +488,16 @@ def pre_request():
@app.after_request
+def add_default_headers(response):
+ # set default http headers
+ for header, value in settings['server'].get('default_http_headers', {}).items():
+ if header in response.headers:
+ continue
+ response.headers[header] = value
+ return response
+
+
+@app.after_request
def post_request(response):
total_time = time() - request.start_time
timings_all = ['total;dur=' + str(round(total_time * 1000, 3))]
@@ -541,13 +537,32 @@ def index_error(output_format, error_message):
request.errors.append(gettext('search error'))
return render(
'index.html',
+ selected_categories=get_selected_categories(request.preferences, request.form),
)
-@app.route('/search', methods=['GET', 'POST'])
@app.route('/', methods=['GET', 'POST'])
def index():
- """Render index page.
+ """Render index page."""
+
+ # UI
+ advanced_search = request.preferences.get_value('advanced_search')
+
+ # redirect to search if there's a query in the request
+ if request.form.get('q'):
+ query = ('?' + request.query_string.decode()) if request.query_string else ''
+ return redirect(url_for('search') + query, 308)
+
+ return render(
+ 'index.html',
+ selected_categories=get_selected_categories(request.preferences, request.form),
+ advanced_search=advanced_search,
+ )
+
+
+@app.route('/search', methods=['GET', 'POST'])
+def search():
+ """Search query in q and return results.
Supported outputs: html, json, csv, rss.
"""
@@ -557,11 +572,13 @@ def index():
if output_format not in ['html', 'csv', 'json', 'rss']:
output_format = 'html'
- # check if there is query
- if request.form.get('q') is None:
+ # check if there is query (not None and not an empty string)
+ if not request.form.get('q'):
if output_format == 'html':
return render(
'index.html',
+ advanced_search=request.preferences.get_value('advanced_search'),
+ selected_categories=get_selected_categories(request.preferences, request.form),
)
else:
return index_error(output_format, 'No query'), 400
@@ -571,21 +588,18 @@ def index():
raw_text_query = None
result_container = None
try:
- search_query, raw_text_query = get_search_query_from_webapp(request.preferences, request.form)
+ search_query, raw_text_query, _, _ = get_search_query_from_webapp(request.preferences, request.form)
# search = Search(search_query) # without plugins
search = SearchWithPlugins(search_query, request.user_plugins, request)
result_container = search.search()
+ except SearxParameterException as e:
+ logger.exception('search error: SearxParameterException')
+ return index_error(output_format, e.message), 400
except Exception as e:
- # log exception
logger.exception('search error')
-
- # is it an invalid input parameter or something else ?
- if (issubclass(e.__class__, SearxParameterException)):
- return index_error(output_format, e.message), 400
- else:
- return index_error(output_format, gettext('search error')), 500
+ return index_error(output_format, gettext('search error')), 500
# results
results = result_container.get_ordered_results()
@@ -597,9 +611,6 @@ def index():
if result_container.redirect_url:
return redirect(result_container.redirect_url)
- # UI
- advanced_search = request.form.get('advanced_search', None)
-
# Server-Timing header
request.timings = result_container.get_timings()
@@ -609,7 +620,7 @@ def index():
if 'content' in result and result['content']:
result['content'] = highlight_content(escape(result['content'][:1024]), search_query.query)
if 'title' in result and result['title']:
- result['title'] = highlight_content(escape(result['title'] or u''), search_query.query)
+ result['title'] = highlight_content(escape(result['title'] or ''), search_query.query)
else:
if result.get('content'):
result['content'] = html_to_text(result['content']).strip()
@@ -631,14 +642,14 @@ def index():
minutes = int((timedifference.seconds / 60) % 60)
hours = int(timedifference.seconds / 60 / 60)
if hours == 0:
- result['publishedDate'] = gettext(u'{minutes} minute(s) ago').format(minutes=minutes)
+ result['publishedDate'] = gettext('{minutes} minute(s) ago').format(minutes=minutes)
else:
- result['publishedDate'] = gettext(u'{hours} hour(s), {minutes} minute(s) ago').format(hours=hours, minutes=minutes) # noqa
+ result['publishedDate'] = gettext('{hours} hour(s), {minutes} minute(s) ago').format(hours=hours, minutes=minutes) # noqa
else:
result['publishedDate'] = format_date(result['publishedDate'])
if output_format == 'json':
- return Response(json.dumps({'query': search_query.query.decode('utf-8'),
+ return Response(json.dumps({'query': search_query.query,
'number_of_results': number_of_results,
'results': results,
'answers': list(result_container.answers),
@@ -667,7 +678,7 @@ def index():
csv.writerow([row.get(key, '') for key in keys])
csv.stream.seek(0)
response = Response(csv.stream.read(), mimetype='application/csv')
- cont_disp = 'attachment;Filename=searx_-_{0}.csv'.format(search_query.query.decode('utf-8'))
+ cont_disp = 'attachment;Filename=searx_-_{0}.csv'.format(search_query.query)
response.headers.add('Content-Disposition', cont_disp)
return response
@@ -689,13 +700,13 @@ def index():
# suggestions: use RawTextQuery to get the suggestion URLs with the same bang
suggestion_urls = list(map(lambda suggestion: {
- 'url': raw_text_query.changeSearchQuery(suggestion).getFullQuery(),
+ 'url': raw_text_query.changeQuery(suggestion).getFullQuery(),
'title': suggestion
},
result_container.suggestions))
correction_urls = list(map(lambda correction: {
- 'url': raw_text_query.changeSearchQuery(correction).getFullQuery(),
+ 'url': raw_text_query.changeQuery(correction).getFullQuery(),
'title': correction
},
result_container.corrections))
@@ -708,7 +719,6 @@ def index():
pageno=search_query.pageno,
time_range=search_query.time_range,
number_of_results=format_decimal(number_of_results),
- advanced_search=advanced_search,
suggestions=suggestion_urls,
answers=result_container.answers,
corrections=correction_urls,
@@ -726,12 +736,12 @@ def index():
def __get_translated_errors(unresponsive_engines):
- translated_errors = []
+ translated_errors = set()
for unresponsive_engine in unresponsive_engines:
error_msg = gettext(unresponsive_engine[1])
if unresponsive_engine[2]:
error_msg = "{} {}".format(error_msg, unresponsive_engine[2])
- translated_errors.append((unresponsive_engine[0], error_msg))
+ translated_errors.add((unresponsive_engine[0], error_msg))
return translated_errors
@@ -751,14 +761,10 @@ def autocompleter():
disabled_engines = request.preferences.engines.get_disabled()
# parse query
- if PY3:
- raw_text_query = RawTextQuery(request.form.get('q', b''), disabled_engines)
- else:
- raw_text_query = RawTextQuery(request.form.get('q', u'').encode('utf-8'), disabled_engines)
- raw_text_query.parse_query()
+ raw_text_query = RawTextQuery(request.form.get('q', ''), disabled_engines)
# check if search query is set
- if not raw_text_query.getSearchQuery():
+ if not raw_text_query.getQuery():
return '', 400
# run autocompleter
@@ -779,23 +785,23 @@ def autocompleter():
else:
language = language.split('-')[0]
# run autocompletion
- raw_results.extend(completer(raw_text_query.getSearchQuery(), language))
+ raw_results.extend(completer(raw_text_query.getQuery(), language))
# parse results (write :language and !engine back to result string)
results = []
for result in raw_results:
- raw_text_query.changeSearchQuery(result)
+ raw_text_query.changeQuery(result)
# add parsed result
results.append(raw_text_query.getFullQuery())
# return autocompleter results
- if request.form.get('format') == 'x-suggestions':
- return Response(json.dumps([raw_text_query.query, results]),
+ if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
+ return Response(json.dumps(results),
mimetype='application/json')
- return Response(json.dumps(results),
- mimetype='application/json')
+ return Response(json.dumps([raw_text_query.query, results]),
+ mimetype='application/x-suggestions+json')
@app.route('/preferences', methods=['GET', 'POST'])
@@ -814,7 +820,6 @@ def preferences():
# render preferences
image_proxy = request.preferences.get_value('image_proxy')
- lang = request.preferences.get_value('language')
disabled_engines = request.preferences.engines.get_disabled()
allowed_plugins = request.preferences.plugins.get_enabled()
@@ -845,7 +850,13 @@ def preferences():
stats[engine_stat.get('name')]['warn_time'] = True
# end of stats
+ locked_preferences = list()
+ if 'preferences' in settings and 'lock' in settings['preferences']:
+ locked_preferences = settings['preferences']['lock']
+
return render('preferences.html',
+ selected_categories=get_selected_categories(request.preferences, request.form),
+ all_categories=_get_ordered_categories(),
locales=settings['locales'],
current_locale=request.preferences.get_value("locale"),
image_proxy=image_proxy,
@@ -863,6 +874,7 @@ def preferences():
theme=get_current_theme_name(),
preferences_url_params=request.preferences.get_as_url_params(),
base_url=get_base_url(),
+ locked_preferences=locked_preferences,
preferences=True)
@@ -876,7 +888,7 @@ def _is_selected_language_supported(engine, preferences):
@app.route('/image_proxy', methods=['GET'])
def image_proxy():
- url = request.args.get('url').encode('utf-8')
+ url = request.args.get('url').encode()
if not url:
return '', 400
@@ -893,7 +905,7 @@ def image_proxy():
stream=True,
timeout=settings['outgoing']['request_timeout'],
headers=headers,
- proxies=outgoing_proxies)
+ proxies=get_global_proxies())
if resp.status_code == 304:
return '', resp.status_code
@@ -932,6 +944,34 @@ def stats():
)
+@app.route('/stats/errors', methods=['GET'])
+def stats_errors():
+ result = {}
+ engine_names = list(errors_per_engines.keys())
+ engine_names.sort()
+ for engine_name in engine_names:
+ error_stats = errors_per_engines[engine_name]
+ sent_search_count = max(engines[engine_name].stats['sent_search_count'], 1)
+ sorted_context_count_list = sorted(error_stats.items(), key=lambda context_count: context_count[1])
+ r = []
+ percentage_sum = 0
+ for context, count in sorted_context_count_list:
+ percentage = round(20 * count / sent_search_count) * 5
+ percentage_sum += percentage
+ r.append({
+ 'filename': context.filename,
+ 'function': context.function,
+ 'line_no': context.line_no,
+ 'code': context.code,
+ 'exception_classname': context.exception_classname,
+ 'log_message': context.log_message,
+ 'log_parameters': context.log_parameters,
+ 'percentage': percentage,
+ })
+ result[engine_name] = sorted(r, reverse=True, key=lambda d: d['percentage'])
+ return jsonify(result)
+
+
@app.route('/robots.txt', methods=['GET'])
def robots():
return Response("""User-agent: *
@@ -1058,7 +1098,7 @@ def run():
)
-class ReverseProxyPathFix(object):
+class ReverseProxyPathFix:
'''Wrap the application in this middleware and configure the
front-end server to add these headers, to let you quietly bind
this to a URL other than / and to an HTTP scheme that is
diff --git a/searx/webutils.py b/searx/webutils.py
new file mode 100644
index 0000000..8be8fce
--- /dev/null
+++ b/searx/webutils.py
@@ -0,0 +1,145 @@
+# -*- coding: utf-8 -*-
+import os
+import csv
+import hashlib
+import hmac
+import re
+import inspect
+
+from io import StringIO
+from codecs import getincrementalencoder
+
+from searx import logger
+
+
+VALID_LANGUAGE_CODE = re.compile(r'^[a-z]{2,3}(-[a-zA-Z]{2})?$')
+
+logger = logger.getChild('webutils')
+
+
+class UnicodeWriter:
+ """
+ A CSV writer which will write rows to CSV file "f",
+ which is encoded in the given encoding.
+ """
+
+ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds):
+ # Redirect output to a queue
+ self.queue = StringIO()
+ self.writer = csv.writer(self.queue, dialect=dialect, **kwds)
+ self.stream = f
+ self.encoder = getincrementalencoder(encoding)()
+
+ def writerow(self, row):
+ self.writer.writerow(row)
+ # Fetch UTF-8 output from the queue ...
+ data = self.queue.getvalue()
+ data = data.strip('\x00')
+ # ... and reencode it into the target encoding
+ data = self.encoder.encode(data)
+ # write to the target stream
+ self.stream.write(data.decode())
+ # empty queue
+ self.queue.truncate(0)
+
+ def writerows(self, rows):
+ for row in rows:
+ self.writerow(row)
+
+
+def get_resources_directory(searx_directory, subdirectory, resources_directory):
+ if not resources_directory:
+ resources_directory = os.path.join(searx_directory, subdirectory)
+ if not os.path.isdir(resources_directory):
+ raise Exception(resources_directory + " is not a directory")
+ return resources_directory
+
+
+def get_themes(templates_path):
+ """Returns available themes list."""
+ themes = os.listdir(templates_path)
+ if '__common__' in themes:
+ themes.remove('__common__')
+ return themes
+
+
+def get_static_files(static_path):
+ static_files = set()
+ static_path_length = len(static_path) + 1
+ for directory, _, files in os.walk(static_path):
+ for filename in files:
+ f = os.path.join(directory[static_path_length:], filename)
+ static_files.add(f)
+ return static_files
+
+
+def get_result_templates(templates_path):
+ result_templates = set()
+ templates_path_length = len(templates_path) + 1
+ for directory, _, files in os.walk(templates_path):
+ if directory.endswith('result_templates'):
+ for filename in files:
+ f = os.path.join(directory[templates_path_length:], filename)
+ result_templates.add(f)
+ return result_templates
+
+
+def new_hmac(secret_key, url):
+ try:
+ secret_key_bytes = bytes(secret_key, 'utf-8')
+ except TypeError as err:
+ if isinstance(secret_key, bytes):
+ secret_key_bytes = secret_key
+ else:
+ raise err
+ return hmac.new(secret_key_bytes, url, hashlib.sha256).hexdigest()
+
+
+def prettify_url(url, max_length=74):
+ if len(url) > max_length:
+ chunk_len = int(max_length / 2 + 1)
+ return '{0}[...]{1}'.format(url[:chunk_len], url[-chunk_len:])
+ else:
+ return url
+
+
+def highlight_content(content, query):
+
+ if not content:
+ return None
+ # ignoring html contents
+ # TODO better html content detection
+ if content.find('<') != -1:
+ return content
+
+ if content.lower().find(query.lower()) > -1:
+ query_regex = '({0})'.format(re.escape(query))
+ content = re.sub(query_regex, '<span class="highlight">\\1</span>',
+ content, flags=re.I | re.U)
+ else:
+ regex_parts = []
+ for chunk in query.split():
+ if len(chunk) == 1:
+ regex_parts.append('\\W+{0}\\W+'.format(re.escape(chunk)))
+ else:
+ regex_parts.append('{0}'.format(re.escape(chunk)))
+ query_regex = '({0})'.format('|'.join(regex_parts))
+ content = re.sub(query_regex, '<span class="highlight">\\1</span>',
+ content, flags=re.I | re.U)
+
+ return content
+
+
+def is_flask_run_cmdline():
+ """Check if the application was started using "flask run" command line
+
+ Inspect the callstack.
+ See https://github.com/pallets/flask/blob/master/src/flask/__main__.py
+
+ Returns:
+ bool: True if the application was started using "flask run".
+ """
+ frames = inspect.stack()
+ if len(frames) < 2:
+ return False
+ return frames[-2].filename.endswith('flask/cli.py')