This is a draft article, it should live under the /drafts/ folder and not be +listed anywhere else.
+ +From 24a1254f034a238f481f8b889a961dbde99c551d Mon Sep 17 00:00:00 2001
From: Julien Palard ", content)
content = content.replace(']*)>', "
\s*(?' + allblocks + '[^>]*>)', "\\1", content) - content = re.sub(r'(?' + allblocks + '[^>]*>)\s*
', "\\1", content) + content = re.sub(r'(?' + allblocks + r'[^>]*>)\s*', "\\1", content) if br: def _preserve_newline(match): return match.group(0).replace("\n", "["\']) # require value to be quoted (?P{0}(?P .*?)) # the url value diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index b4146150..11fa958a 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -771,3 +771,24 @@ class TestStatic(LoggedTestCase): count=1, msg="Unable to find 'foo', skipping url replacement.", level=logging.WARNING) + + def test_index_link_syntax_with_spaces(self): + """{index} link syntax triggers url replacement + with spaces around the equal sign.""" + + html = 'link' + page = Page( + content=html, + metadata={'title': 'fakepage'}, + settings=self.settings, + source_path=os.path.join('dir', 'otherdir', 'fakepage.md'), + context=self.context) + content = page.get_content('') + + self.assertNotEqual(content, html) + + expected_html = ('link') + self.assertEqual(content, expected_html) From 77faffa6f75e69c7028f798b80e7a0bbe68ad794 Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Sun, 16 Apr 2017 13:45:45 +0200 Subject: [PATCH 023/916] Add Python 3.6 classifier to setup.py --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 3645dc04..f3a0ebcb 100755 --- a/setup.py +++ b/setup.py @@ -63,6 +63,7 @@ setup( 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Topic :: Internet :: WWW/HTTP', 'Topic :: Software Development :: Libraries :: Python Modules', ], From 651ccbcddfbaef74de2e5a2b247686e525ebe017 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Thu, 20 Apr 2017 13:40:19 -0600 Subject: [PATCH 024/916] Pelican trove classifier now on PyPI https://github.com/pypa/warehouse/issues/1650 (now sorted alphabetically) --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index f3a0ebcb..c26f1e71 100755 --- a/setup.py +++ b/setup.py @@ -55,6 +55,7 @@ setup( classifiers=[ 'Development Status :: 5 - Production/Stable', 'Environment :: Console', + 'Framework :: Pelican', 'License :: OSI Approved :: GNU Affero General Public License v3', 'Operating System :: OS Independent', 'Programming Language :: Python :: 2', From 24c41195a669070d0970ad5d62f3fa5887902900 Mon Sep 17 00:00:00 2001 From: MinchinWeb Date: Wed, 26 Apr 2017 10:34:47 -0600 Subject: [PATCH 025/916] Use 4-space indentation --- setup.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/setup.py b/setup.py index c26f1e71..be038971 100755 --- a/setup.py +++ b/setup.py @@ -53,20 +53,20 @@ setup( install_requires=requires, entry_points=entry_points, classifiers=[ - 'Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Framework :: Pelican', - 'License :: OSI Approved :: GNU Affero General Public License v3', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 2', - 'Programming Language :: Python :: 2.7', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.3', - 'Programming Language :: Python :: 3.4', - 'Programming Language :: Python :: 3.5', - 'Programming Language :: Python :: 3.6', - 'Topic :: Internet :: WWW/HTTP', - 'Topic :: Software Development :: Libraries :: Python Modules', + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Framework :: Pelican', + 'License :: OSI Approved :: GNU Affero General Public License v3', + 'Operating System :: OS Independent', + 'Programming Language :: Python :: 2', + 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.3', + 'Programming Language :: Python :: 3.4', + 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Topic :: Internet :: WWW/HTTP', + 'Topic :: Software Development :: Libraries :: Python Modules', ], test_suite='pelican.tests', ) From 32c154be95cd71ea96284b1dbee1d3fa04a9adb1 Mon Sep 17 00:00:00 2001 From: Brandon B Date: Fri, 28 Apr 2017 19:18:44 -0700 Subject: [PATCH 026/916] Update tips.rst I found that one of the easiest ways to publish to GitHub User Pages is to make Pelican a subdirectory within the `` .github.io`` project, then generate the output files in the root level of `` .github.io`` and push the entire project to GitHub. --- docs/tips.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/tips.rst b/docs/tips.rst index 50160380..bf0b3599 100644 --- a/docs/tips.rst +++ b/docs/tips.rst @@ -98,6 +98,18 @@ by the ``ghp-import`` command) to the ``elemoine.github.io`` repository's To publish your Pelican site as User Pages, feel free to adjust the ``github`` target of the Makefile. + +Another option for publishing to User Pages is to generate the output files in the root directory of the project. + +For example, your main project folder is `` .github.io`` and you can create the Pelican project in a subdirectory called ``Pelican``. Then from inside the ``Pelican`` folder you can run:: + + $ pelican content -o .. -s pelicanconf.py + +Now you can push the whole project `` .github.io`` to the master branch of your GitHub repository:: + + $ git push origin master + +(assuming origin is set to your remote repository). Custom 404 Pages ---------------- From c68958e6b89459bbd0488208279d843a41cc5681 Mon Sep 17 00:00:00 2001 From: derwinlu Date: Fri, 5 May 2017 16:02:48 +0200 Subject: [PATCH 027/916] Fixup ec5c77b25145f7c20fee24c6b85b478295dbc956 fix forgotten PAGES -> pages --- pelican/themes/notmyidea/templates/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pelican/themes/notmyidea/templates/index.html b/pelican/themes/notmyidea/templates/index.html index 6019987b..20ca7eee 100644 --- a/pelican/themes/notmyidea/templates/index.html +++ b/pelican/themes/notmyidea/templates/index.html @@ -51,7 +51,7 @@ {% else %} From fdf355c377627d82026765872b8660086715a419 Mon Sep 17 00:00:00 2001 From: evilroot Pages
- {% for page in PAGES %} + {% for page in pages %}{{ page.title }} {% endfor %}Date: Thu, 8 Jun 2017 22:54:12 +0100 Subject: [PATCH 028/916] Fix rsync_upload in Makefile template --- pelican/tools/templates/Makefile.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pelican/tools/templates/Makefile.in b/pelican/tools/templates/Makefile.in index 06880c44..5dc81baa 100644 --- a/pelican/tools/templates/Makefile.in +++ b/pelican/tools/templates/Makefile.in @@ -102,7 +102,7 @@ ssh_upload: publish scp -P $$(SSH_PORT) -r $$(OUTPUTDIR)/* $$(SSH_USER)@$$(SSH_HOST):$$(SSH_TARGET_DIR) rsync_upload: publish - rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) --cvs-exclude + rsync -e "ssh -p $(SSH_PORT)" -P -rvzc --cvs-exclude --delete $(OUTPUTDIR)/ $(SSH_USER)@$(SSH_HOST):$(SSH_TARGET_DIR) dropbox_upload: publish cp -r $$(OUTPUTDIR)/* $$(DROPBOX_DIR) From 7336de45cbb5f60e934b65f823d0583b48a6c96b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Tue, 6 Jun 2017 20:34:56 +0200 Subject: [PATCH 029/916] Ability to override docutils HTML writer/translator. The RstReader class can now use user-specified writer/translator classes instead of the hardcoded ones from docutils. This allows for far easier overriding of the default HTML output -- in the past one would need to override the internal _parse_metadata() and _get_publisher() functions. With hypothetical Html5Writer and Html5FieldBodyTranslator classes, based for example on docutils.writers.html5_polyglot.Writer and docutils.writers.html5_polyglot.HTMLTranslator, a plugin that overrides the default behavior would now look just like this: # (definition of Writer / Translator classes omitted) class Html5RstReader(RstReader): writer_class = Html5Writer field_body_translator_class = Html5FieldBodyTranslator def add_reader(readers): readers.reader_classes['rst'] = Html5RstReader def register(): pelican.signals.readers_init.connect(add_reader) --- pelican/readers.py | 36 ++++++++++++++++++++++++++++++------ 1 file changed, 30 insertions(+), 6 deletions(-) diff --git a/pelican/readers.py b/pelican/readers.py index 46055962..61126c9c 100644 --- a/pelican/readers.py +++ b/pelican/readers.py @@ -9,7 +9,7 @@ from collections import OrderedDict import docutils import docutils.core import docutils.io -from docutils.writers.html4css1 import HTMLTranslator +from docutils.writers.html4css1 import HTMLTranslator, Writer import six from six.moves.html_parser import HTMLParser @@ -135,12 +135,19 @@ class _FieldBodyTranslator(HTMLTranslator): pass -def render_node_to_html(document, node): - visitor = _FieldBodyTranslator(document) +def render_node_to_html(document, node, field_body_translator_class): + visitor = field_body_translator_class(document) node.walkabout(visitor) return visitor.astext() +class PelicanHTMLWriter(Writer): + + def __init__(self): + Writer.__init__(self) + self.translator_class = PelicanHTMLTranslator + + class PelicanHTMLTranslator(HTMLTranslator): def visit_abbreviation(self, node): @@ -160,11 +167,26 @@ class PelicanHTMLTranslator(HTMLTranslator): class RstReader(BaseReader): - """Reader for reStructuredText files""" + """Reader for reStructuredText files + + By default the output HTML is written using + docutils.writers.html4css1.Writer and translated using a subclass of + docutils.writers.html4css1.HTMLTranslator. If you want to override it with + your own writer/translator (e.g. a HTML5-based one), pass your classes to + these two attributes. Look in the source code for details. + + writer_class Used for writing contents + field_body_translator_class Used for translating metadata such + as article summary + + """ enabled = bool(docutils) file_extensions = ['rst'] + writer_class = PelicanHTMLWriter + field_body_translator_class = _FieldBodyTranslator + class FileInput(docutils.io.FileInput): """Patch docutils.io.FileInput to remove "U" mode in py3. @@ -192,7 +214,9 @@ class RstReader(BaseReader): name_elem, body_elem = element.children name = name_elem.astext() if name in formatted_fields: - value = render_node_to_html(document, body_elem) + value = render_node_to_html( + document, body_elem, + self.field_body_translator_class) else: value = body_elem.astext() elif element.tagname == 'authors': # author list @@ -217,10 +241,10 @@ class RstReader(BaseReader): extra_params.update(user_params) pub = docutils.core.Publisher( + writer=self.writer_class(), source_class=self.FileInput, destination_class=docutils.io.StringOutput) pub.set_components('standalone', 'restructuredtext', 'html') - pub.writer.translator_class = PelicanHTMLTranslator pub.process_programmatic_settings(None, extra_params, None) pub.set_source(source_path=source_path) pub.publish(enable_exit_status=True) From 43ec3c4f7dd188bfa5a9ad430618a7b1fe570ffd Mon Sep 17 00:00:00 2001 From: Justin Mayer Date: Wed, 19 Jul 2017 13:29:04 -0700 Subject: [PATCH 030/916] Fix copyright year to date of first publication --- docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/conf.py b/docs/conf.py index 81a06e3a..3748fd75 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -17,7 +17,7 @@ extensions = ['sphinx.ext.autodoc', source_suffix = '.rst' master_doc = 'index' project = 'Pelican' -copyright = '2015, Alexis Metaireau and contributors' +copyright = '2010, Alexis Metaireau and contributors' exclude_patterns = ['_build'] release = __version__ version = '.'.join(release.split('.')[:1]) From 1c96d8c933aaf8770b83a228d22936e36e40da3d Mon Sep 17 00:00:00 2001 From: Jonas Lundholm Bertelsen Date: Mon, 24 Jul 2017 12:25:21 +0200 Subject: [PATCH 031/916] Correct import of socketserver on Python 3 --- pelican/tools/templates/fabfile.py.in | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pelican/tools/templates/fabfile.py.in b/pelican/tools/templates/fabfile.py.in index 18131d5f..d3c50a83 100644 --- a/pelican/tools/templates/fabfile.py.in +++ b/pelican/tools/templates/fabfile.py.in @@ -3,7 +3,10 @@ import fabric.contrib.project as project import os import shutil import sys -import SocketServer +try: + import socketserver +except ImportError: + import SocketServer as socketserver from pelican.server import ComplexHTTPRequestHandler @@ -48,7 +51,7 @@ def serve(): """Serve site at http://localhost:8000/""" os.chdir(env.deploy_path) - class AddressReuseTCPServer(SocketServer.TCPServer): + class AddressReuseTCPServer(socketserver.TCPServer): allow_reuse_address = True server = AddressReuseTCPServer(('', PORT), ComplexHTTPRequestHandler) From 089b46b7eb86cb55491d3c8e8bccb956b6dceeff Mon Sep 17 00:00:00 2001 From: winlu Date: Mon, 24 Jul 2017 19:01:14 +0200 Subject: [PATCH 032/916] Consolidate validation of content (#2128) * Consolidate validation of content Previously we validated content outside of the content class via calls to `is_valid_content` and some additional checks in page / article generators (valid status). This commit moves those checks all into content.valid() resulting in a cleaner code structure. This allows us to restructure how generators interact with content, removing several old bugs in pelican (#1748, #1356, #2098). - move verification function into content class - move generator verifying content to contents class - remove unused quote class - remove draft class (no more rereading drafts) - move auto draft status setter into Article.__init__ - add now parsing draft to basic test output - remove problematic DEFAULT_STATUS setting - add setter/getter for content.status removes need for lower() calls when verifying status * expand c4b184fa32f73a737ff9bade440ce0f7914dc350 Mostly implement feedback by @iKevinY. * rename content.valid to content.is_valid * rename valid_* functions to has_valid_* * update tests and function calls in code accordingly --- pelican/contents.py | 108 +++++++++++------- pelican/generators.py | 54 +++------ pelican/settings.py | 1 - .../output/basic/drafts/a-draft-article.html | 69 +++++++++++ pelican/tests/test_contents.py | 16 +-- 5 files changed, 159 insertions(+), 89 deletions(-) create mode 100644 pelican/tests/output/basic/drafts/a-draft-article.html diff --git a/pelican/contents.py b/pelican/contents.py index 3d1128c9..15770fc8 100644 --- a/pelican/contents.py +++ b/pelican/contents.py @@ -138,14 +138,7 @@ class Content(object): # manage status if not hasattr(self, 'status'): - self.status = settings['DEFAULT_STATUS'] - if not settings['WITH_FUTURE_DATES'] and hasattr(self, 'date'): - if self.date.tzinfo is None: - now = SafeDatetime.now() - else: - now = SafeDatetime.utcnow().replace(tzinfo=pytz.utc) - if self.date > now: - self.status = 'draft' + self.status = getattr(self, 'default_status', None) # store the summary metadata if it is set if 'summary' in metadata: @@ -156,13 +149,17 @@ class Content(object): def __str__(self): return self.source_path or repr(self) - def check_properties(self): + def _has_valid_mandatory_properties(self): """Test mandatory properties are set.""" for prop in self.mandatory_properties: if not hasattr(self, prop): - raise NameError(prop) + logger.error( + "Skipping %s: could not find information about '%s'", + self, prop) + return False + return True - def valid_save_as(self): + def _has_valid_save_as(self): """Return true if save_as doesn't write outside output path, false otherwise.""" try: @@ -174,10 +171,35 @@ class Content(object): try: sanitised_join(output_path, self.save_as) except RuntimeError: # outside output_dir + logger.error( + "Skipping %s: file %r would be written outside output path", + self, + self.save_as, + ) return False return True + def _has_valid_status(self): + if hasattr(self, 'allowed_statuses'): + if self.status not in self.allowed_statuses: + logger.error( + "Unknown status '%s' for file %s, skipping it.", + self.status, + self + ) + return False + + # if undefined we allow all + return True + + def is_valid(self): + """Validate Content""" + # Use all() to not short circuit and get results of all validations + return all([self._has_valid_mandatory_properties(), + self._has_valid_save_as(), + self._has_valid_status()]) + @property def url_format(self): """Returns the URL, formatted with the proper values""" @@ -194,8 +216,10 @@ class Content(object): }) return metadata - def _expand_settings(self, key): - fq_key = ('%s_%s' % (self.__class__.__name__, key)).upper() + def _expand_settings(self, key, klass=None): + if not klass: + klass = self.__class__.__name__ + fq_key = ('%s_%s' % (klass, key)).upper() return self.settings[fq_key].format(**self.url_format) def get_url_setting(self, key): @@ -338,6 +362,15 @@ class Content(object): """Dummy function""" pass + @property + def status(self): + return self._status + + @status.setter + def status(self, value): + # TODO maybe typecheck + self._status = value.lower() + @property def url(self): return self.get_url_setting('url') @@ -383,21 +416,36 @@ class Content(object): class Page(Content): mandatory_properties = ('title',) + allowed_statuses = ('published', 'hidden') + default_status = 'published' default_template = 'page' -class Article(Page): +class Article(Content): mandatory_properties = ('title', 'date', 'category') + allowed_statuses = ('published', 'draft') + default_status = 'published' default_template = 'article' + def __init__(self, *args, **kwargs): + super(Article, self).__init__(*args, **kwargs) -class Draft(Page): - mandatory_properties = ('title', 'category') - default_template = 'article' + # handle WITH_FUTURE_DATES (designate article to draft based on date) + if not self.settings['WITH_FUTURE_DATES'] and hasattr(self, 'date'): + if self.date.tzinfo is None: + now = SafeDatetime.now() + else: + now = SafeDatetime.utcnow().replace(tzinfo=pytz.utc) + if self.date > now: + self.status = 'draft' + # if we are a draft and there is no date provided, set max datetime + if not hasattr(self, 'date') and self.status == 'draft': + self.date = SafeDatetime.max -class Quote(Page): - base_properties = ('author', 'date') + def _expand_settings(self, key): + klass = 'article' if self.status == 'published' else 'draft' + return super(Article, self)._expand_settings(key, klass) @python_2_unicode_compatible @@ -482,25 +530,3 @@ class Static(Page): self.override_save_as = new_save_as self.override_url = new_url - - -def is_valid_content(content, f): - try: - content.check_properties() - except NameError as e: - logger.error( - "Skipping %s: could not find information about '%s'", - f, six.text_type(e)) - return False - - if not content.valid_save_as(): - logger.error( - "Skipping %s: file %r would be written outside output path", - f, - content.save_as, - ) - # Note: future code might want to use a result variable instead, to - # allow showing multiple error messages at once. - return False - - return True diff --git a/pelican/generators.py b/pelican/generators.py index f3590155..eb97c115 100644 --- a/pelican/generators.py +++ b/pelican/generators.py @@ -19,7 +19,7 @@ import six from pelican import signals from pelican.cache import FileStampDataCacher -from pelican.contents import Article, Draft, Page, Static, is_valid_content +from pelican.contents import Article, Page, Static from pelican.readers import Readers from pelican.utils import (DateFormatter, copy, mkdir_p, posixize_path, process_translations, python_2_unicode_compatible) @@ -509,12 +509,10 @@ class ArticlesGenerator(CachingGenerator): for f in self.get_files( self.settings['ARTICLE_PATHS'], exclude=self.settings['ARTICLE_EXCLUDES']): - article_or_draft = self.get_cached_data(f, None) - if article_or_draft is None: - # TODO needs overhaul, maybe nomad for read_file - # solution, unified behaviour + article = self.get_cached_data(f, None) + if article is None: try: - article_or_draft = self.readers.read_file( + article = self.readers.read_file( base_path=self.path, path=f, content_class=Article, context=self.context, preread_signal=signals.article_generator_preread, @@ -528,34 +526,17 @@ class ArticlesGenerator(CachingGenerator): self._add_failed_source_path(f) continue - if not is_valid_content(article_or_draft, f): + if not article.is_valid(): self._add_failed_source_path(f) continue - if article_or_draft.status.lower() == "published": - pass - elif article_or_draft.status.lower() == "draft": - article_or_draft = self.readers.read_file( - base_path=self.path, path=f, content_class=Draft, - context=self.context, - preread_signal=signals.article_generator_preread, - preread_sender=self, - context_signal=signals.article_generator_context, - context_sender=self) - else: - logger.error( - "Unknown status '%s' for file %s, skipping it.", - article_or_draft.status, f) - self._add_failed_source_path(f) - continue + self.cache_data(f, article) - self.cache_data(f, article_or_draft) - - if article_or_draft.status.lower() == "published": - all_articles.append(article_or_draft) - else: - all_drafts.append(article_or_draft) - self.add_source_path(article_or_draft) + if article.status == "published": + all_articles.append(article) + elif article.status == "draft": + all_drafts.append(article) + self.add_source_path(article) self.articles, self.translations = process_translations( all_articles, @@ -634,22 +615,15 @@ class PagesGenerator(CachingGenerator): self._add_failed_source_path(f) continue - if not is_valid_content(page, f): - self._add_failed_source_path(f) - continue - - if page.status.lower() not in ("published", "hidden"): - logger.error( - "Unknown status '%s' for file %s, skipping it.", - page.status, f) + if not page.is_valid(): self._add_failed_source_path(f) continue self.cache_data(f, page) - if page.status.lower() == "published": + if page.status == "published": all_pages.append(page) - elif page.status.lower() == "hidden": + elif page.status == "hidden": hidden_pages.append(page) self.add_source_path(page) diff --git a/pelican/settings.py b/pelican/settings.py index 831e1851..d1249a24 100644 --- a/pelican/settings.py +++ b/pelican/settings.py @@ -126,7 +126,6 @@ DEFAULT_CONFIG = { 'FILENAME_METADATA': r'(?P \d{4}-\d{2}-\d{2}).*', 'PATH_METADATA': '', 'EXTRA_PATH_METADATA': {}, - 'DEFAULT_STATUS': 'published', 'ARTICLE_PERMALINK_STRUCTURE': '', 'TYPOGRIFY': False, 'TYPOGRIFY_IGNORE_TAGS': [], diff --git a/pelican/tests/output/basic/drafts/a-draft-article.html b/pelican/tests/output/basic/drafts/a-draft-article.html new file mode 100644 index 00000000..64d56ff9 --- /dev/null +++ b/pelican/tests/output/basic/drafts/a-draft-article.html @@ -0,0 +1,69 @@ + + + + + A draft article + + + + + + + ++ +A Pelican Blog
+ ++ ++ ++ + ++ A draft article
+++ +This is a draft article, it should live under the /drafts/ folder and not be +listed anywhere else.
+ ++ + + + + + + \ No newline at end of file diff --git a/pelican/tests/test_contents.py b/pelican/tests/test_contents.py index 56928b81..d028c7a1 100644 --- a/pelican/tests/test_contents.py +++ b/pelican/tests/test_contents.py @@ -69,11 +69,13 @@ class TestPage(LoggedTestCase): def test_mandatory_properties(self): # If the title is not set, must throw an exception. page = Page('content') - with self.assertRaises(NameError): - page.check_properties() - + self.assertFalse(page._has_valid_mandatory_properties()) + self.assertLogCountEqual( + count=1, + msg="Skipping .*: could not find information about 'title'", + level=logging.ERROR) page = Page('content', metadata={'title': 'foobar'}) - page.check_properties() + self.assertTrue(page._has_valid_mandatory_properties()) def test_summary_from_metadata(self): # If a :summary: metadata is given, it should be used @@ -503,7 +505,7 @@ class TestArticle(TestPage): article_kwargs['metadata']['slug'] = '../foo' article_kwargs['settings'] = settings article = Article(**article_kwargs) - self.assertFalse(article.valid_save_as()) + self.assertFalse(article._has_valid_save_as()) def test_valid_save_as_detects_breakout_to_root(self): settings = get_settings() @@ -511,7 +513,7 @@ class TestArticle(TestPage): article_kwargs['metadata']['slug'] = '/foo' article_kwargs['settings'] = settings article = Article(**article_kwargs) - self.assertFalse(article.valid_save_as()) + self.assertFalse(article._has_valid_save_as()) def test_valid_save_as_passes_valid(self): settings = get_settings() @@ -519,7 +521,7 @@ class TestArticle(TestPage): article_kwargs['metadata']['slug'] = 'foo' article_kwargs['settings'] = settings article = Article(**article_kwargs) - self.assertTrue(article.valid_save_as()) + self.assertTrue(article._has_valid_save_as()) class TestStatic(LoggedTestCase): From 68724e9682f91763104811ff72e092f07d9ad6b5 Mon Sep 17 00:00:00 2001 From: Justin MayerDate: Tue, 25 Jul 2017 09:00:41 -0700 Subject: [PATCH 033/916] Encourage use of https:// in SITEURL Refs #2183 #2186 --- docs/settings.rst | 8 +++++--- pelican/tools/pelican_quickstart.py | 2 +- pelican/tools/templates/publishconf.py.in | 1 + 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 462f9d36..e5ce19f5 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -203,10 +203,12 @@ Basic settings .. data:: SITEURL - Base URL of your website. Not defined by default, so it is best to specify + Base URL of your web site. Not defined by default, so it is best to specify your SITEURL; if you do not, feeds will not be generated with - properly-formed URLs. You should include ``http://`` and your domain, with - no trailing slash at the end. Example: ``SITEURL = 'http://mydomain.com'`` + properly-formed URLs. If your site is available via HTTPS, this setting + should begin with ``https://`` — otherwise use ``http://``. Then append your + domain, with no trailing slash at the end. + Example: ``SITEURL = 'https://example.com'`` .. data:: STATIC_PATHS = ['images'] diff --git a/pelican/tools/pelican_quickstart.py b/pelican/tools/pelican_quickstart.py index ae0e8c9d..eb63ed1f 100755 --- a/pelican/tools/pelican_quickstart.py +++ b/pelican/tools/pelican_quickstart.py @@ -246,7 +246,7 @@ needed by Pelican. CONF['lang'] = ask('What will be the default language of this web site?', str_compat, args.lang or CONF['lang'], 2) - if ask('Do you want to specify a URL prefix? e.g., http://example.com ', + if ask('Do you want to specify a URL prefix? e.g., https://example.com ', answer=bool, default=True): CONF['siteurl'] = ask('What is your URL prefix? (see ' 'above example; no trailing slash)', diff --git a/pelican/tools/templates/publishconf.py.in b/pelican/tools/templates/publishconf.py.in index d1ed994d..473490a9 100755 --- a/pelican/tools/templates/publishconf.py.in +++ b/pelican/tools/templates/publishconf.py.in @@ -10,6 +10,7 @@ import sys sys.path.append(os.curdir) from pelicanconf import * +# If your site is available via HTTPS, make sure SITEURL begins with https:// SITEURL = '$siteurl' RELATIVE_URLS = False From 9495a6c3df8d0417568a78fb03f6c0eccc7adf72 Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Sun, 30 Jul 2017 17:41:03 +0200 Subject: [PATCH 034/916] Remove trailing whitespaces from notmyidea --- pelican/themes/notmyidea/static/css/main.css | 64 +++++++++---------- .../themes/notmyidea/static/css/typogrify.css | 2 +- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pelican/themes/notmyidea/static/css/main.css b/pelican/themes/notmyidea/static/css/main.css index 03a77e69..8f3deef0 100644 --- a/pelican/themes/notmyidea/static/css/main.css +++ b/pelican/themes/notmyidea/static/css/main.css @@ -43,7 +43,7 @@ h1, h2, h3, h4, h5, h6 { } h3, h4, h5, h6 { margin-top: .8em; } - + hr { border: 2px solid #EEEEEE; } /* Anchors */ @@ -64,7 +64,7 @@ a:hover, a:active { h1 a:hover { background-color: inherit } - + /* Paragraphs */ div.line-block, p { margin-top: 1em; @@ -124,7 +124,7 @@ div.note { /* Tables */ table {margin: .5em auto 1.5em auto; width: 98%;} - + /* Thead */ thead th {padding: .5em .4em; text-align: left;} thead td {} @@ -132,14 +132,14 @@ table {margin: .5em auto 1.5em auto; width: 98%;} /* Tbody */ tbody td {padding: .5em .4em;} tbody th {} - + tbody .alt td {} tbody .alt th {} - + /* Tfoot */ tfoot th {} tfoot td {} - + /* HTML5 tags */ header, section, footer, aside, nav, article, figure { @@ -173,9 +173,9 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} color: #C74350; text-shadow: none; } - + #banner h1 strong {font-size: 0.36em; font-weight: normal;} - + /* Main Nav */ #banner nav { background: #000305; @@ -186,15 +186,15 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} padding: 0; text-align: center; width: 800px; - + border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } - + #banner nav ul {list-style: none; margin: 0 auto; width: 800px;} #banner nav li {float: left; display: inline; margin: 0;} - + #banner nav a:link, #banner nav a:visited { color: #fff; display: inline-block; @@ -208,12 +208,12 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} color: #fff; text-shadow: none !important; } - + #banner nav li:first-child a { border-top-left-radius: 5px; -moz-border-radius-topleft: 5px; -webkit-border-top-left-radius: 5px; - + border-bottom-left-radius: 5px; -moz-border-radius-bottomleft: 5px; -webkit-border-bottom-left-radius: 5px; @@ -228,7 +228,7 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} overflow: hidden; padding: 20px; width: 760px; - + border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; @@ -257,7 +257,7 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} overflow: hidden; padding: 20px 20px; width: 760px; - + border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; @@ -292,21 +292,21 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} float: left; width: 615px; } - + #extras .blogroll li {float: left; margin: 0 20px 0 0; width: 185px;} - + /* Social */ #extras .social { float: right; width: 175px; } - + #extras div[class='social'] a { background-repeat: no-repeat; background-position: 3px 6px; padding-left: 25px; } - + /* Icons */ .social a[href*='about.me'] {background-image: url('../images/icons/aboutme.png');} .social a[href*='bitbucket.org'] {background-image: url('../images/icons/bitbucket.png');} @@ -346,7 +346,7 @@ img.left, figure.left {float: left; margin: 0 2em 2em 0;} padding: 20px; text-align: left; width: 760px; - + border-radius: 10px; -moz-border-radius: 10px; -webkit-border-radius: 10px; @@ -390,7 +390,7 @@ li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} /* Blog Index */ #posts-list {list-style: none; margin: 0;} #posts-list .hentry {padding-left: 10px; position: relative;} - + #posts-list footer { left: 10px; position: relative; @@ -398,7 +398,7 @@ li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} top: 0.5em; width: 190px; } - + /* About the Author */ #about-author { background: #f9f9f9; @@ -406,21 +406,21 @@ li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} font-style: normal; margin: 2em 0; padding: 10px 20px 15px 20px; - + border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } - + #about-author strong { color: #C64350; clear: both; display: block; font-size: 1.429em; } - + #about-author .photo {border: 1px solid #ddd; float: left; margin: 5px 1em 0 0;} - + /* Comments */ #comments-list {list-style: none; margin: 0 1em;} #comments-list blockquote { @@ -429,24 +429,24 @@ li:last-child .hentry, #content > .hentry {border: 0; margin: 0;} font-style: normal; margin: 0; padding: 15px 20px; - + border-radius: 5px; -moz-border-radius: 5px; -webkit-border-radius: 5px; } #comments-list footer {color: #888; padding: .5em 1em 0 0; text-align: right;} - + #comments-list li:nth-child(2n) blockquote {background: #F5f5f5;} - + /* Add a Comment */ #add-comment label {clear: left; float: left; text-align: left; width: 150px;} #add-comment input[type='text'], #add-comment input[type='email'], #add-comment input[type='url'] {float: left; width: 200px;} - + #add-comment textarea {float: left; height: 150px; width: 495px;} - + #add-comment p.req {clear: both; margin: 0 .5em 1em 0; text-align: right;} - + #add-comment input[type='submit'] {float: right; margin: 0 .5em;} #add-comment * {margin-bottom: .5em;} diff --git a/pelican/themes/notmyidea/static/css/typogrify.css b/pelican/themes/notmyidea/static/css/typogrify.css index c9b34dc8..3bae4976 100644 --- a/pelican/themes/notmyidea/static/css/typogrify.css +++ b/pelican/themes/notmyidea/static/css/typogrify.css @@ -1,3 +1,3 @@ .caps {font-size:.92em;} -.amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} +.amp {color:#666; font-size:1.05em;font-family:"Warnock Pro", "Goudy Old Style","Palatino","Book Antiqua",serif; font-style:italic;} .dquo {margin-left:-.38em;} From 9ce09c07151e6876025bab2460fcd6b79af3e9da Mon Sep 17 00:00:00 2001 From: Jorge Maldonado Ventura Date: Sun, 30 Jul 2017 17:46:18 +0200 Subject: [PATCH 035/916] Store fonts of notmyidea theme locally Used google-font-download ((commit ecc521e894c55e83773351264fe5bbef99ae70ad)) to download the fonts. font-download -f 'woff woff2' -l 'latin' 'Yanone Kaffeesatz:400' --- pelican/themes/notmyidea/static/css/fonts.css | 12 + pelican/themes/notmyidea/static/css/main.css | 2 +- .../static/fonts/Yanone_Kaffeesatz_400.eot | Bin 0 -> 20932 bytes .../static/fonts/Yanone_Kaffeesatz_400.svg | 407 ++++++++++++++++++ .../static/fonts/Yanone_Kaffeesatz_400.ttf | Bin 0 -> 39168 bytes .../static/fonts/Yanone_Kaffeesatz_400.woff | Bin 0 -> 22256 bytes .../static/fonts/Yanone_Kaffeesatz_400.woff2 | Bin 0 -> 18320 bytes .../themes/notmyidea/static/fonts/font.css | 12 + 8 files changed, 432 insertions(+), 1 deletion(-) create mode 100644 pelican/themes/notmyidea/static/css/fonts.css create mode 100644 pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.eot create mode 100644 pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.svg create mode 100644 pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.ttf create mode 100644 pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.woff create mode 100644 pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.woff2 create mode 100644 pelican/themes/notmyidea/static/fonts/font.css diff --git a/pelican/themes/notmyidea/static/css/fonts.css b/pelican/themes/notmyidea/static/css/fonts.css new file mode 100644 index 00000000..56015076 --- /dev/null +++ b/pelican/themes/notmyidea/static/css/fonts.css @@ -0,0 +1,12 @@ +@font-face { + font-family: 'Yanone Kaffeesatz'; + font-style: normal; + font-weight: 400; + src: + local('Yanone Kaffeesatz Regular'), + local('YanoneKaffeesatz-Regular'), + /* from https://fonts.gstatic.com/s/yanonekaffeesatz/v8/YDAoLskQQ5MOAgvHUQCcLRTHiN2BPBirwIkMLKUspj4.woff */ + url('../fonts/Yanone_Kaffeesatz_400.woff') format('woff'), + /* from https://fonts.gstatic.com/s/yanonekaffeesatz/v8/YDAoLskQQ5MOAgvHUQCcLfGwxTS8d1Q9KiDNCMKLFUM.woff2 */ + url('../fonts/Yanone_Kaffeesatz_400.woff2') format('woff2'); +} diff --git a/pelican/themes/notmyidea/static/css/main.css b/pelican/themes/notmyidea/static/css/main.css index 8f3deef0..9673ca45 100644 --- a/pelican/themes/notmyidea/static/css/main.css +++ b/pelican/themes/notmyidea/static/css/main.css @@ -12,7 +12,7 @@ @import url("reset.css"); @import url("pygment.css"); @import url("typogrify.css"); -@import url(https://fonts.googleapis.com/css?family=Yanone+Kaffeesatz&subset=latin); +@import url("fonts.css"); /***** Global *****/ /* Body */ diff --git a/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.eot b/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.eot new file mode 100644 index 0000000000000000000000000000000000000000..b3b90dbc3ef34775a8689ab6a4494810c14c5a59 GIT binary patch literal 20932 zcmagFRZtvE&^EdYi@Uoo?(S}jySux4Ai-gAcL?t88r&U%yE{PwK@yVx{k}Tq;;(aY z`l*?g>h7w!>glPTQ4IiKQ5^t)`41q#{}9~&?f?J~kPQ4EQCS_~|FQhPEDH#r{2y7A zq*3C3`2S7R00V#pz!l*3-?I77QRzR;_CMJC2e1ERZ@{Pj0?+}P|LJxBAAs|JHqZYo z!~os@ES~@QIQ(xcC4dXS2H^N#0REHz|Fcs5e{uo T{l-!Mw#gC?-%_Za1r zGao42M3Q>o%!K30W)0WC)t1aMPxB*rJ(P)FT%5@u*}@@(4HFk@_L0?Lr!}?(MvURp z3;kC%LmV4)R%~SF0zUKTvOkN_E2HI@@HY%eOp3v{p2KF>#oeB2-NEqt%kHcL 1X(0n#6C4Ek=(OK4Z^BBqr~zta4NNtv|H>IVU0yO zKmCROKE|RNTz~n4&s;KA>4YCy39JneB1UQo`qCBKAa1sB^#wOJ&Wq_L4py`c4A*EY zKln>aFC>HM<66r7B)QuTTSCY5FApaQtZ_a;vvNwMH0(01?v1imCR@lr*m~?2I{V%u z?ETq;T41%GPlv#TklFmH9cxXmI$>zC^{M-GNP97yBwkDb)?qO-a3rxTJlE3!hA?!H z4z|Jn@y6(v$&gL3H`C@yt^h9L^|6z}?Lr*2`N2WEWQo2iLOHRPa9=-w8+RRDe`YN+ z_Ir`F90Y0)w6YVf;hz &6DHj^eU%-$gc?NM z0A?cy+W>u$6XwI~-pAbFbS+ouSl<*xGJ%3{9Vt6XHxqcUSRParN&72T7HDdL;rkCe z!c&*> %b}aSYUMS(GfJGS51BQZ0q^#q47N4zv;3 p@ z)B#g+01o7)RFm(H5n;KuoKiEr`CgMp53KP#b1%sy*BfILg1k&`vLENHY`?T9g3&(3 zdGnED9m$tY>B{ah+1(2ltb|yLyODVO`9NOQp96v4#TmJUBzEHp@g3BN2AZ9W)ZJ zVtC!_T&HlF%MgSWN+~SG;JFHYeraJvs9s@N%2BZ!?YMSuN};IKA~Z&G@-SuL;TYuM z?GYePgGi~3TiEvT0}MZ9(*J`G!I$KLA!WJyg#8Cc%3@SS$dS8buJMA- 9a ziK{ThhbyNoP@=Gb93YMRhRE5h`)E{*L=ObWGE9b)n@h0LqrM`ufGE*SEdZ7~Oj 2=5=A^cps!6&7C zXkSSZ>)@2Q=S!GEBFZ&%w$V3 c}bc!y{n95-GrNCAwa<&HOp{ z6P$~0&JT(6`-wyI?u8oWo4!}i;p$89!wpb5g(xefcLGHq6-<9^zlZz
E%DO>TP6Csfkq32^W3P2LJ^>-x<|3$wQY3Ibxxns#DP z4dd}xiw{!>(&q7t?M#WNd3K}JgEbFm;`Do|1^;wG5|5puzl9awX@>hXLH15Yp+9Is zes2%#dpg243=?rQ!ZfP-Mn+T4VsbIWzuE69&b?C7s8IhfC4Z^IH+^Q^dv>I7H&uS= zb4P#lqjz`9|AC>s9SVEGfufZ2!>PF)@jRBoN3qjOl=ccC{5|q76J)27urqMQ_n}iO zkQ&9Gg_gg$<)wYeXqWOaVkOeeCYm-7sH@-7^)1qhcvl_B2S-D3z}K* +8xW5cMbbP%JnGJUDWeLpoOZLv$?P9eKZO(#!-AnsxG|xxrR^P0 z0oCY-t?ZrM 0oDRvkQ^22eoqU`yT*;oTeZCxgb9$XZT=ZG>fJ{E7c zcaA38XmplUn_@my3weeSe7PQWYW 1oP?#+_hj(gDJ+d6XtfD&@m61$D zBgs}19Ds #Ed2%VTF`0JR4|r1eRSL6Wg#C>C&& zNr~R0 ?j{o2qjb5{AncjxK}Qf)NYkoL%Z)8lj5AbF2m#Z zT{f(_#g`9T+!YO1Y*5t+o;6L9OZ6!cC}s{d{>>~{sv`SsS$MNa_z3;QL?b?pzmq>P zEtZ+VD$zk`JexxZl|)sapTNd^jC&8wdITXh-?2$e<(y?h8xz@igCqAW@mQU%#&y=m5Vc 4`th2$?cLC(K zSS`oBM2G&=QDP06Mviv@Ef-AeavTwIPeJ}}`@;e$cbp)4n5feJixir8GXGahmILl? zPNc5NRS^g8lXq1>fYt%3JN^9=--f3<{Tp6KiPjJTt{67%8vb)7N-PI5>G$YGVqVOd zkR55qG;*xVwBmadV=Ate<0XnVy84tF3|cb*yUt;}-^IvN5~-Z0XsClSZKws`sLv>i z@K+x$f+edYy{-afDTQV50jZo<2wnuuHU12Q$Wj!;gGqXeAs^j=ANWvrUOiJs(J`dC zGYnGtu7Q6BBIKIc%x}BLRh@T@Y pG3arf}kJ_4Bqv9ex<4S5}FDOj<<2DN(HyqC4BySFY!;b>LqQ3npe!#8;f% z%0`)Fl-Y ?Po`C_Qyl2Sxy*{+5+yleP_uqW z+iZlL@V4U_Ry|zAv};XJP|nC+S#xvvk*=}dWE3@P#g3f;@~0?=Untr<7))*&(G6ol zn-?d^-xG;TEP*Q!2#HoRPbf9G72zWK78QTuB2Dq<6By8f?kR*Qr*foIAAQ%S0D62z zHAByeBSf9aNvtGAPO>8pv({MK2nwU19&Vr_yw4^I3j>fuOqN=Y2cMNlhx9R_O%2OA zG?NiLjXrY7dpZ4uIRl{H+XTPbsl)XS(Em(;sKN*;M`DP$vcf28C!{ze-Mi$LS*Y}9 zr+jG~hixN@V8QqSYRwSD&dk-PZsmdH7CWQ54=rS62qm^rGvtV1hrymxQ6b2-S<1`F zVysdCc_g+*Wq8WVOA1m#ldm$FK}ISVSGj}hl95mooCaCNtqByaVR>gEK;LHx4egmy zUd(+<>T7{^TCaD;)bz7#3|bbzM%dy;WV{C&dkPQwk6+lpU1sUUo7BaV#Gec?JM+u_ zhg^=pnCz)xM= V$auT{xj)I8e5=(RJC zg7pz6Nxw>PX)NpPQ%Ys1q=aeZCKH+^tIMeg=~FeSs6P~CQ1u#KCv_*nU{XRU_d~w+ zP}DZJ2x*|eh&|@&Ie@2f1q@gg)lpDerxgqz F>+;A+hjC6Kg&=@Wq?`BZElq>N6 E0=nA8|Dt zK4V1gSSNP<60N^ zB29yr_&vhoB|r$UAyMVnIeyhZn-k(kMBHY>$3wZGlzH>T>^j_q 3UajI&%tjK+xoSkU}RII`9Z@nMZM9f4%RG@SST@QP6-0@Pu6UHE;F^zcBmISn5>3kznROKDJVUG<+UK z!%-{Y^5cBAKoXDZQaIsoNJ=??a7wgF4zVIbO*(?Z%+`Se0>^H|a@iT}OC6-tl`5Ja zov&e`;jUxc;^znWd*sPzHcRo1Zc+{@l dMTLtK$q%z*#1I z^_j5tIQ9|CQB=n58w>hI(#T%=$AWvve@J`ubokPBKEH-2d?DdTv%=BTmqezoBloES zOT4v2VJSb<#ggI7X(b?Zc&B*sPg~--Mi)cBD5oB7OXDRI~*13aY4mQRTES zy=&{6+QM C?lB@}08?Ez+tvrmf1>IjNs zb#`^K_14kXFZoaCRl#2xGfq ;d0?Q#4I)}`R6j;%UjJL zIZ%!;ew^o7C~90?NQ}V8%=Hu>6$Fri -Z=^^DkrW ?)b z+Yrt4(S-)4Y*Q8bN=6z{#algvs>|E^J5uT?Kr|mPxk5@ %Pr5cHPedNsv+HCQeP1?lQ z_CJil9NUYoZd5YRu}>b_@hTKzNbA@}0%leM^HdTjOz`%5JkV`5BJ6ZNRNvU6OV*qO zCef9M;Ioa3S8$p_X8_&4U;{O1m@eRBY*-I3Jkv0VZnaeY;vIvaFCUxk-9?ff$C>od zWq8hqA~0PY?`(;Au3MbN;k|+V&yMHL@1nQhqJ%W!3C1U5VXdC?GB^*xtAqWL!>#$D z=cvz~r36pff|EE+OZ%+m=@O+FdWVUyVcuJBT7(cdAj?k{UDveIf|b^df<^%xAD| z(@d|1eum*&oY*&`&B=0g`$67PfsKhRuOmPWO#b@m_}T78Lf&$d=OtwL? ?| zkeO7ZYIEM@Pv?QooqAcW+NqhCl+Vlg2*6DIW4F$((?m29eL2TXFik*Qq3$Fx+ZPpw ze?5Yb(BHcFEkB5yTH>kVE0gm26y1-bY`GiY6P#Z&31(=pOBMs#KesX*?l7RlCPwoa z)-R;Ho)RDh=f)hPYWT+y{og`f>(g{DRpJklki)DE4$R#MM*f~_-c&w{HGO@lOE-I1 zM=9i(wb{ze5*iwMWOTA_H+yuke=Hu=LUTZ@ujrw^3V+}pj~Fyi{<3URc4)dFXv7TC z!h|87FtWlX4Zj?BSA$eK8_DteeDxHtxKCSA#rM1|vW_lZwsu((BC;a`?p85D-PA;A zRd*$=Ey2hVFe;^UUJ*rOvV;-bnAyP={S0~VRD@p?7LM~N+i2{PAqIP00ZQ> !A+P-<)5TYs05Ld7|&xdV<8|K(wC6~ z+j-%HmPALHgToUHv<8k{f?_>u4>n1Cw&7cf#kA dE|B3vup*#Nnq|HC!#bW7CITSB^a1L&P!HSuugQd*qXMZg`MVRX zJ5c&7&(VqaA!T!gq3$Itl#%6>Iye;Z3XTlLaeA5#Re!5E+VK(6wtyfJF5l!sh_lT^ z(5nvDv2;vZ0=h*Emq__PAzo>~TT;r3L_$jWD);1$fyoENNA9P&t9Yfisp`J3vpm(( z&UeXcKU5w8_AT~zNK_SeT1u$kOTI%r^-&5Gpxs}}<*@OGqeh> ONf&_U@4k z2{N_#;6IUi@>#V+1D1-XQYlJWnF
xa=keZt8)>~UbC8GRlGGia>+C8m;ev#oUk&2zY%&RdhEh6ZP*DD&I z`qkc}PnZ)>)jyn)|GSgF*sb%*5Nj!87p?R!WHxk$lgQPk00>KjiWaAz3`^HZ{Wtn5 zr%(xiO(ts4shOU5GNof^cSem;e!KC|U;|d(ARlNZg4fOha+YvxIS3uKe$a>_l^!BB zNIgO@NBxD#hKAN|dESc{fm}82OsW9?06}~?y{o3PyMYH>-6-R#@Y;6Kxm@F{$wA;v z ht{cZ_L$ZS(=g|CMXQ zIMFbJaq86c4^L|k6TqpFDk{)G8~A-_{eUOx?ALy{%Xr_D)ueI@0SVfB_gBk%f*g8g zrFi#b*ki_?Mdd@(0zi&?#wHC3oCmS0`Wi@gG{PHZr&y`xL8%C>pkaIr&BV~K-y0uw zJNz{F@jDXMx5>a8w*`n1&B{DtS|(w5Xk{49v9F>RHev(|Rr}=33-)fu^ojE$gFEB0 znb=TC2ue*n7?7O0Y?kY#DC8WJao z9T|<(lRhbJD4o~Kt%fgEqg%{3V7~i40mp#R{=3f zW795y=vswqB(M{U<0w!s7(3XD=)2o`EJwCHA+O?WA^ z1 >#q3Nhnfi;7xT( zqTfl2Ygm_%c)`$d5g-kF?wriRfTw%fzWzy%(@2)r3>LuB#n0BDsD$B-j7- j|5Xow}=&uTR9`HN|!_jOG(v*K*Rh zyHlnXesSN11uhJ+X9-!ASvR-0L6xkYK0X^0?pf3{mb=B>9JJ3xvFUr8Nt?#WkSC5; z@}6VfLB7PDhQ*)IP6Hy7w7SH^JsHH01U->xb~WO_QjpQ0|8rzCQbas!d27)Wa%a&j zH1EI5#Ez>jn`WAfo!Y`&TWe ;Fk-^QGZQdr|} ze~GWb-9GL=Xc6*D6&w;VN2I0;DNfMhH0|<0O74-=S%FxIdGxg&CX80N$xX_C$MPA~ z;RFn!hoGQ(rCFF5MCtZdRFq UuZJ(v^P~N zQs e!JOsfSDj6%@(1-B`E1AJKV1j|xKr@HEeu53 z3zDxu`Wm-n?g#pBL_26(<;kj>CZ8@YE%RK~ X=;x2y= zO7}l@D`g9ERbH+k*D6{he+D6iYJe+4lQfsHPVw_px jG&G`;0m_CnoWXYr?l4o|B?5Eih$UK$U;-@Ms#U}q9 zq^YT!fo+{(m||B^w+l_}Bka}8QvswgoXA>3h`e*a2i}CR>0p}%K!ci6W7U0OC?>|j z+Z Rgp -VD?_lbZoDwoP#Xb}#jP(-Mh 44h16<)TVb@>!aYF1BRDm7&J zofbIx={qBNITKoRZa`L0dQ rk-9nmxvje!EQtieLR@E#Bi#$57U8@2n^TjMdtAQ zf|jNudRZ}rPV*eZ{#5ma1~HHnLOf6zwZ?e$K#aJB>fN=awx^lpisboaaGxhE ~#nRbHCV;i-^hV(U4%MPFqRhb)4)Zr}Uy^SH zh_5$_Hn(ebM(x*-KZzbm2^(ic`vd^LAt|V$Bc&aaCBi5sYqt8^diwMH>)Ex56BhnM zUuCwP*3!+Jf^6I@Haej#WX%?x$Jg7XW<7_BrpF1O TW216~>DhW$35#NQ94H5gjP0qa)S}~xb$uddlL=8?yzHFQq=uCc(d6)x! zwYF&XDU+7sX}5XdK-h^WL4qm&9Gy9G9z*&Yrjg}>mVe|!%EDkgA}Q$=B$X*3p5?qU zG5zUm+7F(01>tJOeb|x~4Y_!}UtQ8caeA`z)UWQSTIGBYF6|i`j>U5Xue5q=Uq8SV zm`~dKFVTw0xSCOMy^e~56~K%g3Q((HTN9W>cD|}n!&*@gE;Jb@r3yxVWrm+P#Lp++ ze9q5u8ygEh));UrJ9b=~vUZ?|8@qsq=3Ns-BzkO#YRXu`RhnjJw;0ubv&sen(F;uB z)aE%&-nWa~&|;}CE0^!N#1zkmBn^+16;!qZ#U^H`QVEBdQx_Lr@rmwXX6TpK3H$s} zNxz#;NO!A8UP{?4WV2Iw#| !4uD@TzPVM#Yo#&BnKIOB=mE;!=nuX4*fY0SYQx)+o5Tzo-$Nyh$#?9Q z;BK6NB6O?tvcViELWY0I!RKnWW(c@Z8mTaD{`L5}VzLx~4|z@eU-`d7Lljo-H|MYJ z8aWcfc1ejpynO1b9g~=CsQ%PkK!x?%=fB0rJ&9nmck!YgVf>8tM66J_6xXSd9W}?o z_-TSFQP30|mJXoA*@#acB_m36^q6B}ZFwY97_F4oM>gMbXG8dVK`G~5-!{D8r{)5V z-zWv#E-3Js5kw-taaRTm$BiI%t!(KZ#xda<_5ZNLYj8*GYR>4Gj2b?UV~5X+a !)1I6Vi2 KF)&3?#whNt>JXVy`*b4E4B@CPc0VZ0sWbNq8@Jn~w^)0J z`mH~I !mg^>1FMB$WQIu+PwT!MPvhPe!B@%gZTaG*X_ZH&Ei+=h3#$ zLyMoe*ap7S1+%o+@s!}f9wj;k&|CLhfJ-@AsO|aCP5=!OR+8z_e3Wow9b_<3jx$Km z5l)Vpmu7XoWqr)B)E(GtB|;zK`j%R1iPsRQR?6B0jlL4)BrA)*c^Ifz-U >AXmG%)T33qvC<qD(Q|MwF(p|u5&EuG zXJ-kt_DH<-0c(l7o8+rF9~R&6`AENwY1Lxey18FLBe!79v*5HLZTu&DtIP+kt$iNQ zZx}t(Nhe-+SK4{}m8wPyU8AAhdHGX&Lqz=MmchKMlzt{M^Joxkg=)hQ>bL1pBkA{) zRCG=x`OlBB7P&XB^6<;6QoxT{xp*op|6XiGV-pXNV-9#&rOHC}h6rkt1>3w|Kcfi$ z2=u36_1HQ8&@AXR91%IJ%fdZfFGF+d>iIJ3$B8+4zm3eBwdSSP5$RXRr67e6iIH}S zOLmhz?}~+t`sS5G5CZQ==HF1yWb $q(aa36?!SsSM>IeWuPfq;8x2A z1={WiONpN%TH>HTE3e5*o=>Q2*=xn%JFa*8TaaCBd1 Frn5y3euprmc8vWJ=yeOfe*-k{~` Q{Q$V;-Ssiy- z8Clo?Hb#bUL7dwdo!;WT(CTbqY-PBh>K8%h$^{zh8h6B_l4{*glb9&1guvxs+QdjU zbpxi0ij}`NTQxP9rm$7NLc+16*W%Qc2g^db8MZ=(lc?y3cF6VkNKO`~?J&lOWb11N znz3aAMx}Q!tq55*{JG4rSIQ;_rhzRu^&FK+hm-0{{MSlppQT_2qIWCsfTLa6TlzA{ z&L<_J-$8B2E(ltfU(Lb3t%v1^{Td|1oC-^ XU0Vr$MHFXWn$VZ}E6|U%1jH zU|bK&>XB*1|C)*iHXQ_Tv`Cl!-gHN0)TgVX+wGdk =tgtbscN3Ba{M7aZH zr5Qjn$%iaWm6jqBX2Z-i>_r=CQ?oVE1%>(LC|f}KCJMosFme|V?d|qO3{eu^=u28R zhH)aj{+1jm3H2byzbrUHiJvvh9bzO(>h^M`=I=1Zkb#qfhV^Fq$b3X{@R@au$pESh zkV`-8;)oMmpHzU_xl$FKdtv6v43V+gOU`3TgFYzqG@rms2o4sY#1+5vk$K7ja 2lD%l 5t3ql(M*O)K-$GuqSfcupR~uY6$%jC926|AEqLTT z5EzP?I3Bj93 B0!8}J0dC^a<25vqWXQ8`nU24D=DP_0e-ap7^z)2 zqh=Kb1KGdF6h#E4N6ds%0o-smUr;= wh=1l6tM(yJU(STJ)vd}!{kX30rig@~F_z;5zM;<2tQV?TQMWWO8?UAD0 z04tcr8%rYovk0n^eE2jx6-n4HQh|uL$Y1t{I^0d=x57)d!DC?0m4dq_N>{(LvT3e5 z<%aM@N5{@l_Bty$e-aYiy(WEC0X9u?RZZ5A{4;FubtZnS6b->6@@l-}Ozvr>mc%B5 zS*kROY+C3$#g&73gkz2C_ZjLjGwQ+GL${g%!+&3$E>4msR`vAo|9lwteTMwXks2Pj z4uz@s*C1htRM9M6pe}!QDYMDMby9;Wh=fL5JxQ8?=VVTR&&ZPWoxJP09LQGb)cPW# zYuEgV3073-11&mj^Q~oRT}no6y3<}eIQiF4+Tb+GPH@U7u=$$@U@2uCU6JOUF`hu8 zYjC IQ~-s-6cMjL{4JO>wLooUxX)ZvNfJM0& nhjnrwa{| u4G%LOygOTku?ntw$BIW)W^Jj;;4v=`~D+lK=QHG&Xb_QoU^n7}EB}e^;q=trl zX1PC}_-!+Oy @aOr1p+*U5fBa!_C6p5op8nTny;iysQetK{)~vVrBxa(D zTEFwgM6KI^=rHSQF7akEc8irnS@?-^`iID>H)4xB*H%KJ zam@^TPkeF)LU@}^_9$3M0|uV2E-DpYP%!#kZC_#<78PC^Q8&zQB?VTN0l>oh)FX5w zF^=!!L>N=7m}6x#hL3Rhg4=D;$R)a~-Z$H(=D>3pSS#N1nTa)hacc=622(Xeh3+ha zWgHMd1}X#%W1sowd}BXvz9ry7agpZNuCP{EB_6;$$gh$F>Mg4LVjDu`6U^b#EHN%P z`0*Y6(>1)e` 3$?ahl+nG^&1Loz$kT|_4f!mo<&5Lo+>rrp zZ{UTc5WmZf_I5nxF$wUSR(31R0}m0U5PjLMknX9JGc|i(c-;ONz7V?*`Ii{TE5~JT zaDAwp!YQHFPR=jXS3(f3g>F1Paw{wvtQj5dUE9G7@DhmOC|!+eqdww3b$k$YMC>Qe zWg+t5DwC=Ii-@sBOGXq0n1b$~!9$4a|I+S=>x*W=Yq^YS@F(2%<{0o|D}?p ^xu_U6IGqTT=7YhAUyG85HZvQUx7P4s`6~txg5C^^p^sHu{d6U={Y%= zGoQc-STf1)f3>@M6y$TF&5}rFjnz?4IS@)8V`V$ly151YRm&J ;!&09(LwJwgquPm>ndm!p1C{>u&+7t0c^bk`iY!9pB3(M4UiF9~ccZQ%biy z1NIkToycD~h|gHahhP6?e$Y=un4=z7Ja>yxU#wn~ZOU;}=7hoqwS3$4YpcqZ*TJ%I zA5~}aZ_ZDNHWhAI!M#)=TnSXD#yUVXQ>m4aeDcw*iLr%4)tOcmy~lw0R!4ev-Tl*1 zkk9I?0J~fy^%Q(re-#z1n28g$9Ica}Vk}-aVapjBJ3x5E^fML1e`O>S3v&mRTt!s6 z&!9~S#p2WMf}PMk1_9VtoKqc3Dw6ARrRBG9Dc$2ovahpQUXNh`d9Rm~BYcz}fs37W zI#p_KFu4zEQ4Uu^x(EIZN?$m9$%l*m-j9qwRd&06ytn>zPifplo6n0px*9%pii-M2 zW~8Lsj+%OAqvCJC#!~B5Wz_w I)5BxyKtd~KOo7HT@%3T7>ghp#fbY&9%GhD&}w zOx{9*Sjt9cF;DYZD9^SRIr@2S6*<)+8VYt$<|j`_>+ZHCthgQ=HtO)<^fFnBHEF0l zOD3?EK8jg3pnwV(1??WNz#2SJePkJA{u7qeYWKaCHFwhyR3L7wcJMKb&-$2ZZCp3y zyWQaG5t2+Cwm%Pa@(4*!QAl=84^5VT&bmdjVcRU7 z=5{mot+2h_cGSR@iCD#Fa=qqXn*7k!m=$9%-R=9X^rM _ii%=G@0;5vdL H-|cd zn+&{UWlDGGWM0AgO0JL$RL>)GK8lk*<1NQHAPV#K96FM?H5sGMl@7|D%pb2oYkDuw zQjQJF$&E%w!X%}Ps6^|2$FUzpU8q%Xd6!9#>4-8Xj-KnlDr5Q5$JgJw9n}9TQl}ZL zzH;xunn$Fue_NLxL!nKs?Us}?`^?~Q{xv7JLdrgkMpWLLG6u3Ko;uSJW_3bY*#N^# z($I0Pv(8~ng^rDn`GwDl3z(b3O)g9i&n5u{GrDSB$V35RY04q7t#JEYXv39Z+k?s3 z>|w|$zWhmU*+l50)3^Di>t&LjKGuRt-ds{7FA!yGLdm_yPv0d?=f_mbr?#Yr8lV#s z`yAFkjrxa{>ZSPedxZ%@)fc1DJzwQo#3CgR!Z^FmE(w)o$@0Wg;DE+}iST5^KUz&| zNlL*q@V~^ulgxO@5z`!)q>VH|kDh(iQa_(X%9LBbh#35!AUnA=JpJ=A;DJC|Q^Y6L z^*~g}3FJWNpZ|8K(5Pd&10_GB`+RvCEzyuHX$c`v?Q{5<6IwP;Y~?v~@}Y#c&eaJq z^Q8RyN`AlBjHAVxyuVwl`$aO(5jzydN*8MSl}C5W22U1zhkbygIEd@BsT)6`h=U2l zW@x`|jhtoaQ2phWzv)eq_&WAL{s+uU&9>}+Ma6;c;0{p9`na*)q7v;m#~l18h5nN= zQV48`RvMD8f?U0-1j<*a7;=%6-c_6P%AN0du${S242_K7LoG1SQX*gwQk6Uqd)Q<5 zZnRbsv36CqPA!dU!b6-dNrkT@>HcDa^jET^#+w3-mbM_ZI&<=i1aZSu%_T_zBTd_H zF>XgKp#xW9zkT#UiLaEHPpnXgO{1=<({IQwdd;K(Jike7gn3?7xzuzte9*+O9Ch~= zkEpxr(C34-+9?pa6Z9JL9joAzaS^#MJm8-(l@0UPbjD8!7wHEvd&{|{x-bZTi!ZC` z1HWcl+(})_)s>h`k6o|G<5m$S&GjV-(nY$?`PA*}7G>0g&6?LS(jI&8)b37}piIOw zffa^8S8aM_|HQ191w?0#Q(|cG6xY!~v-pB#Uqm%o*5$?cv7bX_&w~(QPIqjC&~ZDx zo`S80WzsE+#`fZ6b~R!ZYt1)wTe1r8O2|*uQU^3}EQOfEENP<;v&lA0R+T=BGPpMj z0thXUovnu@zJZ&vqbmUnt?9^;_4`)8aV-yIkE>X74BrtwXaU;BRO5-S9YbaG&7101 ztiYXcx5&WXaYQ`YV yGs^bzBx%^@!*fSd{4{t!Zj; zXy;t4IePbK33Z!__8)YAfBr)+{Fe&f9))V t!=R2@eqXoUO40^TO?G<(+rfulK&pUN<|aIIh@bY!30Fy4YNru_t_k$G%hQh z84^>9-Jkns^DVL~X*8a}Owg{ZKPEd2HIx`$qiDs(@hm&E`emf=UYg#2*A(Y{JI|7D zhxoXT)F*>YAI@OpK~9sy_nnz0zLKFw eVt*NuZe+15Vw%(Lk z7b74Z>t-la(nnW~Rw-)7kSRPgv%*<`MKca{L|<8AsGH>|4vcTQ+{T(;VA{}kH35Ze z82YJy-rSozFiGbQyU=&jMEs$A_ z6y@}&B37w=Dq1UC@A(6qB#7xpAZD}XuQAr>Djuou#%~AL1_N%UmZSL@E$&k{KeDeJ znWg$Iia}?0h{4N^hQ`B_hZ0ibn>?TkS4vYj`)`6SYx;y+& N{Q}RrIq5`kE%}FS z>RS|HKEc@6UUPN?VfNN?{WpXFr}e6+Wf~SU;mn|&X+W| %a>Ni%|_#{NF!pFV{%nEru(qX8|t(QXDehJ`N9 z?gU@Al_tU;bIHK2=OSbTWYpFeN%88`FeTH%;ST=txQvoX|25ygRF2Xv4P8*_X;R3o zDu*nKmMW84j~asIqEGlqJuUQ4pRk-=T?(eT1>_JbuwHF)xPHrnj<_#g&lLqPzXa`^ zkRFncx1^E6ib@PLO+M|&uvyKc_Doo0P->rJzhuHoD}m(J(3Gsf#Y9zNXj}3S)STFw z4U1y+W-n`7cs2vJcfDOWOsB L=>TGPN`fdPeP-3tc u#_FiITWVY*FCCS|J 4#mr|8l8CwWghBw{;6h4iIR7JM;GpTP}S&E+@F0<8#ZPb68CFhvd8 z`<7Zikp$rEWmuFN>C%XDY)N7T4rc&2Ywx_0rPcH}PG!j_QB*D_T2;TyF`@tpD_P?o z7fA}hv~t1B97Zaw!zCJm72umhEteox#j6Y{hIY_S%{?;bIJ eSxlR~cK6HaJc!RQjJ3@pxkO71bP818&a>pu-c_5){+X>DaG z&nY(>^s;s- zQm1O-(dvZ%I*kmKvZcz7f z7Ba;` prMz@!Fsk{v*l4} zD!8PqJd`c*S4@5S>?ggP4KTe>cc&4*xA_IKGO3Ys5Oq27vc#QX1moI?gu}-~`zMdE z)KeEmx}m$`1jk(fWJKu*C^qAej4Cn&crNRHZD{w7u7h&2!z?6qu5Z7SqA`T!gnKzQ zlEk%h5kR>ZNTIFF1a>Ys&`8P2Lcv_WlmPw!_c}RhHh+wqRC3zMW4f=2_F-?_p2a^C z89}2a=!wdN^BBIyH`10zuKQ%Hu>EA7hl|Oy^zI=jwFP$P0Yl7bCM`45K_=&yp{)`f zL9y-#V1IsEmlno<*^77PkA=5~24Z)pdlFgbe8lY0nCL-BZX;*+|8SxcUXoWwe7=y% z=f59crhEPz5BbIM1Ndq&lGgwCc(x5%-Ru1Eos2p#u+c_>_$&yeA`oIw#DAP^UEGkH zE9^r&9I?=|&>i);UijcV?#@oT>thjQK5|OR37agbWtj#GmT-Ingq_$50%s24{TimI z5t<~Qoo@k3hdB 0djme# zcLjNM?rI|Av7b6!B8cj }`1(I=DPXuueeRf{L{bV>SqX-AZd(uVm$ zJW|ILxn0Q{_(??4STXvKiF)GDuLEDcS^ ^SXK&pnPepzQ=oiYV__+`OvQV~c z6n1f2rbAoB6$??iE(U7UWRZ8-@Xe=~t0G@NX1bV!m{VISE_-Db9L|Ltf1_ke4yFqw zS1n!j*X(acrPHaP*0354$!|_53#X*na303VsWM^zeMePQrKZCnImMhil2OBj;GQ;A zd**PK{6v8*OI=e-Am#a1kTXKA?!V1%7})G=RBo>#DLbdQv*z749nn#Zu7l4_*jIG& zBR7Z~sW*A+cUN*F5=s!y9v|*G&5t*znjd-Ozo)j}WR(7E!*p=md3Vx}WCTT_*qi?t z0;$M6OW8?&XSH;*rAu8Sijdw2P!8k{&;9P$kkp92)tNc|lx5n{83-?bBnHhMS?{{i z1^J8oy&EZmCxT|DJzk24n^l?qHL3E`SVzNRDFw 7R4HRpaBqc?}Gx8v&!% _ZdgS$BG@jM;yA#>Jt85 Kp?O8e?e02`}y<=1Qnn+Wjt-EY58x050 zyqS$}rU8J=4F6-Xp}wF`dhpGi-d`9ageJ~#Yay^mHYo!ZvQ=>xx9sq KjQarW6d#xyh|sm7 zMZ6%+hLX)c7)-apz?5{*utnzPN}wtBblEa%2 1kE7$DmHHjgB_5C BECLr`M4`;~3fAbxQeD;r_8QO>c8`54z$m(R5{vR- z7zfZN;y3VPi~vRwvUyC8%^_l?b10WGRB=D7K8+fbFPh!4v}m9Lut%|cN)#TKIzdrN z#ZX1#hcJM% 7uT>O2yeA?I08z It-$BVEfx%cj#Q!rYo^5B;82I4Jq9Ly8UO$}GH2jNOwAjF zj6-kuCD21ZIR=@S8qM$&g40CkQKc|IRj~83_;N|t4+j_Wk|#nS5dhXE?JN ADjhW2tK((T1#lXMg=*ox{h;yfq>MQ`Q}tOr z+;Ti|84FwFU6dk^{sb!~6Ry(mXm=yA#Ae^M270;YhZ5U-%Y|MvFp=sMqPX)Z69!CB z%iQDyG3UT)Q )&t>nh_b7 `dacgQfTts6Wm d|Cs-s6k^%b!Rm7ngj3^(NK zEkN5>F@9%Clq^fq(hUJOIoj2y &Y;(HDr} zFNWIky;|#5Yt0S?ONUrk1t@gB-HUzO^!Vl-W! Mw(*4`!Q6=V?o76W0Vro+%8+7(tRMW&j^xus2($7S z93?j@z`-6#;5iDRY@M7PP _s?o}MY1Ue0a z@Xv?uqvZA_whitm42>2rJY5mzP*(%OD?<1HB5DzQN%u?cFnOOexmk*g39eP4_a(@K zLL}xXruIC3BQl$M+*Z7jR$t-uqyMUiIt1Naja@r0M{9uoCB`@Ok)HuG1^S+R$nQ3E zTC(Yo12v6(MLM-)_%rHZp}=dIs`fCC-|)L7xPbJx_TaZBbSbAU2w=wKtyD*^Pm*Jt`}Y+MtSrz~RS0*gS}khx@im zDG?7`J6=FFh2&|sjIi=h6XZbVhQYBB-h~!KCv__z{pqje3L+^VcTb1R(<9eLdpij2 zx5Nc168JKvr&C|dl 9js~_=BsAe|G(&f79BEzYfY7rO%GZS?TV!C(-77dN5 z!i=Cavqs^)j0Md`f{Aa 9Tlv2zDkM8r^ z1pwSc6FqD(Y>Yu2mI5T5v7Kcn?2gh$?9RPFtB3%Hm29sg-CH6JOo0?k)%1nfzAx(J z?LAKz+y%ZTaj!M%SGyGmyB82L6-r?8bqe2NpBX@>yry1&K|ZI_fnf{e+=W};6R@_T zLM}u~$eoV91;xioPu fv62`Z-#s5 zVy}Sk%`r|Yb68v-izs1yFQ9QUq6{ZTo8(>#t i6h+?ob7zJ)!X7UB {9YV3UJBpd0O>`Kdz=}blC6)K`?7pyg;8eP$L!(>Bk zMS`pm7*D1E@ai#0NHFOV8Xtx+PtKr;6o~-9ncR?mW$Ze`6NeDbcypnaI}8}5o=+zb zBG_4JBv=dh^(UC6@x!=D7jRiAV@`#HLAz`v^T-Hxfa6w>E12Zq3z|SNL}G4!fU2m3 zY-e3A=9jvbtP8%Y$x;pmBsSzS5@a6r=G#K6N(P-c-bDx`3)q*QC#%$q3nEDcwZ?tM z`a%=1dfmQKQDl_5Hoj5_+^E!Dg{Jd}d!v#d00(c64OEaGZQ5jqH?}m_F(clX@J4)? z?G(s_GBp-OKvdlXgqC?^$zlrf()x_V=`j$7XeE`=hU((x7UdKp855No4+V?}>?0A# z!?K|qSk!28vN v6kfaYGrW9w z`bt0pr!e)$AS$8bEA$T>FuWeF2S9KRIgqnj;M^jgPP*~k0g)zII_8VD+P&Ct{vbec zV~-6Q-*E>3tCbC41!9;l$OcCpQsx&Dq%_e#lUE8;(tE6Cb7T>qN_vs enk8(In~F^Zvt6Ne zieYFNvH~m$KT`E^KNY{K#D_#n;s#X~Jnq+jLCs%u?qf$sP7psck)bJ&6j<~%Evv+! z3MpHjTtC|4sDomF%4Y)D3mN(Q)=N`@2lK1~lcWXV`X(d}jcBa|% }Dnr|miECQf>%7r$)#(?baKh+rUdy?p0 `G04R06uFm+~nM3}Q?G#~XyeF+Tyw$cMr~eeW69waI;q z3UH?a=tKU6lZjLl=(*aUvE$2?YRx5-5FP<7FjE>1?GGuuCJ@VLztwfLNfwDs&00 z&MH1jCfNpS#SCr$a4Mrqg2LgsJwt&Sb8-V{E$Y>5P|?vwi}G1l)@nPHqG#bB;L*l zSKVOK^XsoCqagmDq&59A3^9-eem~Z)USxOC<%gVtAbA1y1CziBFvx)glrqC=7U6-I zDI}cxAqdWN$O2|a{VSoJ8PCs}6l~7YQ-YzPZ=REs1kyZ%r3a*e31? Elj`X#bUS_?}lKX;6EYD (XH+ z35;?JfOkZVMeT-~-3m#(GAw*01$!0U+3Tc+kjFHMBxr-MAsWIMZx5pl&)kDvBx-oe z=2DqOY?Nd~g@yIv<8d91PQ=WZoQX+tzM09DenJ@pB~I*6 U zQ}Q;8mVMu)+S#;apKLi2AQGqrw;-O-(oR-GXs=yt+LrZ>!bAhJO>tQLu)M}cav(0m zHq%7`Q7x-&4iF9=p+xJoXL=0e+r_*fsw1!Os-<3NeSCAGhM*_5 aF=n)gD8(vo%YrGXfzS;-4B&xBy`Hh{hcj z(w#N=fJyp*{z?g2LtZQc1X^fQI|m@nIlzsIF$$lxE&|w%>ZmP@%M7%$U{|{lqq))o zjCc`bYwbSTl9~iE4_C6Ek79B}?H9dyJy@^aBDYM|EC^o3XcFJgSbifw=yVx1i9oR2 zka}B5SM14K *%BnP(A zW2>`Fc5KR>##G ZcK7MV_CgR2Y(KHMdXw_gSXLPT?MK`L cS;716d=rR5+sVt $_WOG mb?#}R*%4j(VLYH*AKF5oSrn0PZ0T66rs0j%h=b^w~umnB; literal 0 HcmV?d00001 diff --git a/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.svg b/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.svg new file mode 100644 index 00000000..a69669b5 --- /dev/null +++ b/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.svg @@ -0,0 +1,407 @@ + + + diff --git a/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.ttf b/pelican/themes/notmyidea/static/fonts/Yanone_Kaffeesatz_400.ttf new file mode 100644 index 0000000000000000000000000000000000000000..6f4feb02d14c849ba1fb7dc112243386b2ad8f2f GIT binary patch literal 39168 zcmbrn2Y@6;bvItsJ<~lo=RDJs!-kpNnGJV)a~m$~Ue2pad%7s;PFX?;Wk3NWfdmL4 zkPre%2Em>{fI)l)Otdk{SYTTqfj|fw^T&V*Hn;ozUiIwW-XQ^>|0nhIOm}tHt5+|- zSG9~Y#@zTYFxTqwiB*P23?F3d4UgjLm8&;x-1^*k-@J{n+hUA4A78z7`{#%}&D?%#Lh z;-e?7Jaoe~j9r2E*#k!pTy`<8yU^c*IGc_hzxv3N=Nx+u@5cQLHXJ*A;E?$@YYs7X zAr96&h6_qs-ii04PnJD);_|E3-4n#u3-P@C`0 (xb zco@HrqfzR@11Ap0-#YLgjNO9Y{Kktfy6p0Q-SgpZFm~(D0Pm9*UwZiBkM?{8W4XBx z?cd8JW}KhnC#An(9u{WZ?P`D w|NkCwMt@C=lVQ*N|JZZ%g zs$>-{Qz&SvLT7KYQ4e|xg?vF#ResVDjQYzTD#-SLKmHLp8gzc-?o3> 0|e>`FR1!hvf%Y1~bLD%D&H!u`e^zNr}&XdA3nmY;pHui|6@) zS8Q?hVv8TKZF&po%y- 95C&Ut~aOD2 ?Jd zK(W@}!8C6+(&B<&zplCo JJu@-O>{l^8@QP8|4+7uDX)HduZt3cjlhhxVg9P zoclR|WQqCT@RiaRf!S)i6t+nc2VyyA;0e|>1*qix1}@9p@;Y2duy{U~Hv*zSKHuNh z1c?G3HLqn9#qSFQ8ueyN0C?Bx($My1y=qTpasyhZnu^t(wpC3__nYs0=z~M4U^Ec! ze*J6DJzn(MBf&&jz)=@)46tiI)+I@*!Y8L@&6{?$%O FsrM9E}+8YwpSfHBiA_5t_{i=JOSi8Ra&RcdLE}r^V>eUG1 zpkBQ!%a*kVja*VVS0zq_EAKUdB=S>cuBrkSNHU*~F<;iFWm1WFEP}_}8F$_SO7Sd! z;ns+X-SpvE0EjpaWZd`<9j1cO8U%zX9kNYE+lnsfnSs||e(#6Y@~KLchb-n(Z`Psw zK{+-@^jpJ64R8iY+Jd_zkgoyI8;pm6DQPdrLl*}fLU1#xfaiKA%@j;j_fZ8FHjw>+b`(DB69S@{K)fdWNlz za;SeK5vpcGN#m6FmgZK=;C*+#{n6z~Unpj^_g{bUWmgnj=HEA5bGO$3Bgx m{fPz#xd)nW$!Ka8&sOML6xr_BnN zK8TOG7r7m$Q`^uL^~bJ9e`e+tk_9*ytf_e=oh9);>Y!?h*G$EX^mZQ<_BK2YdQ$N0 zNkLCxou1eam(KM3{QR?M@sEO@^cK&ve?6 C;dukZMtvfg2c@*8utj z$3g> jjiQD~=M5tc0N7bT+{~wMA zq)$5y#<`#Fo_pSAl5e=T;Z z8n|kT)jnu4{fG2EyGc5A&oZ-0HW$$xy(Pm^_@=N2uNfeY=CcE^xH`Rj8uzQLt6j-? z%`%J%U|41{XV)7I(h}1UFjQGZE0=Uu6=Q8d7pX8#z^NEMjDcXVL$ZyA7r$`Z3$o>( z#=vFCA-fBfe%Yk;*&AGTaLJrcnM^}7R*x*Z&C{}?O3w%a{I8W?&Mvzr`he+?!l!uh zbE7{M*s&;c-^i@A+1e?tVRRkn-wfzeEYXfeE#M+P3BZ9XSPi6wGNnw~0KvkDcOYiu zd;!uQ_#(C<5QBkWKP-oS-ZmA}?q!#SRvQ$xn076{#J=3%fgSWTag&RC+uy7F-N3H| z9Im-vYM-$6%Y}bv{cHipZ f%VBOrkK3m#0Ho8tLY#A$-y{=+5Tk*Mz zS<8xd-E-@M<16pK?e>RPZ5_Dg*s;s|25&eqb4ee;OS1BA!P_|j@Ao_Kp0>mF7Njfm z7SBVgpJ}P qSi`D0qjIs)3NRv?=RpOGNb4fHXb$(4x>knnfS7Go~$k^8{>aHn^Spq@q z@9<9NU9B@)LTz^m5254O=+6jSMt@$+5TtUn-M{c8GnwT5;=$7n(W^c;jrq#ua(%f* z0U9uy&uA{IDZc0;kp ejj-&%4z3R$h{bC ?yx%)^rNjq%c@XL9^r~CYIQO@!Ol?mjk)Q= zTe6Tls`+4lIajGyrDygXz5M9huXVMc&V69@mceCnzwB7w1c3*NsIT1{jYviViEJ2{ z+;9|D4J<9AbX3 6FkZmzthXgr{uSsw>{y&K6?l3Hj zbm0_1%;mGiyeCUWjzQo9%(v*n&;@9bM!m&4I($Lg@%xm)bYr<^cp{~Xyn*FPD42`P z{X67cZb9}fk68TPW#fj42X52l-+Lbm7t(I7UDCHG1qp}H^!tFr82GH&Zg{y-jsb3I zlIByGWq@4Xi%DG!j3naOOgxv!HMB;bN*W~qO{eR9GE*0|p71{l EN8M6Fr1 zH=^2Uf)&fb{nI;lRcVsB>7FAtlXT&oS>BmwgKgi@d+YrZ8 lRYIvH$QvSQ`E #Fq7R+gjL4c0Y2O4U&^zR_>`! Ma)HRHuC@{T-wq^%e_ps?Ixr1LOSf`NP0Lm~iXl5{w(tc=@T*c5j%4N+sRy zE##$wm}# mRVV}52pN)6 zMc*)smjKo107dY1zDsx9YR-gG);?$~ODkQ9I{e!l++-PD>vS58{t;QV4z70EWX0-O zDXCVNhby^Z@Wr7g9%;|LY*>DbKQn27^*ML#?pqID$EO^Yxp!^6G;!;0e!_0WILw&8 zcViqWmTJe7L8mG#dP3i#L0`-kGh`uV{V)#&+!XE9ymB7+gLT+!wML|d?B(ya?rO#& z@n{nru6oDyvbncdO1mS$f@CgfH{D~F)HkeNzkS7P6$3wyPneAS(*3P%qlZ-^pZn !&-Ae~lw+*DmjlBvRSQpw;T!(YJC)2~Bn<5~}QtWsB*IW%=&?6ZVanh~46k z_*9E~V6^|a-A?bgMakS~DKBeiz^@pE^eu4k2;h~0-(`&ChkpG_i`Sp${Y$Q&>|B@F zkBX;Te|7QdOWmih{$TOy%c5-zcpH^Iy!hr9=*{Rk4y!N?eD<+6ThIP+YBmVFFqw-< zvVr0tEuUnPR`y7WWj#kA(*j0TmC5LzZedj>VJp&$Dwr{gB3X_?+A9cfAGMp|7aI0c z9H)26YLgIjJ8g^i|H;-iiqPqer pIN k4Vo$Ge#(PfEXbU1rebFt;6BLgcd0{Cd{Q?;ps>~wTN^G4>95j2YjSfGk!8E z0|i~n5duiTF4}T|# ScFqN#y?OP)+cvC- z%{}FSbV>rMJZK1ZT)Pyso)LHNJv;6mV^P@Xr{nG&^Frq?fnov6jqUWIjoBV^CRZKs z7E-~A!_@Av6pkNx&xH|hFyP&M)x`RQ-4b{D69R&|fS}1%wa01_C^gNQDuRbV4unA` z&fW|EgQy6Yf{)kn2`eHF)MWj+5@P4Qf&Yi#`B}if2q>3#zhdY-*Bx3qo)H0hocHpx z0_Xdb-lMygjuEp?_}z?Icd;nVIs(?r>%oL03_`QcxtMh^s 3Kuz#yC%xp$Gal-M83VL6mZAS@uVV_%=t&&bi3~xnEO-xi8W5X z&;F&g8)ATq{PgRjmthI_Qd~WkOa%Q-hsq_Ju(+TAmXag!ypDOcE}zf$=6h fU=TsrYUK;Wlu)ECGC5UMg8C@vyx8E^tvR@N$BxNn#*^J|vY3V(d2`C` zv-m<2_?69R#&} cwYn=2BfU$W!W=Pti^MWOfj z_D^=kvjKD*Ml=TF;R_LX$U^BTX^}<7Lf%5q5L*|CFc#4wnRpD3g|hh^=@VV#=)z_} zuqawWBC*mDD%{#sHxD)@ioNUlZm?Fb=#~71RIO?_m?wELo(iOcsr-?BS6p9tcvIc1 zHits|vZ)zcFgHNiPQv^Kp+AHv5B&k=U%XEGL%;q!^!DlNq(A67^hfjbRni~&)t8n- zc_TN&_zvksSU!lu!+wT;qmW|na7%Ftu~fMF6nQF5fw2n8Iv71UO>?P`wq9gLU_FYd zq*)X5)$y_6>S)@Q30Pyj``6TZ%<*z}|2dLkUaMMG@Y!hEwEWm)z#H`2io;|0H8*3l zLPG`ThxrYdl@jY`W9%Q>&N%XqS*K($TDc1PpPG$B)AUfDL^T?Ynz^Frfe45ml7(a@ z;j5|^rYziK5))TJ=x1s+f#(`bH6X%ay8h2Rf5xNj-dBDKtSCAashZLm-61vs9aAnh z$C{(dhRglszDiDW*RocM*b9j#=)aY3^@(T_2)}{LP)GXBf^fbhVS?x`qK6zsIB6nX z+2DO+=kD7xUe;Fd6(iFdg3;HQV)kHu!?uVwTA!GzBx{9SHka%7_0)X9WVUBbqqS=9 z@}A6!kULkb7cbnu%j7^VBENd;9z)b^vzqxO!z+ebqod8 meagOJ$L|dL+lXncbr}#4pn@wLEQwFCze;t z#dJvX7TritNS`Ei^E#}phXgdi>t2(v>ujgXAH1q z!N-EF&_v`Yblv1(?m&)wHH8EtDaq3bih92--<=EE {OZtuu34F@OXxMOzT}=}es-WC;>y zJ0wjAWK1HAWEFQ5%|n@G)!zl=M#fXy`;&zh>~3zZ D9{yx`L&}a8Q z{ox(0^+ETJQA;os#Wcjz$wXftN5KDYXv&AS7JIIvdBrH$4H(5jMhfu0;=EGVrVj0# z>ec6!FreVs4BI1c|KNen8zn2`N|EGT4l!9{)B#6XLK=W`<9=0 X0VeF=!Iu5 z@BwxcPAU2DugGZ0bMhNTOr=aH>nS?{2!GDuTfTPge(G(eo;RCC$Dm{4@?FAXAXO(L zH?c}!FACkW7m(OsgD%NP^g=Hz$w=6tM(h!L*ylk*D`IwfM#2T4gg{#iw+g%C#!>CD z)@WwymVCjP2 2RkVytQjmp0 zVnLQC!uIY^_a?tnVf^?HP;!71|!)9dd{QO7D z;(fbsyWSmW$zGeXVel|Fc!S+4H#yC{TTi5lKk_^0Zr*;PD{Z=GL)f#3CGrDxEWJQj z!pMPDX&GiU%j#?ydu(bp4CUwyfN#JI2CD&86f*q2Gp?vI`FYeZ3#n%?nhZy6W=T tvcc@O%9D|@2?Ddf-9>x z*eX}{a-WuXw&09M1SvjSTQtk86_4t%2a`>rPC1gygdSSoG^@kI9t((cb8O2A5GjA{ z T@Q7Gmm~?Y-{WD-6Z1ro z*K;#hR-^(DtRUI4Ku~@mb#=KDXsmFr*t%)!_I9LX^9G-Gr(>C@FY^VbPr9nO=klj- zaoN5JdHj>%cE~&T$+XZ8^8-RV_*t4wwbyu2 >l`^P%kYzob zqLVs_V3aBakYf&{1F3kFlIa0WgjARgUjg93un~Tyzo};}gop% d=7;zWfzvqQ6m=qq z4+EzN@xm%a?vHS~Xsa)H9cSP)?um79s*z7*DD(?BMYKBziv-Sw@QQ@J#eL4i=+OF$ z_h#xrcXDIS?1^>tl+s_6e_Wlp^_{mnU8k-OTG4Sd%!eFDuG~AS%WL*OfYHUW?KJSj ztSTf41U9~sJQaR1%%f~BEz 7LVMHE>GhUKC=?7O6M?*UYxi(#Mb>8ynxm1RGwPd44dh1G5_| GU$)f=Tqu4oTC9vfo=Dr)O`KCsCc?pJELDteT9s?Y{N_q5Tc)f= zDisP2_Vwf>Puy(bk|*Wk&uv^+8qK8&K~Kcz$wZPpW2Nzp4! bC@5yZDLoEpy6@>Y@@G`&NAfTZrpZsipzD-w!U{DSl^GSjNw AD2{91D4=1oOjwo zu8>EmXD!-_2G2&*=KGOK{%AB~ntQHPP)$Bx$VYUF5$u8m8YElZ0pg_EP(52BOy{L! z6l4KdKMSFo)7g^K$&xp;BS@A+OT{Q`u*9aKCA)f ~M0*RQ?=cb7wp|2JQQF^TMloiAiR zN@r$2DxIpIf=q!2ir5E`Tj&Js742@9azwIMk|{?}mgImvD#2*F%vn~#AwFx75Hx?! z%J+uD?;X7h0nRz(IjG|3za wws3?*Kp@9(RVje L5A%~)Mawv!m=)l9V@D|R K<582zk+WQ(3IMFpT)44 zLjlG?fiskRtjLs=0=(s*pmPP3p$nUqpb~+=1sVaI21T)Go=Dbul@#r7S)7t&H`gR{ zqU%~`u95p}!4@{Drru%xbCYb6f6;r9+jUXnyHsTLpY1gXc!dHc!39?l4B&zlMD3mH zMD27P)LtQc`tdP@5r`_YkQt^wg?;pV3kGpI-;zURv&grIKpJISh{Ta{fjAX87onWB zG~BkoJvyk#HV2#Ms`>v+j}|4n_cz?^v3YF#e52d%adW%X>zjMK#T1PO0SU}{DUIk* z8C3rMwyTIdZViH*h1>`MP%y?1Le5w~$fo@;22G~ulmZ_L#l28~oCk!L;FpQyyU;R4 zZO|HJ??+#`T{~yvW)m~-WPh?9;wvyi8ugwofL6*-1tdkK>}njY+AGDOM2RE>?1E4w zZ>^ys_<~TVzrp{jdOAF%Slibq))gXf^
L#@uh+aI@V7aXsMxj$+N+#!lNvTSgmzpvf{Fe?lA%R3kGCk%u|wL{r>DqT1W zflDwLfV|PeJd$zP sKu8YjI2 j4?*#c(Jb zu-c045fK7Bjn!-jSdDodI$AxQunqq@@dsge5E$-84gCAs?rKru<~qoZgDlBo>yRak zG;ZE+;bwDmN+pC!dr?IpNdcl!Dg|96OSB=2&diU#O1pNBS jt*P_5z zx>wB(tw~1_OFavb(NvnB+9;))IigX4L4GALsKM`VwfkI%`zBv8?yHj7Rze;{kNhI_ z?JFSmYeu2fS+QRjl{7#F>_ir=PA+;ViGFVsBye!^z_8H(@<>&p`iQLU&)buT&1rlV zQ@;HCHQ|sYYO&fJUDc6=kt{~-AQdt9{6gu6fE;U60Gn!pTjhs-#k|AXR`*lNhoaUL zzy?aBk}%Bln2yGX)HQD=M_C_K=IAv23KP?@y&Bv#9)U3MhqUg^py&1?ElWT2xK3>{ z*ra!;g=K3OiI>K3l4!KVQ#^u-oCs|8OWIyLgdSzC6LBclph#WoRGL7h0iKpoJ_zVV z3VW1H0^v1G7^q|sGGC;)|F|IxgSHPbS_Z!%pGl#wa2_dcGnOt04N%up+@ua#!sBpb zBB0MG&8eri4-F6YrBdm5caKF$?d}~6uF}FWR4rLD>13RzdMC#QEJNu~z#ed^TD@=X zdsfeoYP`^32$!=_j8fxi-i=Y(VSPc*0_$+eWPWfVP&F#8b2u1tgdHJ-hV0CiQ_Oxq zr-Qd7Hq?RV>Vd@C(XLi()wrg`QrT=G&C|I(n~xvO?cRLBd1GViHV=<&*faz>sLd}& zT E5_`l_%u5OU_y<&-NJai%txd;GP(HA?q+ z+{U@P( z2T=)G<(RC^VdncP*W``9xw%x%%r1d#Jp@a#%v*5(BncgODE>F z=wdCTSIL !EKYB<@hf2%f=eNhYcdm|-KnB7&RG`w)@~EmZsKZls1xqp1B@0x!aF zBC>R_W#QV2m1}pdk=hf9@}?n6Wn*J<<%P@E4jmai6!VADa%yJ%aIKNtRF37czJfjM zTG@YOqq1i8=1Yb^IW&WJNc)hxO)=Cr6ESVuZPdc!dNs!d~64&tEJSOT|)JK2tz4 zEnI17V)}?xgEIMfy4@z=>ZjTL_opLM=VsmBP(Y3qAvElch8nNg3j18QL~7y3-=B0? z=dOiJv{^#Q^ANrK8c)}r8l`#70EgEBhbdb1f`F#Mi5fvcR}9%sEP2tZ8G%Lw=Ln5r z*$Xog8dEHp8S`XMuX<^L!8!=^isgrJL}=L=IqVnph0WTE_3JjQFAT+b-RSXFUmJ00 zvCm$9`5}kbRE(sq*s*z;o##_=tIXeS{LCE>62B$qf5+b-{T~*94Lsgn>BN*$Y$}0Z zq>Nfi84^%NULPu+0 B-69kGhwe%6)IKhQ_+hgI$%;Ua7l}e|+DeQ }P#jSYk!>KdD!B_|_N z3lgb6tw`!+ntk 6QhP7Xqd-`GW4N}0!ZPMo;)AOisLH%x5 zI%K7w*W_Xxx=U!e1vC^2(P*Ks(1_-vxhkX);?RPAI*CR-b|NN84FoB(NHuGO4S^H# z#q{Xc`H6G3?ccqkQS +~bTTQUh3Z`8W#DQ|RWO|^FF>mz-+E}uVwf~i)UW;r&0Kcw3Mp%YiP$77gX zH j=VZE&OVDS{NQ?TOU_y zO;nPux~bS}kkiH8TTG#q-77cm-`CaaC>8pLdMeU^p_{M!htIp*_N2w~x@)u9^JZ?i zZtnF{hAsQ++qaFb1_V@Vzm30-V$$st$}wI+IKpPvLdCK{)yv;>(MT}BI?`n`O^Tu_ zs>t`IbGFd(dNrDh^+e3Zt~J`kK&Go$QcoHqbN^{`#O<-+?p7ic^Lbo;n @gvgE^goqZ4b)$xLg?u(p%qlA7 z0cpsPcZ=i(5-a32np^<1M6Uo%demO!)$D-{g_hlJHRqO98_9^bUsA*Iu-~1?4A)#{ z&s1aia3sQiTTiTB>$IBvwvZ{3P6XnzEJxL_?2LOnku=s+tL{K=Db@@Cx*D*y Hg~3-?9e?7Zb?1>@g^kl zC|jomLH2rotydxYMXE1#s6O6>BycxT{j#C5Nf14+y%N>;Y#po!q8DQi@@@Zbb2z#< zhvxs~9QM#04%ls0Q(>sumyCL74x hj;ki z(jT!epML~#-3g4rO56+I8Wt+WsJa$Ho%l|+v5b7Mk}qJp0;EB?qBW8>zRBdXCv0<1 zDjti=E r|Nd9FfA^C6kBj>V zON!^O7SG=;EyLM}IOTuwFG{ljEWlEzD{iu@+7TBdCBu>wDHjjGhw1M@6_{bN!sXRd zvqgx~B*ZP&P4VlIb3%!s48v2txucp`o)++DU$F%lsbo*l @j%R^FQP(q*JKBs67ppf?3rw9ag#tM}&gX(YATv*X7e6#o98M z9Nq#sB0 5kJj~#$yk&vrI&Tp|dn!{*7qX?yHww8_ zt&~k8#wxM={C~5z@=u{#KUs2cA3y>OTLnNXpq5tDkXtcmtKaH#I|X! ^^orXi!uDb@=6v(SV}eA~8(>u1cps44o-j#ptq1 zp?IK~$XkvEqgv3F4#tNw6W!n&4c5Sq*>UjAqu5_SV~?`O1>HZ&H{&c})$;GzJ7H0p znU8v3B;GShb}bf*&*IGyd5X {O8l6-)d??A_;aItZy)^#i1e85eV J8y2F|c4kVa$(Il;Yo z*vy#Ni) ^xcF=ttrcV2 zXzi1EtZbMOpF>7#*9T^dGjpZjnANzIj&k7qa$tqkxRH)h@ci?^8L$XJU&nz{eJ!|N z4+&;n!dgova|Kwdl?W>f1PWYwK}AtW&jKn#;C1M$iEtf$HiRBnmK-oFDO;%P?>4L} z7Ew~zi?XyTx!O&Ug;)#<2p_v+3Bl|ow uf@vMzRdbCNGlBNC#BWwr?LmWWSn{0&Y($RtHDz2@>-6> zF3BSSk4T?uB=(m4EL&wYlyEu~HKAT@$M>YuWyE)B|J5l!bXnzXpnCO=v=84)_v1TB zYU=Sq(WA3%Ll9~;=KgYQ52FjeS9$vxZzRslK;GRe 18 ~$z0KGh!}h!jKMR1KKmKQ&}7ke2%fv{11}7r*&j#d9N-fH5}QD#qu5RVh4N+k ztp{X8w1GfIWoc(Dn#Z};phTk4h+^<$;s%#}ZD%kZH %3*k&CBFYI+I8$UR zI@t^Tbd3^Depa^H?|sr>vA-zCY-U3?X8FSd`J{^Xno&( wlagbNPU=x4$u#rgJE?<5V;1=sUipV8-jBDeoL|PBvIgA=I&tf}RS^B$Lhe0E zu+W8%dGo?RSPUy53L>Zgdgt4l#>O_=eO{%1b$&3ec)g#$_T~4y?Ymb5;%mNh?**T@ zIh~+YG=9`5zldJE)XSpnenu}|<|*sF=pj>lV)jVPDO$HrsZXx%SG`{QW_0KHd?GRW z3838|H~k1tPf?sl|IIogKI*s#xb4_w `}RF9teVdsIP7#BKHzYBWY@O!R_oLzmyFdxfDUFFf1?;z4>LX8Qw%z# z9$j|>1bvx3m8%kXonLh*J+QB+Vx`N!4*HuzX7ga5KWMP7YLBkAe%SBrYnkOpx!32H z^-J91bGr8I06e?hHm{kxE;!+IU3|h7r0bg}t(oBs9=h&4_lVO4Kr!#YID1w=7HJ2) z&IO-x0gZ_u$=SagS*{B%ayc(LE)cVKhuyYqHz5Z700ZpDq95fWK_@au3-3I0^y`EE z{?o%;iD8N{?cQ#)@7Sx4>G(xX*F_h&guc6rYr?)yQk}WajlF?%F;CiJC&mH;3ZZO7 z-T20ZZCoND_ydljD26*r!`09FT~bjA5R3&{@tpZu c zfS0ZF*YauUQsg3r+O41mu2l@yxnxs2d3QJmTsn%-2$bJWDy<@KPiExN=UJ{0iI6*) zMSz}+7aUqYF&X0XsBIJ$428&r{%UZ4)nV#Qri nmCC`Lze?}&I N+!tF3CY-lKIRUj*YI2c3rv3+O`? z77h93Euj&ELE?{2@P qg%GGpWL!z z9VKS_=U>k+kbVF!=V03zh5eqlOA`4vqBzS6*B8tN$#W4Bd`7IHJB9&bEe+<6+&B@$ zp_DJX_0{fAx6K82g7zyzS!(w5)akhvGEa3IZ*e9m(IJ+X2I1)W`32WwBI{whDYvS- zE0nyrIXaRl)cY+KY#?&L7rZ(V^@VnNZI?+-ugP4qCaUFFHFL>ev$@hV?XzDk2Q0R< z)np&^Y2m9ABM8uN=0a}%PGnezsDfSN2284zQkh1k7>o*5ZW^#;7WLuST~)GhZiP)| z<5sL72QljVPz 6DOt@W~%VjF}vctX!D4XA#p=igI?yM z(JD_q-0id_`;+zYnlf$kHKkoPU)y_dEK>y`m 2v3 gVs8WHApa3bx{-ecHZiSrqQ&Gp zk-CS^N;};lOD=-&1`( _t0Xu~I8UXER7 zHNLSDrBA)5-=Zh7jFpdoVS6eIc5vowTXr>jBR_{f#^MyAj0c~!kzLcq7&cKc zteY|zRX27|3!fWt8@6pTxFhEtGDa=*)e$t3K+mwvfcpDz&OLzVTz%UIS{&Y~B0xgX zU_6MmWqP=;L{Z`lW4Hi1KvZ?19eUd-5^UlDgvA41Y%$`Edt+hL(>QFx`!}7AzmUpM zI*!7Uz|qrzNU$CaerN$@_v*j-Rgthi(FnwMz>|1?=Q}#jum=GB1HieHA(KTjPUHza zAWPdj{-7kU&tx)UFTjNv@pU?0oSB90`1Nq?@6x@M3fqoc?4$4n-E9Zaj2 gj3Z9&`0_vVkj>)$wLLQTy8{WEM?G*LoKuhcqDlKrL?Hz>!;kR~;f;v+ zVA5r_1`uEFc5yh^sK6ohlM~8QrOD=pIHD{_)Z9p-=7x$zvL)D!ArT6}$VnY26eH6Y_#;daK&Xrek)ZyM zl+P7#x+89f&EezD)s;}(i-in@lwz^_xM#HbZM)54wp&pw5(x&2R-46=F~)r1qRvC- z@guwsb!8Jz17Iwtotm{k=b 3@QQ?9@*PV5J`su7!EX&Cev-FEB zH>R8)arxbWUn+JxFJFYu!# -H z=TZr(F!Q=?A|#aW=j4)Ms|(?Y>8`k5XhujDm1bD`L*hqx>1W+~BoyHH!Tp>2@JMDb zv39(BFn(t$Z4diXDSO1v14D_m6Lc+^wuJ+@5ecX!he`Snw>Zt}sV|<#cgHuc+j~xW z 3{wM=YQZ{k zSlDJLnP~fu?m%tRoz9BGKHv{-3+*gp5~d5(36|LG$A$zYfk}N4Vqpr^<7R l!yi`tfz3Vn$i^FE0uQpv8M$?RIuJ=mmOkKHbRAyVA8^_ JAi-Z1D#F_ApeDQPN`Rdy~^z7Y1iz7I?{4uMN@u$O9yE|^hR!x2F zudIzI{jb?~^vb@mcfJ1Jhlcs3a=qP~4UtlywYx7P DW3Q+^SWc_21r#+5pVAalJd&io^D_x$D-{XqBn6Y}&js9j? zR{l;ko%h jmc@m_ihkW#|9ETliZNZMKDBMc}%z zb}eZ~9Us >Cz76 zqneFE;5r?E0>m>g<@Go-RHl3TXmvo9U77Ao-r>r32fXfRj4qE=TezI6XL5Fz!|yHI ze6CpRSkdSSIGk4f^p$8n)EtSrjMi8n6v1}&-h3? m28?@<0qVC% z(iq{*U?(FBhx4dnpA#rtc_&U->I$7A^NqnEWvqgYU>%!8YKfRFV8cv_%#{^J2W28U zd1}E00wcmRYlr|B@OK(}KypjqPJ7*f^A8=~d+gkijicjl9-HuIJ$*%ILh<3Rc$hsd zuTM6lJiLA6H5VN}c;)fShBj~Cw*JxS$-Jw#zNKX~nnI@h@>J4nQLyqFh2MrVM%x3Q z?GiEGBSmgjd$`e*#p-Cd uqf3xr?;v5JW{X5@r~Z?~KyzVV&ccH2j{8(`pyoT}t(u?j z1SSpxBTXF}10h+lcvK~BFxhPp*-+h_X<5C<{CcF{5jqGhb2oQza%ZE6E&e8>e2*gi zjvLnW_(32ZFH%Ml+a{H`Px?2Qxjr@^FoOLTV2A28<}}lbrRJDvIIqm=vwB^6vYY~i z3$rU`5k>vr5TOAYH`NaHRvJBBUSBX+l1io4fpW8_x6u{y`NLHxvTNoC*x$?Dr~+7$ z1w&3j%ZU073iXK;#Wkix1^Y$FVJw;XLmaEQ0QK7WA@&aGCm^vP8))}qny@C;4);hx zQEG>iMRY;0oj?Xe *qy&r-3o +@_ZB;ISsay8wI7l}`L87wbh z$CL4@e!*elsr{ 8)LonGH5n3VQ`UQ_$?UMI-IYvG8tQi{*-Y?S*{0STss)Sl z_}ovV2D6KOJC0F5`liiMh#An3p30SkTH*Ui@qn13 z-dI$B%SQNR;9)ooY3ziOK|VaZ0IkrpB%&9vK}NkED8Y8v+GPQbI@L{YH!1%0t5m zr^jaX*nNJiRzNb@km!y|4Tl|#!XB?&$lCDF83O*yY1;FnF7>eQVIF9OBmuzLs`)zm z8UT#2L;5Ib-C@cIg94$Di_uVD1OT+2Q83(2cbZ_+n^$Qw-3A)*-VpsIl?As&7lqK3 z$aXX_vd&*nX`sse E};ThWeeA@ft{jXhlfPbeS_4YebwL 8q!?geY5-2l&X@)#2 R>FpTe ztK`(P+Com90_}}X!7=wZUsPR=m!;{T$M1&NAj}q|B>M>>p@i8#FH!#z{0fmunqqrb zUr$f9fe?+S;`K_&N`G%}1wyr133w|$Kl#;lgaK*y9GSg9`_tebNRj;;`vuh4474CB z%@B{i6W2aq58yZ5UHCV_c7Q{#Vz;vg*ayI&yZD1rNjfBbLi!a#*M2!Kx8%#@FUY41 zQA5?R+^_* 4`~ z{8#2rnZIiOo+V