From 2226a74ef84293442674ae458f9e867902bc5094 Mon Sep 17 00:00:00 2001 From: Labrys of Knossos Date: Mon, 28 Nov 2022 19:44:46 -0500 Subject: [PATCH] Update vendored guessit to 3.1.1 Updates python-dateutil to 2.8.2 Updates rebulk to 2.0.1 --- .../bin/{chardetect.exe => guessit.exe} | Bin 108383 -> 108377 bytes libs/common/dateutil/_version.py | 3 +- libs/common/dateutil/easter.py | 16 +- libs/common/dateutil/parser/__init__.py | 3 +- libs/common/dateutil/parser/_parser.py | 163 +++--- libs/common/dateutil/parser/isoparser.py | 56 ++- libs/common/dateutil/relativedelta.py | 33 +- libs/common/dateutil/rrule.py | 207 +++++--- libs/common/dateutil/tz/__init__.py | 5 - libs/common/dateutil/tz/_common.py | 22 +- libs/common/dateutil/tz/_factories.py | 35 +- libs/common/dateutil/tz/tz.py | 168 +++++-- libs/common/dateutil/tz/win.py | 45 +- libs/common/dateutil/utils.py | 4 +- .../zoneinfo/dateutil-zoneinfo.tar.gz | Bin 154226 -> 174394 bytes libs/common/dateutil/zoneinfo/rebuild.py | 34 +- libs/common/guessit/__main__.py | 2 +- libs/common/guessit/__version__.py | 2 +- libs/common/guessit/api.py | 31 ++ libs/common/guessit/backports.py | 2 +- libs/common/guessit/config/options.json | 262 +++++++++- libs/common/guessit/options.py | 6 +- .../common/guessit/rules/common/formatters.py | 2 +- .../common/guessit/rules/common/validators.py | 25 +- libs/common/guessit/rules/match_processors.py | 20 + libs/common/guessit/rules/processors.py | 4 +- .../guessit/rules/properties/audio_codec.py | 29 +- .../guessit/rules/properties/bit_rate.py | 4 +- libs/common/guessit/rules/properties/bonus.py | 3 +- .../guessit/rules/properties/container.py | 3 +- .../guessit/rules/properties/episode_title.py | 12 +- .../guessit/rules/properties/episodes.py | 315 +++++++----- .../guessit/rules/properties/language.py | 11 +- libs/common/guessit/rules/properties/other.py | 39 +- libs/common/guessit/rules/properties/part.py | 4 +- .../guessit/rules/properties/release_group.py | 36 +- .../guessit/rules/properties/screen_size.py | 4 +- .../common/guessit/rules/properties/source.py | 82 ++- .../rules/properties/streaming_service.py | 136 +---- libs/common/guessit/rules/properties/title.py | 31 +- .../guessit/rules/properties/video_codec.py | 9 +- .../guessit/rules/properties/website.py | 6 +- .../test/enable_disable_properties.yml | 8 +- libs/common/guessit/test/episodes.yml | 180 ++++++- libs/common/guessit/test/movies.yml | 21 +- .../guessit/test/rules/common_words.yml | 467 ++++++++++++++++++ libs/common/guessit/test/rules/country.yml | 4 +- libs/common/guessit/test/rules/other.yml | 4 +- libs/common/guessit/test/suggested.json | 21 + libs/common/guessit/test/test_api.py | 26 +- libs/common/guessit/test/test_yml.py | 113 +++-- libs/common/guessit/test/various.yml | 251 ++++++++++ libs/common/guessit/yamlutils.py | 8 +- libs/common/rebulk/__version__.py | 2 +- libs/common/rebulk/builder.py | 217 ++++++++ libs/common/rebulk/chain.py | 347 +++++-------- libs/common/rebulk/formatters.py | 10 + libs/common/rebulk/introspector.py | 5 +- libs/common/rebulk/loose.py | 30 +- libs/common/rebulk/match.py | 18 + libs/common/rebulk/pattern.py | 356 +++++++------ libs/common/rebulk/rebulk.py | 183 +------ libs/common/rebulk/test/test_chain.py | 106 ++-- libs/common/rebulk/test/test_debug.py | 36 +- libs/common/rebulk/test/test_match.py | 3 + libs/common/rebulk/validators.py | 11 + 66 files changed, 2995 insertions(+), 1306 deletions(-) rename libs/common/bin/{chardetect.exe => guessit.exe} (99%) create mode 100644 libs/common/guessit/rules/match_processors.py create mode 100644 libs/common/guessit/test/rules/common_words.yml create mode 100644 libs/common/guessit/test/suggested.json create mode 100644 libs/common/rebulk/builder.py diff --git a/libs/common/bin/chardetect.exe b/libs/common/bin/guessit.exe similarity index 99% rename from libs/common/bin/chardetect.exe rename to libs/common/bin/guessit.exe index f93a4a82c2b5e499858de8dd7a0422f0eb9ce115..550c3cb32d3825f6a7a3b44b729a50ac7d5919f5 100644 GIT binary patch delta 78 zcmcbAj_u|-wuUW?>dSab=GKH-H;7z2!oa|AWV*>RMi+tf($wPO%o4r$_}s+Iy!iO( Veajg8&=hJeXEb1Y3)I8F007wm9GL(B delta 84 zcmcb4j_v+AwuUW?>dScl&aMe9@pasEih+UQ)O3?&j4ooy8Hq(HsU>>JIhlG;c4~6T W^p0hWeQ3&+mopl$eFo}eU;qHk#2^p= diff --git a/libs/common/dateutil/_version.py b/libs/common/dateutil/_version.py index d3ce8561..b723056a 100644 --- a/libs/common/dateutil/_version.py +++ b/libs/common/dateutil/_version.py @@ -1,4 +1,5 @@ # coding: utf-8 # file generated by setuptools_scm # don't change, don't track in version control -version = '2.7.5' +version = '2.8.2' +version_tuple = (2, 8, 2) diff --git a/libs/common/dateutil/easter.py b/libs/common/dateutil/easter.py index 53b7c789..f74d1f74 100644 --- a/libs/common/dateutil/easter.py +++ b/libs/common/dateutil/easter.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- """ -This module offers a generic easter computing method for any given year, using +This module offers a generic Easter computing method for any given year, using Western, Orthodox or Julian algorithms. """ @@ -21,15 +21,15 @@ def easter(year, method=EASTER_WESTERN): quoted in "Explanatory Supplement to the Astronomical Almanac", P. Kenneth Seidelmann, editor. - This algorithm implements three different easter + This algorithm implements three different Easter calculation methods: - 1 - Original calculation in Julian calendar, valid in - dates after 326 AD - 2 - Original method, with date converted to Gregorian - calendar, valid in years 1583 to 4099 - 3 - Revised method, in Gregorian calendar, valid in - years 1583 to 4099 as well + 1. Original calculation in Julian calendar, valid in + dates after 326 AD + 2. Original method, with date converted to Gregorian + calendar, valid in years 1583 to 4099 + 3. Revised method, in Gregorian calendar, valid in + years 1583 to 4099 as well These methods are represented by the constants: diff --git a/libs/common/dateutil/parser/__init__.py b/libs/common/dateutil/parser/__init__.py index 216762c0..d174b0e4 100644 --- a/libs/common/dateutil/parser/__init__.py +++ b/libs/common/dateutil/parser/__init__.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -from ._parser import parse, parser, parserinfo +from ._parser import parse, parser, parserinfo, ParserError from ._parser import DEFAULTPARSER, DEFAULTTZPARSER from ._parser import UnknownTimezoneWarning @@ -9,6 +9,7 @@ from .isoparser import isoparser, isoparse __all__ = ['parse', 'parser', 'parserinfo', 'isoparse', 'isoparser', + 'ParserError', 'UnknownTimezoneWarning'] diff --git a/libs/common/dateutil/parser/_parser.py b/libs/common/dateutil/parser/_parser.py index 9d2bb795..37d1663b 100644 --- a/libs/common/dateutil/parser/_parser.py +++ b/libs/common/dateutil/parser/_parser.py @@ -20,11 +20,11 @@ value falls back to the end of the month. Additional resources about date/time string formats can be found below: - `A summary of the international standard date and time notation - `_ -- `W3C Date and Time Formats `_ + `_ +- `W3C Date and Time Formats `_ - `Time Formats (Planetary Rings Node) `_ - `CPAN ParseDate module - `_ + `_ - `Java SimpleDateFormat Class `_ """ @@ -40,7 +40,7 @@ from calendar import monthrange from io import StringIO import six -from six import binary_type, integer_types, text_type +from six import integer_types, text_type from decimal import Decimal @@ -49,7 +49,7 @@ from warnings import warn from .. import relativedelta from .. import tz -__all__ = ["parse", "parserinfo"] +__all__ = ["parse", "parserinfo", "ParserError"] # TODO: pandas.core.tools.datetimes imports this explicitly. Might be worth @@ -60,14 +60,8 @@ class _timelex(object): _split_decimal = re.compile("([.,])") def __init__(self, instream): - if six.PY2: - # In Python 2, we can't duck type properly because unicode has - # a 'decode' function, and we'd be double-decoding - if isinstance(instream, (binary_type, bytearray)): - instream = instream.decode() - else: - if getattr(instream, 'decode', None) is not None: - instream = instream.decode() + if isinstance(instream, (bytes, bytearray)): + instream = instream.decode() if isinstance(instream, text_type): instream = StringIO(instream) @@ -291,7 +285,7 @@ class parserinfo(object): ("s", "second", "seconds")] AMPM = [("am", "a"), ("pm", "p")] - UTCZONE = ["UTC", "GMT", "Z"] + UTCZONE = ["UTC", "GMT", "Z", "z"] PERTAIN = ["of"] TZOFFSET = {} # TODO: ERA = ["AD", "BC", "CE", "BCE", "Stardate", @@ -388,7 +382,8 @@ class parserinfo(object): if res.year is not None: res.year = self.convertyear(res.year, res.century_specified) - if res.tzoffset == 0 and not res.tzname or res.tzname == 'Z': + if ((res.tzoffset == 0 and not res.tzname) or + (res.tzname == 'Z' or res.tzname == 'z')): res.tzname = "UTC" res.tzoffset = 0 elif res.tzoffset != 0 and res.tzname and self.utczone(res.tzname): @@ -422,7 +417,7 @@ class _ymd(list): elif not self.has_month: return 1 <= value <= 31 elif not self.has_year: - # Be permissive, assume leapyear + # Be permissive, assume leap year month = self[self.mstridx] return 1 <= value <= monthrange(2000, month)[1] else: @@ -538,7 +533,7 @@ class _ymd(list): year, month, day = self else: # 01-Jan-01 - # Give precendence to day-first, since + # Give precedence to day-first, since # two-digit years is usually hand-written. day, month, year = self @@ -625,7 +620,7 @@ class parser(object): first element being a :class:`datetime.datetime` object, the second a tuple containing the fuzzy tokens. - :raises ValueError: + :raises ParserError: Raised for invalid or unknown string format, if the provided :class:`tzinfo` is not in a valid format, or if an invalid date would be created. @@ -645,12 +640,15 @@ class parser(object): res, skipped_tokens = self._parse(timestr, **kwargs) if res is None: - raise ValueError("Unknown string format:", timestr) + raise ParserError("Unknown string format: %s", timestr) if len(res) == 0: - raise ValueError("String does not contain a date:", timestr) + raise ParserError("String does not contain a date: %s", timestr) - ret = self._build_naive(res, default) + try: + ret = self._build_naive(res, default) + except ValueError as e: + six.raise_from(ParserError(str(e) + ": %s", timestr), e) if not ignoretz: ret = self._build_tzaware(ret, res, tzinfos) @@ -1021,7 +1019,7 @@ class parser(object): hms_idx = idx + 2 elif idx > 0 and info.hms(tokens[idx-1]) is not None: - # There is a "h", "m", or "s" preceeding this token. Since neither + # There is a "h", "m", or "s" preceding this token. Since neither # of the previous cases was hit, there is no label following this # token, so we use the previous label. # e.g. the "04" in "12h04" @@ -1060,7 +1058,8 @@ class parser(object): tzname is None and tzoffset is None and len(token) <= 5 and - all(x in string.ascii_uppercase for x in token)) + (all(x in string.ascii_uppercase for x in token) + or token in self.info.UTCZONE)) def _ampm_valid(self, hour, ampm, fuzzy): """ @@ -1100,7 +1099,7 @@ class parser(object): def _parse_min_sec(self, value): # TODO: Every usage of this function sets res.second to the return # value. Are there any cases where second will be returned as None and - # we *dont* want to set res.second = None? + # we *don't* want to set res.second = None? minute = int(value) second = None @@ -1109,14 +1108,6 @@ class parser(object): second = int(60 * sec_remainder) return (minute, second) - def _parsems(self, value): - """Parse a I[.F] seconds value into (seconds, microseconds).""" - if "." not in value: - return int(value), 0 - else: - i, f = value.split(".") - return int(i), int(f.ljust(6, "0")[:6]) - def _parse_hms(self, idx, tokens, info, hms_idx): # TODO: Is this going to admit a lot of false-positives for when we # just happen to have digits and "h", "m" or "s" characters in non-date @@ -1135,21 +1126,35 @@ class parser(object): return (new_idx, hms) - def _recombine_skipped(self, tokens, skipped_idxs): - """ - >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"] - >>> skipped_idxs = [0, 1, 2, 5] - >>> _recombine_skipped(tokens, skipped_idxs) - ["foo bar", "baz"] - """ - skipped_tokens = [] - for i, idx in enumerate(sorted(skipped_idxs)): - if i > 0 and idx - 1 == skipped_idxs[i - 1]: - skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx] - else: - skipped_tokens.append(tokens[idx]) + # ------------------------------------------------------------------ + # Handling for individual tokens. These are kept as methods instead + # of functions for the sake of customizability via subclassing. - return skipped_tokens + def _parsems(self, value): + """Parse a I[.F] seconds value into (seconds, microseconds).""" + if "." not in value: + return int(value), 0 + else: + i, f = value.split(".") + return int(i), int(f.ljust(6, "0")[:6]) + + def _to_decimal(self, val): + try: + decimal_value = Decimal(val) + # See GH 662, edge case, infinite value should not be converted + # via `_to_decimal` + if not decimal_value.is_finite(): + raise ValueError("Converted decimal value is infinite or NaN") + except Exception as e: + msg = "Could not convert %s to decimal" % val + six.raise_from(ValueError(msg), e) + else: + return decimal_value + + # ------------------------------------------------------------------ + # Post-Parsing construction of datetime output. These are kept as + # methods instead of functions for the sake of customizability via + # subclassing. def _build_tzinfo(self, tzinfos, tzname, tzoffset): if callable(tzinfos): @@ -1164,6 +1169,9 @@ class parser(object): tzinfo = tz.tzstr(tzdata) elif isinstance(tzdata, integer_types): tzinfo = tz.tzoffset(tzname, tzdata) + else: + raise TypeError("Offset must be tzinfo subclass, tz string, " + "or int offset.") return tzinfo def _build_tzaware(self, naive, res, tzinfos): @@ -1181,10 +1189,10 @@ class parser(object): # This is mostly relevant for winter GMT zones parsed in the UK if (aware.tzname() != res.tzname and res.tzname in self.info.UTCZONE): - aware = aware.replace(tzinfo=tz.tzutc()) + aware = aware.replace(tzinfo=tz.UTC) elif res.tzoffset == 0: - aware = naive.replace(tzinfo=tz.tzutc()) + aware = naive.replace(tzinfo=tz.UTC) elif res.tzoffset: aware = naive.replace(tzinfo=tz.tzoffset(res.tzname, res.tzoffset)) @@ -1239,17 +1247,21 @@ class parser(object): return dt - def _to_decimal(self, val): - try: - decimal_value = Decimal(val) - # See GH 662, edge case, infinite value should not be converted via `_to_decimal` - if not decimal_value.is_finite(): - raise ValueError("Converted decimal value is infinite or NaN") - except Exception as e: - msg = "Could not convert %s to decimal" % val - six.raise_from(ValueError(msg), e) - else: - return decimal_value + def _recombine_skipped(self, tokens, skipped_idxs): + """ + >>> tokens = ["foo", " ", "bar", " ", "19June2000", "baz"] + >>> skipped_idxs = [0, 1, 2, 5] + >>> _recombine_skipped(tokens, skipped_idxs) + ["foo bar", "baz"] + """ + skipped_tokens = [] + for i, idx in enumerate(sorted(skipped_idxs)): + if i > 0 and idx - 1 == skipped_idxs[i - 1]: + skipped_tokens[-1] = skipped_tokens[-1] + tokens[idx] + else: + skipped_tokens.append(tokens[idx]) + + return skipped_tokens DEFAULTPARSER = parser() @@ -1341,10 +1353,10 @@ def parse(timestr, parserinfo=None, **kwargs): first element being a :class:`datetime.datetime` object, the second a tuple containing the fuzzy tokens. - :raises ValueError: - Raised for invalid or unknown string format, if the provided - :class:`tzinfo` is not in a valid format, or if an invalid date - would be created. + :raises ParserError: + Raised for invalid or unknown string formats, if the provided + :class:`tzinfo` is not in a valid format, or if an invalid date would + be created. :raises OverflowError: Raised if the parsed date exceeds the largest valid C integer on @@ -1573,6 +1585,29 @@ DEFAULTTZPARSER = _tzparser() def _parsetz(tzstr): return DEFAULTTZPARSER.parse(tzstr) + +class ParserError(ValueError): + """Exception subclass used for any failure to parse a datetime string. + + This is a subclass of :py:exc:`ValueError`, and should be raised any time + earlier versions of ``dateutil`` would have raised ``ValueError``. + + .. versionadded:: 2.8.1 + """ + def __str__(self): + try: + return self.args[0] % self.args[1:] + except (TypeError, IndexError): + return super(ParserError, self).__str__() + + def __repr__(self): + args = ", ".join("'%s'" % arg for arg in self.args) + return "%s(%s)" % (self.__class__.__name__, args) + + class UnknownTimezoneWarning(RuntimeWarning): - """Raised when the parser finds a timezone it cannot parse into a tzinfo""" + """Raised when the parser finds a timezone it cannot parse into a tzinfo. + + .. versionadded:: 2.7.0 + """ # vim:ts=4:sw=4:et diff --git a/libs/common/dateutil/parser/isoparser.py b/libs/common/dateutil/parser/isoparser.py index cd27f93d..5d7bee38 100644 --- a/libs/common/dateutil/parser/isoparser.py +++ b/libs/common/dateutil/parser/isoparser.py @@ -88,10 +88,12 @@ class isoparser(object): - ``hh`` - ``hh:mm`` or ``hhmm`` - ``hh:mm:ss`` or ``hhmmss`` - - ``hh:mm:ss.sss`` or ``hh:mm:ss.ssssss`` (3-6 sub-second digits) + - ``hh:mm:ss.ssssss`` (Up to 6 sub-second digits) Midnight is a special case for `hh`, as the standard supports both - 00:00 and 24:00 as a representation. + 00:00 and 24:00 as a representation. The decimal separator can be + either a dot or a comma. + .. caution:: @@ -137,6 +139,10 @@ class isoparser(object): else: raise ValueError('String contains unknown ISO components') + if len(components) > 3 and components[3] == 24: + components[3] = 0 + return datetime(*components) + timedelta(days=1) + return datetime(*components) @_takes_ascii @@ -153,7 +159,7 @@ class isoparser(object): components, pos = self._parse_isodate(datestr) if pos < len(datestr): raise ValueError('String contains unknown ISO ' + - 'components: {}'.format(datestr)) + 'components: {!r}'.format(datestr.decode('ascii'))) return date(*components) @_takes_ascii @@ -167,7 +173,10 @@ class isoparser(object): :return: Returns a :class:`datetime.time` object """ - return time(*self._parse_isotime(timestr)) + components = self._parse_isotime(timestr) + if components[0] == 24: + components[0] = 0 + return time(*components) @_takes_ascii def parse_tzstr(self, tzstr, zero_as_utc=True): @@ -190,10 +199,9 @@ class isoparser(object): return self._parse_tzstr(tzstr, zero_as_utc=zero_as_utc) # Constants - _MICROSECOND_END_REGEX = re.compile(b'[-+Z]+') _DATE_SEP = b'-' _TIME_SEP = b':' - _MICRO_SEP = b'.' + _FRACTION_REGEX = re.compile(b'[\\.,]([0-9]+)') def _parse_isodate(self, dt_str): try: @@ -325,39 +333,42 @@ class isoparser(object): pos = 0 comp = -1 - if len(timestr) < 2: + if len_str < 2: raise ValueError('ISO time too short') - has_sep = len_str >= 3 and timestr[2:3] == self._TIME_SEP + has_sep = False while pos < len_str and comp < 5: comp += 1 - if timestr[pos:pos + 1] in b'-+Z': + if timestr[pos:pos + 1] in b'-+Zz': # Detect time zone boundary components[-1] = self._parse_tzstr(timestr[pos:]) pos = len_str break + if comp == 1 and timestr[pos:pos+1] == self._TIME_SEP: + has_sep = True + pos += 1 + elif comp == 2 and has_sep: + if timestr[pos:pos+1] != self._TIME_SEP: + raise ValueError('Inconsistent use of colon separator') + pos += 1 + if comp < 3: # Hour, minute, second components[comp] = int(timestr[pos:pos + 2]) pos += 2 - if (has_sep and pos < len_str and - timestr[pos:pos + 1] == self._TIME_SEP): - pos += 1 if comp == 3: - # Microsecond - if timestr[pos:pos + 1] != self._MICRO_SEP: + # Fraction of a second + frac = self._FRACTION_REGEX.match(timestr[pos:]) + if not frac: continue - pos += 1 - us_str = self._MICROSECOND_END_REGEX.split(timestr[pos:pos + 6], - 1)[0] - + us_str = frac.group(1)[:6] # Truncate to microseconds components[comp] = int(us_str) * 10**(6 - len(us_str)) - pos += len(us_str) + pos += len(frac.group()) if pos < len_str: raise ValueError('Unused components in ISO string') @@ -366,13 +377,12 @@ class isoparser(object): # Standard supports 00:00 and 24:00 as representations of midnight if any(component != 0 for component in components[1:4]): raise ValueError('Hour may only be 24 at 24:00:00.000') - components[0] = 0 return components def _parse_tzstr(self, tzstr, zero_as_utc=True): - if tzstr == b'Z': - return tz.tzutc() + if tzstr == b'Z' or tzstr == b'z': + return tz.UTC if len(tzstr) not in {3, 5, 6}: raise ValueError('Time zone offset must be 1, 3, 5 or 6 characters') @@ -391,7 +401,7 @@ class isoparser(object): minutes = int(tzstr[(4 if tzstr[3:4] == self._TIME_SEP else 3):]) if zero_as_utc and hours == 0 and minutes == 0: - return tz.tzutc() + return tz.UTC else: if minutes > 59: raise ValueError('Invalid minutes in time zone offset') diff --git a/libs/common/dateutil/relativedelta.py b/libs/common/dateutil/relativedelta.py index 1e0d6165..a9e85f7e 100644 --- a/libs/common/dateutil/relativedelta.py +++ b/libs/common/dateutil/relativedelta.py @@ -17,8 +17,12 @@ __all__ = ["relativedelta", "MO", "TU", "WE", "TH", "FR", "SA", "SU"] class relativedelta(object): """ - The relativedelta type is based on the specification of the excellent - work done by M.-A. Lemburg in his + The relativedelta type is designed to be applied to an existing datetime and + can replace specific components of that datetime, or represents an interval + of time. + + It is based on the specification of the excellent work done by M.-A. Lemburg + in his `mx.DateTime `_ extension. However, notice that this type does *NOT* implement the same algorithm as his work. Do *NOT* expect it to behave like mx.DateTime's counterpart. @@ -41,17 +45,19 @@ class relativedelta(object): years, months, weeks, days, hours, minutes, seconds, microseconds: Relative information, may be negative (argument is plural); adding or subtracting a relativedelta with relative information performs - the corresponding aritmetic operation on the original datetime value + the corresponding arithmetic operation on the original datetime value with the information in the relativedelta. weekday: - One of the weekday instances (MO, TU, etc). These - instances may receive a parameter N, specifying the Nth - weekday, which could be positive or negative (like MO(+1) - or MO(-2). Not specifying it is the same as specifying - +1. You can also use an integer, where 0=MO. Notice that - if the calculated date is already Monday, for example, - using MO(1) or MO(-1) won't change the day. + One of the weekday instances (MO, TU, etc) available in the + relativedelta module. These instances may receive a parameter N, + specifying the Nth weekday, which could be positive or negative + (like MO(+1) or MO(-2)). Not specifying it is the same as specifying + +1. You can also use an integer, where 0=MO. This argument is always + relative e.g. if the calculated date is already Monday, using MO(1) + or MO(-1) won't change the day. To effectively make it absolute, use + it in combination with the day argument (e.g. day=1, MO(1) for first + Monday of the month). leapdays: Will add given days to the date found, if year is a leap @@ -82,9 +88,12 @@ class relativedelta(object): For example + >>> from datetime import datetime + >>> from dateutil.relativedelta import relativedelta, MO >>> dt = datetime(2018, 4, 9, 13, 37, 0) >>> delta = relativedelta(hours=25, day=1, weekday=MO(1)) - datetime(2018, 4, 2, 14, 37, 0) + >>> dt + delta + datetime.datetime(2018, 4, 2, 14, 37) First, the day is set to 1 (the first of the month), then 25 hours are added, to get to the 2nd day and 14th hour, finally the @@ -276,7 +285,7 @@ class relativedelta(object): values for the relative attributes. >>> relativedelta(days=1.5, hours=2).normalized() - relativedelta(days=1, hours=14) + relativedelta(days=+1, hours=+14) :return: Returns a :class:`dateutil.relativedelta.relativedelta` object. diff --git a/libs/common/dateutil/rrule.py b/libs/common/dateutil/rrule.py index 8e9c2af1..b3203393 100644 --- a/libs/common/dateutil/rrule.py +++ b/libs/common/dateutil/rrule.py @@ -5,27 +5,27 @@ the recurrence rules documented in the `iCalendar RFC `_, including support for caching of results. """ -import itertools -import datetime import calendar +import datetime +import heapq +import itertools import re import sys +from functools import wraps +# For warning about deprecation of until and count +from warnings import warn + +from six import advance_iterator, integer_types + +from six.moves import _thread, range + +from ._common import weekday as weekdaybase try: from math import gcd except ImportError: from fractions import gcd -from six import advance_iterator, integer_types -from six.moves import _thread, range -import heapq - -from ._common import weekday as weekdaybase -from .tz import tzutc, tzlocal - -# For warning about deprecation of until and count -from warnings import warn - __all__ = ["rrule", "rruleset", "rrulestr", "YEARLY", "MONTHLY", "WEEKLY", "DAILY", "HOURLY", "MINUTELY", "SECONDLY", @@ -82,6 +82,7 @@ def _invalidates_cache(f): Decorator for rruleset methods which may invalidate the cached length. """ + @wraps(f) def inner_func(self, *args, **kwargs): rv = f(self, *args, **kwargs) self._invalidate_cache() @@ -178,7 +179,7 @@ class rrulebase(object): return False return False - # __len__() introduces a large performance penality. + # __len__() introduces a large performance penalty. def count(self): """ Returns the number of recurrences in this set. It will have go trough the whole recurrence, if this hasn't been done before. """ @@ -353,20 +354,26 @@ class rrule(rrulebase): from calendar.firstweekday(), and may be modified by calendar.setfirstweekday(). :param count: - How many occurrences will be generated. + If given, this determines how many occurrences will be generated. .. note:: - As of version 2.5.0, the use of the ``until`` keyword together - with the ``count`` keyword is deprecated per RFC-5545 Sec. 3.3.10. + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. :param until: - If given, this must be a datetime instance, that will specify the + If given, this must be a datetime instance specifying the upper-bound limit of the recurrence. The last recurrence in the rule is the greatest datetime that is less than or equal to the value specified in the ``until`` parameter. .. note:: - As of version 2.5.0, the use of the ``until`` keyword together - with the ``count`` keyword is deprecated per RFC-5545 Sec. 3.3.10. + As of version 2.5.0, the use of the keyword ``until`` in conjunction + with ``count`` is deprecated, to make sure ``dateutil`` is fully + compliant with `RFC-5545 Sec. 3.3.10 `_. Therefore, ``until`` and ``count`` + **must not** occur in the same call to ``rrule``. :param bysetpos: If given, it must be either an integer, or a sequence of integers, positive or negative. Each given integer will specify an occurrence @@ -429,7 +436,7 @@ class rrule(rrulebase): if not dtstart: if until and until.tzinfo: dtstart = datetime.datetime.now(tz=until.tzinfo).replace(microsecond=0) - else: + else: dtstart = datetime.datetime.now().replace(microsecond=0) elif not isinstance(dtstart, datetime.datetime): dtstart = datetime.datetime.fromordinal(dtstart.toordinal()) @@ -1406,7 +1413,52 @@ class rruleset(rrulebase): self._len = total + + class _rrulestr(object): + """ Parses a string representation of a recurrence rule or set of + recurrence rules. + + :param s: + Required, a string defining one or more recurrence rules. + + :param dtstart: + If given, used as the default recurrence start if not specified in the + rule string. + + :param cache: + If set ``True`` caching of results will be enabled, improving + performance of multiple queries considerably. + + :param unfold: + If set ``True`` indicates that a rule string is split over more + than one line and should be joined before processing. + + :param forceset: + If set ``True`` forces a :class:`dateutil.rrule.rruleset` to + be returned. + + :param compatible: + If set ``True`` forces ``unfold`` and ``forceset`` to be ``True``. + + :param ignoretz: + If set ``True``, time zones in parsed strings are ignored and a naive + :class:`datetime.datetime` object is returned. + + :param tzids: + If given, a callable or mapping used to retrieve a + :class:`datetime.tzinfo` from a string representation. + Defaults to :func:`dateutil.tz.gettz`. + + :param tzinfos: + Additional time zone names / aliases which may be present in a string + representation. See :func:`dateutil.parser.parse` for more + information. + + :return: + Returns a :class:`dateutil.rrule.rruleset` or + :class:`dateutil.rrule.rrule` + """ _freq_map = {"YEARLY": YEARLY, "MONTHLY": MONTHLY, @@ -1508,6 +1560,58 @@ class _rrulestr(object): raise ValueError("invalid '%s': %s" % (name, value)) return rrule(dtstart=dtstart, cache=cache, **rrkwargs) + def _parse_date_value(self, date_value, parms, rule_tzids, + ignoretz, tzids, tzinfos): + global parser + if not parser: + from dateutil import parser + + datevals = [] + value_found = False + TZID = None + + for parm in parms: + if parm.startswith("TZID="): + try: + tzkey = rule_tzids[parm.split('TZID=')[-1]] + except KeyError: + continue + if tzids is None: + from . import tz + tzlookup = tz.gettz + elif callable(tzids): + tzlookup = tzids + else: + tzlookup = getattr(tzids, 'get', None) + if tzlookup is None: + msg = ('tzids must be a callable, mapping, or None, ' + 'not %s' % tzids) + raise ValueError(msg) + + TZID = tzlookup(tzkey) + continue + + # RFC 5445 3.8.2.4: The VALUE parameter is optional, but may be found + # only once. + if parm not in {"VALUE=DATE-TIME", "VALUE=DATE"}: + raise ValueError("unsupported parm: " + parm) + else: + if value_found: + msg = ("Duplicate value parameter found in: " + parm) + raise ValueError(msg) + value_found = True + + for datestr in date_value.split(','): + date = parser.parse(datestr, ignoretz=ignoretz, tzinfos=tzinfos) + if TZID is not None: + if date.tzinfo is None: + date = date.replace(tzinfo=TZID) + else: + raise ValueError('DTSTART/EXDATE specifies multiple timezone') + datevals.append(date) + + return datevals + def _parse_rfc(self, s, dtstart=None, cache=False, @@ -1580,54 +1684,18 @@ class _rrulestr(object): raise ValueError("unsupported EXRULE parm: "+parm) exrulevals.append(value) elif name == "EXDATE": - for parm in parms: - if parm != "VALUE=DATE-TIME": - raise ValueError("unsupported EXDATE parm: "+parm) - exdatevals.append(value) + exdatevals.extend( + self._parse_date_value(value, parms, + TZID_NAMES, ignoretz, + tzids, tzinfos) + ) elif name == "DTSTART": - # RFC 5445 3.8.2.4: The VALUE parameter is optional, but - # may be found only once. - value_found = False - TZID = None - valid_values = {"VALUE=DATE-TIME", "VALUE=DATE"} - for parm in parms: - if parm.startswith("TZID="): - try: - tzkey = TZID_NAMES[parm.split('TZID=')[-1]] - except KeyError: - continue - if tzids is None: - from . import tz - tzlookup = tz.gettz - elif callable(tzids): - tzlookup = tzids - else: - tzlookup = getattr(tzids, 'get', None) - if tzlookup is None: - msg = ('tzids must be a callable, ' + - 'mapping, or None, ' + - 'not %s' % tzids) - raise ValueError(msg) - - TZID = tzlookup(tzkey) - continue - if parm not in valid_values: - raise ValueError("unsupported DTSTART parm: "+parm) - else: - if value_found: - msg = ("Duplicate value parameter found in " + - "DTSTART: " + parm) - raise ValueError(msg) - value_found = True - if not parser: - from dateutil import parser - dtstart = parser.parse(value, ignoretz=ignoretz, - tzinfos=tzinfos) - if TZID is not None: - if dtstart.tzinfo is None: - dtstart = dtstart.replace(tzinfo=TZID) - else: - raise ValueError('DTSTART specifies multiple timezones') + dtvals = self._parse_date_value(value, parms, TZID_NAMES, + ignoretz, tzids, tzinfos) + if len(dtvals) != 1: + raise ValueError("Multiple DTSTART values specified:" + + value) + dtstart = dtvals[0] else: raise ValueError("unsupported property: "+name) if (forceset or len(rrulevals) > 1 or rdatevals @@ -1649,10 +1717,7 @@ class _rrulestr(object): ignoretz=ignoretz, tzinfos=tzinfos)) for value in exdatevals: - for datestr in value.split(','): - rset.exdate(parser.parse(datestr, - ignoretz=ignoretz, - tzinfos=tzinfos)) + rset.exdate(value) if compatible and dtstart: rset.rdate(dtstart) return rset diff --git a/libs/common/dateutil/tz/__init__.py b/libs/common/dateutil/tz/__init__.py index 5a2d9cd6..af1352c4 100644 --- a/libs/common/dateutil/tz/__init__.py +++ b/libs/common/dateutil/tz/__init__.py @@ -2,11 +2,6 @@ from .tz import * from .tz import __doc__ -#: Convenience constant providing a :class:`tzutc()` instance -#: -#: .. versionadded:: 2.7.0 -UTC = tzutc() - __all__ = ["tzutc", "tzoffset", "tzlocal", "tzfile", "tzrange", "tzstr", "tzical", "tzwin", "tzwinlocal", "gettz", "enfold", "datetime_ambiguous", "datetime_exists", diff --git a/libs/common/dateutil/tz/_common.py b/libs/common/dateutil/tz/_common.py index ccabb7da..e6ac1183 100644 --- a/libs/common/dateutil/tz/_common.py +++ b/libs/common/dateutil/tz/_common.py @@ -1,4 +1,4 @@ -from six import PY3 +from six import PY2 from functools import wraps @@ -16,14 +16,18 @@ def tzname_in_python2(namefunc): tzname() API changed in Python 3. It used to return bytes, but was changed to unicode strings """ - def adjust_encoding(*args, **kwargs): - name = namefunc(*args, **kwargs) - if name is not None and not PY3: - name = name.encode() + if PY2: + @wraps(namefunc) + def adjust_encoding(*args, **kwargs): + name = namefunc(*args, **kwargs) + if name is not None: + name = name.encode() - return name + return name - return adjust_encoding + return adjust_encoding + else: + return namefunc # The following is adapted from Alexander Belopolsky's tz library @@ -208,7 +212,7 @@ class _tzinfo(tzinfo): Since this is the one time that we *know* we have an unambiguous datetime object, we take this opportunity to determine whether the datetime is ambiguous and in a "fold" state (e.g. if it's the first - occurence, chronologically, of the ambiguous datetime). + occurrence, chronologically, of the ambiguous datetime). :param dt: A timezone-aware :class:`datetime.datetime` object. @@ -246,7 +250,7 @@ class _tzinfo(tzinfo): Since this is the one time that we *know* we have an unambiguous datetime object, we take this opportunity to determine whether the datetime is ambiguous and in a "fold" state (e.g. if it's the first - occurance, chronologically, of the ambiguous datetime). + occurrence, chronologically, of the ambiguous datetime). :param dt: A timezone-aware :class:`datetime.datetime` object. diff --git a/libs/common/dateutil/tz/_factories.py b/libs/common/dateutil/tz/_factories.py index de2e0c1d..f8a65891 100644 --- a/libs/common/dateutil/tz/_factories.py +++ b/libs/common/dateutil/tz/_factories.py @@ -1,4 +1,8 @@ from datetime import timedelta +import weakref +from collections import OrderedDict + +from six.moves import _thread class _TzSingleton(type): @@ -11,6 +15,7 @@ class _TzSingleton(type): cls.__instance = super(_TzSingleton, cls).__call__() return cls.__instance + class _TzFactory(type): def instance(cls, *args, **kwargs): """Alternate constructor that returns a fresh instance""" @@ -19,7 +24,11 @@ class _TzFactory(type): class _TzOffsetFactory(_TzFactory): def __init__(cls, *args, **kwargs): - cls.__instances = {} + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 + + cls._cache_lock = _thread.allocate_lock() def __call__(cls, name, offset): if isinstance(offset, timedelta): @@ -31,12 +40,25 @@ class _TzOffsetFactory(_TzFactory): if instance is None: instance = cls.__instances.setdefault(key, cls.instance(name, offset)) + + # This lock may not be necessary in Python 3. See GH issue #901 + with cls._cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + return instance class _TzStrFactory(_TzFactory): def __init__(cls, *args, **kwargs): - cls.__instances = {} + cls.__instances = weakref.WeakValueDictionary() + cls.__strong_cache = OrderedDict() + cls.__strong_cache_size = 8 + + cls.__cache_lock = _thread.allocate_lock() def __call__(cls, s, posix_offset=False): key = (s, posix_offset) @@ -45,5 +67,14 @@ class _TzStrFactory(_TzFactory): if instance is None: instance = cls.__instances.setdefault(key, cls.instance(s, posix_offset)) + + # This lock may not be necessary in Python 3. See GH issue #901 + with cls.__cache_lock: + cls.__strong_cache[key] = cls.__strong_cache.pop(key, instance) + + # Remove an item if the strong cache is overpopulated + if len(cls.__strong_cache) > cls.__strong_cache_size: + cls.__strong_cache.popitem(last=False) + return instance diff --git a/libs/common/dateutil/tz/tz.py b/libs/common/dateutil/tz/tz.py index ac82b9c8..c67f56d4 100644 --- a/libs/common/dateutil/tz/tz.py +++ b/libs/common/dateutil/tz/tz.py @@ -13,6 +13,8 @@ import time import sys import os import bisect +import weakref +from collections import OrderedDict import six from six import string_types @@ -28,6 +30,9 @@ try: except ImportError: tzwin = tzwinlocal = None +# For warning about rounding tzinfo +from warnings import warn + ZERO = datetime.timedelta(0) EPOCH = datetime.datetime.utcfromtimestamp(0) EPOCHORDINAL = EPOCH.toordinal() @@ -118,6 +123,12 @@ class tzutc(datetime.tzinfo): __reduce__ = object.__reduce__ +#: Convenience constant providing a :class:`tzutc()` instance +#: +#: .. versionadded:: 2.7.0 +UTC = tzutc() + + @six.add_metaclass(_TzOffsetFactory) class tzoffset(datetime.tzinfo): """ @@ -137,7 +148,8 @@ class tzoffset(datetime.tzinfo): offset = offset.total_seconds() except (TypeError, AttributeError): pass - self._offset = datetime.timedelta(seconds=offset) + + self._offset = datetime.timedelta(seconds=_get_supported_offset(offset)) def utcoffset(self, dt): return self._offset @@ -373,7 +385,7 @@ class _tzfile(object): class tzfile(_tzinfo): """ - This is a ``tzinfo`` subclass thant allows one to use the ``tzfile(5)`` + This is a ``tzinfo`` subclass that allows one to use the ``tzfile(5)`` format timezone files to extract current and historical zone information. :param fileobj: @@ -460,7 +472,7 @@ class tzfile(_tzinfo): if fileobj is not None: if not file_opened_here: - fileobj = _ContextWrapper(fileobj) + fileobj = _nullcontext(fileobj) with fileobj as file_stream: tzobj = self._read_tzfile(file_stream) @@ -600,10 +612,7 @@ class tzfile(_tzinfo): out.ttinfo_list = [] for i in range(typecnt): gmtoff, isdst, abbrind = ttinfo[i] - # Round to full-minutes if that's not the case. Python's - # datetime doesn't accept sub-minute timezones. Check - # http://python.org/sf/1447945 for some information. - gmtoff = 60 * ((gmtoff + 30) // 60) + gmtoff = _get_supported_offset(gmtoff) tti = _ttinfo() tti.offset = gmtoff tti.dstoffset = datetime.timedelta(0) @@ -655,37 +664,44 @@ class tzfile(_tzinfo): # isgmt are off, so it should be in wall time. OTOH, it's # always in gmt time. Let me know if you have comments # about this. - laststdoffset = None + lastdst = None + lastoffset = None + lastdstoffset = None + lastbaseoffset = None out.trans_list = [] + for i, tti in enumerate(out.trans_idx): - if not tti.isdst: - offset = tti.offset - laststdoffset = offset - else: - if laststdoffset is not None: - # Store the DST offset as well and update it in the list - tti.dstoffset = tti.offset - laststdoffset - out.trans_idx[i] = tti + offset = tti.offset + dstoffset = 0 - offset = laststdoffset or 0 + if lastdst is not None: + if tti.isdst: + if not lastdst: + dstoffset = offset - lastoffset - out.trans_list.append(out.trans_list_utc[i] + offset) + if not dstoffset and lastdstoffset: + dstoffset = lastdstoffset - # In case we missed any DST offsets on the way in for some reason, make - # a second pass over the list, looking for the /next/ DST offset. - laststdoffset = None - for i in reversed(range(len(out.trans_idx))): - tti = out.trans_idx[i] - if tti.isdst: - if not (tti.dstoffset or laststdoffset is None): - tti.dstoffset = tti.offset - laststdoffset - else: - laststdoffset = tti.offset + tti.dstoffset = datetime.timedelta(seconds=dstoffset) + lastdstoffset = dstoffset - if not isinstance(tti.dstoffset, datetime.timedelta): - tti.dstoffset = datetime.timedelta(seconds=tti.dstoffset) + # If a time zone changes its base offset during a DST transition, + # then you need to adjust by the previous base offset to get the + # transition time in local time. Otherwise you use the current + # base offset. Ideally, I would have some mathematical proof of + # why this is true, but I haven't really thought about it enough. + baseoffset = offset - dstoffset + adjustment = baseoffset + if (lastbaseoffset is not None and baseoffset != lastbaseoffset + and tti.isdst != lastdst): + # The base DST has changed + adjustment = lastbaseoffset - out.trans_idx[i] = tti + lastdst = tti.isdst + lastoffset = offset + lastbaseoffset = baseoffset + + out.trans_list.append(out.trans_list_utc[i] + adjustment) out.trans_idx = tuple(out.trans_idx) out.trans_list = tuple(out.trans_list) @@ -1255,7 +1271,7 @@ class tzical(object): fileobj = open(fileobj, 'r') else: self._s = getattr(fileobj, 'name', repr(fileobj)) - fileobj = _ContextWrapper(fileobj) + fileobj = _nullcontext(fileobj) self._vtz = {} @@ -1528,7 +1544,9 @@ def __get_gettz(): """ def __init__(self): - self.__instances = {} + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache_size = 8 + self.__strong_cache = OrderedDict() self._cache_lock = _thread.allocate_lock() def __call__(self, name=None): @@ -1537,17 +1555,37 @@ def __get_gettz(): if rv is None: rv = self.nocache(name=name) - if not (name is None or isinstance(rv, tzlocal_classes)): + if not (name is None + or isinstance(rv, tzlocal_classes) + or rv is None): # tzlocal is slightly more complicated than the other # time zone providers because it depends on environment # at construction time, so don't cache that. + # + # We also cannot store weak references to None, so we + # will also not store that. self.__instances[name] = rv + else: + # No need for strong caching, return immediately + return rv + + self.__strong_cache[name] = self.__strong_cache.pop(name, rv) + + if len(self.__strong_cache) > self.__strong_cache_size: + self.__strong_cache.popitem(last=False) return rv + def set_cache_size(self, size): + with self._cache_lock: + self.__strong_cache_size = size + while len(self.__strong_cache) > size: + self.__strong_cache.popitem(last=False) + def cache_clear(self): with self._cache_lock: - self.__instances = {} + self.__instances = weakref.WeakValueDictionary() + self.__strong_cache.clear() @staticmethod def nocache(name=None): @@ -1558,7 +1596,7 @@ def __get_gettz(): name = os.environ["TZ"] except KeyError: pass - if name is None or name == ":": + if name is None or name in ("", ":"): for filepath in TZFILES: if not os.path.isabs(filepath): filename = filepath @@ -1577,8 +1615,15 @@ def __get_gettz(): else: tz = tzlocal() else: - if name.startswith(":"): - name = name[1:] + try: + if name.startswith(":"): + name = name[1:] + except TypeError as e: + if isinstance(name, bytes): + new_msg = "gettz argument should be str, not bytes" + six.raise_from(TypeError(new_msg), e) + else: + raise if os.path.isabs(name): if os.path.isfile(name): tz = tzfile(name) @@ -1601,7 +1646,8 @@ def __get_gettz(): if tzwin is not None: try: tz = tzwin(name) - except WindowsError: + except (WindowsError, UnicodeEncodeError): + # UnicodeEncodeError is for Python 2.7 compat tz = None if not tz: @@ -1622,7 +1668,7 @@ def __get_gettz(): break else: if name in ("GMT", "UTC"): - tz = tzutc() + tz = UTC elif name in time.tzname: tz = tzlocal() return tz @@ -1662,7 +1708,7 @@ def datetime_exists(dt, tz=None): # This is essentially a test of whether or not the datetime can survive # a round trip to UTC. - dt_rt = dt.replace(tzinfo=tz).astimezone(tzutc()).astimezone(tz) + dt_rt = dt.replace(tzinfo=tz).astimezone(UTC).astimezone(tz) dt_rt = dt_rt.replace(tzinfo=None) return dt == dt_rt @@ -1768,18 +1814,36 @@ def _datetime_to_timestamp(dt): return (dt.replace(tzinfo=None) - EPOCH).total_seconds() -class _ContextWrapper(object): - """ - Class for wrapping contexts so that they are passed through in a - with statement. - """ - def __init__(self, context): - self.context = context +if sys.version_info >= (3, 6): + def _get_supported_offset(second_offset): + return second_offset +else: + def _get_supported_offset(second_offset): + # For python pre-3.6, round to full-minutes if that's not the case. + # Python's datetime doesn't accept sub-minute timezones. Check + # http://python.org/sf/1447945 or https://bugs.python.org/issue5288 + # for some information. + old_offset = second_offset + calculated_offset = 60 * ((second_offset + 30) // 60) + return calculated_offset - def __enter__(self): - return self.context - def __exit__(*args, **kwargs): - pass +try: + # Python 3.7 feature + from contextlib import nullcontext as _nullcontext +except ImportError: + class _nullcontext(object): + """ + Class for wrapping contexts so that they are passed through in a + with statement. + """ + def __init__(self, context): + self.context = context + + def __enter__(self): + return self.context + + def __exit__(*args, **kwargs): + pass # vim:ts=4:sw=4:et diff --git a/libs/common/dateutil/tz/win.py b/libs/common/dateutil/tz/win.py index def4353a..cde07ba7 100644 --- a/libs/common/dateutil/tz/win.py +++ b/libs/common/dateutil/tz/win.py @@ -1,3 +1,11 @@ +# -*- coding: utf-8 -*- +""" +This module provides an interface to the native time zone data on Windows, +including :py:class:`datetime.tzinfo` implementations. + +Attempting to import this module on a non-Windows platform will raise an +:py:obj:`ImportError`. +""" # This code was originally contributed by Jeffrey Harris. import datetime import struct @@ -39,7 +47,7 @@ TZKEYNAME = _settzkeyname() class tzres(object): """ - Class for accessing `tzres.dll`, which contains timezone name related + Class for accessing ``tzres.dll``, which contains timezone name related resources. .. versionadded:: 2.5.0 @@ -72,9 +80,10 @@ class tzres(object): :param offset: A positive integer value referring to a string from the tzres dll. - ..note: + .. note:: + Offsets found in the registry are generally of the form - `@tzres.dll,-114`. The offset in this case if 114, not -114. + ``@tzres.dll,-114``. The offset in this case is 114, not -114. """ resource = self.p_wchar() @@ -146,6 +155,9 @@ class tzwinbase(tzrangebase): return result def display(self): + """ + Return the display name of the time zone. + """ return self._display def transitions(self, year): @@ -188,6 +200,17 @@ class tzwinbase(tzrangebase): class tzwin(tzwinbase): + """ + Time zone object created from the zone info in the Windows registry + + These are similar to :py:class:`dateutil.tz.tzrange` objects in that + the time zone data is provided in the format of a single offset rule + for either 0 or 2 time zone transitions per year. + + :param: name + The name of a Windows time zone key, e.g. "Eastern Standard Time". + The full list of keys can be retrieved with :func:`tzwin.list`. + """ def __init__(self, name): self._name = name @@ -234,6 +257,22 @@ class tzwin(tzwinbase): class tzwinlocal(tzwinbase): + """ + Class representing the local time zone information in the Windows registry + + While :class:`dateutil.tz.tzlocal` makes system calls (via the :mod:`time` + module) to retrieve time zone information, ``tzwinlocal`` retrieves the + rules directly from the Windows registry and creates an object like + :class:`dateutil.tz.tzwin`. + + Because Windows does not have an equivalent of :func:`time.tzset`, on + Windows, :class:`dateutil.tz.tzlocal` instances will always reflect the + time zone settings *at the time that the process was started*, meaning + changes to the machine's time zone settings during the run of a program + on Windows will **not** be reflected by :class:`dateutil.tz.tzlocal`. + Because ``tzwinlocal`` reads the registry directly, it is unaffected by + this issue. + """ def __init__(self): with winreg.ConnectRegistry(None, winreg.HKEY_LOCAL_MACHINE) as handle: with winreg.OpenKey(handle, TZLOCALKEYNAME) as tzlocalkey: diff --git a/libs/common/dateutil/utils.py b/libs/common/dateutil/utils.py index ebcce6aa..dd2d245a 100644 --- a/libs/common/dateutil/utils.py +++ b/libs/common/dateutil/utils.py @@ -28,7 +28,7 @@ def today(tzinfo=None): def default_tzinfo(dt, tzinfo): """ - Sets the the ``tzinfo`` parameter on naive datetimes only + Sets the ``tzinfo`` parameter on naive datetimes only This is useful for example when you are provided a datetime that may have either an implicit or explicit time zone, such as when parsing a time zone @@ -63,7 +63,7 @@ def default_tzinfo(dt, tzinfo): def within_delta(dt1, dt2, delta): """ - Useful for comparing two datetimes that may a negilible difference + Useful for comparing two datetimes that may have a negligible difference to be considered equal. """ delta = abs(delta) diff --git a/libs/common/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz b/libs/common/dateutil/zoneinfo/dateutil-zoneinfo.tar.gz index 6e8c05efd4f06dcb3b18cd919438255cd71ace47..524c48e12db7dfe159f282e4664f71ce249e1970 100644 GIT binary patch literal 174394 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 z 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 z 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

oF5%wc?0lVIdiCvTMwKQ}m1M4pzSU2C#ISwFq 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
oHJaZa%&cRgbKqQScY`o5It4F}rqGD>-kDeG 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 literal 154226 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 z zZ?S>7+Ew2O(mhBL66cLV>4`6K%NBWTj<-0^T-~5=vckk>+3_>d%G`Z&AeQ9rN66QA6~NOA-2yK zui2p~w2u&9F-NfO8pQo%`R)$*XS||ie`Ek+d;?*vf$YZvPg@qu%!`XdY+tSy2d;2D zW?$E7*$8AHy(D^?@-dbbn026}Qk}K+>5&oe_Dh{NKhaK-%fv&9?vbE;`3l63FX>UW z(fPKKYZ%1(j>YOhE?S!mwu)aBQt^+jDl+=I`CKjlf4hd($+ z&R^QFfcQ+RK^+$h_J-TShkIRB(ONa9-x@IIOQJVb$6O0_T~pQPL)E0h?WwFI_h4*@3^D& z6wCu5ajon0yekM8=^=K=C~2DHBmEo9cN_b&H&Hp_(T5h>($WcwNp(iM8~E|Gcbn`_ zV)LLPcvQ;qkd%OX_&9ddIOdN<(}RxEgKPv5_NbzX@f>2E!GYDEsW1|YU6Y?G)TPau zbr$a(>)z@9nRS$l*B*H}uxqIbF~BU8d0@aqHJT5jnPs?dj+#WT=p9 zb(=F5Y}FNgcEYf>YGCEQG&J+ssikaohw=7D1SugO%Iq>a6Ci&TO3CwP;$0J=hH)ry3~bZ<}8`*iG*!!H%J*V2?j(` z_R+9ApXRCr{kDjYU_b4>0iBGBE54_a%nC>B@w1@}C=4dOn{Yzmt@mGq?BSBL-C#!K zwf%Q#+dD5YP4ynaxhkJ~iPe3!J^*P1APonk19oWzyDl+{{Certy|-{;@8L(}i2`?N zvw+|{P-Dw29K{oAX>Wx=7}FRUCI4(_gqFunMqPZD+3Thmtl0&>WPstpY*p9#FL^0!Rl=`CY#U)II_gMZ)}BVj@*?sk&wPdlDZU=An?S2|D?+nXHR|q0TRE+x+=?rL5Az+i0@VkF7iMXg zbMFg@>fbX-5R!0MnRq%?1>RhwJ=W7^%dzvXHjUm|De3lHQ4QU0O-KANpMy`I&d;2) z>S?d%DZxcqlwHSnbi=LNWA`#1RplRy)q3bned>}biC`Z(*g7yBw2a~0hfSQMD(P55lPaf9>;#&lz!=%(z5Dw+p4c5sy4Zp)P_E-rl?LOZLeM_ zg-}aI$i6O#XQ4;oHZr1Y<(EXrB_%H&{dZ-QZ(O#9eIkn}NzcoRpBo<56bh<~$}Cnv zAr^gW^{PzvU79ZsMH2JxL#;W+@1#*N& zp*Hj{5y&prZxkN1%1$ zsb~4JXQY)rvAnQ^R@ER^AWY(%X()O)>VNt%OO}=1`(Fa>o|AM^oFgk42I7S@{x$tPxzQF-&xUo7lyeFbZYH) zhMM~o4K)cQX@~k*+Q4`N%k7pBX83Hda6~{cSZdHtFplx1yT?fO4Swyw*q{{+< zD_ZW#HfM01qjHQT1h&ZP7yZjHU3wmE)7B2us95b$c!b$JCh4X|c!Ka2H9x&Qrqpwg zDRneVc+q)bud18!7X4f)hUq^++O=*<4A)>aq9_QdBc2q0h#D1R4?RZqCU*Gr`OjWU zH}O5rJ?vgv;7`;l;;?-n0Wn{k$P!xATlp1<5O(y_u9BV7eiT0 z>z!HQInI9)bAF}vc~L|WcffmPqKFKD_^I%m0GT=IQcu2bXU*2iQ)!^^l;}SiLCRJ# z^E@+5q0ar%C^O6i!93aT1mT=4hg3_w`AI-Pr<*X|Bp^FKU3f~aHdI>3KR?&(Lqar+ zw9G#m8UgY2RCa7@gDKV8aA_?d;QbcB0RkF8!15nW7FD@M=dTD(`@}{QXiFwQvqN}F zuQs$K!V;$v=eNLj4-_g{iS$$_e4xezsL2LIq9oGYqTcu%0Ds;L(-T>++UB?H_oXPH zFD~F|BFZD~^H#v~*o6X~cd7RZj#Oj)9}NlR{UC1)CyTkjukZPHQ;_P7tKF%#m%cw> z0q|whcdeF|tKeyf)&4EhCB*yp`>%~{K9IAclNZT3NG{|ka~A?Bd^r>PM8n8SLqWsn z)M>c{f&6*h?(@OF>qsfGoxAac)IXl7mFp+I;&IA=E!js34`I?LPVI-deP@C}$oXA! zy*fQEWyEunmF3|^TI=F_`7tJuzb3U1~`pd?(J26<~X=?nr3c7aG<-_hrdC5m?lku))#tx?WeBs98|& zna#|_Di3F;(w}jPmD}3V?)m8S#_nHO<oTBD)-+j5(q3~?na^1pMY)Rsup+o1`(DbIT=sYaIRD}I254dROx!iZx zo_S)Z>fns>zdF@Fysw+emsUgPz(qI*+N56AWf!}*y}xLa)h!t^veiAWwB~rX*Q84M zO0s7eO6Bv$`G+>v*vbC&U|FAAxry!@o0*@FFMr=p5E|M@zf#ZB`D`|MHdc1kqB){z z`@jKu5qKy=U0W-%Y`m_oQ|y>+?zbhbCgAl-Sja!~uvDH%3V#(L1#VML`-QjBKK{{8 zUKZsGd(THVzI4U|xmI$wWin8N7zl+SA;0&BHiSA(5#ypQ&?R)ghf_i=w8% zlco>>?{%0g%8=*O)SQlVHlS9SP&~QF|sfY7#&ScWnzTtfNi6E zOXZ2`Yw9>Qoeq09vl}%ey>?3oA56%Pip2|@ej9=b`XfE_2$v-|!;WP6c=%p2*63FE zb0o*LA+et0xJ>oF{W$(v)1VNRS)$1+mh^;-+g84tsTtw}Mag~H4@@3zul$FyeQF!~ z0qi~|rI;fp21e}$8U*$@BNJf_>Mjz%#YUzrCa}~NGkB0DPsfnaa1r+cf22KZTK!hM zwZFPzDo@bJ$M6Byo(Kr;7c+$)32*U%ziqV^)8B2(bdGwHU69^Tm_vcZ=b)eaUh;IP z1Ui$+WQE(Ln*BWDYN2m{&r`7Y6oR7g{($Ek64@al=zA*+-8!XIil~smFv|9V+5s1*UisV}O?O zMw5S|(E&hJc#3`|DqjOgG<Gec|KH1>!QTrfp)GQolmeU=B&ZU#A4g4oLx7VL&zz&_h-PRs{AZ`xV$*7_c{V zU~iNr$oX-p46$V-YRdE?oYXA(ZI)wsY&3$bXCp^6Jg^ZxXRuf@8dI-~;+ z)op#FC@m?bmDW;}k8jV*qKbMWL;wUFfWUD1#hj7yh%vSn*O~H=DV81YhVqaZEIDN` z6O%tsOe&qAC?tn-F|ic+$fDURWXTR5&_jom&K8q`#Gh+S4AamLIb&-HZ?=hn=w>nL zhwyt-2FaJk9{`sZJa9*4MFfRpB}5MK z_0ENow0{I4Fjz8dU~^yD5SX%hToyJ3OTJ0D*YMjW?~h%!`eyFGkYa1y)(J*=9V|YX z>K{TB7#P5b8Z+r#U);d~W zYj9t_{&-0VKY~o@^6x2uEoXf9_~^fo`ueW%KDnWBrfW*<6Il zg~$)9OfnqmRWZ6R3EG?2p3uTvUIUnWg-z4rgb1cK4 zgd6gK=gPAT)#sIDwS}A`^~I9Pnxj}~dI}BZddIAP5yU&BNUbRC{&gNnk_^|XIjge~ zP|ZW;*;^^m?JmA6YUao&P>9_e;=V4WQsUmaC$rZ?}gvml4lmPG}46 ztc!j|RcBX!sLK=(nsTzy$hdfp&MLH}b!A=J=iv0lE#uO`Q~u|~(pY=ppa=hy)J<(o zH=B7(=Ss3%zT0Zn;c`%V^0=FMOK9o3aQa=#pqbC5`eH4o;k(fFscq|eefHr%e_7Or z70on~W{G7I>{3gQjFy6viyoX?S~_PddHK0|A(>a9+jjW!q9+KXQKDC$LK;m%^wBA) z(p%vObL#yNZ6s#F?p$0x=SWrXVtcybUiHP8{qll|_aHUf$#yd*8#+$>woTYJt7b9e z>BVQsb?Fu|-oBpA^yE__*(P*WugX_+cLh8UIQ|3@s`%29_2c#54ZlrpxoTQcwwm*> zNZGIa^pc4AUV^>AyM zN^Q)w)73<%VUOU18mwKTEhfK1hbj=q$8r7Dg2IEsHLR4DRli_?(mSuo^!|I5+NiK& z?7j?z2bIvIDF5Sr@Q(bfD6!Y2XibP^TLkgd;}>`FW6$1YBF-D}s`WyNy>tDEh=VvQ zx@r>X6hM$_BD_@cQX3mpAl{VyTIzIelJX%ggk)%u08qsGNBIyEMl!?#@Sc7i#2r)R zNyg*;qg+%Ji!l-aN}2&?Ai(4@JBZ^a%adf4`5Lq1g)R`U{PkK&A{?mrT%DCBw4S2# zQdQR~RDO4P38L6d2)+7SxkfllGIaD_j&3(rAYgDn_>v{nE0xq~ty13i-3AHH5!S(i z;x^oIWknC$yZRVdXaSsj^bNx&&X4DB4$25{AB~&Q3+u|>L;{kaRe6JtpY9`(s3?>5?-ZzkJasqnSZAss^MY=4$|@T$Ns%qy~-DS zsegK?jrn$!@3fWp7o?C7Zq3j295tmda4b^xE#P^Cuyg}}fQ25_c($91&h_mpr44KPba(G} z8l?cU_TgHCT$`)@#Km>Ibt zKr{h}@KFGES&oH=G52Q-KE^jfQ)hu%P+KAkrN$a0g~^cKL^ z8c?3nl>tr;aOE^Vta?|;f0*@B2PXr4EU*H7Xw%>sOm==pw(XNx{jhLXB%T_T|B=mc z2pV;?mW&M`7_)=hyI(yuGtz)vv%l@y1n6@Ho6uS7CpLkz^k(@&v8P<=WU&mAJD|a) z3Aoia7gPH)s=1~PaHKy0_WDP9PH;3j;BK)2=Yj#aO9Oxx{YLfx9H?|&m%zD7$Jcyj zHAmHIrqAQ0KoR%oCguNU{tGsg+{Z|)ew(_OkPa1isJ4yqWq*2I0b4?5z!04(%y-AN3KCy+GyQy1q z`&|@knmPDj$>Wuf$v*Vm&&N%X&?d@m!57btF>UCSKcvoH*?fP;W@8d;UHM&8b<}GW z1gj+CemW@aCe&b3GZ+?oeHIku&71=XVuG16iPuC0_fM%ZKOFXh%nnL)og8-=*UUuZo)JC0!2tJYDS7_I+~KzpK-&UlRO*sB|=FYtpCDGlXxS>eSlZA&E9U zHTi36xV$g-szV-Na3HHKid4w5)UFF3cepv=bwIrmXez8yuV=#=stbB?uwJ8Cc04lj z^ls9YOsAa}c%;r{PT2L(N=64?GUhT=U=GKBJ^1z|_j6oOVbI5)7@ZuaTjLz|t~9k& z>Nc83B>UR4vM%kLR9t)@Ef*ez&s^(18ZIEUPYvqz@;LEFn9Xr?4Fpb^laaQFeS@^u zTWq2XoEVz9AHUfPyEMpCsZhw+_|gR^ggrP6cuC(5rc$^L6OefpiVuajw^yrav+fK0 zsXE3qAivJ}dh3WxRlAY8vN#?*>CYF0l!#7Xm#6?0l?W-zzg|yhv3=pAdl0|8iYSUx zvQ6;JXG-=AVM_7rYyEt;l#v7PUO3Vv@=~yoo-Qp-S`oU_A^*+2k>uA665XbbM>aL` zZoA~8w7#6FpC&%C}?ZIQ1_54l5*4$#r=wbFaT50LL z>#|n-CSS5b3o?H=1QFTPbPvWUXPEmuOFFCxrm%OvKk_E^_)&mMXVB)uXkbSF_fqQo zyzfkWmBqB|jAi!wMnDuCYfe_mkivuz3y0)p;2&`qas^Lg2lzV4ji5gQFm&Hf(AE8y z_(nxePNs8jIUN-|(|Bjro``1Fv^k4ndn91^6nv45i-p7k9%YhpUoohQJ91fPbc5h- z=0PEkSEi0gvQ}zBF!Bn4tK7vRy2KWfNn>={EZAnDN22=37U%5g%J&9ZULO$*0f!ez zpgq(s6wFrKw#GW6!&-kpHu%zD0$4$P#^g?(OY}f+r`wg)OlJOpJo(l~HjU6HqA}71RG0C=9@U$xOdIyxg2iE(FX2B#Avebi=r+`{VJEY*L35V;6MUrLU16u- zt;4IbE()Zx;bv1li{0Q;6}RVF$;lw9=(^(nJxhk0ofi!O^L6jlwhG@E%P4r46RE6| z-(HzD`Gc49#cne9avpIG6}(%xi`!G2i`zf&6u0XGl4$sUnN$P7T6AJJs7X1GCc_He ztJDC+sJI;mLq*q?vxpk`Z^dtvSyzbwF!FBB<1kQ+258f97VV<^wJk!M4Rw~0Ayiq1 zM*C}<{J$Bo3h5jJgS&#adPD8C$c_H$6b8b7G;)=7JwP$8q%^#gW{Q^Q#q$NbclGy? z5IdB-8^zl5tV0V$p^h(qYj}4VpY$^AA3Qm3umk7t z)W*FOb!QpHpY5)%9wnWh%u965{#3LZObWU@Xg=QCrQQ#<$>+;+dHl3QUQZTGUl$&I zrVyzvbT>OnzD}7NxWTC@e3T*-<^4$*%JVIK1stBl~{jcFu@(9i?4#D?O(CbDl<3 zRcTi5WH4rFpg696xO0rBID(KM*VjRoC3lrL9#oGxfo4mV>DYif5$bk;OHe<{*gQM$ zYvv`^qH@*jb9hUBa{1u(G8`wXd65CVjT_SC4;C#`p(o-7F5k*VQ*MnA-TnYL+R)KZWgdN`|s9gGcEEY@xD(6|) z%JQuWf z`oOD4$HL{Wx)YC`xJA2n$3gQc-=Dr}=e*d_Lx!RWOf6L2vIdfbKLSS$GPcv6<#Tfv zVyk5@RAXgUMLRY^QjScT)O8&*8b`5gGT>BFau1_knat{E@rhc&c>Sz|18m$PPuk?4 zg5K!Lxe-Tf^jO$Lfth|UKuQ&>ydGL!JCA+JF+g0bX(i3O} zI^6P2zN<6cNM+O9qWH>#u`wCmxzosWiL~`@q?g=$j6v6wdQJBz7W=@!Zke&x(pWcV zI%M_d4E;AAr*r9ytuj4}mwKv^jsoa-eN35v`Jt72vcMmU<&#=uqo?xE>nHU{el^{O z#?yaaTFQ?UjZ5mt>91~b#ceHmrntaNdy&&217Bt&jjpGAD^ZoMORKh|V&JEW8<|=9 z$;E%7USJtUgi6`lp!PO;ujb$X;_ADvE1yce3hk>xhPknSs<7Nn09_-dJ!p34u!4To zD5f729fl(!*GWh7UFV;xF#I{rPb8`o{?53>SioHnM#n>+KNC;BHGV2zXL zjE{n2jzjci(Ek8oMo&AZwUUEQH13A`szLMJ4=c?MCS6(BIE@)vH5n08?+vH{!0!!c z03hcLXaS(pSc4fF#EG#XPV-Eet_)@3d5`(g1V|bHN#-|T1OSCMU{ZLA$St-@Tf+ly z{wDDjvwV{<(O`zQZiH@DVR;Hp7ZxE}JVQja=^SvkgZ;6v@$MP85v>!2aK#T1=rAh^ zZYK>{*pI}f(+bh1(~@GvuL@(u4-ef&I2Dd-10LPRuLzDSCli4y#~+TXQzwXUBew_D zEaH1A*8BPfA-a!)Ar(E?WWg{t!h)R7RPeAiof1~}(n#-@&l9jd9A9)OesyUT5p`)* z2-2#ABJ_z52sq}32gdGzW4ExNW4E90xN_6sxX8Z+rt5WuWan>m$|Cdv<9Vm7-M=_u zO2d3{1REGu3C+k@;*{{g=rh9}c{X60u|Y!y6E8xh|-H6r2z>LnN}a2kQ>v9w*Xcz?QN)tS0vQ)#+o-Q)w( zKQeTSONDp}BXMX4&DwpC>I#WCr&)njYTTrVoZh6Uo!g)oP2Qlu6K_N?q;5ng``U=0 zkD(m|rqG6yM`Y}FM`sj;ZG4|UNy*oac;|=Z)rfGjNz&LYk=sYg*lmHzDB6yOyD5vx z*eyZK*v$=$qQs1%LcsVAs8&a3?1n*P6ir3IC5JzSCP%SD59t&j>xE_%5Kg7BnvOQ4+?- zMg;YW#IR2BPLF~hI7XN`dTJUwbWx!Hj6qe_L`l6*w>u*~T@dJ)P5;*qGO7IJbi6*@ z36qd^pY{&-*ZB?5A4oRNOUJ$b3q<0dtEPlYVYO39W+~&ZlH&KKgCpy$#iddeLuEu) zQPsn?MbDd^$j_3|B|Ec%x>qG5E_R-#^Qy6^eD~1WGC~ zHh;+i+e*j+1#-y(Uz9}NwR{(O_tYGK@?$rytG%BxFlrMRJ1GOL2Wn92>jh#^>dU%W z7Xs_Bj4D$A8*?|R+~sFoPzEd$ummL5g%iNA0mBE38y??^HwMLpJqBg27f_j~LAezL zk>DSzW*Jxh@Px-d#st+ZYLkJf0Fr5#5=m9X|mtu-uZm(S6BLbnRuX4vlB;hl%!~X;Sky5 z`OQj-l&79sBi!*ScKcQ%(XHjt;dx2ec=X}uasfW@!QTBwYUr?AesHEKXwamUeV>eu z>eTB*U zVe=ltB=ZPuqtioc($7rU6-wHWuLX^-uEATp?qgY&u;roX+8-zzNhIt9jwe1(^mP>R zA65rmj;f?yQjNsW$ydWIN+pvkXBpA4?n)<90zmo=P&dahoktEP><(ekYUEi_jU>`B zR;$qORmc%x&Ebl!xrzQsrQK2~(!Kne0lt>W z3RBMX8NyU;H^{mt&}EU2+@#+N=bk-G;YTmxeW8>ujruRY{2BZ5D-0p_)&GhXGAdGO zldrI^dX>HU`0Z(dLjFH0qnHi!KnVLA5DHNOw3I*Zg&)2V*Z~6j1(3V-3g(aNRPE!x z_^eAVPj#-!BHx+^6n4B(f9!7Z$8{58bt3G9!|mlj6;jBL4$xU)UFJa9ArS@(e)3aA z!s=wkN774%fj`ecf&W+`42{5w1tq8ddlCWOPkG_fR|?5qpyG2b6z>)mGfdhb`q6~~ z6ap5VmngJXuLv|zuel!Fx7`2qR6hCf!vk6<@Rd6LFkvbGi)wy?%IKCL$3=oFs#H7( zhUo<40&=0=)nrTN;{6wtl86oimSPu!-oWBS`lkTJ9ULXffdw^3A8hprs#FbWRRK!9 z0;@Y0s#1q8Q4AXRz>o@k(}DC&+Q_%B@Elj*APa6lUJQyNX)wt4s;r={-#>TMq})|x zLvC&=_#sc>myo3of(OfW?<>-$l3I-*gU!CW?you$E=%jlK0Zc&n-8P9jiGnFQzmSA zt;8SO+UXNc(X_CYXYP77Ws!uCs&7E6FGbxP6O3n1_E+1%*(&m9PeU)(!P!~FtF9;E z1;N=To+rzr*3-ykmWJ)1JN^F38{3X^>$&gl3n3RL?W^1#JC(Bfx9c`O4*}QH4swyZv(N8Nj$iPebsvGjIb&fkcZ=9}l=TVJ>b8O3s^TZ`5 z)bz+|O8D)nw5A+7{i@mhe!x~(!?aeDVR`ra&?`*2D>wwzfvKK>q0#NdA>VVg;F8uO}y<=4o=fpf*=<%tfx z=52f{I&&`8yP`*%^_E7Y^5Bt7=m>(d;6)!O|D;VAHOOS%T~__Ji3$zTKg5O zB?qlMTGC*hpWRJZGcRjTGSAZ9rMaC2NGL`(MdwB#5xid+vYtA1@mDU9C@kEm=2mO6 zc4&Y7U9k8ECSk^hT4k=5Xmh7)3s6G90#4?p@`m(obF|EbF zJZFE&&~Pg-(VWzlzGDM9*0{^d&%aHv$U2F|Oq*fpaE_Fe5LPNGC1A-iAD0esW$Jb7 zdsx4ed*_-fTK zYAwCm5R&a}Gd`8SkL#JqLGxW69Jj_)XnJ3qufr0ON;a{PzmXHd(#2J@f^>1<#7QLt z{!t9;%gJ7HRJNvOlW|hh8$WX=^^#io$6xw|lP9%16kdJwsv_;t)v+EW)vJ@ea#290 zH|L9T?<$2%{<@d)&f*kI#8I>MNO^ZaakYDs*pEFd6oy|Jd|yBeZY-vDr{}5jND@X) zL)bmZnt7(;za%_>_s9K2X71yTtnLlrPB(}MWU#kBOWV3_(%7=ZN!yyAtB>TdWs3q$ z7V53McCTCvxxizxIyzv!dr=@8Q*@+#JYkUf?#AF6zr7TYf1bLMUv2wk2zpv}NIY9p zDMKPn$ziQ3KN&7vXFT>x1y*BPVIgW|>o3r9BIn9HtM#VwG-XmpDB7Wyoq}oIz`4zx zdb?#G@cYPF>fMjVY9yTmQ62S8oqa(!P>MIr-`%Oc&r#>{=Kg1rNM1rp8&7dtYqrdp z?{kM8J2HA6%o_hdBGW%0H*KzZS8TYQ$2r^c-#>VMbTRi8%Xc&SjOhfYrjajInS{s} zQ1Q_PxJoE|eFB3g}9oE}RA79z2;x_mqa1i_706zfc-hcoA_TGRX0B+xaPy~)Ns-Ed%9B(HH8+DyuR6a>1L!*>z zF&I@=Hm~@$59OWO}FAh{3f#T8mHkENRXmf7g!S4yBQAKuA zjYM|1*MbIFrUC|8R)DcHVDR5a(BQwtfWZrV&LZa!pk|KD!RfQ`&Vrw}ucqrcH+W3@ zYjiNYnXq6+#2`x%RLpOiaq*pE95Uel3nX_~F%j7*{`HZEv5w5aYbx859k+ilJ^B@hAw66;cxaZg%tV59opz~)0h{O1@F6{4F;U(R!SrmN zXyc*5eqkoUaM0)e{>g81QV2IBun8(8P@WOx{TU1%T67aL5drpw{VZRToA!+hG)kxh z&DUsncwkbG7*q0UCbFXrtajf9i0;$ip=kkP$-q0%z^_`&L=yd-cIvLkA%RW^Aw8`? zptpvZh-N)tbMop7N~mjs9yh-yPKcNi21@8JQ+@8QG+lOP#IQZ&WQZYRQFwT0<5qH( z94PN0T46*T(f*qoPRJoWz}L(pE|ky)!}CUqO$K0V;}i~~P4GRNWq|e!uttBj_)a4O zpm48&hb9B8;g%V^$t(Z_IsnPv@p{~N2726Zw7^<;us!<2fJWwcw_R8>e2>2na!)RO zy0Q&aPggu#Pp%INN@yn)9vT|3F=!nAa*r{%p02mE4VA9^3e`gnocyXm;4llOD+@yR z=z|z32D*V`b_E>F9W3BzXCU{8F!*gUbK{2eSi&6;Q;K$ z5?PPC7Z3%$L}a`Rft{n@F@KU{Fbt0ZB``-t}0(ec~t zK5oYtAtur+$)ROp)+UcdMQTGLnY=108bJlz`Y5g_|Jsh&B^OdI+V=fqX|U+omXB99 zwT8tyrD0;_pQ~A)^vBPeJ%z=4@R^CPt9difL#?cn1tkP52O${t6-@+(u2SLrxS!Ou zE3T4P8AVkz1ci)%OFp$`ltN!Xm^z~xgCAlR$s-4)cKa$RI6UUOjPpZfiLtrF!|m0} z`$N9cRrMWOWN4{T+pL>$td%!mbj;;P^XQgGf~ca#u7TYk)*^7Zwm|Q=1T{O!pCo2X2upv+BdUS z3Gtj>@x0cGp1T!IzI{w-{p)yy_bsCMokVGd=~X}U)2k?^nG+~%X;jz0e{O%6=%3Yn z)zKDc^}Gy}0N%B>Wg!WFQC*|SqGK~+VEB{Ft@Tco#Qw?|+Wv}~1hwq}hQOm^_upiT zV&`^S_J!GjKxaFXIDYZb7i{pOGCbI$9m)A68pc^bJh(X-tN7>>HrT^2AY`rlGl7RU zcClpyl=Et~q?m1v-+-sL8~@r-_a0V3PWcF2@ev>YOdZX}#oBNFnHz!I7dj6S5bhs^ z`DLIg9m%;()W2D$Tog2+kW)UbT70w%u*|T*yqTfRJ|Mqlk})yR0FuHy4GEa{tFU&= zLJ9?0%cd>aZGlwSK;SZ6*ww0v%k~rHZNVUda}IJL!q5bpL zGY!(#bN}a=8+oJ|=WrxvZ*7r`brHYjwf;SKx7`+Ad_415iHD%^E(6YfEk5( z)(_5Yy1~sPLt>x`<=paV;Apvjo~bJq2Fd?G-@jAIDPPC_xGz*945F>#5qIrU&0&Z3aZr1rN4B9VNn75@< znE#99EI?8v_y-G^Qq0j}!-74C47`n!xJY!wjzd2e7 zeg6vBTRE^d)ZWMZDPa()XsP^Xw3!=cV0sD2Un$HR1AR#V#|ty39QRUTo)6fn3ebR5 zaC26LFlZT&rURrMfRlv;G@u@K)dDn-glzBQ2xtU|fKuoc=Br?~yl~&nonJHKHu}C{ z+Z4EercP*%zRW>kz7JU7TkqqpdPOZ*1oW1B?;LgWt%Pib10aMb%mazfq9A#o+Xl5p z$m*q;d^?fet4zek`$t>7>-?&J(!X_nW?~3z3Y9@xc_H`DbXUw5J!3KOldN3zLtY1F!2|8n)&OJPT|Yy=eqjXfuSsw$Hi#h>!!^*EL%% zUE%x##etan-@k^5>6iZyHMI3(_0FG?@72+AZU;-26 zQ(<^O`d&=v{@L`jvxg{sEqvV)vA{K$+J0xek}7(IIJq~DPi1pc(4j~jM)LGWaOl$@ z$WWT7$?=OmrE3he)ec&9P}GWea%CLf5C*3Mmqxe5=_i?mL69*bVN;D2m21iy2U3Hh z>@koFjp5Ui0Bqkn&_5OxG04?@SS20 zU(L36!BhFRnJ0MQ6HJUE9L8@1eu=chXHyDNEJgC^zn5l5!msYc{Mx~~nGbsyDw}OT zR5s^E!*h=UZ_Z*l0{+gAYgU0Dkn9}dlR`6znq58<$9x<3J$2#MOdJETV18yg=lHx% za#Ch$a6NLdoz;G|{>-bE1-T_{g$PJc_Y2NFK_;GsY|nJFA$!}qY7ftl=_$y+%dVs5 zL@1_vx59XkFMEo&Z>sf(bIrpQMW5T34Z^D``lzvB*|U9Yn=~ta`}q;=+Qu2T%U+rq z9CVx3x?+vB7!DoIwfdnwz8e^8>KEC)_zF3EnUjjWq;hkk7SDpDhc&IUxvq5 z2c_g?!@WM;zwSNDGeL%5J7~ipvm{>3bdZf3*yot2q4ISOrl8K2%i;NN$g{H8UiI`0MIW#=XCJi9t^fS37ZixMoqi}? z+MC2_zdEtvAoE08-`&yA9r>V|Sl%>0YlE0^IZ$~$!slP4Ec1yUG*8E$`OhbWis^Fm zg-JW(r!zU{JLgxzR8dVVu5AQmIL^MkwB;bww4 zt>l=#fCJJbL196EzB00c14{gwEAg#Gb^>bRw4Hw74hBntq&iP=cHZSMdPS`=sMNkp zru#QDs|bVcGsX_1^ta7Z`LEwq#jQ}84961ojp8}fq~eR&;1LeV8k(Rq*^fq&bDjMI z4`;Xf*Jim1skuwslWqyELY|~Ae6z>fJLZ5}ltYI1feZZ4**fSDOfIAO53|*0gtH9u z-l*BQ)QAHxf^0-B+7_RzJcczJslRdC&;L`XZIt46-+~Rq*`!<{P+C4WjN0tB){5Me z6Hu$m_mvbIQfmoTdJ3GInxzJ>(sQ8Rt$CEO#rd19dcIgupFv`4rb?@3 zZM|7mCNCqJKF(EYjpj|=SXXLmx9lR}ykAbZvhFEk<~!82q+i;w^soNk28&0^q%_Fv z+-p;;i>!#C^;hVhwLth1`7xFNTj8Lt2BVe@rdsCvGhgWwFV7g@^o30B?%<1UWJFuc zuQ*sX1bJB8fgDjMZl-7V_mlA>GtvGEm?YzQa5m9ggFAXAkH(?Nxvg?I)aieS5sb12 zS!FS$eoN63!<9q#AeCvjjobg@EktUKib-4YBFL=KBesq`S}{QIhzy#6{w<0E+hk(# zmC04C_XD)3(GhRRU_~ap%&bA6@r?jE_}Zr@mg{Fwu6UmFf(++oUq;s4X5nskSfpuL zo?0}4KuM^+5v(dP_WTm_U#Iksgi1XhJ;@}ZEIqqEHk`t9wC~M_+<%ZjG#vLezT7=Ykv7GN?dKH z(9j`SEQa$D%qfc39IMdas8}%+AiA3T5gZ#F-28$Ka5@*HaPXzZojHplP;;YUpY9Ix z40F*m+`i0^N5lm48bMbpgnkhXi83O80}?pkSok5J?2`tdOG7xcWdx9c53mRE%X;DMY|PBRh)%Q(?VaG-&w35=7=og-}1( zrzdKtu71*w7K%A~+w%x@pY$s2IYb$dh=5f${1qgPgkk~^L^HFjI z?}+s6|2TWgxTv2050p|uVnH$JQd&R+B$qBF1OWj75kx{l>0C-dx&$Ppky<20Vnw=B zmQX;tVd+@*+`;efe_!|UeX#SH`sAE>@9f!`b4XmLUpSL#lDM{mzp=T4CH?}rWLf!OWTyuWE)J$O@F{nZ*n+tPKlIMPUws-;wk zvWD3%Lil&hZMyBzb!+}rW^29^o*8XhxYJ|1w6>%VW%|NJL;RI})?o#y z3}*>{ftFBBk#j2miIEkd)6ah&FR;eGGxL3n88_vlW402*oj|K$*yl#DjD;vIY#m}jq%x|#gvY*pWGC#pK5xZvjujaQ#dwrpSn9)<8 z12Ul4GiZ4iAz-!!87x7dG-JWwd%WCLiZFu<%$OY^j_G+aAx<-tHLM?J>F) zt)HfhUGMSJez$PDK)Z|0b1WFnApnNY&zDl?5l+RxIjSeEc!o{X|{4Ajgb*!5(}x^1JSI@{Fd}4a^=%>efEJ*C8 zG9A)uxMWLps*OIbiQp!@`;6S6W^jjJjXUA1CXM)*iecXMvu8=Z?_MDp4H0?5>m@EP zk;c0EQx+^IHy_FLF0?3e<`bWPls+XI((<4w_?fQ;%~V@Kvq4RbXS1&LAul`jB)6EK zH!f9rB@aH_ax5NyIDPe=e~F6JA9#0Y!I>EzWo&hq-<1lPRaG?Ch@@ruaBP{L#PET- z%6BVJ#ZTWg`SP>um;ikjofYbVVTVhu-KQuQ>5)UOXd3^XoNFzUmlE|!=op?UXHo^`feDhOYXNH3slXQ?;uEI1WyzM1G|_5 zug1X3W4TNPja|rJbA-|NUcWsqrxL~t=*^$Xf$Y84t3x6cF+_)4pq2NLCiQFcw_&qa zDpg3^1-%ny$$1%x?2@I`civCr#6K_A`E6dq)yyQJgT0_ER^gL>aXNf2<}dv=3sdW5 zy8W$n<8h!yFH`j#PAB5UVPW9e!>?fzIi%lE*D906u0?@jc+@piGQYZDL?ls1@_Ux2 z?aG0#fHBE{+5rjU?LdMf$lUAz8E24rdXaGlndFO%_eGzJ4B|B-HMu2wvz%2p4IiKi zfIb3L$ts%WwdEmKv&wjmHKS`@QrFJ0#|1i)^L#y0>+^X%) ziD$$e3`iBWJHr2>{EveS4)-%%vY>v1g16K>^ff+yE{9V}2)8|TA~t~VIst&GMGrZW z;+PYNagL&iObnL%JsH+_%^1xWu2bAM@NAiRD$+La%zh5f_+SO+DRO!?X?wWSRk>&T zy3*U*$JD;5Ro{D)%F6pZxire{K5}bFQki&atij7Tif$drEx5PsC?cACURP(nHWN9} zDj*~lmSW{Xt|2V8MPvVZ?ruuDQKPM$QGLNg-5N=%bBKQ69z|v8gbj0XkDR0N9%Ga~ z`XKT(f8w97WL>Q7i6hZQ#!BDmjic-AJ;qQ`Up2M~6pTAw zvfmWQyCt!(QR&(X{aA~QwOLOP`L*^*6m69(_Ir)?=+lsQ+|b(9?3=#CH5I3Ix9QG( zi;N|wlx`9}GomB7drV*dyV!~Z+ub#Oa4fDMR*Wn?8$*&0a7Wq?2$)(3-bonu%H6Ix zB!^qA)9%HJbnaa-b{c$bx6^0W4vVIuU_Bv@$f9(-DPLI;(HP!w6X2oay0>M%$m=x; zW0Zz~VM|C~<)<6_HHX`x6QV42Ij*03o*OG#O53$I-mOuE|Dp4|J8W(9_j&mSrJ(Xh z6Jc`0#n%i*E1QQ6@+sq+7p}SD-hUD{<0W>QafP{V z`y5E`%hH9c`JWN-$F*4BIk@G6P=vOr(ww6*O3W~n1$VWN1xKw6g95Bz2n2g5D)Uw= z!k?m**>}bzEAaSiA>df-JswN=^;Q%Sfj^%q46+b~K{=i*IQIw^objG4HkwWjd!-lT zBUx~nsd8Azfe2&v;xZ=FiU^}69CWNgFNakU4uy&VUj|S@LPJKtg0rFzMMcxL&P-jN z+qS-hakM1Fpn{r62w*HYl~NYm7O-fF{2TXk|Kl4sWwCEIu3e%MrNP6;m<2Y4vhDZj z3gTmCUJ+uTA7pcxHiVc=+e?^CJ3 zl2+!Uq(JIWR6KPnl!pJWbTt&dC2)xwhWKqprq6-{FjpmuMU@8}4*<9EF3&-%M0oi3 zV2~IK9?9o`<7grO{udlIV>TF7y6<%(Cv@k3T05Y!h7)M%q)p8nT~iEf$D%`WM$y-jY(PTvY{N-`85kJ zo)wQICh(XFSmIAMH**OH;|)a!^M*n$?4bxC1d%}9Ix~ScN7bw;ccYa#Fg;L!9Y^FZ zhqZ^{Ey6agMNFvT-D-ss14iLc6o^sC^8yx%i|);It%xX!R_N0Dh$}R z1wRQfy*z?g+$&FjINMQaf`5fB;~^5DlM}D=6o|f|f#(Fex&ZxR_9^FqW<|745bYrW z56;~4!z(s|m@U7jj^OTanj8*@AK6U1yh_R(IPl%M_Ee;%Wje4JRhvG9tQ9=HiqiR$ ziO3^M?bq)}q~A9vaZ=_v(VNg`SU~%F5b~VbRmNi1Tyjx3@g zvT_S~{l01prFZS4Pt0E3dr}5**5WpqdmU{kubH??B5zb6%$JQ#P_MdP$}y zbXd63>&;kI+3EM&>QhzT#3j!jaNgA@ zN21nsfO0jwa=Fg_lag0|*|V)4anV1b3naCFCN(BwabgY^=el^U2x_OCtC~1BG){_7 z??|I9($b7+czx#wwQ%_?ij!x`pU9!?nhf~K9rsQTL%7t6pu6ID0b;xM6YuQ3gPf>s zXO-%@)2|hgyKkmA8q2M-d|pJd(Jtn8bH3tKH)_{DdEyi7B2ilJb7#~{LbBnVkAsug zxsR&Ymi#M&^XydKBZaG)D8;hLys3hNo@Fg(gQ$(+@S}~nGCxoC?}=Z!PKVQn55y%G z=tuO`#IEXh*DCkM`H^RG&-lrhexE;ydp7Lw9;bUg{nn=RL1Pt1RK2&*6O;k0`_I7U z=cJeJv)u-gE5F%@%eui)=U?3D(A;8Pz34J_w4m8XTe|RVO>Qq2T@nbrrY z)*R(ZOiI;lJucpQp2~-w+AT9h^wle-++L-y;-pr){sn%OSuOXe|JF@9S&rn&>DE7= zRFVBUBSuG|3${GsGfr`->EC(l7`Q&BI>K4&%6Jou`Ob7`z|k=7>PNOBD-yBVQ~R&Z zcR#oo71g@_R^=FR`BS>#zu^E^cNgf6n=&IClU(Rcl3a>Tkh+)OnO+gdF;K-dA&4wp zpiO$jq0QgL+4}Q@@*BrV-KDp<=^6F(&1c{It!^Cn@4bAMR6ny4;C-LXUglT*%V}^# z%vS~Bpc#wBzEBgpGrqvI>iAH)C8?+J1x+r?fQ$HpLew=MXW>|$`GXkj(Fa9Rv_hpR z>u~GC?Mln6-$$x&?$@?Oza8V{$e2Z+hzeM99c+)8FbSR{-XF|+#~`#4dhHD|jA1p2 zUn#?Rk+1CHd>9YE=)dz}aWDRz4~wPw?|c}|i~m38!yJC&-un8yC3cWs;+AF|4$y|u zPZd#i!MjLs2!@H}2_iA$i9R1EaY;g4_+byXrf^RScyf)A9kHr_?Sp$(fu100v zm&|KhpYINZCv2E5g?0RX;(6^EAMVx--k2EMmprPfDz}zT&N%{tN8{z>qbkMQG~6F1s%mfcfb8dzOO-8?cQ0SW#95h)AGScDa&SAx`ImWyD_t=jwlAApsd2o?D1xe4( zvX9rCCp`U#+%FREiv)3z1Wnw{CJMPo!Y`6&!yevd%duT`r%#bYsS{gSM41z+f+?G9 z>P{C)c}n`c%Fab1me3^LrY5$siDrPX zj996_J=)TW$qiIa@_^f|+ux#1l&PG@U%F&QnJ9~a%zfRCyE)qywU2eE%6nFnZ`DU= z4u9=gkp~$b8n;^-AHVikX9t@ohjfF!@;~q9{CT-?Z%x2FY3MrGC_?OZYqQ;tsg!;E z<><#g8|h{>!ehxC*Gu(L8B68sD|Z>|qqgRpqGq^BIVr5~^<$>E|KUkeW508!&xQGa{Eb{~%^jn~{?u`0WFm&q0(AD+q}n4&!si z#;3ID-~3|S8<+MrGU&FULEvpe6{|#!FBZLV9Muv0QaS_A)xLL?bD$rVa~Sx)jz7Kp z@NEY9!{MTqII!S~^DzjyeR7xh;XSpG+aH#htj~jP-|A|PBOf$ZyX;iXk?#65uAhOg ztAAs8Xp-b%#TO#pxFL?HF*PftIHRr-RULs(v}(3@N;(B@KaD*Qe;V5}o;IfaG=t^^? zrk15Dx0bL3m#49!xAYgLfQUsPiilL-@;f44ybRP-xqovbWPf>%~ub`?z^ZX>KXKhdh$pw~6^+@!>TOxiz_8sP~g`S6hZ2zilU9{TS#l zH(K>z_19|yA$yO)`}WkFxXK_RTddr(qtI=|`UWyh1+ znid989*xL` zh^c;Vu}~WPdx>VnDVanfjezb^BFD-OZ18!-eYueOfXnf>$s{&-0w|fU%Y_iS4*p%I zTPY8xlt>#`aybd4bR3lp5n*)k$hs`iKnQHM8T=dnx!KYth|-am;?6?`7ms&D5>kpp zj2Wx}len=3&b&#lUV%ISGRntdil)$q%38X8V{QpF{6!pQ`Xq+ zNmjWW7?!x~-xhN^Y$gjde2Pu<(AN;5Iu7g#Pq zzvjKMK6Q0^#4Q(9v`wxx=GGQ5=7Jtz&A*`yJOjCq}8fni_a_4xI7) zfO&!`ON5`4_;q^7OG;Ts`zaploJ~7coBrS*iIQmg!u-n=9re+dgR!>F_MK8?-c>u( ztKo0k)j3~vgc>O)yYS#HVO&xQT<%n*d$@TJuKu3YoIHV1oy)&6tzXeMgR(Fbn>u~# zr+HH$RXxjl2fQkxHf`RbYX+#^8_1VT3Hy2UZR^gWs$%*4*BtNg#W+N&(jv&UVjbY{ zCk^xBiaa)AN@rjE#J*JNC+Hi!7}_@7DEh-oGP=DiiuUV!SFAa-Z>#g^sY!#tFG0H( z8uMyh{pAW(-t}Leq?&P$nVw}hAP26kTMOrYS4py?targ zc@ls4$R~7~tEh45=31H9mX3kloT-Yt?c!b0QoRyMgHm>hnewERbe`)bl+R*Q9A^Z+ zmz`wVzR3?TXcQw}Y!W^Gj)tiA8N{`t&%IW&Ef zVc*}Xqso5|4W8188YDPk7_4U+82tXy^y7EOkJZad3u*%bOkZwY9eXG}T<}4l<-CwOHC@&g=m71@u*U-(Dm#MUn;-)qa4vvYRg?o3q3LSYDJTn-f4W%(4&0eS= zdHhoicKd8R?FC0g6Z3e@+iSdrV=6l|hBIOk6-^Ut6-`>MmcGUJEq%9Hz+x$^L~A(q zpv|uH^zusQ>8W++sSjvoqN`}a(Nr`|vsK72lNy?-P#b3E1eYMejkFD=v4Zf<(=y2_1W|Xw!LG1Eh?BrJHr)0d<=4*b$HBH4cx+5=SCHzX4hlTp|GD zB%>i$854V|IQA-doE;qfEqF+)$kgl>+E6K>I892y<`_*Gdz5!Mw$>=5(>Pylp^@~f zN;xyzHajVsfPPSCDnF>YBfk*&k!AOVVrYXPDcklXYPJF0z)m|(`2~@fm;=}0m;+B> ziwA|FnXhO;b0rLh^21;i00B{PN<$y!P7AnTiTve)kgWTf)Aai zEQ!{e@?#;7BF6+lkXJiTt-}6QYAB2me^s=juV_Mp5a$3HUnMGJ;@_7DD5{L1O%=wL z%h=b8i&@u;bJ*9NZ^RzZ0z=n8Y&U>`ZNMO2Fe2xGZUY0?6)ki*ZAV!9!LWYyt(2M~* z$7P9a{mL((5m+h#qV^U@?{u=^R~`!?Pa3lXF#=xSqN|Xx{8pvRzOL~8p`FOTg4KTo z_q@8tHV#kXl2lj(p!`(%eH6Esx{Ht0QR_acd0^_S_6&NG0iALjKrIDYQ_>!N`_LF& z<0E5Z&8m&`KhifmwXA>qt>ygGnfa!AP0uzVDY{r4it8|3(G?d!DQ0%FX0BHZNHL8R zAO_%Y2MadDz@5EJ8Cd<;0BX3!MM^FH?O@ngxP81lLSz5TeV{ZMKlrksgsPwY7PNEJ zZXu5lqK_|uh=-6JvK6rQcHA-=g+%>D4?t&L^gIKQm(lJF70wWXTI#mvS8^b6sL|!~ zLgwMn2(ArEl<_>)hvt3P5vt3$cVlIAkj&$=jZ}D4i{GDw11E;Vg87{`NHggK62Re# zU8Eri$^x#PZIJoB_-vvY>*C4}W$*LWdqHC0!#RuN-e|s!h4cB1KE%Aya)Jc5!4qTF z=NC;rL2&+4sE-(F_#ydg>94_~`o<3Fv>Yfc6_RkTS=LwmShok6ZegGIBp1v!Hu(6` zzn=JU9`&_bM(o9)ba{58(N~+&?o6ZGRC_MpjaF0*df^Xwm^Im$ZjbfTLStpR-U8hIg#D#j3)w<- z_t%Q_?l-AFZ~WWMcJhR~`%_+8+Idv=%U0fkx!a2_M$F(u65is56V+l`J@Tzgt{5WA z9D&O=R>93tFyrD(q;bP?D!5(GbX3I_rCGx=3*x{1(Rxb%_D6GS)&1KaZQl6Su9a-D zW9KMgYG6Qn%i|93?ajnJ_^(>7yz1eT;W+fW`Wq^HM`SPFoz>lG;*(V5GW(OUe7)|9 z-gIG)fyNj1C#mC_Uzj%Y$5tGXqZ^NntA(FE-k9FX8(Tu@+9J<&%F(6jjQqN#-Y(4B z&r^%XrsBH52Fp)BQ1B#2L1SvVe9gJc4_epglqlvH71)E@O(ga-exF||&?o$uU!6|0 zT;vzFM`2byv3e)0r@7sBZxha4wyr*Uy(fxS{w;CV;=a9lu_|%aL9zw5(hnUh+K8H+ zl3;@Uo_w|A@UpF_zOlFd#-_oP8C{oqr(uCxuNF9Py7VQzLa|NQzQQ&ct&0isHrUD7 zFPXa<$8k(q^5wWri3~S=<72-YzP$fK3Ypo!%E860OEOLa(pl>mH-(ydCBD#7Cr zMl)ajERy1b&WrGoUk_@_)PFY(**2Is-}Wn2V{~qMcB`I6|7Ozi&uA@5>N}Q+7}D6S z!22rmoTq4NnyYR*@eJYba(6!Z=y=+Ti2umvxM8BNo0iDSEq*pS8t1aO81d-fW8hHt zXjR=>@x-0m_QxEqli7#eX0_>s4L%OW-GjI??UuJuk8aUjYyz~3RJ8ip)*GDqiBwD& znz*}CikiA)@@L{bUw7_{DJ7LlhEKd{4M!O-+28E9ZR0EApR$V0zC6-IBpxHO`6Nb! zTdE>okE|kJi`G)3@|vZ_HdklL9LUE7mVAj0EV1zqEa?i0yk-+4a$q%+#70?>A9a&- zm&L9qB$fqMaVI_U+J_hsMoV@j4oeM#iKD#E;1X^vIrOI6C6n59T1ze7Yc7A93O=v9 zy$>v#vILbqo-TikKxO`3XOZcR7`@1)SiLr~&Z0+B6-6+7Lp^UM!;kep9Ju5jBV{%KM`SKZT%Y1%BAw?DS(&dh9{rN7iuJ>~N1O z`yMjjGf%_&%xfMLw*j3eYj{sd(D2^=wdT-u(-t8nQ$kAog3c>Q{1AU#qW5Tjg&*8B zEp|V$)~?0=6)DmEE0W8-L+3>DK*`#J;sH?_n@GcD1_DiLdQ%0ORNaO5Xc+eoyKjX* z?0&G$UhA6hxDcZl@=r{KFiv15^Z<21LX%|5HtiXR6SIhy1I- zWZI$({CWVWJie&{9Qc<=hBS{LK$%BueDac(%KLb=X z01e{;mh`iSJ5$e!EbQ&jbrX3|&;y+*AWE!MNb?XpBE6#CV|W8IaloZu30Zp_2#FUP@IwC^0aqOGeK|AE@)* zY zrx~Rnq(w)AT7gIVebvple!ji@XF_%#Ldd7-uR#Gr^H-UcF-U|5VAIWS{hQ_8oX6ky`qXB zJL-V9XEf~Z7VSquk+n=8a^mJxq^E^{K-iO+X_+R|kIM*%cpEVjO#0@_*P##Wx)z*L ziD3KdDZGO}st11fPi5N$ShvYyC;jf|nk_VvFy zHg*U(W=`E$a@_m=wxjY6LIqxUAM22Xd-N1G(^>H3&1+vn8|nQ&E+Dwrn(ad*aLFly#qA4<* zex|1E>b8DP(%fMVa(L?*ecQQ{Mc%oCWM0dAn!NdL=4;VMQQYanM?4v7W?b)+tHaRY zDxTY|6b)KOr48Humm19WPnHBm1UGt-e>T`(N)SZG~0Zkq9bVXF1X>*GxoKJ6c_JJ>IAD*Pf4c^(Gdw z*fzq;E~+_fu058}Z+gsG3Zs>7z(_X{JaT#R)r7U7TMt`l*{8{;VvZ=ANNEjf+(GF(($z*8f=?Ud&0@r^RuXoI8QkHd-8SRV z^xf*28_~tJrDq|N&>wWfvGPE3!_!FLjH#Pkik5Xg-VKW+IE-$*IVFv4SGq ztu-r4DG|lKwDDmlzA)_q%C#aZ4eMOZD>hkHN9RiEre=?wB}4_^He?nHuj5|#_97J0 z5BfOUU!!%`(vE8A>ZrB^m&&|Hlf~9aEpXC%;+aNu-ItoWt)h#1uxwLKgv*h9etOsP z%EBu77YndUzqdW_rn*1b^#lZERN zQK|pu>zR)gz!UInLtn@aM#L8?ifHQ4{CS|JmN3t8dnhVCK~Wl1oP&yM3mh-Anb`|F z)zq`uIk`W?rR8!My^Yg3xX#I4j1l4L?rJ#7eNOmf(UNKCW4x!Lq2>~`z4#}U(U%;j zZ*`)%dex+}g*f*@yVH8vC7iWGhXFNmz878C*CmxL1{&r-Mao4*Kd6ud6}zBf@}gou zO)4ACu7(G@_oGWHjzDuMmci*>G)F+ZC&v}g$7a@&sf&S>X;6q^(YiasQSv7)VkKiV&NL=rF zD?}N`-qm2`L$UgogQ<%OM$-z|Se4`0H0NR&gyJ~f0HGg%Pz|8lbIy`U?HbUXf1$Sx z=;gi8d(kBvbTRqe7vqC*isy)k_u#OI;CPwV$}Vofp*9aJrUP7)fNQrMa6JHAy?`q> z3UIjt!Ce30CHO5(v}J1>H68H}Diz(T!`-0W0JOJWh)4t?sxL%< zaa6ktM7Vvl({?{!HE3o%R#;eLdtgw2FZupc%MV`9-zoQHB!%tt>!Kl?0gm(jJ{GH$ z>xnZ^Iz_-2e+wml49heKfHJl2%x;*GEkS)fp6}vs<9?nX7iK<|*BcUhh%ozB_K2T2 zE1hJaz&zqZsXY$RHD1RE2oyp;X*V!3p$^IOnip7OFG&c?_?rSA)W4 z5y?o*%swR32Sx8TPnO@iXe5AIzNfxpplybn%;r(6kZ%g)Sl2wc^M8%?A*om-9!}+$ z4(i)8^GSh>pFOu%{AY6jME!^T5zYV)V)u=JVpF;hW=l||X1Qnu`7vVa;}58FEA|e= z>kmC{YKLI)P*X30PmFXdyW1aHHYLSIuQ9#cMG+h`Z`xt0L{7GQux3R;)k80TK+Z@a zoQiw2=!qFVc6-4NE4GdRX1PE3F{$~#R`<2(F7W65GNL@X6e9U0-+RDpAdI7}$FcuR zgH9Ay;m8q#$&bya(Q*HV*1OygGNi^L2M?HIm(hrnJvfL#eR}I;OvO_Om>LSP(qU$v z;pyOGsWAMwkko%2LV%}+`~PfJfgI`l$z~CS(U_Su2xEgox&~Ee{m+;X8mNzK2ec;t zU#nw3v0cmm+@xa1rP9vQ{(zjA=fUD)egunXAsl<3g#T|`nKiLuyg!gK5U<<$t6)Ru zoOmAI|IDu7<2wk9Y$p^CiESb-?ZA6GjvdDkXQI%QEimf%Ux@y%?Kk?^aR~xLGo)W$ z!-xGhs9oT_su!{S3!=A&0Nxtg|9^)qsPEEeV3H~r@=p-B(m2PPCp-T)5XlVrNzVh7O<$qVi(4YT_)@%Y7>Up%* z9wGyO%#DW-m+5_b2c>(#yaL9pt_IC34)KmkL7QuBs5HmD#SSo#3be%L&2X3j)t)S3qC?>#mv1)c4i z2yh{GDPS^U$|=-BYYx5);@}KH=is7eeY|vxV(WnP!cdrRsN=ftYhRu&ua#1eFK5^E zi%^}vZm7)t;;gmK%-|j8@K`JT*>mypUqsc<&B7LY%br#X3bgA~)sz-V!7MTL#WhAY zR{Reazt~6cs0H*F1z{s?rR^k&?K&dX5Zjw2Uz%Qx`rt&uQRtVWyCv>pILlh24qs&D zR^owex?oO zHKy}$AePwPoLL)b+gNr$vM9@LQp44z$O2(n~;vXmQ%i-qeHGV^Lm;~Zf9}>TU%TP z^JmSj4__@y1fB?oTry;MD7`k?X_Q#f%eYo`xr2X#FjKoS+*ZOl`;T&e7BXF!9&Xk9 zyJkv!eL>#hu;`#){Or!ny1gye{=RULrN~c9X^^b30!A0hqj#w5vvwsl?zC$xSnt@A z0%u4suNL@a{QXER|6lZd^kPh5C=&|}%#t8bTQ-J_xkt)uoG_x79B~A4Pgpw1h|B|6_+hP= z0vlvuH%Vv+ zvY}+Kp9I0*@K^<9L&;(CEvhdFgJE`Gdsz}TST;$pAOUNXEC~mUjWk&M zUffdx*5n9|6j>5Z_79ve0>_w{ zL*giuISxj<9fX4qKZBNoaHz_!UUsg3>bQP9-5Z2fxB0%xsu10$&e{`GGA+pVzT{`AZHuOy zCG})sr18P8)X{x|RDH71R6qCdp^d#1uOAt7%6pq;>-?e&B1UBsrN(blip8eCnmUS9 zsoG1gnyjr+6^k7itC(QdZCSpUJpcPjIR+33K_YjQ6=QcXp3CEkGCU}SGy zC+U}3-_z~9vZ7CGPrrlLPrgy^>-LHLo+>Qb)4 z7*r4BF4_tipxYqgn{yDPbptY+;@X7hdFP;l;yLIlEe2}Q!$9ePra!?z_`79_GPoE; z*+WQC9s_B(g3q@ZV%7=hDt8;iJlqC_4_uaOgB-QnAb5T_WM&ZxAvCBV)DIYhQl^Hs zpR_>&+N}_zLG!@u}-V}Y*yS% zRyc$jfkE)6H=s=0P>2fnD*#Lp8*PKMX6;DAkD;e}Sjf)=i;7rhxjzTJd`8?%4MCAS zI7BfU&aB-P#)5(Fl?A~*KuK>HiPZk}do%}aU!Bn+xQ#;;9Q)DmU?8pVZO&#I2&G61 zJZgpDHlYx69*Dy0P-wd>9MTeQg^XP=Q0=Wbh<9}k3Tiuw|M3ArayDfKYhn@Jm~#$~ zIcU8I_{cK{H3Fv!K-|4S+#g=UKmwqilXniu)G(F)|o z!5{m;Nehml{`bewRS?0yK+1Oz8qK0(1QNJ%OlJNPVrKPu_ah8~9)Z667Fj#AfxI~A zGw{I_10jKN&Oj_cudm05zq~|-SVR~r4x*#Bf?jyrokGyziZlmnMJ?4SSj-8S?L(Uf zzXYH;r@KYPNY54B4oP=fFoJeoTIrAUG!eAR{NpzY(k6cO8z-YRxs8lFilwweHacpj z)rFgGPd%P`eEUnH>951coRouarY1e^PayBlrn=1LiV{f$3 z>kf4T#@nCHI%O=q*9E%nObPaS`%Vg0Tp60a{AS4VYKj;AC6U|SutjT~9RJsHS5-!~ z>DK!wGu?=MoYWng&Ohh0y(jeQ5kZRci60bBnax{^>=U^jA-x>K#vlH{+HUhxh(12@ z3lS^dA(ZY!G>EMXDmQKpHBGxsZK0>O8J9^+MHIHnzea%FNukTgREx{f=IR^nU$QuD$`&_UqEqTMwyLrJ3A3 zNmhIpgCT6uAG@4Gi-)^6#@W(pzs76J9 z?HtZD8#<7lM>Sp|emUy9Np0!3exX7;G2fkiW(EZUqcu_mxEsf{@zBf)x3w3Edb{Ffmi=N5i^0PBXi)U@-|(` zOZ}0UN;l?%m+kY1Dr;MQUPi8PmC3!$12vTC6eLyjRMz~;yR@B>WH z7h&M%E=6D%gm?yk={GA5@#!vZW|0Z^d+pm7d5 z0;U>x18AfHkOAfsp$Qi90Ky}IX-#0>9RXPD5O0ORYviCKAeZ?9v)Wj3a20CEtOd}= z)DU8n6|4o=aF9vJG2#|l&iZC_=QqkgcHB%3z}YAys|hQxt&Fkr<;U zh3YUUlM8U`Vi9m4GYt$G@Ehd>LOOpG6cYwH7KB3Z4O&RR=Uq7%s3!U6Z4iP50Hi(^ z^&d|80zNR*Vk-a+C0d~?W~{Aq&^sjf9R;-jSVV_jEUJu0AP9YmWF@8c^&Nsz*CC%l zsMe{(@5HX&Id%@Lq8!d7-8~sMpv?m50?j*KT8Lk5y5-2qqu#QmjGqm7jzc3#OfO$% zp&c>iT6wpa9ABzrHHMu>BXLJ}qEgnb9;OTk9G!aKn6UHQav8-f z2x&387v*dvzRU0$;M*yp(%cy}i<@h7&@Wj&t-85Q!9M9l*Lum5-mPfU=Gv2N% z>$cKQr=I;;ugh!Jo&HfXA{FosDH(_j@d~7rUbXhV-#y|m^+M&Wk@Rp@&nAkJo_&*X z`Onf|qDW0hZoZd7rRGG-i@AosK~&@H1XG^u3bhkCMQDt&*wpq1ncdRbkyQh!^cn1r zsl^e!jIwpq8<(jf@9zSA?)x4dX&osifnaTQa%f7JB_m z_G?CRBjTX_*XrtrspPFq_lD}_8kNKcr-;|p9m|?-_{N4L?^RI;q`8k5h7iM%>Z{mxFBJ#&1$@qExsI_J8>Zq#(* z)~)!4VM(`Nc+t{0C6(d1uERIYybSZY^P64Z-nq^TiAmk4XqVi}W3>faTWhMthmF#k zC)cCYRAef&Oot{?aX8X}gfu+I_S43U-mG_~9m5(KU#OWJ^_SEKsxC`5Oc1{EthfSq zUQk4qFEdPTB~N(d`!3aVFji_tRSlTB7FhH*l^y=}{1R2?$-lAJ-YUKX|2*znmFn3O z>0lLpzLRsnagx9fkk)<}v^_@+ z%}ns(P<1L;1fH2NX6FLP;2U7w^w$m+3ulRaj74?a#X-WDbHzs(Xs%LD8+`u*aJezj z2FEiqtQfj7_s28MYSEC#bdbSy!1XhC!^K#cHz>n>*Q|KQBvKR7df&GlE z!yJU9Ha`@osm+HV$LMj^MO5on_Bu3R3{lf$eZryG&JkU|&R!uuycyYeW!!rkTVFXa zPnGcr!|*(-~Me}7qlCV zSlh4K-_HfNkF6C~JkL-{$!92oT&Va7)@0X{BHfQKoXnfjb6o7|^X2Kcyn3e{oLti3 zD%44Pwwwr&cS=goncn&82T!g?p5QHv{H|UnB%6!th-LjX{#)m4% zkwb*9y5!(O`TCDU>cpS|dg~A-8OxK6S%nl%*52KgZZ>qZUdL0vx14rxwEbTx@TwTM z-O}_#U7Yu`g0T#j3>ke5-s7oful8!Uhm3l$NtJoRKVOo1&v?!=+87lZ)u)wS)iYQh zU`$NSX>$I9{cC((BQx*a{b=|1l(pY}7HL!jt8iNX<*YSk^yj=m zUg1iPPu}J4#n1T@np(j)-UJ1F>xyv63HUZ4``d}dL4y5{2aAIY`z5?k7CdSa zmOy+(S$`5TSO7lT16d-HP!=Jb&)*J%1KU*b=jpDI(V;(U&+bf6OR*4;D8d53y^&@j zw$HLeA7crwC_3HZ{?W@xb`KVCnQdH_h#~Z|u+D4%i44049t#~li~>Kj9ZxX`FZ(gx zkf6UcgY1163mqwp;?mQy$Tk$O^tLHAv026lG38sdi^n&sB?J!_t}(yB z(o&OtN|>Mb<)q#!q@d701;OvB3m-wnoj8;cMvV6bW{-Xlg1gP=*zct^k0qrvZFbvz z9ZfmPQt+-DdUn*4%H(b@UDtft9fq($`t3R%)qKL0p=(5IzN_4IwMXnfUXQwqv_lT` zxTC0d;_V6=!(3mP8*i3oJl?96TCX;7=c~mD`$ev2&hWiO-7w2-T$b3HroZ<0wA{Vo zEW|;iidi38zT}uJ%T0svf_e&C{yZ{Fcx;D z*uG0jak1H?ii!cDJh0eHY~N)SZ-#OaQroa(Qz*6ugi63-U*)b44iVh^LW?&<<8Mt7 zG0Ns|O&c+K&)=F+whAUHJgR>4OJ3*~wPm}io65E#udNCfL%&S)Afm3f=D#}N^2U7A`7P?3-d{QXD@WH$uY_K2zw_Sc7L30%;ZxRiV#Q*M+(crD@SbqeX0<6CPh{Al)5Dy1P&9yZzs_?)`E<+z-#1nRlLd-q~lJv(}k;W3Si-{YtwA(v;rtM%SFE zmbRcFK>_u^Z66x?$6pd9Z_LixIP&N|l=lc2Zp+L<0gV%Yt=8ZxhMe@2)ST3mbkC=7 z;PO)b`}%j%q8-T4WX{+7{L78}v>eH*XS<>NFyN(Ev3hD-6{}@H(nE^5W z_jN9*HjI$CTL6{PPoy=Rlj?a52NKU}U}JzCbJik&Pz7L{S+v0E+Ln{YFy9P5|r^a;n`8Z@a2j`-Q4MSAE33~>Io%*9+AJeudwf@}ktmi|>AGEw2JFBFJ z_sd=2#V9I&1PSrG0yKLnL)*=L8YR;Xh}`?ymi&oKG_Fxqho-WTUOvE>3`*T+>Fq$knrpN(V3(3>QHn( z9$;yiJT z0*I|e6=!V6XB!Ctj1KX@=sggV1wi~7D{QStjf*dV>P{WEOMuo)@c5Ug2%tThQk0!# zcRvaM=o<&A&+<+H4C24kP_Y20|J?%E5N+-4&eltqq0Cptc;%vTD~|F5r#t5 zVcCwXbyqErOU|{#tycvzvKd#`;3+huLO%PK`v?@5Tx5SKJ7E7j;xA?eU3|RpavER% z8}YXtpKc2bhnS4naXoVDLYs$5dbmGYu_mn`+Byn;jV9B?NM<+?zQ0+b%{`4R&c6mk z=0MP&GJ)H)bEv_6{V{MghCe5?ivMkDk$p~@=-p>Fg>gWL^DKPv-u#91a~;~wiN8=M zA3Uz!2*(>VBoPhSYlxmsnd0d{!{`8nIsojJ1It3+jt&7W!*?iHMEi&tKvN177!JOv zx`uF$%AvJa0BuGivw>%3PQXCT#2M&3`>;;BgN8g^1Ttib_l_>x_JEAWy$N^;etci@ zQldp{ghk6`%+p?TqNWGL)4{TBrx$DAW|Bg#l%K6;T-xlYg&K_j_S3@sCDu0j7(j1h z4Ga#Pz4idK^UnbYcW_l0;1?GxQr@)eT50yz>mHhaT-A7yU$sOV>^7hIwsh8%!l_bR z=y#FL^6GU;KzkK!+loJ`vi+U7l6b8c!Ltb(vHepQ{rZB6N$%C9yFK5^!4le4O&Chu zv59YqzNRX(;{L$X@k;ZSx$m5EK29y5vNA&7r|~4ku9Lgti?_!(|C|YpRSQ-{ zrwt);Ur_VrEXJ!b2r%$z=M!zb8JBY;^q%qdYC$BnZ~k(9XWS1)od1b7-a8{Ysqq(R z=_%0nxf{G~{1X9dWhI6j$H4br_*~trR%tQ1di$8wugz{ZcFt8DiaV|r)0~`WFi!Z# z2Cg}b=2Twiz~dT?7CfrfK3!A>RY3=4#kX)BVW;#}UyDy${i@DVhetg=BThYFO`Tun zfPEGpWY*47NMGbC_BG4s4p##aO=1;cli$x5QjaId8tCV~dx<)Kg@=1BjH66@JHPyl z1`htxB*{-oU9iu3A<{pe=*-%L8yt?UsG~4e}eyruv zs-|I&jFT?1D@r#mOBcPaf4lU%cc9X~dbLV(3Eky&0ajSP5~cmAcS5s1)MA+_>R~~d zVL9c0JF~D;^)vXktpt~%wQgC|i5;id zh8-GhJC6*}rZJCaQ#-b~a4-G_^_Rgq#Ai*EotUU+9}LH}UJkn6;VhEbTnm|?!s;u# ztV&XwTDrP7*)1@G@j1?XLl%Cahy}3-3^BSNGc91^ya;*!faDcs7@xv_cm#78-E>R~ z*f^g;-jlKlJ|Gao?B-&6gNsui@}839F?N`>!heJWO_<#hOm7A@v*d)*2yV`OBd7>) zz$$_-URkk;UFh#rOXobTcI2?RXo*;Ofb$~sJvYfK+_1`LKYqVqdh-a!BlNuh$zvNf z3hZtxWsCaQY`HDR8X5u{>~0q(Dk7ZW(Dza$5>dx8Q5^l35?|hocd`mH65L>a$51H6 zAW{FN>hNn*P&ZsxufFhcQL&90bI9ulOsQA|jTnl8A+HIUQn3lHF%+MNye4%SC}dM8 zeLxb^qgsv?UWf6WUxDi}2@iJo6vlTk1ui0za_sO6jPG&^TqGnsIN@ZN-<1`($XLtB zNQQpjWzy{se8y5N3VF@LH1m+44@S56v1kzXw5 z2iI?WPIzW+8_?agoMpw7wyTC!x{alKj2$t)UmiuS${mKYOkOS__4>58@y1wgzPr*i z-7;vwnsAC-&q>y*?{?V(f6~~>81=9zY7gl3jcs){J)2wA(f0*==?8`>cVLIr>OwpY>(pjFc6V-&uBgf z+;9b((ZZn{j49Y3MP%cP29mBM;u%yXH>v#To+oVXx?Rb{=ME%YO1LnnjBbAQqZ3Tn z+;(e_iBB6yx{%OfP#N5$@}px;*xYpUl!=cUNII9`XHe$l!TE3y=%}=80(f>piF%HK<&AN5W_&ge{j0XEQw1;$dMsccD&S3k+z$U?l^>b-Q8%oo zNA)`Qa^nCE(UB*L`E{ z?!^g6f{szY8=B2Ui-8lHA(`!A*5B$+V;8Ow zJ8UQUZpZ-?uwbS}J;?o5ZF=ZNmVXL}oMc4L0iUxDp}Y-%K}bNxO>^z#4h)^x4R zaQ?kAqn9A*S50G7)X326nzeKaGq_&9h$u(-n4iW$m{h6HRua}ig&nz@+JSBQ)F-9H zTCffJsrur)3E;!&>*0BL&5cKAZ`!KA#ivNR=)7xq6r%?{>+0=6Geo3c@F3G`Xiw8{ z;46EC&<)yEA%h<6d zX(!ECh3lm0e0;(<5wBh+qI##VtZJIPploci@6+d{)J5B!-azmpJS>2dnkUv^uu z9j=`yOSkJyzs-$%;Qz+RlV+kgTfr0z-6e`5q~o-}8K)=V^&JcO+UTrwyO7ZRqf8gU&sJ;VyU)_|*#}}G6ClC*eV2qO} zdHz>|TcrtPi1KqwdKmk44D?+BOMdr2&41H?!8f2n7a6Bgxv~2WxE%SJ-8Itgfz0qq zJC*UufaRLI7H#O%3tt@W2A;I?cc(*83oHmiW1sAeTgO&6oyjVjM0WV#CoL$AjPT&> z@6P|E)p|Ut!cQ;cbk(p!6Z-K&u z15#FOa&pCgE|pA8Hd0oJ1M-j@BIotBH57yb@5EyAXBc0K|JC-_&olYj@4R z2OT&@jF^+{{L>Y@Fo1aXg>y+dv<4*6SYt;Cs?WHX-$4;5E ztY7u0+R8@dv7g`d-tWqMoJI3Y80+~gU*pko|Jv8PCG3IY6NWVM=J7ySSAphmP&KDZ z4OFMs6*jhKeUl5^Tfj`jt8P24=f;9uK@WruTa3U@K7P9M-CA$cN#$6VmUo5PJx^D!b-!5b zop`)`^b#YA3xo85*{<3o1`CUV(q|9HC)CO@L?omZg#j1k34IxofBs$nE?g~o8 zQ3UQ)@jnQZ*g~T?NJw#6$`zE-lYR`h%EtW1`ZBX!KSqT0Wp=w^jD%0+6ECw!^`u>| z(kDS+hc9IQyDslvuhJPZUwWQKynmuFP*m|xB=k>2WCl^^3r{kBP%U4S-lJNH8%5Ep zS{VUyhSzgg8yT34Nk}TAQnF`~smeq#Cx1{?J5+20#sNsg8E4$(`KTxC*B@UsYc&?FoNBeFBIp~`GGV(ny4Jy0 z+-WdCu)2HuGx*gNwm+(AuwUHP!S)seDE;$*N5pX=sQl_!z$AkK7{A?`r9Byy7XH<^ ztt4`6M!cfmf&l_)(9-=mv4$Fu}gUST! zT(dQy%4u89pSkGj*2AfXAENe4AMp%&?o0Lh^8MZhPBX?Hj8OI}HY>VgVZTcz-?L83 z`DM;Vsn8sew~z`|bjHs)YXZ!g1#mr`Xf9kEp)VP*X|yF7vc`G%VZu{s-K{5lBwW}ar*i^54@Q^!B>#KQ8|&I$aNj(vpl z=a-B#*J73*wb+AH6>5_HyMp;EK9>bujM?xSf#r&5zOL6~K63^tPfqle<<<>c<*yoq z9M&1UuA10~zHa?b7#Hu&T_CIdxkb>svq$}RGa|CBWA3c%J7TiizVS&kR6k2jv_z)L z=clLhPMuy!xhv*(ShQs2nHyy$PydVKG7yRs)uY$A<Bx12wg$v4^_!i($68!O(PlSqH9ny4&+qvR^8--6Ur}!kg5h4FdC%E3h#$ z6k74ebgT4Fjf%Jf0$wMk&?~*r!Xkev`QVi&PFQjd4zqE(+2O)hbNnaUwV0Es19(aX zYe(^WL)ojLbx1|bzWicpO1iKv-;f>|RTdhLW=(yYd#u3V$#d60w-JFo;#LNa{lH3qw4e@;pyV&JVz>QPmVicKs0k4(1*`(-k@3=_A)pN9;I6ii#6li2VG zGC#1DeGvE1H-5;5Pq2uo=pT~E$ix;EkYlY&^>zohn(eK^9|{I*)3b-s*or$;Y6l^S z(#pv)@8uVH!-|Lr?y(iILKB}e6_OB0;wX}ZCcb1UOlp@(R#8q?WwJ_6DkLLlwPG8@ zQ4~85@x)@z_f=2~P1KQLDpL5v&5)?iWc8H59#_#UH1Q3SReBP5FWqX*Hi)a}O|9l1 znrP0%Mnyo~kFEPSoNg0S4No!sJVXSWdE8gwM`)sbzv4RYR#p-lEy1D<+diIRS7_o# zCM!AuZhXbD&_qw~O}4|KeARi>{=CjPR|erB$Ka;_)XTi~a|R56eG+sOP_fhbzH?WN zH2`Uhfxd-($%j4mGQV7P>D=-?-Hm6Z=UiUdzrH_TNKzD%0Is~NE+Aqaue|Log^Gl1 zUhx`rHdG(XI_Os$xBl!JBMK;ev~z&Zc2=r~_7bLmYhnklg*$?IP5!6-_0R#>V-B+P zlNv;h$zIshgT>~)({}~8?PR*Cbl*ei0LLxdx-%z2(tf(u)b2mqQL(Deofuk4T1QD^ zCBwLK>Pxq6G%QI{jN=il!n^Hr^Edi;euu!1p3!T_(|tgL;@8Ue)N&w` zKDhA^V$9j}u^Anh=k3w3(RJUO(C~{k+XUNOc6~z_nJ!=2D7!SW>QXm5yM}5L_3dG( z{B)`2IACHvBN9|AT6lj9-ifv^z2cMc&q=!lns7{5VdLBeMl*i)wniDvhb`?kcr9(6 zwM$Du3g0URf*LF5h!~8<`(}T3(&SFoAY4!L<)`8OoUI6dt#*q8f#&{>tCoHQq`E_I z69v5%twIafwr?IkdWX$Gv%^5OJLB}I_$~fhi+7&}h#QG?!rndTEcp2V@Tm~{=|z56 z)4XgKou*|%o_{{C92h(ybx~!xbQ~$PQozww61QgKkr3@=Z)x zwXz<#D0Li@`y%SI5;(uop+4u=Ec;{B{NDBObUCE-aaT;tT2S-j@-_-C%AW^W^l01C z1FY{<(fUWX(Qjgv_;2o&{!?b5Mj-1WpO7v7J{^wkW1>d{u`qyO1i=J?*^!kr2_=`5 zghDSmcSfgzs$XMmo3ESxi0w0RBhY~EXS}Jpan2187a*|e$2rMBuz(QqC{YQw$=5El z$v5w)6#p}d&LbF8WwV8tn>ShGFNQ*04mAsH^C8|Qt}OBhWQH}ZZxjY1kPPeQo(=El zQjKI`H-)Qaob$u`eC>^2#~Cxg3QJADto{i9P4 zw16e@%6-ZD+Tt3vp0sp-4cS4DgFhejst&u7)HlHS)(+|>;)`6}|1%(H?e$U8_fx4K z<@j8aqg@y1EDuy|%$oHjk?Z_5u77jot#7-4Y~ii%!g`}k+jZU};ABtqOt90(y|_So z;IltW?h{?}T=uttl_xt43zkj(I_`Q8o+xB*6Fm{Fk?#aVX$U@9^%N>&uP46xI%CK5 zEcrnS4Pm&7(1%Ct*vcQUSoBwfbz7*k)#LDb`dhS>QwSJu6aA9+pH+-jR9Tb)ub2JJ zyYJ+A?E|M8VkRJj*+EEUpnzrMTK;JnK*`gWehuSW^65(o6l{j=QUzZM$D5B2u)8=n zhnXxRLQGC%Ufv9rnQTnFKA0Jo%+T;ZJs83@d|txm;*bW0UHPD{qZFcugE*MvD3{yJ zwO@9I5#MsYjdza+{B#Y7@cW|={qA8k zrCjxBn9&8)Kz#>tiu#@#s#o`=u~AoNG9VD=X|#PAeQ1w>>t+!TrTV~n=UCp5sp7c6 zzU-)J6n{3Lm&{{>tp5Btry0#DGy`TE@FJ`AlK}{Vd7n3@zhe*+&&A;}-V{N3|6A7C zTXmw~D$}La)t+JEGp(Vb&e=vuk@hxZzN);QFmE_ODFJXN|IQhQ9BB3n@N%ziLGA}2 z8&_=b(}Mwdk%JC6?CifwWaPtHAQ}I7)ePAo0R*gHGAinNq)yoXPZX{C-QR-v3Xh!^ zyzJ;uF0Wsg2C1RK*`-bG30$9&Sz^2Q+f$ikX{jHefbWkRkrs~~A(2~*cP;~hWZ*F+Q;>#fqHZh|$NOZFY6I()6)tw?wwzs9S(zh)FI z3J9|9@$zPEyuVdH@ac?=ww2SJx>>P$C3Tl9bpP2w8J-<*&3zkeZ6(vFHl735?ya>e zlJnYv%=~;%e`TKwGpu**G|gYTdMjG8`HFpa1~!{{t;{2QYg=C5bzD9Y?3XCDi=t3J z+0=_|J*+iBDu4;j`Mg7|aliQU<~us7fBaB6K_82qyN|6`JDQiLt}u1^fG<8attwo6 zx6e$ROgX*|`BKd8=eFh=m;H6CuR5)l&X_xyIAOz4#C|YRT!)=8SScycH(WnLmpmiT zm$eMM^pD5Sk|xp2)B6Bs3)sP9XON-aFi1rHz9)Se@(r6L6(fv7;WajaKgM%X83l5t z(lGozEF9}I4CjzCTbq-LWYr+S?2=r@~e@xpQeW_vHt$p zg@h|3=YYt_%zrUFfPf_at~s(p&VObA>Of^KFEnNb6g^(PCR|>uHn*?Gt-4xRwsIOH z&Z_NYXxL0aCfnLN5xkIBmY4L~G)f7mm)dKOxZ-t7zp)O?skep92;_=5(2mnGP7m~+ zo{>`TTVkE-Q15SIohOCfEhq$fD#P!FPVbOLb-2~8XY#z(#@;sfY#{p{0@>-MJ>{v4d<;Mjh5drPCPuE!<%9uP+nwYofUaREdB>RV z*v@>EI{EE-Ub**>m@1CvRE#DFI%LM<6IcCY zmcNHo-bmIG8dz-j@jj6}7&yIf(NvRGE+@`6p!o%c3Nz(i{YPnyvnJ8)*|2H4b zh8UI`Z)i*I5n?aB?zCWes4KyR4LIF^KOV)<1B(j-sm8`ik7A+^G_Qngh14hJSvA!#?t{Y;+*C z!Sq}6B)EA2=*@K@J5-#@GR21T z@znDr)^A;?1ofRsGTz%SaH~5%d17zB;t(}iXk)1{txl>uecF>dD(7m2b7a5g)P#y(jDbQpGh7+6JI+opLBRbuW_h`n9XMCYFt@4eR`da$M^K)G-I^Gmd34xxy?`Qi%~V zYIqu{f$S0){cD3bw6>l`$uyuN4SoB5|6+gH!N|zcwz+b=d^ID_{l@q1v|RKuq<*)@ zHr5QgSu%hV7~Pwm+&@~jjhVbfbf$m(3oRE65P!RIP*~wcYh(OeflFZ!+0UHRBcT@iE@v@q@jMS5)xaq}LNGlFv3?ST1Db@6S>5Z^1<~+=LA`zelG%1@0}!jH|)d$|1R&`sBqTm5B#@Jgnxm$>JS6A!lEY85Ci?`^yoB8_qe-Ma?cY9XJeowtlbc>hs(8@+h})dVIF53^(vxhqRG@ z`Iw_w>)5SmjrRGNd-=d#JhO?STz{@$OYctTUGL6^@F!8BDozYiYN1qjzl%d9`iet+ z`-;COgJN?h2DuC@!L!)WUTg><{>FE6rDGwx6f#|C9Ti^moe8YP};7SlldlAitzkgY3Q4s!HF*D`m_kX$` zbx|#&s>q$fNqdkrE@^*N25#dtM`VcyRF)-K!4Csg0-EQ-oS9N#3B|)u$BILgpML7W#FN z@&Kf0zk#ahQK=b8_$e**sKR>&S*NI!r>H^x+&?~e`p>?jX=7C@ObaALC9zFC>xv*! zBij!S4%$m%OR_l=^;An%Wwmlto#NDDNKzI|)^fXuYKTd?QcqTW8A!Og0otJi?LgV0 z_5aLI2&%F8-O>1Ss1?!&5}Ky4O_A$jsKPna*qWUP)ucGp3J3lzC9TH7x8=B($Cku# zCVHivtXdmLNWV3f*zme_u5ThA&9r3Wg1RfY1S|t=iwa+L4WZ@rrB9L7XQiqhfC}hM z_T&#T*hCj!V{_hrkk ziRqU1WbQ^h`oBBhO3RzLC#=5}?e&uw{SYYU8h-hurMn+G;OQ1j{ltYXTCD-O+xGmx zC^VPPJczQGp_1XfWLrrn{5nZ-xRy}9VgPparmOXq{CfEsSL<}9@*uh>G6yyaa|z7f z_eTGBbREW-|yv_oMGWsD2te` zrOEkR$F9=CsqT-dZ6|&8jA1L4FSJ38Go(6EhW5AIj?YLXnSS6a;ehTYxmF|HDbtP-(hkxs42=>aA;o7oP*7rs`WNCDVu!2HfTQd{sL(*5 z?C?~f;W3jjJ_#RAlp&Uq2Ih}Oj7f_SJ5hxOy1cBSxn8~cnJ{06bmOF!%gvR+aQWg{12dj!JRjbabZ`iIhy9X| zB+9Tcc3A>fSv=oas#dx+Oi&>5LdN^O<_>k zJs0$iyc3^I@Tto_U8?H?#8S{Ez0Z>IEWEkB6M=1VhLa#VCkGSr4Su>9aK!TI+t31s zQ#Su{`2EvUI#2K6n)-Hv!SoNLM!wSO^CYk$4Z?Grmkv=Xtwj+FHYqd~FB~HG4b=$U zUS!XZad zY`9(&Mcm;v&yY0NsS(!BSZt(UdXlVq=Mnud8J~XciLjR1(?WZMhnBcEBwJX(Rw*F%EYRm`hdh8E4&bcnO8ye5y=Hs_-_nmVTF2`nPBeg-5RBr)csk#W@l}nD1z*ve;|G|no%e#R4*G<-tD=BASzN7(Llc=4@iTZ=2 zZ(At%jee0nP9#_8N7nO9{^v7y)ElqZZBC!M8;@0rv6N3sj-0S1d&zC+fS1Fu+U~yP zY(p4y)JqJ4V5saHfk>K2vA#>Mxy=<{ODb+GZya8f((!6UuY72gJdmCrW$dz!hVN?{ zd9LNAYvl)h_kvgD7Y$dj7|oBgjcH^CN+1lPJI;;vg1XM`(xj9)t}ckG9_aG76pU>3 z3(-E=O!D znj=C$27j0Gdn#^;BQ%#n>=QO`(~WgN;lUxq*KWZN&PZc(0C{-;8GLXGnQ&a@3g;xd8Xfu{&Mn?3ueoM9K(uf4Z=| z+40{v2;UxXrrX^2>3EKIP8g}Z1texD@}-yL-d_?ng%acFCf-1Ew}6o7}p676(dhYS`y9t+bjE-08?T-NCg)x?HZjs6_%NuZJ4C0Z+ic4qt0*oFDlsk31-Y zZ+Ai&G18ynB;35}n(tKyb-pR5zL7*oEx7N-)r^noIbZgB){dLs=Z==(<-UCBirP`| z3O37zT%1E??SC$&^k@8QrVTA}_I)Ikxc6}ts0OcA2RThbBy#pyFH(oDNTb=v=X?1x zTkP^SaK7KgMd|0*vskDV@4w8p$`V^*pKj>k$Sg)2C);P)r@Wee+-{YXzN=AeA8sn7 zDR~b{Pm*5gS#()tMFg--&q$gJY39l#+dur1@k&p)3r|vVS_vl&>;}t|qzS)LGE`=H zW}6k&0NU74FSc*j&m#$CpT3eX|MX`=G=^6@Y9iU*I7J|{c$8sKgb!R~8XN2sZGi?; zK!bvH^}?iPLYmM28MX#zD|H7Iv6wQ8#l!|hyy`WI2Vvl5Nx|GZTyVVZ81>02D+}D$ z)`lYiZU6(>BW1G3gCdo~pynaCE_EOwCb)Y;aQ9Z64pGroS$Q>}rE*On%`ZpE_B0mY z11o_K%;J=6@BfE2lcQ`a^sj0$_cQP*Ey1UBNCbB(={+d&d5LXWWQjksm=Zg>bLvxNcyHHigY_%}>u2L%FJ zk`27@Uzp793Iy~d76Ynb_~Cnk$^VMA#Il7bL@|*l5`F@x8rEF?Vy;SyNPi3(9{ zB#IBh-w07WG-u9=jSR0Q(e8KdF^b|MQG6Kw6^pr40nBOX88W*!CNqM-y?nJjy4`T$ zz{u87wA$v-wk&@W;GyJucfSi{?LtjO0md7s^XTIuCDdsz{P#l`z-M*E>0mea#o*SY*MK^UFRCXcJp=Gt=64PwLX zy2%T8jesJuNFn2^2O+z2RM^5o`pc`2VxRW{4v)381tXM-Xdj>~W537YQS~n2Q}+hX z#s0=?E{_J<#;DFMX}z{~7-N^^FN{8M5AX)Az4??#s;^d@v-EzhW?b zEdzAi0QINC`0%KLpd?ZeGL`l)Qcp4!X}v@{_IPheAYej+&Y8&klg)-5`8|y%xyo`T zX#=?m?Joj&bipxL_E6-B%5rS=a~1D8B{e3yL9O)CLDefOPK_tlY*}>$?ByWZKn#Ic z0&xHW4&q^b0Xq!{9uQLXB4kCO-$bR~{t#oG%+7tLlXGr9|1`gBUb$(Gxea6tfmi}@ z00Iu;!Fv@Ap$qt)M!Ey@xANVNMqT^6;yG-iAUfB^^u*L z*urG8XH5b7J*Y|66Q6DsPS2K^p0(gkNd-ac^<+MhXwij1@$h z?=(Cd0+b^n@|pn+JN?pqfagEJq~eY?!RJdpdNL~j$!T{s2yBxUVDm@(be%u( z{R`ilR|%}SiKCWRK0Ru1JI+?SzFc!~2bN6dPA}K0t`xH&#&Sc5-QD5kj*5;{&if74 z_M5d?TUaEDXCPSQJUxgJKZqJpy+DJwnGNKWPkh_Q4TF6(L%brimO8d}Dq~`jb zWpdX>HW6wdod$os886@a-D}TWn?LTDb@y`Rx)xwCO}w+tX0%NBEwXl-e|T^TKS6ayxRE-${SS?y*4|xK(1lL87vM6)WU4n zlJ0sJwiX!iW!a>d>0lIL$Zk8ij#d~x~ESUbz@Z*f%QLzj~b z|D$xgR@_kM&3If2xv#Wau#-0v-z8g}6Xqo6T$cA%ZUUBz@v9G#mOoe?U&UX#jLe=O zIAqxxO`h8s2K&ExH5_)uVus_F5UJJD+8u>%V=O3>G9d}GyWhsd?PeniKx}0v6UdhoTc5jZS**Z^eFCSWj zvBviuHB$bbwfB7HVp$y)JP<7Dz07Lqfq<<1Co9)%d(!w7aZ|Bn)T$m`?O>o`imtAv znHAWq*s(?(^CEb7{2ib8_ur-$Xv>`8z<=L*pI-*~YRNlZYNuVwihsl_6}-*Hyr8|x z!;YBnVT3nL-ky^SXWfq5l5EAn=KCMwIJEEuJy?ihkEtF3}#+%lu zNnTWU3;J+F+^q$oOZ9KW);QBTukWv!OJmu}-%V=t45@DLq;)Res9B$Cv=`RR56+XA zlpO`7nKS+X)hqs~3)Jc^2B`edzu_1FZQOx2Iz?fwT-mD8cNe~&<8tL<7s{w z9Q&a8YH*`0Ap1)v*rB0M@yjp^jEmRaG40<0ci0P>-_LX$YezocF&)Y4eC+S-F*T6U z54;5f?=8uTZ8iB3w=H`}?FGL>`Ciu1bI8khK!gANFn{pawfXQt=bJYWwV2zsx3zhP z(-s}#v37^{B$Qju3uR3uIW){>JCO+msV++!xtI-Xupc2}MOAo<%n*3Av|`#8Q-@;d3oBMeu`io*;m4Q#a1x ztyh`ZOtNl+#Y8!el&=X78?Y(smewgsF`ymtg>-m*4%md%yhIfsO}&Ss&Vy^rqF+@iefpR z__egtIGOa0(t|wSk&Vl2ByRP7kdn*yFMpkd?B&$NabPtcM_qprhplyf+BvN^CHUw$ zhn3A>gguTf_8LMc9e3P*yXm>*o%wd1@tc2{t?^JMd%^kMZZ@$+=Sa>mVuIB@iHgqg ziDJjp?}^0s%vT4-d?OyIH0hTy6elaDgs>;o*If(h$Co?rYEMZ&kt9hzKWZ*2B9W9) z+@drhh2#50W9yDT#5O&Q(fM@qK*!Ih&kh9%|9-k<*XwSs6FCllO7r_oH4?~cpgqkn1AL2hdP``~8F zhyG>lWsy~pUL&WXNtaq3eJQ8Uxo^P7?G~N2awg2jF7!fkP@cOOm!D$F-6v+Be_s)P zV_?yL{k2xmhJ-S|{w&B2gK*xcL|VEn68`#25sJ zQb&yN9Oc3Vg8pc8Wy&i)+D%fSt1o+L*<_XCE1q@o*piCdCnqAcJtHPn`qhh}RkN2v z$Ir((_KWMf5My%RzVs)u%rzETOL8}VlIU(ulH|@vlIRX$W!YX+7{|m{ZKZsu z+N$lS+B#pM+Uf(gyI>2OO?2n993t<2pnLM1NB3lwMfU{bDYs90RI0SP!jLmXk~`v& zYAYh@>%kTa)3%tsYO5=OYHP1(;fg%iO53TnHcxx}qSigx{Cc5u7Lke|f69IPoRItW zA=t8$ayJ*UY&S)#wyJ=}#A8%jZ9y$ca2$uFdm=*0?ekx;3~3I_Hp6FbZJcV=*7kpU z;VYJE)J<|9f12b@i&MBlu2i_fhg-NpdPVnNTDk zTIL~AI8$A!S|&e}s5?-hT9#p_T81c7EffEuTE+>^Q-UokPT|Zxi>`w};oNU|rlP7Z zGg)^J3TKRxjL9LPsqmVR)VBJFRCrxX>XN|=_1prMqOtizT}UZQk)deejD~*UOuoHp znQ)>pIe1&+FR1IdVVkI1!rI7z#^b(zjmdrOM9S@z7?Qfg#!}=>o~Ro+?Q!;UWcnaB z=a2c`i+p2>fJh+C_&#Hx450aY>RJuFEgqMjrJ|+G|H@++i^}&u#XwvNZ0_chiBD3Q z6Cva!p#g^wIDFyS-0uLoVM3St)dC?8gWujW(&2XsNSv5EIj#tr+6DeqSwkV&8&|v5 zn-WVg740tNWb~eK-T{rlSfcALkWU*<3|$Wh{}B5#Vqb32>KLw(E)oO^4gH$I!NHK63(xp~o9WL3yhhH3P;$=d$< z)b~kElSnmN!o<>T1z*qYurT6fOy8zhOS=R4@VEy)#m)f;SjpGJ7htXWAH;mzf0w5k z)t@*3HNz__>)U2X|%@WeMwq20M!OK z<%!@>oRWC4^c%t&c}O7IO^uv9W%T?!+8RJ&w*(wO_D~WCq;mh5>8pA#x;y#*xOi@Mq?49(& zR2v#Uu<-oAElM@ug-@G#jRU&hr zZ@Es~@#^zHm4cmN$Fh$9;imk{;hd$ZA@MFssK2Cnj~oeDp29stm2)knZ+g02)wT!K z$EYHf5q$BHbUXrAP=5Y$daSiwaJNciYAgj%|;*N0)smttrvsrD#GoJ&iWGNuEAC#L;w+RO$DK2pyYWlUEOW4yCu8$WlsYMo|dPH4_X+^~|| zS@b$RKV`Ky*9N8LZUoS4pH{KUWsg%mWolYqJIEi%G!HS1{7}^ZCu&bQsyOf473}q{ zQ}2gYj_tQfSCz9Q+mNVzvb3#G_dbO|aaNVO(nKp^dq8(gM ztRUU}L9TTQvR~V{PiTagGiWHE`v-hU{8_0A+G=4PB_rti38@R<9Hhma3=y``BIwRf zpd2wfih&3RcOO`{^+kB7S6-fyE+D<_@zMcx<~fAriyG zqj5-|OZmt7jL>5t8`+TZho!aC-c(vhrOKn&hWySI?31D5iN>MsVC|0%lXTY!VmDf} zN4hS@QTl}I0U5@om#cx!y`Tr@Hghw<@c9951?n6B*2SYKYSk^ux1sQ#DCJwYiqXV^ z^1FCTST6`}3GaY99^yZ%dXa>#;?W()A0!9?Hn>hUkVPNrZUwG zHLb&{c1#kp`@X!R-+Sh9nurXUoiFSj{&`$J+w?bf_ckG@m_W`p3Uol@aQfV9xaz&( zjedj&(Smt1d>k7H3d0XKje576MCHV0Wi3F%;aG1l%Z7MLEwLfQpsiCBhw_S96bH4f zBE1z<5ROixHi=KAmLOg6-alU6(^k49Ra&~_IYPRGgNjNmE8NT`J=m-wC)}(eD%k9# zmm;zJ5Hqoy5*WT6FK9sN`EE+`3_==;j2{3!2`q|)!W&n2q0)fsOBToYK$&quN1nk)Ns)nM8843m zOy^?*AZJ{lcoNI?2@~n5rlG!5sUfK7WBsPg5WPm(mf~;|7UkeVkil_+lP(znypHD& zQWNF~*(bZUJXuO|Lva)YBgg zAz?9)e)XrkJKYyPX0Kh^x)If)uQ+17aP#kyC55ZQZQnLG5hM}=QeV5Xp|tX*fd1Hj;Jl4*Di>tB zyeDu!+z7he{TgzQbWdFCdK4%`_u-S*j{k0c3=T=K;+9R5Xhf9fNZZ;n2LLc_Nv-*3~ zZW$Tn+q8iqNE_+vs1PbosER%57)0TM;25)+4J1$hN4~OUFki**68;J8hWH{5>5}TA84qU5wN-JXU zboV_fy~D*^-`9m{%}5%5j;)J!tt<)QCQIteVzGJId|N2iT2W%>{JyMi`|&Yh;%WYg zb7OX|tUb}M$tkV#G*|1XWn9iBIc5Z$y6O?oRMTRv$=a>KXw$d0C^rXI&hsZ)bM#WG z5lZ*cb+8Ziobd}oyJ;+)XH7b@P_MQBKGz173-TM-vN{85^xn>B&Q^YVx_MdAb2R;z zH)}nsPj3vOYSuo>8hFYz+g;?m#pj)=^sD5#pl$m+rD{TuX{ijk0rLLucoo$@3j%iO zmNev_ZI>O75`usKH1{_A^ns#L=iJ+@4Lc!&`eAKWBa+xY^=X)|9HdOJB(XQ_14ax$&c(K3XXD*0W%Rggv*aJSG zW!n9mNR;%pPaaMGsakbI!OKz=hwaX;@VVVvw&abyVWmFS44l`<5B_UzJ+Rwv*H!(Q z94&h}_>M3Me0+9{qF($dn`oY^(hP;Rwiuq)gF1 zHsgN~kl#Zg(?KCiLm^v1A%{aDmq8(qK_UNvLVh2Bmj}o65#GQbx6U8m2GOPu#<`68 z4>a=oK)k&7Odk=M@(`ImA~EGf@^J<-)y1iAga^caJVVwUHZ06V_yddlJ{T|W1Jg$g z1Aoane`ybBhJF~19r!;*jo2b|+QRhO!VD9M@XHK2A92mcN$oH$G9s>n^YF~arRD9Z z=p?_I7%8V#rK+T&q$#JGjnm0>$kNIEuoH<>%M5<-ic{Ov0HO??+~)}Z z5pyC@f@304FnwLR3t<9N2{3K|mqd7K0-VV~Fqa_(oFIK~K8|RIp~R0dkw^l-enK=KmnATli4Jbqr~c;! z_Cz9&9R_6Hi$SNBv0yhmVeQo+kzH^hOO@r7^^rjuAHQe-KzV^DGJkCd}K1WN{LS(@KJsyx&Dm6XPNZ$NU zJtc2Xc!H2%9#flkevnYFzxPWo@P|9C63p0h=4G(sr289WIQ7k>-zT@l&hLAAjnOyn z)UPM`E*|Z;y7b*8HP=PoopA~~i)}!(?K%&HxKihVe;;d&gWwQb`aYv@_?szL@zaDMQ%94cUQ~wRR~tWzw z>o_pEMKqG}Zs z5Xj9>p~*IZo2Z{l4fLXQ16VASyzQmI^c%kyn%j)qJ6#7Y^>-!h46BId1+`Rc&YDomg-7dKf8E{N{k$5IcyD@1RX1hw7>Sb0U?qdu!^MexghD3dl1H@pw zt*4K}e7JOCzK}lk=dlC*TtgxAoYXIM3ntX24;32Pci?k(ji!Z)FR447c}5nbY;~TP z$(xW?l(+t|3*Z|OGU)ub|0_{~Q~qepZ5#YPv9NX=t!or5aWt)~?fchwq0>!-AFvPo z76H`U%tFxqtB!Q9T_~}V1?b*#rh9YKI7^cSSw8T zlPkN)XTenL88Vf{esL;`?JYRkrcx%!oy+Iz8P4YetA?FCQUNbtl8QZk_=PK5KJ`&r zZ1vFsw1q1)fUm?=A7#W*A4LQxD}7n4Cvt@;a@ZuJ;6HxW#gV5h)|6L$6r`<8@=$cN z?eFMWOaj2Ud!hY$zi{Qw2Y6AL$G0gv-OroPXHX;N=3^k@_L=}7FCkUznFA=NfHgJd zvREa+yR;K!l8aqs5~Uen@Kin@DKMc+O~ftBUc{|SR>X~eKJdh&CGdo2EbwHxX!|-c z6Mn&oM*v|I@Q4J!DFtx60UTu4wyxP6z*uBXkeaw#mmJ^{X4r{GGulFZjF?+iF`yCw zASVJ(9*F>7?0~2wMBMBe^7st$^7znN^Y|21fKY+}_)h?QlrvB=ztUYMKa*?tVya1 zR{Qe9JSOXvmab!;?eA)yAs6hez?-4g`StGnml|fSZBJRda&pqLp;W@%2(YtQE0Lej zrJ}ZZdxj3_nP6XMzBWi#qCQs6WcygTs<$X#o2;@xJ8n+7>Ou8PZdu6$k*Lx#D6ECm zcrC3i_jR!f^r~*LwR5+BYbZ|9q!Z_z7?VfV1$I}0;29bMg^rO05L|Zjb_hh~!Ls~j z6J|hGwW-5J?LAS%;z?#9A~NDUVJHIT{fxNxuR=s)5@?gX6K=#cE2huwyA)gkDYPA= zUF2MAo}#X6mqGJB2WTp3nqhSjDJGL5X^2se>bBL>SGEbGq5%Th=f2iDm(q*{PGAT`+TFzqSpLqoj z?$ADk*U~e}p4(v9K0byxt9L0 zQt$+&y4b;0NAQGcQ}~2w1Hg-mAFzvy9?WQpA0&)yUmLjrcql;=dtKoZg`5Dj#YhQb z1Zb9pQcg2t9Fj8j?y>vkbX!Z?6a))%PAcS~68|Z86AbMI@`gNc_=06d9(kN=N0rLn zPYe0KMqxhnmKVw~BCmsAkD1SHiHC_w*$x6hLg)5x7nKjKOCT1dH()!r^pPET|I^yH ztGJakG|-ozvG+h}6boHl$3U{2UlRR8W^8=iO?yhY1g-Y2{v+TN_Vx9cMC&*^eKHbeiGPPOCNb*|)vk>4-fY&T z&B$h4V#`StbTrYgd)#@FEsG9`7%%LgP2b(!OPnNzJnTUHHi@r6n>-`@i~J+8klA~P zlHl3JRc>#bJJi#W`yFC zUorb`9`5(fHz3wWpo0kr10MLddDMXE1Oyjisb}#$+mY)fwZGx6f$YJ_J`%`r;5&b; zLG4-!Hs~CHT&Gp=BoDTS%y#zoormUZ!k4< z-+JEkMr8=H+#BD^^^tj}^!;7wP^6u9%&xgz?5?X7MwG4kmhXC+5Boa>3CYMiV2!{m}<@do`y+#MY<@4d=-+>Q+>yb-p^s7po0NXXJ9~)&v^fL|qx?_Uun9 z3G1pq{z}_3DtxDEO{MvgxF***7_Tc2G;1ih_FUCcV)oqs8s6spmY@(_CFb@wqaBRj z)MD58+ns}jdC_V7XcHdel=(mhx9-xaZ(t7^IWBy4t_=%~6sLLLNyRl@N;0i!%(PHW zV}E9bn&JBK49SLnBx1hlNWS!sP!udqNJM5(>&yT zTPcK*8PW0qa&QEx!~yq3G4tC)fgx(s21ga}rSG{mk0+MSK>F1$-zW^XUfOg(E}+dp z9>XO+OR^rZOT>kvsI5m*c1^Cf%nbAh*?7@Rbd1P}Gj*0Gc=%K6G5c<0HM{oM_HI3` zc~U+K7`zkFD28?Z)rVT$+c&vTIKEjA3O)2U^f9i0kkbMPM*C-*@w+w$mn7SF$V;fWH6%=WLfUNzMmvIR#ZHt~mUgARA&_~q61_`M?z2!6q|iN%Y7g6` zYiYY}9~*euu?C^dP>7(%*?&TC6oekWGYq6p3HK{}drCXJQDUb}r!7tudp+8`69WEy z`o7f`3_+q|PY2*WgBE(?pD_?a-}%L0r;i{Z-TT3);XUbxu(U1Y75~jL?l@UVdObnY z{Tnr<5myJL-MSyVVZ^Qd2;)jYV+h0KgK=2j6M^*v`|`Z??X?u2mWGBp^&Pwi6xjFt z3^<+0)(}$5c9omHdzHJO8;dOAd5fNn4)Ml04q?u<7CCj0)o#vV6314DDB#geR;?zX4J!1^j2Sp&(&MKn_5suypx+wg;Im9f#NboZe zw+NkgK&F*MBcr*BI*oV>>X3$2g)pMIeq)h9<)e_?aE&jxTQRv+vX_ruYt{KlI`*_) zfa-hniId5_{Ik!Zy~WTy{p#4Vdxi>QsIBObWgC(i*2iVNjSnr&A>3)&5c6 z)H24S&XD3R(!chONqhP?@O^-RCQvRsT#5i;c!MJvf$)6?qtjW;`7pc`sFmFGj|%YI1B)xQ@ci z{V>{nu-biaT~K&N&_tIoKK}60eaMb5xOFhBeaPBDBG8dbI5GF{whWZ?CHAowyM3};deJG$IDt>S%8S(Zy3PFeI7ifT$e?O$a3ontv6vpOlM z-(%uQFgvNKgE6(t(|VQKUwub>og|W$l@K9H9HXhKv1hP*5b(o2~e9I z-(lCqhB$mWs@tAzMK?UWg8XGGxd1=w45^}*Y`yf_CLD7SfEO;Bz>@CP!mpa&j2;M8 z)wd2-KW@~jx{g|}8d>yW&t0OjOX{)>x@b6;rDu}ceFORvRAWmJAB1a_j|+2AtSEmER#`laVI``c80b{Wyc`RJRx?DTu~=JDQ)Ppplp-%Z~o8I;DQ z`mK+dy&je;Jn^Jwc;&^Ww%a6s`nF;I?OAT4n4tE+>O)$U9+JZ@zXNWZ+@@3AC9N;S zQgx;~}Gu@QtDq zDFQiVBhidV@cW3UB~I(mP_|YTi$55zeV3V#2N3 zJH)f^qAxkg9~2?BZ0fA9`7W9}^=of0>P`wdQ-T^n+R-KgI=Kwqxdqo}YObAz344@X z1c%bP_=`#?My=jR0o7J-!RJ3Ab@PG@%UOvki#L$B>t5ftTlYoC;4bEFV)WJhQ}3r- zp(4Lg+EgiUSZ&-^_gik)*=sHTli`)?-z)k0XQi7~xSHx*wvh_Cx0ywgLo=~S5$|u+ zBdkp=i?z+o$JsVOf)h@r_e;O#!z));m>O-R)VW^I+f&IR+8XU8i3<#B4kN|m5jPjR zhr+{dJ3Ke)W{KeE+#QxoJ>(1*Uj%g^Kggd)D_iheA=;+j$y!jyK?{7h*>QG*&RA80mduSY%fED`MiiT4 zbaqT}C{nLSs-y?4rs-etlUm6aJ$cCRG`Bvu*E2fUymaUn#yL~F-fpl*-r(%D{g%Pt(2Bnh>d+5XIdAjh*~yF&wX+ROba(8HO&^9R!ousQ;G*oB(* zLj2F41i+ugcY5bh`%dk(KY+1a$GjgA(_T()+SVVa1rXGCoVQ+XiGPQ{J#l%V(TN4V zl0AF+f2JC%)p2USpd`ZFhhxOtHwOe=IEdHkM3`n|0AI|Hxi1ZixlhlJY32aX9e{s+ zM>W=ViWMIT_f={dx?Vb-@v3dTb-^EQWh!*iH>_GZo`47lPkb7BN;*F6E3jy-r~o2> z=Kf7OUP>Df;KjjtMnWTA+mIq&I|8swq=?R1u$X4+8c3v2h#ZpI{a7DG?tzUhjI!$A z2KkP(f=_323q4j^im$Bf#`3bqzk3m`gg^st=ZB!I+-yh+ErhWL1Qy<5pBhVGaoEu^ zo5tOIeuV2~ru*IU&4qEWv_`=$m!-mHImdmjh4RTV=t?N@*yzTlcg^V#(qD0E|T ztL3a5!a8Vh)p6!>^cL#d&9Zi{ujlaCFeAN|Ce_p6cXw?aFoGQt)si(&dD0pR+cFr` zut3>?+H!I0P$rcT(qf9rxnOEj0X%)=*zrC!T0?JF3&FZ5zHDEUdQW>Kd2{1s+XE3CUgE*q;vN(gM{SnS41q&jZi?ky?AQv7EmF{cV2p`X1-CGp4gP z+-*BA_vQYww|a}&%AtCPb=q62jl+}$#C2u9(_2V$*(()`2mXWGZ+LUUsOMnW^7i$} zb4T({u!U&JyVCQB{~LGQcXfxeO4G^dnrhrC^2TRO1-G$@dW|1G($!2hJ~%tv`3#`& z+L|@0c_X|V#h<5vNvXe<)M=5MW0@Oxb;I5_x0bA&bfr}^Oq$ra9ieHSn!C0vaJ#D# zp*S^jp*U20M*7(*uyme!GTT7E)%GmY95Kk;Gk%aMI;TeKxfIkc+L-;tvlUe{|7k*_ zi{&nI)#T8w=OE8vL32-QRp+#|?3-7wneCcm`N^i>ufrTj{`L;G#m$&LMU&8l@oAl} zxW#DJ{Z$TQhq+*Hxn|eWEpEnopxo7F2@AJxqTN-G@sz_e>N0+ zfIrdsGi?$o1GaOsR#yaR6SWMzKeN}qzQYR zL8h>~VqMP`p`o8*(Yv2R2@hAca8r}YL%+PN4sge)dmGwWo!%U(=U-ru2~xNO|8|gr z6?FFC4gkHO_kfg5EO>5W*uQU( z0o-eEz^3&Q!42v|+MD+KrKG*C5+md|@|nH51oU(T+(ELEo2C(UH5J*JPZekaDTqBhFHEj1u$4*V_cv_nfJE zJ0#~{v^2|g+Go|CSm>5<0(rmi4C8666^}B#Z9tX0{2mZ!b-g$@qx>NxqlbB@l#_R~{iBTfJRp#f-F8b~ z;AugMXvE9E2DuPui2gN`8R!MTZs{jD%4Yv|9HO21Gf-(3I1LuYt zeYtMM{IdYU5(4fznYLqqQ9r7xoE~{Kp2Rx&=TTz2!NYVlc)Qq)0aKTs7%-nlqYvwO zEx4gGP2XKF6E}wVPqAlS0v!$jAp+ZMSYLlo3q~PR~iYaVJu&B9ak}{j;7Ee${TIm?cpS zkE^QFaQ^}@MB$iM9@=#{KpwVj_jmGW*GkeYaS5Ewc$2?pBdzDp%qbi;hwrqSb<}fk zhf_7XD$<53D$>)3D$=0Jf_MXKG4gH+3Gz2pKrSv!er7C2 zE5E_D_UxOAa*{P_NE0iP4M%r=yuB6Rjt1b?U|~Edd0xDIA26OKFCH8OcqJ-K z?)xwP3BYa~Fz@(7$ZaNF*?3d9C?9ZtZU(7}bT1H2x0D2V_P?+tCCCM4Lq)x6B1Kn? z#K_-j05{>{M4!!}LtME@LvB3)iVQ4=&TtA%l|RZHBhqoMGT;tw$n6o}UMvHWbyXh9 z919TTXYAQ79q{L2Htj^LwAQQhiA25H*q5W z#Q$|`wp_06y7&H>>|W1McK>gC&p~8k!^Ej?)sxT^F;SZK;Y}~=(WzxEM63P~R63AL z(ThI%4O+PN`ECE@KCnu`7P*JJ%e_7JI(JSC2C|iJbpEDaYXPdGS6I2x^zNIzhwVuVdLk;#Kv=> z{TB--hEZaYyh@HooZ^YiU$~>g3OJ)lqiLF3FPfc%VlPfyJxYtb+~uRZ(_;P$vwF0SEdLtRIf;+e(qL~&CCsQJ!d{~Ja55| z3R6QE7CW}Hu03=lG1HQJ=m9wjczJyd@~&pZ%ENw&q0CVwe^<~+w1NR67$pBph}peYxZJu z-u5dm0tqQz3du;Qcu$Ys%n7qVpx4P}&-xbW*I@$qXtp}G39A}50&64VrhpI(1YAiH zZG2B7oHURC(8IIqWve51w_gJMCHrG6}$pr z7;<9WX7hm|33AK?-Ty|hY2y#iCnm^?6_|Zelau^}8k4A^z)Z06sYynXyV)#w?l(2T z!6#S5|D~$zNJ#RdDkQ1^8!JzM7iw}JgvCmJjiw3grQDOwEj7Ta=5)g?Hn%lvBORnb{)k6>_F}H#9#P`Db!~5}rn1cX7 zFvJ`RtythbVv0Fz03U_1#2l&tDYlq{2EgICX#0(<;{bo;9Cx9$>%)^u|Y2yudw zu(kMP7UR?)s3*N%2t-)X^^ rp~f@s>k~!%Qw9j{2=ELnUUnk%U9T2aL@hoh56I# z3qev+OnLDQ0eTJO&|T>b0ptzVl8At?u#iIZ@qh27Y*Ee)3w5Ak)p(-f)V5|;fxps9 zcd7V>d+m8er@EiR-yP2UTCMh-nt!#^sy0#xm|z-TB5qJDPob&QF=sa{qgcnRysq$X z-VwyAIQ<^Uwd@W@YmxG&XbQuoqH$PfbW=0Cnx_7K@vBYtgTd^wx#>cO%U+WgLHGRg zAzO8S{JqVfBYL$;sm_TDDHm5-Dyit+30^ZziVc!N4NruEl0LQ`y1|FcGyacl-yS9H zdYpsu4zIq{H~5waI`Vhn3r7B3c8Z*yu}zCG3)ZVG;No8F@K;z3mvaMp@Cn?@)j zX|aqTaVdbC#<941QUC`o-3n5){+77>obf5Qh$zrOyX}yB8$sk^Q{?7hg$0g>&o)3I zt}?(9G{<+~Tkw6;TiJW(1;^(1vz$rVx5QPq9EHCvK20{#>vZ39xy1fpv`eGJav_l$ zSesZ$*M0DEtHwR#l|`NOlt6YruL*UCT=FusE57%1sabvq7YQHB`gp%Ks~S#BN`4(x z`Ti}aYY4jBG9;kJZMaP2CAh4s(xeG2Bzmjl)`Z{MZS(Vday9<7`Q*2|bCYpDw@enE`Rj1msT=cth?!~v`6;az;S;18!+EF&SFh)#H6ku(n-f!3gStD5f` zY@ltLSRrri^t!f2T+ns{AN!PsoOW&@4cf%gkSAG1(rra*a+|n<{bNQdW=4L=elGSL z3?8y|`- z?if!ovGZhNuTQtwOKtuX@(wb1?A_++{>RK>67miiRVH3?@!n6^!b6Q?b6fG2lJRkrX7cU~XVQBWjMY zMyE=PeZ#ypl<<2GP~&uA;>oj1!nR?a7Ebs*9uQPY$h#vdvu{w#4Y{V#0a!mNN;)5r z0sCP&L3sTdm`S0>EZlH<)QC%tDfY)YQY>p{Uqv@S;(B1z zCXMxAoL|2JVsBDaaWQQo>%z0KkG>DW6Pt>e@w>DrYwrfa;$<}Ikkbd2u#3p%yz<{9 zUU~O^D<<)s z{X>wEcPEHE*a>e1V*mILnx>?)Eh7CqFvYPi2>5xJ16X=o0I&-C2K*J00lo~tf&jVfL^4bVQ#J#dyejl^rG)hI{a{G8ykC^Q_Rxk2 zItz-x+LJxyBprg>J?sN{#$GRLPaxiF2w{lOWg>E%HE?RIiS=acmKbj}c7 zRSXB49Ktmk>kAP>@#)h<(mU-+{Fk+g`-eu&({o#wTYEFN*ClaX)ccO+5rp1L#Z@O; zg}e0X#d_O!mZzVAyHZC{+%~^VG)}e;V^|jtwm+5IW{w#wz&;1IKrwm$J9n6L`oK!hl9n;Tavy|7i)I8rasE2H`F$p;qFum@u z@ebS7@lqS3klk|%khhwCoccPo)l6r8N$HWAWyZ*;O!m_a)u9NR)_fcmNd=40m<#{N zG|#hb!^D}=F0lWuoU=+;rU5z8ukJ7<=s`v@VeQ|?8x{Mm(EvrX{V(}TN!x4PU(?Gq zKZR8P*aV9yY<@y+?-0@CaS$4@ky3GyeH$Xe~7Bz&K zo8j8&)N1BjgxMyN_cW8~N9_QXK)J-OF<+k7LO3H(R||TBPR;R@A&=M`$zC76sZc)S zSD`#Rp>oN4{)uGk+nYYvJb40%>3*y{yxy6SyZH*;zYUTud;GYmyJk! zgQ`e-qLE1Zbz-1%NNb*6J+QgxL7dD8q<~%W(`lLTCNlylU^TbEPFX}5_2&D7iHlp} zF3gFPi$A;`w8@OR$Gjf&$&8b3bXva{>9hnJ^7Ni`0N9^_&gR*`s{;ODf*$Q)LX~79 zMW1*gg`O{&u@V3s1SWiEpwpUVrqj}-r_&16QLg!^saym1Rk_B9l-@%ynQ`ZqnEzul zH+$T?fm!R%$iHB71)Kjbqe>UEPbjqlp?7ZpIgUZ+Zj*K#l7xvhq7e_S-Gr{AmOk2` z9OoG(zQDoMiro6u16I3zRU3&xVpo)wXZK1OxIzDYO1ATK%KHaW)q2_sl#2=Ms_wcftXgk|U69e;0aL9G@PobOQ}wslMDy6nuIm`XqT0j7M0V2cf%UeW ziNowDV|!APpPQ>o8ROIEL%3CL)JR42r|~J%>OXvn_7#1oXEB>){}_KbWtsBb|lihN1kNyj-U&}Tk#@r5@#Q3Kn)GX zDE^)FZGJq6F8F(u+@x~36Dn*tC-)WSPkjnUEHo{)b2$(h7<%w^YhBR!CJ)X>dJ_};~U z`9Xj~@0s@Y9ZQINb4A=8kiOFu+u2THh4B7;Op@tpJK~xupOLOCUdLSI?~(Tdgp}_~ zqqi@b%9%ze$Z8ZW6DgWf=-jo6Qv<&RewlQQNci|+4XzV7$nFsj(G<3MKd~Mf@7;~0 z+Si{%F~)2Tu53}Bh1mqr1g<9R7XBLeQ1!Qrmc}^mgjq&Ven{hUTFFl$Lq%Hu^#7P) z@IDOC&){?RF`)R{MH3hSqj*M8zO&(TddQ5V_shOBeTR!{`c69pIzEma7DY7(p)Va; z(-=z0pB=Vp0E!ga^j$vY2uc>4q%vY9n}1lJ_W!g2a+$ys{&yotbx5!tXwf(T@a0E* z#>XH1+Wqvnrttr?NdIYZ|I@PJGxlM?>TlJY(MHX5+edh_GX+PHxz9IcFN<(a&J9B?08_XN(MT zS{q~D$+4gKX$Y6^b^ zH3Yv3iHn1U#6`hdn&MzcaOJ6SDA}E6`s$-up0@{2KCC*X4W;c^~AsyLCFwYRCKdo0nbSv}nw@x>L@0 z>8No>Lq}#uDrsd?NHgVpf5>e7t;IEkA}rI~uU_$lY+i~qUQ>qf&k4O0>a$8@$5*M? z#fy{z(8<_HTQ+%4&*v{xAoQzC!Y@qjs8@f(mNC|jFyneMNSaMxuJ%8#q^D5F+^^Hc zv1b%(A4xdtX_L{PoBXhIen^&oF*R#6B^iGevGjahnVbzC4qEZh{kEI%r5^E=Yd0dZ zVYf?c2zJXP36mRZ+B;DpLQkIGJ|_#eO+|K6fV{MmDRH*-BA&CRR7Op+D!G(2CV`{0 zmr7~!oJoO(%P+mjK21nMduhesEajk$Q5HaqZEqGM6V~P-v~*9qZNtG4j@eEsv(R$puA=$MT`0 zmfPpf4&-s-p4IJsy!woZ8RMZi4mCcKeyNJ{x(Nz2Oe*E)CG8e9DDH zCjYmlldgnQd^r6VGJ{n=X~MCOqg@&KkS!e<;jX=h^3Mb7h-M!38rK)!-U^Qt2BBY_ zdD~cMhh0jdb?#+is0;{MQDk!&alMrRp+SRU=rR2gVug=QcE4;Ck$?9q=kFkK=&|Wt zWkL_)EGy%LqJ=Wn0g`VafIdW&IpT;~?(0k$$ z;@g9_AoNo`9&_8N;H24gOuL1r9ObgmGEeb*r>tIij2d<2y0rtvs#h1rmXN{F2fsL{ z^5G{YJ&q|E%Cwkv>$g7^C~ZDvrj-||w|k?I`30QskIOzXIHj<$URXVA#4@0r$V zRzr+-S&oL_+P@%HB*TNC~@iPzT7U+8mbT9XZk+pCk6 zUQF_L*L;4g@2>4M^nx7@Pu9KK-cOt815bpcX(O}lAX0x>APY5@s1 zS_U5S51^lW170j-U@VB{;c+)(hK#29{(d(RjXS&D-(Sn0hr<`AnBN}JzjT`}tFD;6 zl#RPD#`)>}vfLuH-*|41g{*S*U%I_cw+!|KRfWyr;@gv;aO|_TQwa<(SNn?Aba-;Jd^!`#-IosW;UM4sdVKb1O0+4 z)i>~Ze{;9<#)+RD_0svOedVZSF2h-`_tNUlS!;4ES-0Jtk5kF@YvPq=?Tjh5;sl4s z!+Q-MxW@k0N%ySW{5TOq&fpvOU!URBzf{3-xS<3XY8>&s&GxT82_3cL^*FY?>%Qh% zGCy-ztl3*~+At8b;zD^H7w{-eNx9D<>dGF}QZ!Le6 z(AMx*!|Xm%|L~Ii043mGL4h%{i6q*g9@E_c7 zFqj<@ME;_X9lwcPXtvu~M5{g+$FeN)?R?G(v^7(xa5lRO`DtkRc}(FMB5`4OTz`q< zFVJ|}Q25$V1lmx9+E7H=P{i6$B-&7<+E8TLP#?9S$hDz>Bsj|Ew0ePe{)wwWK+Suf zj27a1;bR79XnK9>kHWe0zbRh{(i? zUbW8D71RqVNKCw#RqFy>K}gwn0#4Mf>Os7?EexV*X!;41m?0H%*o9)uPE1DK%}Vm5 zueBUGjJhWRkS&l1Ninq?KO1#l1R(E;Yx1r3xwEea?=zq{Nw_9_<9**UBua{#9uTIQ zBQM*>t}LI1r@upqdDy_DP?~VY4Xs`&5^kL2L z8Ze-5zq!cV>^S-sQfV-nRCNn^Q{HkKp!RKr?lU_H4Xs_Qma0D8%;y5j(OI?P+gW6t z^gBYf;~M<((`Ebu1F1TVHPVq!Z*hybUSoZI=VqNFxHl2(WJOHLUEv>RrBYlyza1Vi zeXW+U?|uG#+IA0Z0-V01a+Sa@p|3+$(EsoMX7{9MYzfck9JwTOx35huazFiaau8N^ z855@S;*FXRaOROc84I<(eV1XT*;^=fU8|3WB;-@N={Pqad->aYKSvG|TyJFz?+{3z z!Gu989kRvo&FfvJb#h^BuTjQ;?z>$p z-@l;n8F2F^EAd8Qbpgr-rZ8C#0M@!YzvS`I%haTA6~0z=Le>+SyjT!GEIGn!4S_BGaf=VOGS7U-oZ z0@JN>J93aieTjVGMnXlgPvVo^DX;VoH#56F4y^zD$^V-mg5x8F1tpQi8C#ZA`l_+#gO4(n%>@_TK*QH;8r zdG?SEy!4rgZ4oZ3UanuXPds|&cb*eo%Wd6om1(ZNZTWB}#&x<2DAay}ZE}q=Kl97G zL>NpwkXO|uTkY!1E?Za;^fHtyMznAvXvTA|`Bz}vn^xi`3+m1tY!g>ZvAQv_9y2Nh z;o9hur*&yjCtT31;QC7SAEHYZM+)_GzYrc8p-*AA9vX<8a3q-XeM9)~?adaO=_koh z;@l%Pm-uCYe{TizjRy9y$;>0Uw?T_0XmM~%Wx z4~plc1qjd$A^+{o(F+h@)0-+22Yfso<1v1Qdia!|$qIE@_}$&cT>~Fo#6rOB+t!bI z**~8dnFg`X?sJVN3v?%QnCmTXtI#1@t^vyTPjPr#s;Zkq8xL!&@U1P=N6CE&zj z4bX2G6J}pX{;J57FyQMe215cvNT%ZouLdBJHUcMr6J#nF{9guoqUQz5+2BR~*tnDN+o@2{u7;bi;- zm8-0&0LJB$zj``aHaUZfgH_hbYtUvnZ7|%;(s|Y$u@En2P99|{y+%BJ=ndJXIO$k= ze@QS0{EjNg6pWMDR2HayX<$*6L2v|-V=4`XUj8t%zOV~O+Jgi`?0vNgOy#rPSEKM0-&a*7*GfbqO zC?$atp(fH3sQTqT{37m8$~6-tztA}(&>z;hi;s(QU|?>2{Wf^q_u&TVm_z0gH$3DFews!>`t{ z!@k>nZFS6OyP@xO589Y-I{I(R9z#fH4{1o;512>{yl6?_BSH;#DeAVFZh$e&zg;}q z^F+O24aT_hH~3{D^yWh|u&%j{aN%^>72wHN;*cz`-|X+~DvibW_>T6^r{lo^Urh-4 zr4PURej+f`i^*Tz%j~v*^P9Emy@j5cH1p$k0x2@{sHxH6+*ZH7XyS`{(j{MFk~y<< zfriJ>n&K3u-=oa2e^%svjlejzFKBbN(QHBoFMMdL@eEI?Y1{aJDv-|U5$^3T$Uc9Y z&#NA*9$dAzmD|s>wbuWxaAi$bXjQmyy*Rh+x@6D2HOcN3e#ydr^V`mOw`OeH>IlvZ z8S|9RxLADMTm+G-hY^Ud%ah*#&t_R`PO#6~ITeL;p3!)Cagxz>kdmTf zFg~3fvfhym^cVWS9d&#y{*LLjO%+>RchC7N4DmD_j(^=fN+=k;WK6HUs@RUZd&UcE ze!qq?w4%K%I{wI(Rr6aUaL67J1q5ii5Sh9VKXoArbRkM~A$}?PpoD{l1f8i1ok;|PsSATiiIJwN_0Xabiyoj!gV?3KqjpKa15x$ z2%*CWp~nbezzAW;2w~I+VbTa;)(BzI2w~L-VRKp^H~AZK(KqBKRe4G*LL8|tXh9&O}gJ(x2DIj>jPNB#jl7?7I3KX*F;GcHC+bj;*C}WY@JY2^PU)GT|A|6yBp5 zfOZDhOS91C74nBU5P)(u{y?^Y*O^___PQe5EY9wTAmHtSL`J=0lB#%)fcd|(9Y5P9g$|IH$?hza^B6dp|5P?7zN`C3YWC> zufN%|I*hD-(P-A9mcHA{zxQR z*QeEKonsVdVt*K4}M*S{~A(L0Oib@N+YF1{B0 zW&h)^UjFqG$22aVZ$l3&X3aGg2R+i{G82-1Z$gpf0Ipl@H{5bzyC3jkBBCvgtcZoF z43b|^IUZLxW_ztumX&kuq$Zpt%_FIS#U^FO8dtGC60=CFh7Ysa%9}l3 z5}P70@Z)@%`s;)x+4!Hkau+*u^QNddEMf;+dtmO~my9K)rB8bTV_vH+qp%FR z7JJ#y`q$t7&DSmm={GytA8LN%i$*}P%TE_bX2Gj3b zB1*}~IusS*T{{##aaF^@1@|GPpfXimm4{#7=01gFC)Q> z*+I)+unFwBG8iwTK!6Jb=0U*eKOhUS9LZGi`FlE>qUpoQsZc4v7WfBK27q~? zs(^XPfQeE`>R|k5rk2zx*879s9}Au-1BRlZpG3^glfmfw1p;3{;1gQs-sb|kj9}^i z-03!?Don#oq9`wwSN9~aZzeiRoR5mb+ zo?yy8(BrLYUVZpcat@tp9#?-3b#FvLZoU^W6_*6ViN`=6M9ZV>66%C|x%onfu0;7Stt4_oTIFE(J z*PX{L4>c1&x~yL-9^m7(n~gtyDx3bYlyCTZaGARGq3Md=^80>)Ur$Kk! zs=Cg>ta>OxBXAyhe9*AGZV8QJ*RTN??15O%OCJpbrMk}ktOMvw1Hc4}Z~O7%fsZe# z14EAq=*8Cbg|C@>dRPAdych+1&QcaDR1#*AOsD8InjMsCA5`E;a z;7L@yJ_M$|6W$ zvJf&g9G}r*olx?Iir`VVz3}UW!!F|4Z!)!YGPrw2YLx4};)vA5-IhgQSSCus+kml` zIKo5{Pqx?>SE7AmVc0^n5>I8IBGxzd8b_E%;^`Pv#QVmuafGEa4sQSpS?zy1gntM) z0ZsvCvSVlqvuewA?s5MBw3fZ0?}6349PUDSv)0C1F%cFyTWT-4u zzth}m!(Dr-VuY8D#h*g$omU*!-|P%bVQR*VgnLenl4_2H-u-CTcvv_OfEPf^e(n z%Gv_IOr`>9&Bg+X1BOK#U#ohD=^v_{-ou|yE=J{ct6BA?EN0bfxH}Jq$g>$Hdyn)u znf@fC9mDjRqZ$~z#0#1)N81@kBRl6lU&ST$Ehwv&*Lnzl9DQJ3`0O#mbkTs-qO&(b z@qV>K-y&UjL+T>hOjsAWlj2p4h3Meaiq9R{X@ZhkEPS(d!kcjBPfy3UuxAt;7&i6o zdx>NDu=z~vY6z7{r&wQyr0X|$NSNPi92hb6EtkZxL)iQtcJ&&S$(nc{TpHC68wW;3 zeJd$(91}KAi&Je#ZL%iO2mcY~7w?MyNKbvME^%D>2`-W;+2=2h>PLhFW2L$_mN@xEDD$I`r2gXBv>m+f!7dAhKQ{4#~3f;f?Ls0!FaA3kzjxTV$L{Rla zB!nobX|ZF8!v4OI*hZmteu?8H7KNoJD$zknZGj!j6ZV%(VjGLf5f#Tv0##2;LI?-3 z5Ia^g>@Ty#HW9V+YaFldVS3^c9aPkN*s&gAe+4DBDX1K=alB+u^&}*Oa1m*7Vw1xD zDoAY8Qaj`0c!h`QNxmlRP&qU_tI@1!9{|dx>(YMs*}9Z?Kk<-^d>Dg%vfhGL{R0Hn z1%a#cn@0N3Q}qw2cQ}Aru-V@9PsvRB8FPATw}Z5|3~=TUZ31>ZphZnylTr#5B9C(@ zR^8wnga5FhlRvuZT6`LfEZ4qws^JFtqI|fPRKT6gDbhT!YG}t>kUMEO~xOX9*^tF3g^ z(>r0(^a^WIf!{2Dua~8GE?ibl>^4H>4A~>h@4EoQhl0hvjumq`SwFn~JfK1o=8;l# zE$r0!xk}N&Y+XL(aAd7f`BixvL{2Dyvf$tEk8k{&>v^|l@dqD0i#+9H>?g;cD*KF? z59NEMN%2F02Sckovv0hY!`_Gc8YuA-Feq63p<5Zr%$pqz+xFj?MP8b|Xyr^mD;}Qy zQTmF}WJqJM!7`P%czA1a`x>9Ue$cJ*U_mcbe{*y_yjGi9_o)THgV zidoAtCx^+V2-Sw9);|RQ65LE<5NuOOF;<>VJ2sQE&-Jrj{mCb{+6>80xrmA26!y|j zCF9afYlm4`jXIe2HI=_L4|}0k@kw`l z9aO&2tm*3{VyXsjUz%XLP11R4@fEfNO@&6t{}%f9uu(DU+QX|9I`&QNL#CB@9?oij z-1Tq5>JOrFv5km26LsWD7&r%#7wk%}ajc|Nu+-kGEd){SV8^PjbtsuxTj?@AuUGgDQw4Xn}`c=>t!LMZ9VfMSL0(BWM~DdnFqZ-G7vu zmHnM{{@FLnA@|iLrJ|<(N&Kq~pOTr4m(*9A1z9tj=HDGs#YQ#{IJ#eczHUf7{RI7q z*^pR@-;gLQW6Nw7Ql2kwV#6nEY%{nQlv7q!zwIKbY%s4gx;<1#$!W_x=dz>vlcXW> z?mte}keI@tJIsx)I}8IeK%>?jw!+mNo&`Dn<2y4j8J-{IJDQ;SsP};XHN1QW+I&g> zmq2&eTkoNcAjx0yz{IB6z}Uu13{0@IXV&@m&@6|lu}$+AGaEiFkgJ2aD15bfXaXA~ z2{z<6V`k8Dbv@~D0z~w7Ugvfl%nEADtSf8F3<aOgj<#-kE_ucOwvSxTnDcO{W#SyYuGek|Ucucdn`j+OO#LpL#zoO)CeOS=Y*8L1 z{Tk=c-okFDo;j8xV|H$#)mwgrtn%PUuyHuc$E3ak?pONy&F*q>=Ku@IyXcfMhfj{b zvYqZ|{NgbE-YA#bjTY1|5~r%myIS7}S9Cp6P;vE?ocqI{PN?FwST@pjdN~T>dtGP* zkM^6Xo^4dqn)B)|l+UXYe+iwAl4IcvseiHf0c%k|;1b@vJs-Hd)%E2`{C%T$Wf~l4 z`^B*7UZZ zzIvpeW&dM!Z9#RzU5qlNH=r;C3Lb}E$gvlkUjIXoPIO2Aor@ecQ$o9Z>t$}fes>ILm|Ct-Y^g_GaB^C_v= zNQSfZ-A!?wt|ENDy=^I)m35xd!D%s{$=NX%Zglwsv?VTYdN$?m9IXwN8{7{#out06 z@i&)War3ZG)Q#b-wBfvAdp(kQu(;ZW_I;bjb%KnH4Ig^Aj~$C7etr}kz4kgZ`_4*w z5AWBq*^FRx1?!uH))9!uTXObc_5%#pf#rdkVgNtgYu};fgLeSS?0qb$W^FD@$3rDs zu+(7-@R04;8%W{Gld*~>ZXUcUg>Tt|J5|g&G?2r~98>2OeZ}&tqW9$hCEp1wCHi`w#rZLI0@G*2 zyT)(pO?0v0GY!PYH=bomo#=b=X-nA%!)xXdx5?f=A;gKDZhQ;6#&i#ANj%{0QfJGV z(J2?KL!817^X&YG%3impg3)}PBk_9`I$KRA-zF~G9z6K%*ZjW;K*dtGqIa0TW`B;x z@Whl%SQG3>R>j{)84^T`jc*dC52uPck5`9SQ|Hrf{wSrd%ck5mac`UMII;Uv9b-t> zi3by)An=PB;^tBR!`;}~#hnx(@*Zn`*BQrh8)-?81u?44$Y&`!A{0q@e)ap*++Vz! zMpj4Ah_SSks3$<`DSk`X)O&kd)pdKz$wH1PVB!ONMTB)GBmAAW|29$6=clf%gIAkG zbai{e*M`PB#|y`GlBFeA(6!Cfr!@c!49u@8IuT(33g$liUHSq~?^90fq&+Uq4Urof zV^23XC?@CrDmOIpgDMWFLMG<^YBw}`pxQdbv_ynf{#;nK2T$+RH}`3c2g7A9tac1a z_6E+`I?OpuIIi<7Ey0>RdC${MPB<|e8XJdf9f(Fe;fB0r;N%?a_qZ`-^y*jd+ z&=Y1NJ83d%ADa!(NBVz0xKx&SU?j7KMhce+$8q}qxrYCr>xzlbu;h|*=YJQzWt99w zy>7Uv^0cKD_v<@s#Z>PfpdH!&Y#50wL^J{*j{@p0!eREOM>=lkANdc3#=mGfi2f2! zB04I{e0O5WCNSirAZMsAK1C5NW!K?mx!0`+-|G(8e|gB_`YCI(ejLMCwoVg&8x2dj zNQNgrMQ*?3lPcOuf;mI>@Z^^duDYqk!4>kH3FCf)J)%S(F;G^LnMhsDY8)3ISiw(_ zJ6v9542mYi7akD7BIP^i@++eFoQCMij4Lh~*AuYd?i)xvhq5m|8B#uH-tq0_Gv&q}St?Xf2ti9J#T7J5c zHqf&54UaU{p-sovwEnQ$QMy}dp`sM8r>#;|sYm-7f|^C$n*7m*u+jMdVr1qHgLl$AQkAW;*|m`3L(=^ z0D&I~0X|IFL~azYxuK|krbvzHJiLWY&otL^^+;_5e3DxNviU4V_-tUpLGsbm>pg5k zHZbYPKct5Cv%K`ew7POfyB+|MMYUQMJahuz0{5D51W;Fp-DO07xK**6LRtryt6#}q zJPGIWNnHU5*MQp!R-2uRp&@PWRQTVDwQ^ps!`TE1`xxI6Bgl4%o85a&RvXd-*K30| z^IeBnn|$twO!5ciuYp{)7o63t)R}ht_7^Stb3~Py=lz>|)J;)h z*z`NXWM1_!e=2u~9F4nOt2XrJ^v`n@c~bW~Y9YNbS|cha(yQFRZ_MletSMb4{)Z;< z${@}eVceO#(o~D8uW=r2Jagc6(X?bhJi*O6W(^LjC1y7*!qqA;C4tt z#o9&BP_eF;v6&AIYuPcCL_&55fzmq(H4+ImQVBIO2{rQ1A26p;a0pOw)KPH~!VU`q z-cjXH;{-8K<#15te8ve9qsoz^%2A=p(V@yQp~|tQ%5kR3@utcNqRI)U%K1f=lS-A7 zLzPp46I4T$(}EM!LzOc`l{2aQouP<~nt`0Ugq)gzg1Ur)ijI=Hgp!(pin@e~nt__S zgqm3^kOQ8JTpH~w5lHB7v(ZTCZ%DP#$Sq+IPQ@XUG$n9hsA27{7!4hQ8oECJ`5MXS z54X^ZBm|H-;218#GI`5$H|%hq$~!C32s@UT`2xh2=a{oBrxeMhLJ{U(S>g8&?-E?p zCeKaeWFb5I0aJoxcDe3K(#2Q#^80}Em9y;>hpjfk zIaDe)fBUJEUgHXia1E^&Afb2s>S%a04%mgs4J~OXEiKYL{%DWNjeeIJOd)G|Dg8IG z$RW600iyeQ1aqyn@u4DLE@JOYL#N`Ost&WFYDGGa%7n$OW<@KPfmQmlsMS<%inHI| zqTCW8j&$gOPNDcNh|oGSuU2Jq+r@gVAv7;fLh^*D0essx&s+pT8)pJ%Fs1{g zf&A5{elfT40+gBUUWhzBmRV_UoNoAgs2$x3LZUe8#c{#wH!f?{j#icrhrhqizD7({K6>&t?FOzxs`AA85+ku?>BFH}bHJ@0eF`oPPnET+>-jB9C6c=di zVG7A{|LJ`nZIfVO5Fu+^AHv^Nd0{_Q;*!H~q zp`fL3hm+|$O>_H&!#M5%^v(XCwfKLm+O`M%ZT4Obnr=}Invaqh-hi}%3B+7=M&&Es z%+Hwk*M|mV6G#SU3;ktLhj0?$ies|I8L1YSv*k!g2C9?mpF0Cdf%o93$;w%Wz0?tK z>2?|IWsyLJ!ri(G_o}&!wim3-caYJDsfbdE7Boo`YBx`~KVZa})mc-(wvm2@l=*#) z!+uz_&Q|P3Z9d(+aBfF-sW_g6HzF%u?=~KHeSt`Z^{%^#oO~gL+3Zb1`F|ID~U0 zB?DZ^bypNf#DG^O!28EfA0=voe}+lU%BN5t8Z2{Gq5TC`nEUIaoX)X(%7A_LCuCGb zYML@R$k*U;>I_7jbRS~2cs;SEGtQ1^c-Js4zFh+YC;HXth>KwR0zdliad9#cWy0&z z@MCDd0R(20z2|fGP4boHL=54xYp>a zYv7%Iek%dH0HZR}`AQN6QFP2IGle0igvV2zwjg_R^H#g49Vu;VXQ^-synbu@QEx*n zw7lhxpJ&QX>Bwm%bjHBL*VDbBqI<%uB+su8v|JNTQk2?L~<^S6s6DDIOk;l2A%^f0Rqa!!|tK$=AdCI{s)xlBt z>_MqFMfD$GZ~pSQIi(?`LF67~1Z54)AK;ab4F6<#gJkO1ptAPuyMqY@G-0RD;7-O7OPW zg!n#qEX?GFT=~)G4IM$%b4*huiPsWb11ag($(X>c!ptJnh<3rxhz=xrkQk_{5^ROo z60x;>L|d_#ZW~~K%~xgfW_-twJIw*s-{}$|RxgaRn~ICR!$J-N9f5s7yKsYV+D5KD z`iu+J(eF%i97rmd7y9t7Vi!AW9N632EiikeMOx3f0ls{Af<`J21K_W-^2C4rME%aq z^con3Va97pG$hDHAZSoLkF4WoD$o5}qc1;M6!G)6uhB7TR`oL%BRN=TAav8eMtAf3 zgMHJS+E_aFY?R3DE2#WD2h+HDX!I^6Su-fK*O`-AIVPpH)5b68a9sOzBT2vTpfVaU zT0UDbYKQda(2#pSt@5qK=f*kMLi6(z(I}a4$DZ%aG}2=_#Z%sz+quiL%@Snaqq1YH z+2Vowd6i(~rgF@nU@gh15*{_-at-rwbLk)!R)ns9pSy90658=S%GDYD#=|p{6sA3J zf}^jEN1CA%K$}Rj@3^U2iss2RGqRpc(}w8u5)$V`sme&LOuz@q5de|%+; zMPx;-7Sq9dN@K@7ks-04Sir3dOgH5=jy;?1?u@Fmcki`LUi4QYQh0c8c0LUfH>7<6 zz6R*oJ{Q(KvYwylJQ0x|3E%lt0&O)rp7+ri0D;F-lZx-n6iR>kpWTR7OrgTIhG$u` zyGN9G!Qnl6pR@FeHX)y&8dlS=%YpruWy zq>j?%lB65M^oayaP7)i{KIQG|nhrRqMDjH@*WDlB_Ct*OvB)F>Sx?x+?jlaDq@YZv z5+fgJd0Rc-nJg5C`n9QIHP6pW5_z;8Tn2=)tWrUC**~O}35|!A2`Ys#!{x;CaJ7B2 z@N}Q{@Eh(SxYYIYn`7@K!mIl;v#RBm1%os4#%#1eH%&g{B&2)_9Yuk-jqa@9AINzub?_!QWLi|e+~LQw;rEHj5;w9mUfLty%O?MkRln#)0QOzYJo+53Heu`T z3?HJEncr>%{(E%$bfpSy#lbEn?p8<(JKq(;d{4Y@B6R%;0lz!q19?^5ozk|k>B^%{ zCb-4D(}u9{iHlwwE~BLltL8kM%`=FfwZQX?2%~tnL(|TmVx^lCfQiBS!VNAKT$ns( z80j_rFXP1M9|l#Sp2d>Qx4{S`4{dpvif0M9Uq6=re8FE_g3nf`;x*c3kh*~KYU-a* z)x1yT+nNOnhqqNNWop6LJS5|sl@I>UqlaV z5X%Z-?oL&4?w5m^wS<&`H{iwE$*CH|4L~8WX&x8W`C8{WQ{)kPwxwy_T-gkV#1;4O zXO3ZGKBqE~uJU{t_q`+7YAwASkICs3wtiA>xW1*QY9w-=;9ACdm$f`66n8#Xx;8G9 zOMEt?B{Son#fm2emFg2xsCfHWze~<_SJeE+sMPK-Jx)o|W2}dKUoFK8CBw?jq1+i_ zjnc~Q3hV59&Hq+J*I#58YHA9;Ll0Qr07wUb>nX}AxwB!TIM8Ulc=%Vo8fAOELb}hx ze8rxb9U?GK#T{<2XHDw%FfEG(W|&b$R*f&rTlq%cF@WCH~GoT5kHT*pan*~{1**N$Y0iz?OQ|cSpG1;=?sm} zd`FOqRcm+^s|IJF!^e2p=j}jSG27}$K(&1~DR9B|c8g=1#Gtlo-o18tYe9GWx4V0y z56h>)c8%!-yn;`^d|3Bsu4Nz96~B}tZOw){t8B)w8Jxt!8oh`Him{9$z0n2=HH~e( zUk~IbuzhT&EEM=eF_0s@O{Gm8Df)29oVzq~VJ? z4rprc!t zWLP6V#Y;j6?)#O48Er4_`LaocI!~LmWJQH04R;;n&)kvV@@e{U+oOWw+1H)Lq%S^VOv>7OUUg zEJfb2@wQc!EpK-Fc9+NHV%LN7h`=|@pC~BIlvtSFBC8~y0jRXj|aWt#aB!q z{t^E&+G_u0EYsA|Rx;MoI)MC40-&&d2cFnKV`mD1=XPcI7XHh4(hn4TKtc4mOnMvB z!B9mD{bB^^P%(nQgZ^dsc64Pt;eet2Nb^FE2lob#2c8gnfzRKy5! z8ov-%8MhF(){mMxoFSlY4iQo?hpa-tjaR5^X)~FsXwN>@(n4_Ox>)UNEv)k=6wBy0Cq2ocr-2me2-+~X$;FYCP1Rpd&>gDjc`~&)M zeig;L4ae~LLBFU_Uky|vL%jrb>oNw;dc5qZnTqZ-y9jx=j6FMeTUa&{-+2fcKT@9m)+Te|7 zkzdojTFqUs^Tg2)g4L{z_DTs-Zs@1nwn0ghXUuf2Fqr*!(6*=koSFjV zn=2@v7WP{bwdh_y8MW|!E`~Og7a0=yiF9_DT0B2GKwa#y6?u8mZ1aFQZFS&DH{~(P zfnv@FtPH<|w+}-N7|o1?;+qZ>^<3;SlTP94Cj)e!#T*EiFdhg$-ts>mu>R&9BmGlgLB*S$z>;D5cP6Ylqjc_lPSmlsr6-M%wH zcxL21-HMZqFYs*^J7`s@0m%~6g1=2PY*AbrGfOyr=fyh-P!Lx`L9Yut6bU3(CZijt zDM3PR>2u4H5S$DAoVE8^DV z7<|mFfvTXO*N+xr;#+1wz&JvgpOvx#iOP_WQ}(HlJ0+0Fb{B_ z{Q7F278Jh!Cs16Nzb432;eN5;9j}oO)uMo0J-eNG?6>rE4lEl!C(be?skl$nP3O zk=A-yd^=pp-x6rH8b7%26FKe^U2q5RfStmfuR8@JXus~k(z`y(J*cMflQ1PS=UfKY z2zl5okG4tu6F?aOw7bxow^Ukf$%@*$Ux`aQ;9#9S*TlEz>pXdD&mLWtP^%`89R2=T z)9bPya@ha+yqrk2uDXL%-y=~;?%jBm=2Cf=kKh!8 zVU3NY>=q`g*+4UIJBi`Eoqm%ET0jh!%>`7w0ie_^5FE}($S{>Jzr5uc(3YD9D4*vx zfq;JCW*O`9@EUh)1zrP|e5HS*>Kj7KLX)4otIby=}eXDy>`G;YKB&vWN+dV~La z4;Ef#53lR0Ww&k{=f*aL8Y;JXQcgJbOWrZ`z`qBi8OySl#TCl$%f9cu4DPA*v6fB* z3}{ubE3$nHFw(v&_&l6{77Bz6>>d;O-nQY2@v(_dHICfy zjb$y94ILgRt%AdWi%v)-oAXmWD(>U-&G9Qzax#6RvJ=p88q!4NhZfHqDp%idc=nac zH4yc00t@O?Zm7btz-jV(*B$5poN`6=i4Vl9Jv z%E9zs|7GXvYId-`Fpgd7H-NQ$Z}{gq%ZucWD+(YciC_i& z8LHT@h8Per0uY;ShQpvPk%<7F3~-iyzPjXB-a7$}8rNU_|F8Qw{LhhesHFTvr-bbB zO=rSqJHhvEEWFfiUapPPZr$d^x*4h*c`UIe17|8xe8Xx}3Z-gS<9sFg`DFv|{uEb3 zAu3zH#}YS%PfOhamonF0o0Dl0$lXtGf!}m1b+rl8F2=gWbLgUS$ttRc?O7ptC(4V!^uJbK!$mX&MV$DJ4&sxp8dM;~9BhBoRiyq6+bUdT=$70|cxJ!Rc z=$R~6Pw}l|5pRa6qyL z$^6Gkp{mJUvjj-;W_N=GxK*6hu(aG7SiHJ>=GNP67f@rah8>sIz(^UZVYY=euw$xf z*q8WuzlL8RCCvMwLXSuI`z6QHSvsj0bVl6-K_gn`_l^jHYvZFX%9 zOs}X0=Bs3O_fXe&%BgF{v+zr(G3&SwM{wQH$9-b57l{i_yW~P^h5~^%_FHz}7}~fi z8u)`Hxg@~zDqQu7)=aV9Y#}K3dF%Cy$G2k}_*N-RZ0QB{oxq|nKOAU zykS`sDrCl|XT}-aoH+d8N|*L;%pv_qmCDph&PInjToi{~*%yhCSQ=27rd=J?CHv&@*FfnoxCU~R(e zD@Fki-DAy|eTOjLBayGm!)}z`Zj8z(n?@AhI{Gpaj+ym(9UX(V`hLA!@%gsMd+7S4 zTcXOgpnMl--r|k%i?pRpOZs`*Qu^D5GG=+=MnXOOLlagHy&$C4+|%lAu}M9E8&~a$ z#Z$K)?B`m7X1Albxly%w&vae=tL*CJ&N?gGx;ch-`nr=v_CzR4qFe+A<7a+m@i{3| zaKMw&0m@Ixp&JC^oJlN7 zNxjGJ9Or}3H;768sM(dusi>kEmdsc*;h^UirvsGIu6&BwV$g}s@gS56H_6{p#xU0x zG<^G)PjQ;Spz?^YGg5es^fwIxhUL!$L;4UgJ-^`CSA9g-t`f+nP@*2LZ$q<27p_97Z$3yU<=|0%iWD>IJgVrcZ(QsG@_K2sw zGuR8mg?Hwwl%Mf1;+*Zs)_XK4Q3Er2<*MWQWj?@K39ZzWUnYZ<(_#W~VMwCNY@tr^ zd!>={cOgs7rPp97mSM!;mbdle^yO=!khxEJs0u?Z1KoL!uZa`3bzPbrYw!AdSsl2E zJm-(e{6}I|q{5C1s?gsm8WU8d^)MKH4iWEiKdai`G#=N>zGf>z@QW(xG9L5{gv1_7 z8s>^Ac_K21ZlKa3Qxzd6*uLn`s(PvRtp`^L6J1_Jkd6rfIU59mK>!zBUIO#IvNDLN zi%OVL2@FSc6tM+oaZKxEeX3JLvlgeIqr;>w!3^bGv2r4qDXepRl^}y*Q&%O0VZ)MJ zB}HN)M`BX93D?|&$KW%;Pb=4)Cho_SsNtO2bx)Nd1JG5j)J(j#F(4dJ&~dt~s<|8y zKUA$m-7JBP%9f@x;~U&9(N(l_DSCfyPVr=$%6Tj+_nOfV&hXU}oZuX|Snb+siDQN) zD7tACWISrP`~EjDaaLe=ct&xm3Ac69dvy7uaZ}mZAO{t`X!1UlPx6LWB++b)5Y7CQ zjgg(vh)yWEOZgD8%BlM1=sHX%H$}FD*r^?VHLn^U9;;n)V1Tz)4R&m z+uOk+bvyIbthl=`#Y{i>&^tam%=*@ zMt7Bb$i|!qsiua7*~Q?W$rwiYigPEk)#H_Q<4TV<+IIIKmFb@&ZOiV-n-pKUm>Usl z>B(QZy9msSUFe%H$pF!|g=XCU4|8w*71j4W4uiCSgoJbnh;#`^4B`;d(kUI10#Xt~ zcZxJfDc#*AA&qo*cjwI9?|r>LKRo}!vsio1?7h#9Gu)YV?>Re+#W=|=E~@oXhomhu zFlD8)8}T&!*#qcyH%BCC3NM6Sp)(YsYa%g!OG4}D(R(GK)AZ=ulF(~OD8{>&q+L|6 zaaJUi_7c#g-$DQTU%rF7zJmt80}td0Ui=8zc&|z&rAl3Gko}f~^@OR4MAhe&GCD@C zFp)+WobnY>Z+Ny030(l=M{n$6=sCly=e?oX${<1N^LY*#oz1xkVQ;ARtZH7bkG2~; z*-T}qQt5UGOv5|^Vt74|fg4*VXM2FV4vd;~*Yn$e<@K6#!~>tlZvad_W187qtIuS z6HC)*OTAJ3x`7hGm@PJP4wN-6O3g-I=3lvp+>QdHJF<741>)rI<_S;L(J>wrn%)pg z(dEjq{*A~nhHYVoPO8>j*aD?+%7UCv{yj~@YP#Z^Ft;RoXE*Rz4BSMUg4Lwd-UG(- zK;0i7A5LPAaBG_CT)@t?_c8N#VoQ>o$}vs$1*N2H;ta}`T%rr?yXGk3Gn3QF*i%=; zp4)_rprf|PtyS(r#ckQarQ@}h=cx`=;%!WDQO4t>-bR~Q&P2Wc@>Ft*4|AKTVp9FA z=qr0j$NPozP0ami_1xymK(vGMz>2~Od!vezPvRdJYT&-ErwPRm4@ZiwMtvUF(f26b0><_g}WhWm@#Q`Ly)E$*@rq7YGfJ9tFQd)BR&8r; zesSGS6^x>zpRV^p8&opfc=kU+r=IKiqbM<;8|EZpkCW+zqxhT~hVK^Fk4R*FxR8{Yi)!ZR(jUQoByGRdg{(jBf& z3(Ydl5;&Z?$KJ_|3n<^s(>ry?7CLv2p(Z}}{q#{}-KuR62lAX*`K~FeU1nr6C`%D! z^tHIp;P245X8UKHnW>7bhiXGr34BJsVHmzdxBr#tmL0o&ah#pn``pi?z`(uBy&xm$ zF0ahbnw?%-rV46bSvqb^5oG%+_}u7Z>qyr>9FQ*oOav&WIL8)?=8#*bS^ z1}&WQ;OQ*$9K+N%9GIkZBqoX0okjl5n zT5hDFFKYGI3-zQ%MIjLqmt=$F-xe{sy?sFK8yRV3J%YAh?qBxN{wjFU#Z1u!1z8}wtvhRYBcNhE)|}3uo`|ZTR)6yYo+g+?Ep-!l);d^b}YEb<4Q4L|2b-Ur5F^8Xq3j;?dH) z*|7xD_jZ|hMY5g7XXR9%Sv!+(X8(JV)~U(YIE;Rhm1yh!*ul`0I`4b=BC!atuJi*R zR`^B6Bq$=E=Z}4;*;Y(TNcw#b>9~WHaQ6SC%D!pnNmFFL1*~@=;7(cA@rmu&!z!9~ z_rq$}u=Ver=GC|{68q!R*PkA7OU}Mp3X?%ANcGqm#kwK=-9JwEQfzq1(?+fgHW>mr zue@8cADdE74?PS`Eo;7D;VC(h{iI~l*jOs1p=CQaeA;@CdaJgEwxDKw#(|LwO|so5 zFjv=qGL?i<7j|!B@MNlQ7{+Ib=`B6}9IzWWc>3@Xx6JS7w;!@k&(bb)3c`XJ>bG14@UJgcFTlZ zl&|5{VZYFE!SFtTBg^u>$#=)TrFb0g+OAv|@a28bUmhuA3MEmL$yXd$_5Yq38XGiq zyBISt@WglTW)GCwzW#DItW2Idvd)h)@_VcjjhP-@uu$U#zI;ybnBJXtcr4ZI%R0Lc z)5?q$d_b1?GOYi|&<-(c&69iv$dn=9(}QPO7)`suFg@VBT&(x`bLz(pzm3_qak{Z` zg0{OQ>mP&)*H>fIn3`k0Gd^?GW;%3Bw&uKDjgYrOr@q&p*cMDUaD;2v@Ema${TKaE z|I^E&m%UxIZm*+S;VbDfnraTN?bqoQ`ICoS!R8RHM(SU;x@YNNyja`&xOBIMw~7`F z?#pbNpLOL3LnfriNWzDj6<>xC7QMnI5=03jV!$RoX2$%;h;EXb_>qt`i*y2ZIe!}5 zk3+q#KB-!19ZUj^yd?p8J${T;&uYonC8}{w;m)Xzd65bTL?KJGmNW5n#W`wAy<82r z$_`qrgafQ-y}Li36>WO%Xh(dyg?g=^CCm<>>fQgPj|D>J^B0}rbx*!lJ-}F8*mgTU zA42@20PvukvUh0~pBJgm^fkGGbgKSMgs-XNW?^0k%epLa8l0$_`GCsAadMLEea)ZS zBl~vSqHYl%&!@Xr(Hg=9+@IDn+AW`MU)6=FE>0uWqn|}4J+(#PIO1f?-d6qf^znj@ z9_lkWe_CB;+`iskDp38jI{x|T?)C3iRWJhWjdT^#O-PJpGmy%$a;Epgd2_$qG}elf zQ5dyqx0}VZf)z&ge8QL9i@UJo>cd-37Gp@VR; zSo>G-BfTS~3~%9U=y&hC&urT{cGKz&r8;j#Z7e-TY%EGVQf3=M0)Dw6=qPB=25r5c z=w0~E#QoivWmx}t%BG0(&+}9NDRjQq**p`^(nDv>)RGXxFK5nU8fxQ67iNeu z_MfEP>%ctBPY~hmL+o)}4}|30&> zy6Ng=`7&p9(^uB=cVlKQ`^pA^wEvru)Q#O1KeDY6KVnhZy~C$#?n3dqvgzn`byIDa z9hWO(`VdRdoY{bZRE33$ZZZ;b)Mn0=gH_Yytz_=vX<*{gq-XBZqzR7dCNB5FOjizX zl50rcB)h+|~enbMAPWVkMe|jAPrn!XloaYDo$3`a+BO#-uWdQmFFzXBvD<`aQ zO&$fvr|)lWfTPF%pX~!pZ$5^yHjv1&K1-UzCso=c`NqH_vYoDn!z?s4ptBXy`B>Q! zekJDh2`Bu@SutLErC$nJFn&vt_A{c^^2;~)M2Tba_IacjqJh}!fgc1W5SBq0A@=%K z(DTzb9E9Y-pFdg0tE{RDvhu16k~MFxyt#O81a7Wsm~XCpK(v+KPdrxKhagF=a8@T-*0_$FxVqNm`pFL+xng<+vvw_L3SpZRC_x!YEF^uHWPI zHSD$oSe^EuQ)u2u$x>@Xc8a#+85xLKlqol|Iz8z9zF?*C$a3$jj#>?56yw-76}?{4 zwQH~8xUvyx{%5Qrbg>L?g=ECyvW>)Gx2<`QrOT==dO|P=wdg^a*R6y=! zZ3Btge%Pwnv{34mt5donSEldM+SC&Mnw7Hv%Z#!umy5HEKXS;VPKx-?<>yVFU3D>s3bo!)D=bA7YO_EO}eR#`SHVm?7w>;<@eWY6jH#ZRdH{my9h-!v2O1ULa5udAXmd z)vVg|J;@PlC^^*__v1_FP8U;9`$3?OaCd)@^{au zNQ2ouz*sX(T8nUVoW!Y#i}JtstF1=^lYG_u1z4RxI)_sg^C*Ba4u`G5JKR0tx&gEI z1nmDi%7n`eCAM7Hco}S%?rb;zIh%U=_ySKYhq?NxRH!F`Tz7BG*TQw*ak-QBn-4Bj zzRrS~BEpW)lb7<2f$hVe9q2yqs|O@W{GLBrtDm2i`csVL!hZYq^|Pu6OY^;Z~}v+Gu!e+Ki~F+~~OcF$c`66%{ZOfNFo z{5)g)$y2N6nsLyZx=IP&Pu093S~{FAqH-&G{oH?uFJYE1InnR+_{)m%zn2xkk!8`| z|eST~YG`+J3nZRv<>nk+f| z5Cr`vrsG7)mB#mW0>+_JcWLCkEWE7KEHE0)w5PH1N-8QO=`<^)HZJ|i|C%~2vf^}u zT?PWijXlqcwsH@*encoTCodq{l*A_dhDB6!1k__{J5Qx;2%m^s8EBL(* zlOu=z!b1>AQbB(`lO~moUcdblf+(aoOxTSji)HZ^%mVd1+@or~#7p@P|wucpvk_wgB@i zgs}1bXFsD0CxWg|!%sv8B#LuC`z&mgz47#-I2LM8lU7|UaT2@-;_Ij2O~?nD#6rN7 z4~&ienPodBuW~td^3@)hya*YSm`@_*0C)LoQtBR7HRq8xwWXyfnSkk=zC=$i)8rsd<6Pgdr zn*}2W;R7T0OJgUFd&;hJ#aCr!% zFLlSo`1>i;F3C63VEz4@Hj2x*P~Mdqw0T=rw>&#D<2csClxMT(EdSQiI`h>o-}&i& zEo7;Td^U|9qG_GfWoY-;C5(kH?%5qCUppWMT^Lot9H7JE8|)AX!ALr2MAEFfqFVF?5{2-JCaU)FS+s3Bjt8)t|Dnb4?Rv&Ej#)V*_ANxLlfpios3 z7~)J@craDH2ablX?8M9&P>>xzF6l;O?2(XcWXI7Z9cRrp>4K_o=F$i)s77Hc*O?qOowH9t1_ zY=dRb{8Ojlb=QU}CgCgF5<@Hj8K#D5VK$NpYSH3jYfR~0$Y~cE=d%Bfb={I=@^Y4B zZN8~|)TGDV`?ji!5L%L5kgz|Km>{EY$(i>uSN$@wVDz%2c_P&7^W*1QUBr-;mQjL~ zeK|5B7UIG22?^X@Px5kQe6L`nVBkuLQ4>{)pC3y|MI1Yc|wIf`d z&Q=M8Lx+p=bP6)m9f(9D-aoPpRtCvAd9?TphS|ahWoKTg%KUT>&uiB!j6z;XI}Q8e zSseY8?R82&C2}Gz+h<{2uH%^3P3)FPIDYO3aG?qDb*XOIFdIuHx4;;$wyy zEJ%2}VL|>u#mThqah3hXJv~C*NF-lz@uDE5=?KH3dDD#7c7{p5zE<`}59dY{Z$V;4 z&~Htdjp8 z?kK77knN*;S{@dp@uzGuapA$>J>i+$&gCwvnuf56AK^EoclirqC!}{8sr|wbmw?k_ zVqBl~NOMn53f@^%?28=rC>+|Ih=wVppGg-nvNaCh(h2pS5$VTn5Lv&Akj*A#qxDaE z88icyU)TFV@4Yikf{P`;`{}oB6fwtD9u(p7W?|7dSdRE>!4WNMICn={7UjN}zPB>RDx>pBPM zg)_cX<09{_QfhocnHT)DOB}hY@^h!6w;n9mkh)>o1rX4dL<5>rNT2GA*swZvA~)M?red{V{L05=!%IC_57fBvRHO+ryrS1Z;SyglGSqVg3r!Z z1lgwc2vIBr42iL>Xv@z#UN1l(u(T}S{@#UEom^zWfN9vjD~R8N(Fo$KJ%5XO0#5kO z$;tiam1YS@{qhXsGS_8)9yOI@489({Q_+2v`Ot{M5Dp%g77H-+ znWBRwnJTUFn^qS(4S*olG^ER;O4T;T9vp(k;zd3Qs{xZ(MB^TemJyx$&u?8{9sm}5;M&?XK6Jh-6HVL0cPh-aO-{eB zAC%o+*4j&~E|k}E<}7FB3O+3M1l<5XcMrboa^ld8J^SKXok}cstsu^dgBelqY|~4p zgIqz{&usU2gI9(-?^8Ua%WJ#~f>Cik_O1tlLj-U@;gf{t;PnC_A_5elaCM^dG3g!% z1rcBeazI43C)STp0uu^j`*%J#E^df`8t)F7`4#LF9V@$xpS&3;${A>^_Wt2Nd zt|nm8{2$z?vIqESI|$hD@O^b`s65dZzNz>G)`|&dk5|qk{_-F^65&b9-Ezkf!Zl7H zp3s|^;&?WonnouSfC+;m!tQ8WnGjDq;=7v;N){Eq-K~zj8A%dn7Ny_p7|_T?ni-V7 z0mwNvVXmj=u(MT_#wH{D7eZ7NSO&Pv<-skp;jJE8F?4i#3v+m13)1lK4qL51m9G}@ zw(!9lRO%iN-3`71q5o8!fzUTdZ3;k%oW+wS^XRA@I zkFQjQ7_)jtt7Ce~jALa=y<2L^$|!w4*e=nu;-6%#ikD*Q!#2?KIna_Vwg2njm9p87 zQY8rce4V4luh13sUyk~(MRd8@MNXILckn-zZ`s>3j7BZ8jCyZn2)7LIIk}ZHj^4Y* z2)oZooY&v>hhHjUY#diCy&QF{(rz-FuiK!3m1z#X+1Ty~v@nvz+_50nySerfPg;i7 zw{1jkl%>rHdqm?yv7>{+@TIY%gTwG;u%ko5@I%9*Ws7m~!@{EF7*X**U`L0C;mc!3 z%b$`{CJ|DS6H%oQQc@66r4dq65m8YSQPB`l(GpS75s9KOx;=p&VTa985LUe>lq!(y ziFt>eiAE%f&G3~Ndh{x2T$ixw56F1e6B8JgiA5wz$mqrhJ(3HXO9dr}qza^ZVx+M% zafw7G6gNTeFOt{h{fUJra@T4;e{1)?7fr(((QhYU{Rja=@wuCkH4;B| zGsSQP`Yw>Qd^0dc;C1!A1@cbn{-61d+GR%v=OoMgM2!ntCm4Cv)B~rhZR`WqQh<{6 zb`}6|epkKp+NPsUJpudoWE7x_JLXpg1`AyF?9k|cdE(HYMCgG`o}|g9;y4Q{n{vFK z!GRwOkP@8w<^NqbB8r1hy;oYc7*GcES*E8HmT}q&v2FGWc-*cjiRA#g=Ss;sUaoWHXduH&ktb z=?5_P0dp^+fvy37A-^}63sD8EcR-qYHz&-H6u`RdBRcAD;Eo-p;^21&SvKm}%sqtd zq-=oS#q4uP9Q^jDP5DlH{^hEJTn2qeCwrvzA)dqdFDtM{{5eW;RQJOe>73r0i>lV2 zu@$l5geQj9+ zqq^cCX=+ja6o|2Z<)zSW1-N_q7St>JQiG4B#%Cqj;`Sg3)IZ-FEg)khFFI;_)3D7~ z@@BSBgK=vc`kC~1ElIe>(_R~3(s#RK2zyErEpngXTI0`|@697H6W;vs`h4f8l4+5? znYH>c{J!Ib7(lT5-vNWwq5$%-4S}_I;c^k&S=%vh&Y=rPivr9#8vy0XB}@gj%yuuo*k|OwK`i0|3y)&)vW7_fE@+FNh0u!^Wd@(y!?7A*0@nL!85BmSAFn(PT zY$b;ac|%q%pCo#!Xs3H}Y;}mQ8f`-ctAGY{Fw?c8O9+@Hyoa&;V?4N63Fl4&$Qu~h zrCF7mRbJ44x!1`Q<(##C#X(J_9>2Puief@l@3J>>LH9=_AAoYP+CprFe=9f*gG@dOHEFfE^V!%xegPvrjVu~n z{hr!O2vT(**eFtQnYegtF1rY6lx76nVjB%oG5eQaFp2kT9JP5A2fVq=-1seh_pIJwFiLjfA)P^%QXn35Z?n;EZ`N|4d|WNx+5wOo~|9= zru7`RM%$Xv*vqareHD4$Vin~VwyS-lbapkL8wiZRSQmo27x;|utE(UK{n5bdhQ2#Ov=x|`#BMWR6A(Lc< z_jG1<;g_)Cs)Yw5u((I={puyv24uv&QAij5XR6}9s%n)~q?QjR_O~p@Ym7_pB$@8c zaV*`gW*6NY45|eypjt&~0c_cDZhJ%r*Tw2YgNla_b({AVwUl!j&FJUY{ zN66g;@MP?nUvqncxFH(?7nY-arZu`6fg5x#zA2dVN(iXoul^+f*wt1*5#)jOfM{bs zAj>v=p!VB$G`)sZ` z)Ouw$4esUG9b_sgAu~BM@g%mXKJpC0lHY@*s~IRg25?>iZL=Ht*q;u8=H2v$id9>E zjX)9igNi0MU5!7y3D@{zW8pSS;vZJ;AhDdWHuf$uG#PcRx^+;inrpKpA)vLarngOq z%dx2SFi>AGX16-=y*5C8jV4q0NQ-1u;FNv)~hXjYp6vsK8M^1%|CY-fZo5}lvQ_Kcwr zL9n234(#u7b$_S8;U@Ep#k$1<%_u?5>Gn!zwf^i;mGZB|#A8!IM0gg8~LAXl?`KMMe- z4ltmsMso+Q5~-^Xlnma`ISf_q&ZA8t`z9_r>h8F8HabkN>16G=6~_j|!%k4V-xV$r z!Sg;y!vB3r@UuX8j2PdA0wVRgs0)DR;C%=9lj?}ezuLgqtajv>Y|15EDx(x~q(flJC=fh-i?eJsCs{W&4eq8g)tV0qN{t22@ z81h6ZY5QA3{7<2Mc6PxArj7Kz*|TVHknMr^5hAgn@b`r0vEY4k7$LHd(X;snOt*8a zn0*VTj1+(&V&tcR%NXD}{{`aar1maWV&h}|XVf8py%$I|6#&SmkdE8TH?WWGNXOqh zKyez7ntHR8y$&ng0Rqy2vDo%nIDygWA7BF3+6U`6heat}ES?sE#~S^q0)RGY!^+w1 z?i}B7y+eS}BIFr*8~oUjuO|Sgv3@WLK3)}d@-V)0e4{5H1z6@K0i=J=S4FpP7;eE> zf>LVu(O_cB)j`fWH%{mZB{Pk$#V>DjL-+kcer@6U!X^#F1Fq1S&kRAj=|d&}Irr?* zO@qOu20!?FsIslMi2Tmv>up%x)?7q*-^D7Gc@KN)+HgvGpme7*&S}Ixb=o9r&Ew_& zMX5wk>d!y*ppe}YGRl4e!Zhd#tE^%2YuPr}f+db$Sxa`y=1uoj$J=C)-?x$~WdD}! zl>VqNyvfa`<2PzomU!K8QX^$;252?5Umr^?`pX8@LwuQ_?sFVaI#G_Vg>}%qO3#Gx zbG!2K&-bFvyPE_W7ut{zM3Zq zwQ_P9t!gKW*Plh$oZ6ST?c&BeqF>ztu4O!Hhq6Kbr`&`NzU)RXt_DdMJeOZFSj?lC zoaLT$$LZ2wln6+*OCPZk)b$PgAzm2zgRitr^nmSY-Uiu@-|a|{Mch@1Jxu0Zq?mba zRe9C_-K@_daxjEJUvzjk@T{+lbob0FzZ=$JoRe8)R-}w$SBz01Ra=ZDoXCB^Q9l@q zn|#kQun)mc;FmaLUtF#Gt8N5#bN9*#&uC&X_<3??IQqRKzUKF2wLo1ykJ+%J)M#go zl*4UoQ0ueMAUN1kKDF-6Q+}8c^YGipN}k8}x+#}8cqS(?AG+o`iyF22e6AM* zxIVTs?UFT}MeQHty!%2Pgmr7y;Ondq=A}?{E4VPS^1ac zl_Ye9@QHh&8|hgnp>R-`m=u(Yfia6PUfn$1|Gz4>551k-Qfpv|kEk<}#C^gz$DmG; z>d{Wov|)^sf8K0o1de~-wK5Q#hZyuwT@X3`{m{z5eIBv|A_;_Giuj`I-eeyWQM!p0b(Ezxz}G#&bt z=TC0WL*V^XHYkh-D2z6!j0dQUHctjb_nt7?pfMhxG1{Or9-uSYU@#tFFj!+Mi3Bs_CyBP<*7I(NfS%DQFpEyWb~w4hVk&?%jWjCWSS?C-3Z&JMYFG2soPY`h`myoUIh z>ciN}ih4_@vOrc^(&w6j2NTk@TqJ}Gtj`Sr?=?<=`4-~F!h>TN(YVtGS(kT2G}7qM zFP46&i54V;MC0jc3J&C`sP7sX_8L{1l=f=|YKOf=w)MuosTbWVy1Z6UpG=>>m@T!n zv4~W*2`;(^GF>cndJy67D@-K5oZ#(obhxzddbM|KPrX5|`rQHSCE9kl9E+kJC8nq4 z|3Z8mWB7b(l^y3CQ;UUpI`X>Ir_x(bF10-_X_QtvdeaYz+7z!P4vmXfxAfH!BR}&o zt=!Tn%Qe_2eVo*sR!iST^y#~?rA0~PsB(FI_$P3JCe8onNiX7fhCPiSJ=+?&yBU%6 z4~>MgL*MpdKhE)D-h!|0Tu!J?S7>F+t2Djn7%q^oDypP(oL|aU2it)>ojz;If7Yj> zMB~*_cs3?lvNz=v!$`j!m+O-06w$dh648m4^(x?yTOIv$gwIt(P?Mx=;ags`61FpiJwe`Z^T=mUjU3CDyske zJGJq}TG2J_aLF!L$+u;8e~UaYETo|m!Ojig5iPISK;otaX3h+&|Ds$=oYp`?Px^>o zsrgQ@(;96WB~MWUZ4X}qO;J-7fBc`Mpx+8q(61xF#xI7Y7HROv_j@h+%fXM?%! z5-7F^a^*qM54D7$8fZsqs`y`|KvdyrF{*^BDt@IThSy<8lyDQPMzbEzG7|D+SGqfEu6W z1bY-v8uROt-D;q5Fb!>F+4vRxXX(vH{4)W)PPAfFJZn_)LQIdpP(jHMP{oVq(3v@GpGmtO%C!%m8*;^{?Vy|EI-r}NG|T^_GykVHMD0Jd zI`V>@-r(vmLGT0@mGpluME(As%k>k!T->L6Up5x(O5wK)F1qZmLNg{##efm;^o#D~>0%xU0HQkp{%lKbwK+yQ^>lPwBuof>-K z?p;VlZ_MFiNd!thM`c3m%wL!+FG|2{qA3bGfZvOPi77;a_Ci>L2`$lILM2X{-90W#4}ESOsD-RBTHp3L7V&EP^sM%Ub!e7{Bc3(uF%;GY50()v zks`C=J_^5SX>7#2@muY>kNwyzr~JE#Jo5SSAtZCtNY5Zco5`!w0fw*&debcq=r8WT zJ_4R6>VfA!D}XC%zrz9V7~4kMa$p#zb^T#%)U_|}nX4~9`PC(_*;$T-L2~R0e~4Yi zpsSBXH1F2|Ij$qR%jjkK4dLq`F+D)UoVNTpVtjiejmvPzw=s$RprKrI7Iv~{+H;-7 zPDSB_*d3mfF#tsLa<8+TDkdMs+!U-4R&BG59g7btR{Ogj6?R~|1Ef=CP1AYpm#kuH z?}WY+pY}bBedpmO)d@@Q=zUNjE73Ty03Wr6)tcNR4P_xehY*ID66{Kjopsy| z+M%}hI)`R(v!;F?lp*mDG@TP(j!x&;b<`0=A5km6LALW)6*6HREzv9HI_s?+ul9c! zMxs|O^7)s*!Pdi4z+70$;-?v6SKh8c^FQX(L{D%ko>Aej%YV%G|1nwrP`$nci~UfX zsHX0I0zO!*0Ba9p07kZJ1@M&!P#J#pGh_EV5;D676i+vg!Q7aE3U6aCpZ;sk5#Yxm ze46y81U*AvB&I26^P$+nH8ONr5KL@n!uzvuJ*!uw=Hn`_IbGBR$iZ0?Ey<>aQT>Dr z0jFprgy`gcbwLdfayMXSLpBs@+f9zni+b#SZ)>?|y=hBbgy*>yeY#GEPqZR;`bHK# z@N8Es4L@J5`T36o0&Qj=CjL+*U!Bu7y`1l8^t{+-8&Ma-5>lCmjR#$&i*?*lf}r z?7{7-Bk~j(*mCutcydv`zLb?v+Q)wQtvc7S>YrIVoi;0SHAA27E0~g~PgnZNh|W=; z>FqlI>)nTFB584AGk z?IsLs4(8HU6#x`mD;4GJHsSyTu~FlVW3b{jct?*@wB#au%*lDk+DCWjly>ZTpJ#Bb zri8vBTDCQ3q#4=N-v9Q+!l?G{L)+$OYaxsHIb>?`kj5YBsz9gY9JAA4H=uRXBJ(ZT z0-D+iH?FWt5ABQAa*nf3H?J><{=opCZDM6x!&mojwY}+VAj|v0bx+=->+=wYKT)~g zoYLO$zgC(e3#I5b`_mKVFaQ2mmfFQv{lOYC zouRJncUaaT6LQZJ_r0IAcsMFJZnNw#*~>JqWHsj!d>O(?nn27#_2AJzmw*Tb8*IS_ zS8iJ{EZDM=7aot(RFfWdRJ|6OQ7!hzzBb%uRj^U<%+HQSBJc^Y|7}QqvVZZ*k?EP1 z5Wm_*}5$Gk0H+|(&i`x-~C=g@FRFx6APrfNdkKNeb~56Pr+-0+52 zSV*1Z-9(wF5B1%QR9nf!atu8^FdMrGXQ!GKP#->jVeODBEvI$K=pEWx3lF4^zaDG{Sqwe8 zCGMx-e18COyQ~Y7PxDg%UbTvs&rg$w$XsDFr*e~>Jg~k(F9J{V@o(Z`$n2Y>`zkiZir%V8ZRm%r|V zP0RS*#Dgv%EbJHY>3g0W3)EoriR6Rl*c^=CS6_t5IrKdennPa_Y#as}Gch(1oxUF@ ziua~GeSbz2FRM@9Q(ewst^yGH|sP7SNY;b9tgNm6z$plbC z6(-|%f6%}UI9`KvT5yC!Kwrj!AFprFEh;oj?q~J$crh&*sB;BqzzdW&s(K!8pe_Tw zzyU4Y|7WTGdHgUtxRk%3rJw#`FMHAa2#5y$)9V}JoO8(?4xMuorlume#nu+ppET-a zpn|*J8GSO*x(Q0#L-njdcGxJ@Av@yrZXd=Lz-?q_cPGG+Ttd73;b_Fh>(9Y>{u~C? z+WzT7-mN12vdtM_fCsRC7dBag+eem2M!s@+-Z6uWeRZ>Y0yh%9=olIU9PXC~^&x=Q z1@TGqWs8s~K(*rz-qZkNS%5h3NV%RkD*||xkFD;*9mA$yUsk(=0f_^Rb_X}R7Qo_V zN9JYq$z{j#Wp&0Q{FD+)?-ofwehwf5Lz*p-w|a<v&?ggiz zes}4dRPcPD*ff1+eUF^^ua9f7gmIDW#W&T+cj~BvedR8tVNPNh^W(a_tE1 z-H-&yNx9E!{54|cLbv;!VGyl6ULb8TV~-Zr zFDv$vyXIG6qgGUh77cAt5g$@eNM!$i3;{3G42&LB82xEG08QqTSn(WD#0&3$yupf;1|R0x)A7?;^e$Y~HJIH~hTW z&eyb>;(TJIqxaBSZui?mY5Ji1L(N#x^Q0MBJ@&<;p_)5~baUGlhW?!f)0DF1ZW8^+ zeQ~?u07CuHczb)A$&;Gn_ ze&SrqxzNxd@nB7*e;aAz6KkJrCmt&>*X3>sMm7N-l?3l(bI72g@a?~f7s1Xme@ zj2f3im|W)z54!e_IVnXM*;~pjHA92K(M$zk)A!pd-&!!D(@ z+brc4Yt}7%dK#SZ2CVkSdW-G((`d-^)RC}{4kkNlR3rDw!!c3J8$hq@}1>v09Dy^SWbrn4Ox2OR*AIZDUnq*Qg)R{~U(rH zLl7lAX6k63JHN()brpQSv(H3-y50F8B+J@vyL{l`v9c2V50ib`y)q@I>?zrsaTO2r zYHi|DJSF+&k!jlP6TMUl|HW>>MlPK%MwM&b)~QrxQs(7RNlpAZUp`l^%@}vpbp?0@ zVvu9uI>bbUH@)R!**W=}k}||(X6g_N5+pzZ@^6X`Hockr@7+*U$-bU$REp=gIOg&k z9C2(_wx3k*KP!X-o@Ge+T%MAh*_ zt3<&uMkNEgIs0LFNDk41jh)f;FiDM3xjLVi`(ezXfbE>g*3dX4v32~2Dp8n?QI$KN z{PM%l>EigCjS(2tg}bo&nHtq{oUagU0gXmRkHyjXOvjJ55(Q$68W6_-)EO6|wonxZ z8+}zGAc(|^+{=&d>^+D#iC-4LM>@kRc$jSEtA?(!zG!6{lmXD@F`$_9LB+A()nx(( z*Rs>A8=qku*Iu5m^81~b+fg?i%sMSmF#IqR>aMqVWSeulJoC}IW!<;SF*teLp{qjb z@$>4_V)$6_GbT4&8g+o_?$%p(j|AN3Uu#j_Tlx}0xL5b-nHW$?{na#8d@j2Ii!P1D zeO{M7)Q+0j-Ei6HnISQE=*Y*RW%;*%4@xboEj2Q-IUP8I`iq0Yu(+Pa`?{iM?i6OX ze3c4waCsMlygqSn)=>UqbEiCUGa15oSfk`zF+Yaeme4nZ zlPbf&ORuCX|APJM{8>T*;(74aWRX;al@)^ptZ@9aQA*CIE_0aX3!g=>W)f&g7?A%q3cbqD*q7~w2!ta$o#F`ma{Hs32 zzM=W#^lIcdQf`|`UlV$v|Bi7&iYi>L-G(?GQ%4SZ;K)q0|3NTZ&XPpb`04}HCWn=% zC{L1+_&3TK<}WDjD-1tvdgj3b5|kDHA7P%@;d0!#FB!#U!S}e~a{OV$ycG;Y`?|T% zVJ|u8M1sX9D5ILcBICrXT$$lKIcNl{O^;Y4n3Ta6E;kZJ$;-_|R3!M3X~$kJI;B58 zOe3_A=u)h9_%V+7|IzhTVQ~aYxM&C#2n4qf+$}i4f)m^=xO;%$EH1$b?gR_&1lJ(J z-JRg>w(Q)=Ip;pyhx<^|-GBX6JrDcM^iEY*b6`mfw_%sOzLLO+pWF65mno1MVUm^5 zW%wRmuSxs*;B^|fum&Ap-Jf;o#S?SHO4|Hx!w32LAkjM>w3ixgBV>4eWmZ3u@lP)W z>WM+U9jI?D3)g5^>)nK-wb%bCb(CBM8-@Z-vQj0(*Axos>J3*Sv&45$NBcj(YmGff z@?eIh!Q8Lw#j2v_92fi?HOq>MSftXW;|#l-RUT=Z);#q~Jq|^iUrs+~{JachH6{!W z*=r+bI7YQDW38#((3+W%@3WHyc%iyz*A9ay*`2>pvYP0TNHkHq!#cKFkA=Fz?CLKJ zv^x94SUuyhGOpf$ON5%-v2+$Isdh%&NQ&>hrlVheclq#7RcX&zPn)mqbbqNo^PqhE zsd(zgp|D@GDt+on{V80BgyDBb;hU}92Ar*w9K7pAg5b|C#KXZ~F#aA^FLR42s#HB< zI#rM;=1CmEcRrr$(@3u6^=PU7g}-5hCA@if8OB)EI$ciYd{UA_!)b1xt{ZSsBCz8! zCcgMso>b(6ppjTXr^lc-P6=;{h)Txp_kM><{RaaD&Ko0U>!IRE2{qvkD`R~IJ;P*r zy&PKjplA*YYo4*h3bu>H3Wms@RJBIfw_-bA|6)7)Z3ey0eziuw_+q=~H%g1?!N}*R zLvvL_i4_#z8T2yD(=Y#|Fz9`+hU*Yl6Q*YNAD>9XLPg&YOs)6@g2Lcb@ziE*l069b zxaPJv_+3@lN@MhV0w8L-(k)&KIN$!vpdQWICB;i=$IqQ=Vid zJE$J^^Tkx}BAtC=PcRFzrPX~#mPCbbD+GL2+8%wNm$+@hPtqOpq>7BODw!$mZbid^ z@4x8WyuG2%NpAlfrx|>H^Ko|j6-u!Ur*@(qKT(&FifVNU?AP}m((D9r1|`| zv?{6|>OTtD<$e^z(Wt0~(+!h`C-lgGj5rBd%9!GU3DF+~xmyejNSBFk4$nckN_?XT zwtjyZ7@Sm-3Y7K8P7jYaV2|E25L_1*&VGxTiQCwWIf$-;M*|G&wZrp#(nDv*Hc6fT z_EJ0m#A|Z{XUgj*P)P5NYIZh8@h=U3${;>uaeb;ir9CP*-yQ$Op9pYnF9Q{!t#z?K zY#N`Xx1#G#Ufmc{F1PHPy6=sjzxfWRj%_lNbH+sL z;xz;e6@b~Md0WH;_|hK%2`UE-iu|wC4LZ^ z7d$~_rMxvYHQ8_NFSuRP&*|@U{-a<2+M6<&_w7|jG)d6j#%yX!bp#=z9g->B?l)Wi zziT_yq?@AKda(QaEDFeudJgXy_sRiEZ$L>FCaNwEbL!UOgz`6~3AJw!G&M2|+#(Mi z^~5cCGr5a;2hz}JRiD~V48poaZz!16zBvZrhbE{(Y0|)4LC!)CU1sEukqj_Ffg;jS zLN#I%i%%zZKRFtJNE5VBQZ+%6ui$u}qm*{yVsQf@b;(m;jZ7b2tu=HhHAvn_&e9=3 zcvv6tgkPYNL?21*$ zK@+aF6GQce<~edDvf;+(q!NE7pW{%HU9$Tez07#6{dZ8UFs(D7EPAT>Vm;*k?BG6> zjctIN=Nn}6SY-BdEZf)PtV*@8cIOUpJfyI4WoXaY20vpEsSp9|(s^mjTX6h9m}aZ- z-p~(|6=;2UgcyK{LIM@7fSUaz{d(-}J-kA+wDqM{ zUA0)(&p2!B`?8E#x3jzz*vW$(s5nOug!N4Mb@3tpC+t=_!(s+tXy_wJTEddl^EhTI zkKwH$hM{V9##%N!^_Dy2SVjp8gwGx|_meME>13^q6V~0rn;z>KL_1&gL|=?^^BfK| zu-~TR_S`5wuBOJhQKS%_L;4GXx%4T{entI(QMmjm?%YrnTHjE;b=-L*GaM@HXbF^G zzDwuuo%~b@gce63q9Ml^YTNi2?YnMw1?KgOspLloO}CIx*cI}=Iykg#+bobZU{jKO zzMO01?clgZU)F3sbf3A2&J@Xt<->s_b(ZMfNUOhr?%;KX4V*-|YG_z9C^~lkoW7o` zYb-sSlJ@$MP5u)+tO5HbN*(tm)0WE3y5`g2lwGq_$zD~x`Rld_^+FK|)uf-VIX&=8 zB!Ob;1}iF^UGoBB6-)ec9@XgZ!+`mC8;LBPt|u98Fd-trld?oAm}(=sfcS$E_3Te3 zFs_m&!;;gBILm*otQsvIuFI(;Y4fKIuf!a#AsD`@Ps}7c5;SAe-R(X{{v4I;$>|fo z+e_f_-X}mS2zfk|?cAYyV-r-p!WSZA_7K!Q_mKGZ{!kP-8w05wegZkTw+38VO|0HDq{%|qt!VP`sNKqsHDCEWo{RA_AfkM!r?L6+g6YIwvq zhN=K%#@;Csx{?+cMT7EFj^uBN=dT$19bFjer>f{~{J5VFl~&gS$SU3Dfrb!(PGc8f z^AXsdD$*EGXF-S@Ve!@Ey8R`$c-XTim7|uErbl5txUlxJ?yOPYb{Vs`!jI`uXPM>L z+Fqo+OhaSC@`Sy%ror?OuMDEp+MqVbVe5Y;X1f=9ri0i%_7ib@_%IjO@F)oL>ZUtv zO~ZZhAymL@+s18vR(>{5ez&A|_mieO(;p4@@>eA(*t?b4+Y~VMn^P{4%d(P6z!T9=@AQuR%wVea8cBHp%uD z-Zsx!#E>eHug0XzP7CwMGMK%MQe!z|(xm8q?V0oEdhdkUCkYH<0%W{}PVM5#Ub5R& zTbnO);Hd!bxKto-sGa}wA>nX5)BmRkixP_E+ru1NnnRHlxtY$Kq@NHaCKaGk^9Rfi zl<3L8y0&d6M+Qc^u7RoJ6m zJJMXDPH3I4N;wS<-+V|yll7n=C1((EdCX9SE&aWBV05y55D~0ustm~r=#>Xk2ZwEjbdkj*y9)V@yZ z4u^cQTu*AsP83nqmFYIYP+ETSxy}jt&hdgQl&=qga=?)==js`W^6m?ku;U$^F?6!g z2j&&6d@ff1zT34^xv4Q)J@KmS?N~eY2dJo8Gv5=F^^eC){RFe`a!ENu-+N*%zaKje zh4u@21YMU4?OdZn)sNnLF2NR|*On=$T%SjGEfv!kM|2ZM)}fz@y**4vez2i_8mr5$ z6kb1=duI~Q^{zCz{LG;{AxZM3b~sKoHiHqRZkPCP{}Avma(qy-B$jsg+j{12UEzdV$U*vnCrc5jP3_BU6MtPZC^U;eKNT<^i?=z{E+a)3;>3th9z zbgm0t-v8%HX-|wqO_^{PEkW(rDoX8G3w&Ox_=$A4kE`p#*Pt7;|k&$6Nm!6X2A1_6B# z8Gi!3kSx^52)?fiAt3r;qP*4qPDb!M6PyKz=vFBB*jUWD2gM>ba zia&wN{FYu@RHfR#K&FK#{R`v+U;E=vAvfNJ?E;~%JG(m#LBO8E$msajBv_S(mLR|{ zq`$oe=;&RG7|cEZX+z*z^!%1l@7!JGkX3O0r})^zkc`;7ZmRIkolW0!j4j6! z4+^2+d%c*D`(;zZI2m3u-iu#QHkpFRH3cZkGy0Yz)-4Te?gZ?p_(pVcKL_6H9d-O( z?+J~Uaj#*!;N4;0a+H3;fd~plNwlE1Ms$+(JZ;$X;*RSdIiEUUL*}7|`nsuEdyLOY zWaO_8P62iA8<9Pv53E{VI~M{GdM*hHc(|7jO%`I*)iEooJ4+Pf zGbE_&Sai{H*v)g&|5YA^mi6lqDL~==R2ux-qF}V?77#KYn%pj2eNKF^z`_>Fju<~$ zGk+LTr4dlo@VY~jCU@}0knQ7}TO%v8*mHnvGjL0Ux2iu7z(0go-TJu!bXkHh10o

C_7r>R~m$Lm*d&1!>ByKw8HyJML1X^8E@Dlf9vOE3g3 zvKbfRs?db%H5bkIxQ61QY0c+n)e`gM`|$!r*W&57aKCWofqlZv}s&{d> zfnGrSJFwocnt^wgoMBUVGXMQXwc<^&3n-Y1tu^+?#P}Gr@PG1+;cN-_xtd zKH2op$*JOg{ef&K&K>Z8tGlaKz$lbophNjRK|O>)E*+1!idw@sIKd)hDzSj^H>0&C zJwXl%G)6td&q5UsVWfc3mHT_CaxC+eq$-}kW+zGxwMHK68p^taM!*AIDcXp%tj0nR zzE6^R2&SAW-kNekY4!4_(jHZsQM7iuBAvWH;2gSEU}qETFutEIS1w7j2=S;L`DLvs zV+-P^7T`_ff_G%th6RhM6ByZZEc!en)fq;d>#c9)?vCly3pGsS<;gcP!Q>8TJ9xm_ z)T#m^{F5iZuu2QmaQq^AVi#P%%D(BE%w__1pR~L;hl?W zfuBgL#Npjlg3PlYe)!CpW!8uN-`ii#^9GJ*j_B4E+x@0aW{!$8vb>%PB9^Wl#69d% z312U%hhM9GYmwRuCNG{#^>*-CBdmMO*xFt)hJWcrBN@b^KZwC2yA1k) zW5>YMoos6QCDAnA#2u+jkivf`g6IW8r7=7G#VOBc!3%-qb60GJ3xTEc>VTf#dTXJ3 z1u_xyi=mb&|7rGU;&H0#Fvk)8+Xx8KtPPmUHN`G6Yzi!&{ayY~Q}Ex$wN92$(dFf*pCb(Hd7J}X!9$sdAb<@5vLGNW24^-Fh{_$0 zBgltIJENGm(Cx_{z=;Az!-7%c`Ehi2KN)rBG0Lh}x|Ql_b!6Tfrd~OHHjc5q&NWPUZzFC*-|})`2(Q>X=a*=t z=N579)x5!NLG28G;g6#=hK{(Qr{~)JPHrn7aML(oxLllE2E{-rmD`fdV-@(^BL4UU%a)Q zX`RRZlN4X&*VE&nprPR`;^nS=K7XF)ob4!Tx9tGjsjL@eTiB4X-~74^i-G=jIDkro z%Oy|OLJOlJTrLv^j)Z|fNf(Bm=KY+NQ?M$6G1&0=7S(E0nG~R=pEWttMC*{;qzM^o zsx$~~`g~JzQRu~W+$qEnCn#tV;^ANtci}UhwpE4IVFImqHhMa1Fp{`M)WNAvST-dzQlyPS?mygP$OP$=k(+B3KKG~ z%E;Y1-Tb$JWVZ-}NYoIgqF=g+TUpFOd!E$~5_+W!pW@|!P-NaS3d zxm3h{!d~`Si@jR))3m$G6`6-!eE-4d$vD4RGj|&Uo?ZumUEL}!k@frgQ`fjeN|@%l z=Mvs8zvSN+U9PI11m|_Lb+lZl74J7pNcBGuiseGw23by(43}?D4k1 z!n@ZG7vfd%xP@!heP6_n1%x?VE8=F3IoFHh6%|i$2Iv3*85!&Q>crYRtmbtrxBD4| zir{)IrSk)M)|bzQkNy&z${~f6E!4cQs4}jZ(Z0wNjXhyGrY+ zw%9H-mbU!UJ6%e=c2SIkiG8T<1=JbQ0Ib?u2H_+nr^?sA?P2W?G{Q9=8%nR$aYG8Q&5s zh5Xczp1|@pk@i0kP4Z2zp%%!LzVyqaMw? zZf3XrqosPXw5sfx^HI7W88~UIxfCt+8rktnoZidJI>8&P6+i?jbQheyQ^#9=}IRE?c!L@C-W9v2uQ ziX7SfO`Q6`54)ZZxfg+e8Hvpgj@iFk96KmPv>zio_g!Ay>w_rl87mzl(+;!l=vz3D z`}Z6<;1zx#88ed5A$TsGz{ibza<6P!W_UPdEc3ViUi63vGa^KUxv&SmgKRjopAb$X z(Pyqu9tlLzT-YB`gd3$7Z+=1=->zcAA+jK1f?OvM??TK9g@1XNgCU^|n2830XPM%H zn%sXD$X72B@ykCFHW`uiz`X#?Ie$WI_6rQ*NI=GhKk|f_cg(ACl=E&>=@+6uV>z+K zeG}ndALe63DN~sH2S3sy(#%K~PvkwrDav3=O*QhuG0aF4DH|L7?n1j!d7;g>xe(si z4)2uroRp0Phrxo#L9H(`0n)fKouF}`=4Sx15hD7=3w*d&%>JZbI9|9K!5_1qzWC?r z!;EP|{Rw6l7Bk%2rF^jGkIn2)sSPJl4fo9mp0FE%FA&)u3H>c9zCVt+?u%q2c=m1t zt3c!pB=ikbe7H9!vP-uwM872mFlfW6SHqPW!E1LTG=VnA=x@QA#TZuI2n&J8UC8LU z==lBw4`_&n)o@)_L@$Go-%364+j}F5zCh2#!1pI&_UF=uv#N%hl8FNjMSX8V>jy6} zt>YoRnAX1m7p_YKZNTs&5FLDF$bBcC>2%b2Of|+dxUJ6%+feY z!~6Q<@yb*A+}b%x!@_gBWtJCeCHNEI1tfH6at26Z~^B1vQa>4f8_|!2iLyE zYRi0;WKV!4iLD&~WYgV~RI*hLIJ@57SDgBHELQFEsXQPXzmv3l$sDs&Sr~` zPr0>+FFKX_gQG~{#8WmP9_ll*SHSU7J20GdZ|M1O!93um1{cEpec7!7xa!<_Ax$8U z2@EEXv_Hc`)(=m`w+CWn6?X5@hNj?Er$>gx>%=%A5HH(i&-+#%bih40`L1eL&$ALo zH!EY{i8P0)9!8zwc=b6(^f@q33*#C+^fSi<8=+U9Xs6LW-n7h*{|(>&tTkmIoA6y;(X=i=T2>D~<3xi=Sb$wl?-IY!}>LodkaT)hP1l$p5t1skeA`&uD&F z#>O;#d%|AKru*}_a})W>zek*=)2ZY2XF@^!=#i}>`KBXh67eStO(2SuGm8TJ% zlN=3;fest;;svv@3$6^84oH8dck@E#FYj-j(8=yy=nd5fGKElirqMTUf=aRi<{^7W z{5?rV3ct5fIzp96Uw#y2)lwe>*48r=XUF;8SE)}6-1`Do)Lem%BM)( zRyJb)wSAVvC4B!uKj_R<(G(UdhZG5)ne3HO#PSy3N%vbHqN4n0p7q;s^lEGpBTC^e z@hJZgJ~7&E6XZ0cNCGo#W{Zj1rhj9UwBK~^F_AbVKJ_fNE-o4j{NHO@Q5K^YuVCvD zpBHb6`@Hk5!`H9#&e#90#us7J`phq!jfT8=<|nKpnH?r;7y3%$`q*^wdw(L;@bz1> z;t%tU_H7XrH*0^|eoqi-o4IRJ6AfB*IHyPU@$HJ??}2&~GEm?4Pwxrponte@`-Bx8 zYwo3o+2M+R5x&Yb*Y=;*A2_gb?Lq0QjJjDO!#@@ zJwY$VZ|hK!e+VLI?U!p#h=A{e1a^}*uJLewA#c2tw#P)^+0Mh`n0p!D;6U{-B44$ioR-$3W=i@xM?S^VYw#} z_~n0m5=F;$xn&8sJ@$Jbth(}XGIDcAnoVE__b=oRk(#Yj=uXj5XOEl8>^0!z4p3-a zb`Bje<+$pbX4J0s8m8Q3`Gf&hy*Vo|tTB0%Y(hGDHidZMY^p&N3P2f3y=)_t$R@vj z#2He$=MNYI*3(F*dx&+%#X0=LSv4J$OT|cp5YJ1!r^T>Pmp$6X*W-8kR?wU7q%Fsj zbYjRnSv}xK6VbY%rq$+Thjlj)a(WvX(C*oHja<7`t5FIpV~GbfY^pB*8aC@3@QYtM zX?<5ukiDZ3+d=CpvqU-zd~9Kbort_ zj6vDr@Q%XQJapwb>g~qhg;?ASa%DE)UWzwQS0N={r5Zc z2U|!Z!7)@LmHo`W-RWjee6nf&cqzYXD2sK3A{>0i+E)GALz^ygxcYp z)!5cXluJ(22$6i%*ltFYm*>Y$_`bZtAE8+Kf019yT85AJJYlD~hTfCh1LDD3Tb%fX zO-)gfj4Z6SR8w2EAyT^fjbH-&U$7rkKNuy+&dO-2@+oro)~UX!To6Y7ju@F2f7VLJ zjB40oGMYI@kWx|s4$ZA(z>ci2Lu@+D1z;*&_k@cgf zSt|x|{7Gf5q`H6T;Md~mcZ{NvX024#ukmuJYF7z$C6MVOn18Xb{6MIeXdK4I1#J|} zTIv4j>1tQA{`q^ecxnUktiIW$P%_r83fI%)#NmNFEzq}dybpV#WHO1IWfBm~5taK4cO0YVTk1%dcxKtZNb&X20cb@lzL%i+ouIaj>rUyf47 z@#uR1Rh2VLD-ld&2lMfdw041_kcbGSN;K+Yo^3#%oF4TD zV@gHZuZJVh(aDlJVb-B$EP|c)h0<@sAIg-tnx?h1(zLqEkkG5%JiPI47|d8;l3M%y z8T=}_W3)M|H4?cx>aM&j7{|ZW>0$RdZ+NTo@p1h8WjN#x26%JB7EL1~^?6{gUoV~8 z?1@OX+yS%rP{1TQ|`O18x zhObOw4mA60`A8fiEk!uL&yS?!us4WwL#-Xm2P-g|kqTCqCN!X(R-eQj)>5zAdi1qs zAOdb?4OfO#?;T)<^7oM5(nqDh3*E=@h*7#I5qG_Q?(kI&Nl7s>n#fiHIptnkCNb3h zWtG4U-?vzYjZwLQ?Kx#hd963uHbFdp!-1YmjuOd+J?MZ8%P}y~bu?5}ld=;7e7nd= z+-bQHAvS0#dVHj~dvw&=g6x1>&|+*?0Isv|^785Lq1{_9U~uq=3bUE#Nh;O%S07Qy zdf1T6v+yBd$@%~))y>m=7dV>~Ww*!6YTAk|l z@g*j=NmcAqI-z%_*T9m?wx;~ZA)sxVQeORg)N_p3kaPOSc)IZkw|4clBB`lD_`bdD z@yu}gUtXyjqsW^%$~DP;%1&ViGOtT`(^)e1Up`l6c!Ns!&8V(&T*tx2MrZp{xh@+% zGi1IU8nJgBNCNOEIo#U!ZQVVVuME$dgF?p1kG3v5h#A`qC$;iltyS%pIU}5DUC-Xb z{kv*A7PKrZY6Znimh6|+#N>kmrELz7s}!{KQtNtJX5b0$`F+dg^Q9lLom~z2*V}0$ z)2N&3x||mzw&gC19;R8t{iH|wJg3@wwKW3*DbXTx%_At)W9EMT_x(QbNBX;1+IyTi zT>>c&$e@PzXQe(ENs#_o=|g%JRHgnGNWV+*9!13l)V^KG%hR@$11@~M(6Vvhe;FL> zgBQ`1+fDs2EH)n7TGQ!Lr9>74t|%7Y;KtA*%)g-AxwP%(QAe}vhf~X-s6~E{&$y?e1RcWq~dbV zkJgnroRcyQNytNS;ZxskDfzOQ{CIC?iOHP4W}m~eI3Dkvtp@b6g3nYMGpzw!^`8R=(VAj)Sc5hvkGV{-uOkk>#ngrnQ7en_3$Cb$X4*A4bC) zGvi6Fb0unr=aqT~no24=r#Fr_?d|-m+hmF9YtA#+NhE9ZSzvC4C_3EUx^f2To*_bF zL1GHgDig7h*UA@?pF_P_`=qC(#dIRXvBfhro5j&pGY+ULaLi2z+D<6-BQ*5({H?0` zwQ5UpysArHgW}dqv!L{YG9zwXmK8FkiCe!R0B(w}QC@lk;Uir1!ip?>IlT<##KxEs zdV4Z;m8D0*k2oulQ}a@Ig>2H_t#@q_J4h9Z(uP$Yzr0VgsFXe!o-|8uep|%08=BY= znuqLOa6OC2(nO=Xn@+#Zc_%Tf|HfQ@wtxYY#;yjHj+K5I-Ufry7bcy*(OFGPQh^5sbJ~Exjjv_7vTF_fA2Yh@~u}(z-5oO z-M$CEbuHVCpB4T4i>E)LSv2IxUk@Fks#i(jmr(-RSh~JC2HID&v_W{g?dBD$aIDY0X z)g`X3zrfLd+THS0v`Z^ubW8AL2W}YZDn`n+X{3o*!goXtJc}BE2}$dyJ}W zRE?@{XgM!f+Dp_~e>_*T&G2Qpp22$bgMSiZyVuC|o5(>2haw0!L4Jzhhzscu<@x`~ z>sC|RSK+(~j!7w@b45w>5+6Wa+L{yhD3=TO*!Y2cpd~$F9fQ^)PZzw;L-2Q>O$56I zaF#f&v2UNaI{(UVF{;S_^+=B2;Z&F3?}4gTc$xYx{kd&I(7G)%&iV}w;?&=Q;2Lp? zGj{$(5fvHXEXD$lulTCBVQ9}WOu;i+885A$>Tj$)YXHt3y<1bRf+VwSLvvX3r{` z2{+P9GIJ1Bh1w1srCOLG)1OC{Yw9Dx425Z%`AdswbgKqi$vSJ@6WvL>bj?=H_ZdaA zm3X5?*8hXi$UoM0WFJ%N-sn!crfarqzRxPssKQeyww|?>oIc& z1RhPb7MkoyN=votMtubFzw3UInKNXIEAKR*)qxa$s)fm=nLRgf{&}n?CK38>_PmFj za5FGWeMADb(`H~Fjru6;5A_ip*cOB0PCG1=YUUdvTI+`!VCE|zO(xXxu6a(g%HofH zel+^5)oMgr(Iv!L%EBS~1g^6LM&f+)SmmS%*L2m1eg)ZaYltSD_lpB4GCZxhuP21G zr|cFdZ!RAN5MhNe5AF%vU(MqR9oZrU3XN-Nc7Ch4b>h#yABHh}^EXm@1Q3euZ3ByPl{i@%;8Tra1O zF)2UQ@gn1|5%ySrOvel14X@Vy?pO=&ox3~!>FaOc_ey4ziB=!v28Ok{2_}@sGHnAb z&lKelhfzky3HE9h7(w9GOQ%(PASEdu7j}fk`DGR8NamS(w%r2~R#1sTbP8FgfJzmh z^$wUPejaBSH+}|s7KvPz9)8Yi4LT#TY7_{;1C!gZKO;#{NlGo%K z&rpiHhtA61z!MlA=i#q(e!fGOR)jWL&pzo#c8QtD=RAC2>J#!VLw7_KE^ho*ft8cI zd>l#O`>Qa`T0}WD?G}+?w4P!gtniFT#yRbmJ8H3nbsdp#i`ZU_#`Cw#N@;>iZVC6j zq^x(K6uq^QayiZ&5*}Tuv(iKt9M>u8)Ew6lD=&}q(^pj~h&8W!r?%Fj>9Uy1c<(xs z>0G8tzr$*NRK`;cr{BX1bLb-O4`FZ2dD~k})3bsHeeqp1Qxj40ltlLFg#p1N`CEdh zKgBLl4B73`3{PrN&oSvUK) zz84jRptF!CX*TtM+0QYvm7m|{bn7mJ;AmlLX^@lHPJvMHBoVzEaz7TBeait zH36~_jV6fGI$W~-W0;@9MyQDddD-oGzMCDdbV)GHGV!pt7r*<%mt*%JRb-j?Ps^#G zk^pK4-;2v8)VNTol_yY}4oK1N#(_#6PL2WUKMOVS5&ZPJy9M-kT+%du7GmzYjb%B7 zt!V$;d(+7F|8sK&`heCXP;X`ODhJ=K@1G#9(LJHVEE==}Lsq}S~T zQdI+!CV0K`7lKNJoK{G~eS5e9jg5vlgFB~wFc9@|*P)yjJpnycbHKa$*Qbx`;QKXi zn}jQTJN*zqzsp*!KTIu^G>UI79Jfi{)nd>yxL?tB6Y;2QI0@aZbGM0zs+;c6hsTYNXQi#j zJ|D?yof}$?4hs(_Xs%|AU1-Z%lm3>@>h#WnZ@2QLEsnYK1?Rc&fcEluKi>+0icSsp z=1A@(t*RK|rNO0V6KS_t`{IfZu^uI+b3Ez;4$qooymyvv(92aD-&=UMszti;_V1t7 z=*;|#6fivGvJ$J;mIhkYvyOo#?uYB|b8p5GY=>YGbAAI)dTNHg6X}g?hFKl-Ljrs^ z1&5tEEH}5RqJbn!3k*)0YsAOU1E1gdDt+sss;w8aTZbgs4wm6%>_R*U%T6LB=iWpjco%xtkWIMeQ#+CszS*8f8~RIE0mHE*op4Qvo1^WIjfqDy zD7~}4&v&&WHYf4FI0>3~)Q6C+#1dwU=n4lXbW_Le6;#k$OtXF0YkDe+ zai#~_=YV!!%OV!ZlyU0>jcF|I($iB{Q8Z1yDwRYmPU3%cGBx>HA40a0mTCa6vpe_u z_)#xn@q-nOMM@Q|1%Ww@l)I|iUeuWR>E~r7{mSTv&iDCmO+V=#Al200ukAq^SZkMH zB45X|0E1M3$z8Patf~Lm@XBJ`pnzI?=yNfT`mj$p&(GvulC{mcE3S59ML<^2RT%JWO8Tss~p#z^Y zN7{cq;2!wSKKI|H%x=4TQoFPkUB`W;SRe4^GYPA=+{4>mOLc*+(Sk0OeHbZ?`U-BN;Q7#bmYlLQ{!!lRG zD4QNAdVxPgo-~<}=YZ~>$bJu1=A&U%`LQ@JY<~Z~*wW16jdLY2#NI=q0am3VP$3Ak zvIAPeYI#-L#Cwpv-DvH4-sYK(yJK?C^}Y(IbPkl^7}z5|FzQ#o!2Ou!@$-)9R!I$@ z@zYGO0EGPFo+BM1ZrO%l*jVd#B_8*YY<*NBoeX}>JN6g*Fp6WtcBci{&91`Nhj{y2 zQza2oz(Tb8`M!YR7I&3+Nh!ut7ut9+etWiMs0$eA3?-|b5R{ADNDd}bRDuPRx09b5 zq1QM5HzFb~7Q+Xt$YPeXkhZ>#4#))C$MuCTa|N#iic@}!@A05NYTS5TJO0@V^216c zGMF=o8%K7eeC(-;7lvdWllfkhaU8LoP_*w{F1ODC52b#?Nqf)pE|CHb7pVvB9g2DL z_~R<;6?byL*GTtTE#+1E@qMqXPRvqXL7o=B)m5<@$THsQ#&Sv!vEQw#Yd#kK3vS;^ zZ`ZmXfj2QiC(a7Uzw=L7*7+QKE^aJ3gc8RFHiU2>fg2+k-v!Wc$$&t3B ze1fC7b$QmBT+^fZv-3y#$(~fJYot4R`YE22*eSYTxFcBS`sTanM%@(WQJA~9M%`=^ zoa^gd|zQ5u>j_roNdNO5S?}ZVL0M#NduEhR9 z*dS#1dm1fO!~~>%U!VwjptOjSZ;y#(MQ%DX&-~6NWfmVjyf#ZS5oyd_L=!P4e z=Y2keAN(IUw9n0}H^z;+i@O62sVFTvqF;4GNm#C&nIF?~^36M9gyJ6rOZ!Lmx&zmP zkk?W4^qxE6pBge&*Ti9LZaT0|d?0crX&jhi=Xbsmxes^YtmQ;Acn@1Tm$7enHWc^; z)6?69;4+N^9V@z)i}g0`EAQC9IUam>v@IlLYiOxfJ##tq?6}zsYUFu>dam2s)SQIA z`mz4a!lX4M+vLf5Pf`OWThkjp{yV0mRRYM?`>jaH76IQe+&6|v5FYS3<0N2je(^%c zsTYp*e!}#YRj_#JBhT(~YbCigmO+98RtB!+nda1J<(TRscm9-wy>l)hISH*4Mmd|* zBZFktuC$8#K{?@x-Z=U54rR>~Me*^6Mtgj3@-^F79hV96)*C$Um6hn*`yHi)n?cYaG6QP=i?FNN{BhPWpD(CxbRX@7sISV>)ok*{sctGo$Xkvn8|h57*uc zf|U{IvrT$_>+Hau<)=(-QxZ|fe&F4^%1L0p9X6cwu)cg@@BkK3X?OaX=xIBwH0rJ3 zC&kB$TP)6B`BE(Cnc1*W3^~Jv_}ywVG#StOquPtRmR>DoH_HY3^b+H$7kFs5-!h9m zVRuz%V=s?ycJIx?De{nLhuuGd zGp|+s?-j({PcxJZ>vx&ryYNR&5U=kOG0vufVJfnbQDbp>4HaTW=&}9Ik5CZ|)M&4Q2j^7{6#K+q~ zzsp5N{yt9k^*p_>+%|k)Lf`3XWBhgWeL%~@L+tEhCzvhp1Tjbhs=Q&_!@`Wq>n^~+ z8{fwt)XS>^3}^7*3eA@ViaFo8K53@?O+L&=U%u_mP{Df6DrAV9EuY+OcGjFsXI zRT|qKd(nJIL{TC5%r=eS#QFoJ>{BTt1yw^@7y3QDF4GSVZ)G zHyp`i5GBtK6yn+uq6qTqdE5_Hrc_?JbGRRx%&5F3J}F)2He~O2dw!Sj_02tMX|d!ZD|2<@y#h~qhPC|UPuSUk)-L0Gbntb*&4VRk+Sh9oY4 z!7_GE6N*Z@J6r~W*nf+szzOZGJAE619PnLE)nuq^sR*oQT~RD3tKAkKqkU9d1l)!m z?e-a-a^9=miWuh|uj|S#ij0ddLK32DAu-Xl06U2}@CFoeo*@_|DE5LIaKH(uA2&;vPj_n88=_P*50vli=S zWoM22s>_G3gSRa-+o7T!)j$(074s)ofI6vS9}BtSk)G<7kFAi=J5}%(H44$CTq_i7D7yp&e7bsxcm`ik1TF&D4 z=~XQE@N2}Y9hpuOonnO)w-l7&$&T%i{d|Gur@r@j179hc_u|Gv?*O z4gEAHEDf=}My;7sD0ch@HA^5LR!Db=dG~dzPJ@XgG1>dNN=chu4l#;Mg`wPko9msk z^T-rsUV%3gIM#Q^9KC9MQFIu%THNuweDp;`?JWY6xqU{d&781hUb*j_oQ|Nfq>guO zQtd5iMD5oS2_5fDP<~42v{r%A3QDAe&N2ZD2B-PSFpl|&JlN(;_T=W9BP!`+=rRW& zD$jwN*UJ?ulDmlLZO^djZS|0cme^hr z9r2{MjU}MBJu(|wvIf(D!P!$qbp&x(`0y?4cl8q+#?cZR*m9Aj%Lacm%q*TKUNFrS^S^Jo7x>fIw24@@$I#*-+7i2Isy z{Tj*!miH170Pz$s_u;AcNU(Al5zuoofBmarXMSakp$xBj>hUTS>rGgd>+YDN*YeD! zQ^adkeX=TnH8*|-(lOMi-q9A%7nXWo^*I+YAdSCq#tBlCGzCgS6?=Ma7Cx$Z0R&aQ zI9USc70UWLrO>O^n{`R=3hV9yp2iow^G+`vGvek}g6?MgKm28kPTzvasThwXMx_hD z9~V7|lny`=mwaIKb`Ji6#u?q|H+f7 z9D)I!;0_Dcqq7*8yYAu2xh=y)Do3`glP#|3rm^_s=fD$KyQ?jPr>dz8|&>WW(60^AaDyOV#{m{=Ze#PZVRkx!pZ@Vq`Ld-u_3bdh;g1F!Zp|4w^P62T3J&cjuGImeHlz7sfFeiJx?RE{4f zA5Gw}rl{jFaU~FZ1^*uCq)Jmbe&htrp`d94q%x}K-zf!;cpz3ncwg#)<40~V3)|Gd z+stQl_*mDww&-aO)51!|rv$60RLTHq%#I}QJe7GFmMqd3?9 z{&}7juq^A+BU8^GW@RzgzN6wtDW^6qmPvci!8`>@<3aHr~ygN{TBYP6GR=Fv50Y^rtw)n%<&wSch?VFwX&Q2=7}BZ1;(ft zFfx1qkUxou8x@V!kw9(lB|nGd1Nj2V^`jmFk`;hq@>if}0t|2bY#w$TJ05)GSqk_K zc-bttzfR)!-3G*|riU}4Gj{oNw{>28iE-}h&O$2vySlZlyp3&p6Q^I)m{k=xayj1~ z8Xe$4{@G5e(QNKk((A-~wr@ourHSWko0&ofG=6E?6CG0AXtT>67b=vxZ_z6Np&9q8z{>7b> zM+M{`g?WR1e$TLmLrhTC#Jv-QA#)S-eoU0e*1q)nE|zIK=%qwVw)4;DqMP}IUD(iZ zVH4m-@*#}v5aA=Ql7GAS9e|1U_#lDf56qXY#FFYsuZTP03P;v+i9cpF{9moY+I+n+ z{aqKbD4ocsv2#T=8P>=`^nYXT)~ zt8kH!JDF|84ofG#=~!$ILWFzLTEay1QyBJL9q!)o#%@ec$Sr#$!DMBadA9fCWH zt$>x`8z2qbHe5Cy3wYfEvrk_IBXw4Qje2pYmbQCPsP#dd-Yt+YbvDBaetaIZ45oK@ zEC2?f`X9O^iL zdqD563)VuOas7x%+q$vXgn7P`tkThbZ@d)*hNFYZM)kFarl;BMexa0ss-KW49oS4jtK zOuqZkzs7x-AWJ9ptupA(oU?mY4YKu~eRMkKcip+jk<{yM88a@g5A{cLU2}!{WcHCr z$WG}u*?pb8zi8G>AOZuC0?2P+a_4{>7QhV{{|C#&MAQK8SF9u0-Z_}mEvr4S_J4x_ zv<$QPv0}8mu(F+)ez-im$%7|=*0sO*Rf$ad39Ax6eSl$+Z{gcJCF8hL(LSWcYLiy< zdeK>5r!Uc0fmC|4=aT=J09tX|cPno=OQGGXhOI|-jt_Cf~te9mIoE4knWRLVCK-ZWAa}nMK z*xmRM{6D^H7=ru!^Swhb#saW$bDPl6Z1Qp6vUQmtk{>jzZ)B~3d6Y=t$QF^ZHv0i#G3Tq`!USR4)QAvkk>ylCH!=?l`6=BJe zFGeXX>4WURb~zfnEb(5lYHEKe0tR~rG-iOGU4D*K3CQ>ahyQYUSF}lhnHe9<`0PdT? zg-<9~vzIn{sVes-Fo=(P(TgXtA5XV1hyfcw?fKAXKU0<1X8x@Wfin_=c%b;w9}U=a zK2mn69NpF*z_N}(7OeX;#BSb^><;h4+-lOC(11goIl!zAj0R9u4FtWwuIO{O>y+wm ze4%kaW&U+q0x{RV&mCR9+)~!J-*ymHzIiHrv2McRVEMmkeFHC-*M%nJbxK1^!tE}Hzx*nuJhz-?EJqat zyN6M6bv{`p6NTT(gY+V_f^Nxbdddv+5E7bBN;R+1a01c_&dz(=35b!}SQ&a(A(uY` zXp*hQ5B?GabntDGydcqN7AG2gsr?p?12bm=ymGOu4O6k%eP)keZo}zLDFULi1N!Dm zhBlQcMUBluZNhw&*z{$3TBB^5bf+!e%4NR)Az%{w%=vZPFX>{NUI{mU)w<;9HRsdO zy}TFOWRR7+e=D`E=NDDF@%1YWonc(TvD&<7S}Av%+C#Cl0eQ1K4%$N0W8cgl=SVkc zKJ)QN`FOR-cL&pNh|9ueM11q{g7E~mNwb3-1a;!e@B9&nwc&pP@T%sW{DrYHa?fEqsm#u}b%+a5u626) zy8xNQrkyRyMXu>NEC=Rdxx>ytr)<4j^-?A6D^Tzy;Tj;#2aF~$%7qg_EQ(0PWVSQx zZMQ=5ol5;rvxzfIMNsd>6P$A^S2Ja_GQV5UoYeCt@22}cPhWtS$xl5a=aNGL{@7}V zr`zIhMO+8bgpb5MFY6n7J09<*mq~ta@_pvNyu3rghvp?|^VO_=S0MO0!i4esOuKMC&EHo(xSh_R{MZj%-C0@uk=EYZ^ZG?AA}I zb$_N?N@ZMWTzbYTN^o`m?KP}f&FIc8q~{4QWYmY&TCxEcNJO$CkybC~0ox)(JAwxg zTbL`J*RNDHTAorfUvzN^+z+r%>TDZMkWI`lbPCWIrt?Y27NzwA(c22&( zda)x5kxe)jJ+N$dvZNBuzh2MlwbdZeYR&&AuC7Ps%3t!$EAeSmY2xcSqr%k} zt$pu0l9ixd_mbX{s++7TbjS5PR*3a_Q>6X+PhG3ThFAM2^|5*ob=JlPcXJx-_H+GQ_~0?;miMh(4wIc5pmY9qo!FBO1`WRCKcqT+eaD| zclca?@_gZ3Lwz_Gu~zB_*uMVBXi@7kd{_gh?@#E<*Q75IPKezCg;{gJp`9Io@DaUT zSs3~UOYHgw6ONn%gs5r&!AEw0pOOuw9RN%Gih=Np+yd=g{{RKhEC`y*xa#UybK*Z{LuAR7Rs03lFD1eB?hs{yLcLH$k^TigZFTSU10 z0R9yiM=}en(*uye1lB7sat_9{ksl`Gc6Gs0&aXgWuyVTi_xz(eS<$Acut%NVygiC;?Go>nWbw< znfrEhMXCw^rqJp8Ut%(g<1o;Tf8OF6D?#?3YkK#DP+4VDC`;EfRAbS@y#QgfM%8d* z?y*=|eU0lM#~?I*T8-7hchu*bjS=i?t;@&?Nm*(HY*PBkh2Ks`p0F(8_wU0H^HHmQs2HmP#y>~2goo79&>iB6eAiQIeXTybuqTFWY<0!^l)0@79XsjUfF zCTH0fLy1=7Vp^69{Q^iw`I=23?wUczgdAWeuPeD2ptJ#mp?X+hff)}3S8xxIa`O;w z5%l_m6yX$s_KA7&6q^{pLgK=!858%6N)wnA0-8Gwx~Suf&i!zztx=Bj-m(dKbkfWFxf8sQ&J3m6o)#HSR7dMqay!j~^T zc^s|?_Q9%O|49xE?e<-0dFH|aXu|JT1!09pVWj2g0M}2!*|%t+nIq@lxo9st|>;o#Y1J<#I<@MoVOhlla!34+(Gn zy8e1IT?vaagg9`#sya_M#>7CnPFTI8#Zx7=-vwXr8XY8*nIFFQt{lN+yP=~8o0{EQ z8e0m7!B?%VdZt-1I7UDfcVqZ3yhha@%1!Xpy*FKR4wV|}uwVWA#BVltn7ayVsJrZ1 zI=i>i54-7vo!4`FZpGPtJJx(61b;i&xDi-6&}Nd(ktImyG4@JbH-Vl`Wu~ zv8g`jrq)hhva%XXcpwR1cyx78t@PXhD{vrL+?=4*TARt}wgxnYu#T(~F!${cxCVWE zd#m^Pb9nNvj?%y?KEqaVo@ryF>%c!F^4Xqsx`-y;k8dv7o5PA5a!i{Q zoA%-2HaaOGc@zm{6bUsH2`v-}ofHX!6bX}kbILAx3Slh&v_cMcXFi_y4d7g_g)pfv z+f)<|t>bW0;Yv=#;HpvK8YLDHXKD~FYDnCbqM>Y}A>TBRi#I!c7Tb;2L`S}9E*Bqg z`s{uWUeg2eO&g_EyMYQkHT@Uz$zFvV_S9LnvP>Ki)VOK-F3eKjJq|h!lg$WYixy?v ztjya1m>iAnTihMjp%Lx@`uVwG56Af0hEbu(j zGj>^8QoTdf>2Yu*K@!iDYUb0R`w^d=u3i^>^PQ=sB?k9V)Yjjn_cUxK0=*;iJTL$7 z^d33p;b`PBwG@HISdV{M5>W*-#WZ!GU-kd?Nci6#3CV8>OY)gy)gKT3`mZo0VquZy z+^yaBW?wvoGMP03e{4Y*E!^fIl8<<(P!j zs0gMkpdkGIu0SxO>ln+@#vSnI?6Kvvw^!Uewl|h$ZM3el4kq}D^zOOAd?`P{Txp$% z2_vzrGo@kA9A|7yt+>L28<+gj}%$zS3N6h-e{u$?pO={)bJ@_s03>2tj= zb1@2=QEs2AcSJ{yNu<^^v{h?4Tu<5t+{UF5GYcKo`2+?O9UhSz%^jPxPt7EjPA zzHx208C78{gidn-*n^*A2h*(o+^J_t+jf|0ob;FLF8lqLmW`Tb=pd`o0SJGc1*%+0 zN9tgS1*!vuGHvva#3!r0CG#P&&;R7S&8rJ-aIepgS*q*5EhAC>5VsH^Wa&D2iTSJG zTxi1>JnA~1d@E2t^^nz3tvi!m_5IC^f((|IajsgEJnTKuMrJVH+ zA3aUxhtCH5JW>buN+Ng6#YefbV793>H94PHxzLT$zp2@AQX?R(?mEcqZ14+1J6z{(3U@{6TY4cpmW^)ArVj4`otnz~{q zyeh*TWi;Y=2)(I$a#|oD2m&o20Q?6$--p`d9VDcI-obXd=Mfi}zFE-bs$Y8#tvxP! zBBe6evGcj(fJWTP=9?PlsQy%7{Ck#|Rvq2*GUs!Lbm{tDe3W}Rbx%}L zSFG=@$}k%vjd*Av#iuVXYwvj|5mhVcp2s$|23_^4VB|u}d_DJCZz$ok-*t!`-Tx7fWk8yK;bgcwZxb_jr9)RmhaIGSv8okk2 z`R8n|RlZ7~WB{+d`7>4+dHHotzsD<;tm7~hFo@=rmBl%$dYL=~@X&Z*x#Q1{E&S6v z{H9@76)Am}hpdmgi`33A^Oo^c>%iu11amT#8LWpp7?#EQp!plC?*()4*c>f-_0s7k zzq2KOvuNj3c}6HHe0%ex*-uBkQx&82FzY*eL6?nIiALlETva(g;k%3`r!euvE&&EP z&brJMgRH}Ycn=Csv~hPLZ_B-q?%xnw$FK|gV04X|ALb^hb#1Mxpmx~|NxX4iYfsQ} zUCh5CjivZ1JbCVUqA0>&aR4>R!LX7pq>X-Lm~pY+rgw$qMQ=*CoCkDHOP&@M`K(@cDT&f&JR4$Q`)ANFc zf{0m!fV^l>!Nu-moMwKpk}}`Ye%VQg>SS^JK-eDb$hood9SANdRaJI8Z;JKuvN%;N z1zhcp97Q~?FB=C&?U_3C(c`;E&t59A@qq_pB{reEC-!s8Fm)S})sQio4!mEy9|=F{ zS3$kMOslPy((GKTC}Iis60b@V=k$zFK%+BfPKG z#x^8`w4wr${@{Hh1$T$5in+Z?k&P|A7yS>X4@H{}AtN>$EI7B22_w85{#BqXcMCO| za{&m)X7O8Y5ejK-0NCMt`uZ>?W6kH=3=7tQj(fGXVO zeheZwACeKm+Zz zVs><;_p!{&=?XhPJ#nVlX1wO$!x@jdIc}*5_8;W2ULDU^gUi5(ws%~eLL@)IB}3to zpMA|-_?WPJ*$J;b24R7z?32j{c}~d)tbWNv9|j0X1`cLmBSD)JZ`RP<^|_`)H^RK{ zb2<@tRuvDwt>y|{%<@?Rk+Zo4VF$F*;kGS>|F}~1v4TB|t^MI2!M@Yej6|drIKB_Y z3fEjdWxXs2dH?;{u)$yM`E@Gr%l;($X!wkXXT~i}AMZ2$0Ri*4i>(NmTN`QoYa2bjFkMIJw7PIog)pJlb1g8BD zEMnzIB9La%#)q$d$ja*7zRzZA0p&l(ku3V?4@z^Dys|{J2|!@9$mmzrugI!#E)2{M z`*y4kX6TB{zIFH;P5FAok@JNae!WqTSZwaHX1va&(U2p#yX%(zg@dYLh!$M{6MkBc zXR93hBJMA@wL(JY+gy+35y(O|PcpDq*eb^whC|y26#vAkjQ}?>*iNxC&oAxsHZ{1X zR$tg40O`PuD|XFA1<6{d(^HTO(1K9NRq`@s zT^BpX_!v9Z;C=M-Yd5n(O*G_e@d>ss>-lN1Expf&7011{KrUc;-X!zwjp)efz>B@V za02u%KXSKTS{=9EY;(Tv56-0lY{v$=-(|%SvU^i<)!B3G2q|@$4gO%8ceN2cSZ9w- ztHRhMO=I`YkXNI0axOj!Sx&%Wq6@(B{xjy^3HD0(w&(9Cugu@khIh^giu4>zX}Id` z^z_wy^a|7gp|cHA+HuTp-a9O4(OWP%xGWQz zHZrV{a0u$2|G7Lnqxz$$A|_bDIYug=Z|0`U-ziC6t0F=6zKXa-3uo!vx|i-8`Aqn)o}^zF|$y>L*g>4o_w`)rmME3B|}V6EqVnPn2Zs z)HAdEGeQG0eT`+3@4j;~X#y`qYX0?-;$u(2#=qw@mI9wL%>4ETL2F@Zu0kT~f~6 z$EwixU*HcJDCfp}gEM!AJ1}vav<~uK6_*Z&vI2+0 z6gNYMd5Txrbiu{9UPxE@<>-7{#k;-t&(cWk*^&!7h(a5{X- z3Zj^P9Ia3Ana>mgBz2=9hKkTZFn5l0!64(D4dRvvf@66DGRh#0qzh& zF-|fLh5UrV9bz1ES&bhl{nUIUWt~njF2kN1rUc~=gQt>ER?u>o3Q)ZTV>CH5QH=Yu z=icSS=T~)v{Ir2P3{#BfvgaBqLkGj*Gh~#4OdO`t(Ap1hheL|-b@tq8&=3KiA*U2% z<1kfJ`uQ2|Kt?&v!I5hSg$}~uGnABqk2p*SJae(+#IGl(Apfh zg9`EQL_PC+GszSJd>p2R(Asjig9YXIACBA<6{uD;e1?uvP)G&W+KY1Q&YiQ5IGUZl zqAf zDBDE;Lr{c5L7a}x_~k)HfzEEx3>Ug}Ed8(FSI*O}=Q|yyn!O#f$3FK_l_76W)*~)7 zSb0A5i}mhBIG0p0`dhiS9W||d==86jA|D0R(|RmN$hbD0Iz#;=H~dgP{KC$Q;cSbuX@y=6*TqE;`DcI1H6ty3ne?u@C6=>Ra=T zHIId7z8GcxxIi4TL78wsnQ-2JeD{bOLI3C@+A<#ZEI^T}@A$4G8wh*?0g`HFHipgX zPaon}NU4;tLh8iG7B=3^<4?8m2vRC#B0c3`VfFjSHa2;XgrBfNss{xDDiF{H0qB2# z3JB1FfCUJA{tr+EWgfDtGlEL)pV_=XcoT#t)Ic5^$O{93M~NVy9!2#i5v+se_I0q< zv93(|N^BsM^$c?SiYqmh+y9AtY0l^9;lg zJ|sa9P08~Ba138l8r0tV%ytM?zKiJFN zJE%YcDwzDIpafDLfRw@iDB&PQ0;Ke?<5wtyQY=bi3ZN7L2fiS9?i@Hk9wT@@9!7#Z zO^|2D0ZLJWQa?Z`LGWxk@PQPw|0vNEwRFgqoF*cO?OD{rFDHVJtBU*kjxGLd(uzMs zw#7a1QyEqT9VE|ujvtWG-*+`Up|em`q5tq8uLbJEYo%}S1E7z)OE-ykidHKTY62Q^ zCi<{eI2Z)q5vv@_hwNDuz}0Z;*8KRoiN;VEe8J8LDZ(C$ zFR31*V_fh!U|TCe*85C*wsPm2pyhyMHutHZokEYAt=UcLwf3qRSHW3Dz~htmGLAR( z+6(80?^I6?JJ$=Y5T*I|cjh&jbtICHmW>P(v&C+9r14^(pY{ibNd_x+3H-*M5V ziN*ODFvPH-W@kJhhCT#{OA|4W42LFguzK%qqF?>9Y zXYVNELP)z=a`eIwY1G}@U1<^0ZNqq?B}`rYikVDZca13Mrv|oPz-I#Y0ptLt>={s` z8gmZG!>nZvU?9$sgbW@%+>C{{Z*Yy9_NpjoG;<+`&nLwDlar+7JFPX&yO;Ve>@RdA z^6ei8h7^N$AkA%9?%PcydB_)_wS`pyTqN}tncY2+`&b+D~LVrA<=d&icqZK$s^)bQwU zt8V2+l-%qo_f9l-Pv+_}Yh#-1+@aW7Xzcy9&YqUAxKdXth30Cdo168TKk0xiNw%}8 z_3Z~Fb^R#a=3Hi+{a=NKFSS7lsSdKTax+)9E3x&SQIG4-E8hJTg7y$uP4BV=de!}M zJN@RicA#$*=DLh|b>n@@{l~{CmSjbEkqdny{B1Sk*Yg|qb=iK`t|0O1SP>7iY z(4+@SC;nHM2$-n;3nKX8)+y?49iqC-{}6LYdbKYN2uWW>?OXrW(`6Pg<}Yo zi2nXc+L4?4a5MiqB+w=RrUU1Qpr@xLT{5IM;ReFk~pV|1UH3eRj-o&0%n580CVygVio=A4inKX z>#r=rGM=2s{*oiWj9-Y~>KW zFDs|3pJ9g0)-zDNaWcbvskivx`D3ZOp_X~yLn&gT=pVC%6_JnY{A)z-FQeUB>&Uj6 z_bFrD9P=%jp7^hQGvxhIn%{DJ^GvtC7CD!yhrU`890a#UsETov>!b5*u8_FWx2lYYNx?~y zMtVaIw0A?09x0DD>u)3nH?x#a*W~>SrS=4>V1qCPy(V?p4(0hbBY*!j%TgpvC6C?p z&{v{Ye?e@)Cd>69MDH{jlOC@^a5US>m`yiB>1HJ`wm&+wYoF|yz%9^;1 zIr$k>;>Tx}pCnutA1!!(5DF+0%Ud&Q?%p|gsYL!ag32EZurh`xkqc6&K+5<3C@LU@ zU&&ffbMsCBC2q7XNc;j4-+@H$Jdnr)5)VOQxf)1>OyG3R;ehveP?KK|q$YsWM37ql z2!93&y?TUCR{;9(fn)u0eE4*P?@G8LQ>f*s%Ab=rUx zC<%g30~5e?R^p?^QKvj`;?mdpoMc*gJ&GE(Yw7qiBw#D1GS(0g#9kR3{OM>q?x6<| zbmG^WaTwh=+oLKoBP7FDc_3oYfL+sE3@?n6b-pfBS;#i~@U3>CTYH41c~}s!BXK<9 z?o9li*TtmWyy0??aWD?bYVTJxZlFu@_0M)Y9F!h z&22&H1Cv#5DAKZb8BOqt4f48JZ@FeW}=*zPOKRWT` z@PQ6XH+tNEt!R~!NLf!Y<3crZ^@D;&>9tF4Aph>6-G-)KTSU}!%xaWg8(}#gd%1u% z-^Xc{E?U(tL)EU7LVpV5_fT_psJT}uc}PkTio!Ukl>83K%OIkcArw4{m+Ypm;zDSC zpeS-k*k2M*mM9a^oWk)8D203fXMFx#OzY_?ur@(zq( z0&C<6yj188TE;&F0^3}6bGsZXRam`6g_lKE(A7a7o%$CMLs}I+E#)X9^TDo+$}Ni{ zkBYAeo2DhfLvRruhR@)BbbD!BdmBH!X!d-wx!*jLIRwk5{aBeTDKpe$^^&@x4AN zHNUG+5yfrDZ?x8^X}|kg`NOZCD$}eL?L4LZ^&NBNtE%E@ul^F1%ZI1FRN1S0_xWf2 z>#oYv8tSqyMxJrM_qcnYW|;dk{PWLP13?lejp^K0*OUF4K@=9Qx;_mudF zYuOtJc9o-vp8mnx`wXuIzr)~9m7&e-9ETJM!FRZH{(4Ok+(YVS3yPdoHZNIxR+)qPHPsP-Jdp)ynok zM4UZkL(d~+x1tZiH@}zqaR?^R4e09vaRR{a9YB5=wj#{qI=r(65s!J3Wr`L=!6dQZ zop4XUC+NliD;UlocJF`I2w~Fzy)y`|0uXtn=EipmtL;KkpK}*&5!!%LJ{Lx1ZM(-> z8;>Sg)1;QIYj5~4Mt4wU$sk>)FVkft=@4PHo9(2IC-Tku1cJ$XOT%>q({tF|0YWZ- zRy6@1&uo44HToxi^fmnyJ^2?)rygR3-ZWnGqG|r7$(05li}z0BmO;0Ko^={EUGHwW zTiyj4CY3p=f0&l}YgUfA(Ak#Z4v!4HrQLpPX5>E1`MmN@&`31iva>DAR5P*UE`)nH zbo6g`zWdHlzpyiPMDcc0xKO>R*YtAjelET0o~V&o#BkuE%)dP4nYGti<()O26}%#1 z<-7-Grurinahlo>Uo(&IDjdMmM~W${4C`b6(Y$5$;~kOVv#s}H^S54=@Ovaf$>txVjwl5gUs-6#D29I|Vf*u_h5z1^S1B!<{mr1FmiZee{%r>Kg^o z3nHi*^ba-eDP_VPq7Y(=1WKY12BHvlhwmZ06bT|kA<{%4iWCVNL?OBq2_{4#uPG87 zi9*~d68wllLWn{lDH0NhLeeP`eh`I}P+)qD*W}ld8qYQd1SwCBi3ZHSg#=oTo-hp-)oSA~ny7`YP0KIE=|<>G!md#H45OTtMMY;pk5ERyE-n z)4*z$vPp?sa7&tZDbuTNi11H~l<0Ds@kc&-Vau1+by36Kan}Z)+`qDW(|@w?+02ui zjAkjku1CZdcA8CB)6gb`}J^Hh$(j)r<0?s_S4v0KI8^2ni-3O+5wov4d2}Jhm#NSkM zNUInb)k@$(7$dkL=Fwa9pqeba|4tD?>17G62c`kC2O0lrH!vzj5Q*+Bp8oV42Afz( zCeLMkin3zPOU(vuld!~d8@CU>Ape_3tTlB%L|fT@F$ZYJ&{fy>7cCZd^oX&mQsRPu0LTO0BxZYHs| zr>w1gvy#d|>#TfI1+E)xY&O$b?!mFb!+?J2QxEix8jAbj#B)0R7pn1NR(S~r|6P&p z5Jdl0BQYc))e6QW)l_n3LB4$Ua;{-&~;}pJgwqN%>5%a8+s*I!qS{3oJmrJ;>`2A$0^-%fwsXK{=@@W^| z$=r}BwZROP<-y$FE^drZ|B|_cNnk@4eo#ufX_-qO^D?bqr~{tMon>cl*PK;->j4Tb z05$%n)o8*zt5W9k>OEya z8Qt`($#*UH&z|oy*Rn@vrrln-&n%kh8#&Dyjm%eFcuyf+zh=SsjEsCn?qV#`%a|^! z@9!UwH}{TPcQ~QKufNQS@1L*+L5J_g_DnxV^{gDuiX%@~M$~()EhgV4eIJ%kSclV6 z=ej8LQ+`IwX|@7Nzp7$){z?1EkwC7}xGpp*#!P+rADdFkSzA!Jy{B*wqHvGdjkf;I z!-eCd5=A=`UCUg~z){J_QOV59Weia=Rvx(5A*06z-pJDL80&zU3_UxXnG{jHpY`y@ zc6ehCym18HIFnCH`18(b<2JnU2;O)FZ^V9nh6l~Z=UW<3NQ$-xWmt40yk|!*V-%Hx$F_ ziPW-SaMtFEbrMRobN-9;(td%Y+kR;OG3ooA2CjET({k`T%9nNt`c;;=kAGQ{dAr^8A$WiunX%1j&XqvL_s@kvNvZ3a{=`U$?(T-@qp?zg!@w0@j-YDGH${KBkkqO%dZt^<=M<9$`Y-zss)7gLe+klU z{V;pK>|xHg9T*L`jGzhN%u~Hy~#R1M)0GWcN%bQDPeu{*o zs78(gNnac%$rLPc(y>qg&Ga^BAIMAjRM>@u@cCht*$!c}*W@e}i#t<*v{e;jGvbzM zCuCgfg78IyNBgZx>G_yU-oZ)OZ*&46kr>;$6ff)Xw};iDa(me;Nk?lrH`s8`FaxH~8G!)+4ZgZ4xJkp-1o3;sxrw$fZ`L7lxx zD<(w*bAb5-AB4)*{nq>SeLi*Ug-D|fywMrn_~GdwL28`cTn81^A5p45dK1o!#xFA7 z<7q{~2czIxTC#}WXY2B-RQh%_sSK294=K~WIS^~TkR%_Bg=@vZ2jk$6omQH*v_C{4B<8_qIYgwr=^P&P$eC{3`LiMujD@n|5Vd^S~r%yVWep9I+yM zhH(OVE+K}YI<0|eQr0>Fj;j#}c<3vGGy+%5v*-S3#>j2bBIbl}g~pdtmrHD9ldfCg z4H?1(4p!@WPUSmlQ2DNy8`X6+_l-u~2m!Q%y{pTRQ^|wgS0rWTBlNra4~YkRqQqm? z|CG4OXNGsr{LtBNYOpsTaUOd>kbl~Zni;IUdN?{y&-z)ycm9&#M* zPw97;5_y->kAQrW5xU8oOMODlaYnHw=`1V0$@NG1zXPvad{yH!(NsAqMTJe}|G&=$ Rs}CAN=Sk9x^OX$ee*qyL&5r;8 diff --git a/libs/common/dateutil/zoneinfo/rebuild.py b/libs/common/dateutil/zoneinfo/rebuild.py index 78f0d1a0..684c6586 100644 --- a/libs/common/dateutil/zoneinfo/rebuild.py +++ b/libs/common/dateutil/zoneinfo/rebuild.py @@ -3,7 +3,7 @@ import os import tempfile import shutil import json -from subprocess import check_call +from subprocess import check_call, check_output from tarfile import TarFile from dateutil.zoneinfo import METADATA_FN, ZONEFILENAME @@ -23,11 +23,9 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None): for name in zonegroups: tf.extract(name, tmpdir) filepaths = [os.path.join(tmpdir, n) for n in zonegroups] - try: - check_call(["zic", "-d", zonedir] + filepaths) - except OSError as e: - _print_on_nosuchfile(e) - raise + + _run_zic(zonedir, filepaths) + # write metadata file with open(os.path.join(zonedir, METADATA_FN), 'w') as f: json.dump(metadata, f, indent=4, sort_keys=True) @@ -40,6 +38,30 @@ def rebuild(filename, tag=None, format="gz", zonegroups=[], metadata=None): shutil.rmtree(tmpdir) +def _run_zic(zonedir, filepaths): + """Calls the ``zic`` compiler in a compatible way to get a "fat" binary. + + Recent versions of ``zic`` default to ``-b slim``, while older versions + don't even have the ``-b`` option (but default to "fat" binaries). The + current version of dateutil does not support Version 2+ TZif files, which + causes problems when used in conjunction with "slim" binaries, so this + function is used to ensure that we always get a "fat" binary. + """ + + try: + help_text = check_output(["zic", "--help"]) + except OSError as e: + _print_on_nosuchfile(e) + raise + + if b"-b " in help_text: + bloat_args = ["-b", "fat"] + else: + bloat_args = [] + + check_call(["zic"] + bloat_args + ["-d", zonedir] + filepaths) + + def _print_on_nosuchfile(e): """Print helpful troubleshooting message diff --git a/libs/common/guessit/__main__.py b/libs/common/guessit/__main__.py index 9894180a..fad196d6 100644 --- a/libs/common/guessit/__main__.py +++ b/libs/common/guessit/__main__.py @@ -142,7 +142,7 @@ def main(args=None): # pylint:disable=too-many-branches if options.get('yaml'): try: - import yaml # pylint:disable=unused-variable + import yaml # pylint:disable=unused-variable,unused-import except ImportError: # pragma: no cover del options['yaml'] print('PyYAML is not installed. \'--yaml\' option will be ignored ...', file=sys.stderr) diff --git a/libs/common/guessit/__version__.py b/libs/common/guessit/__version__.py index f5913166..e505897b 100644 --- a/libs/common/guessit/__version__.py +++ b/libs/common/guessit/__version__.py @@ -4,4 +4,4 @@ Version module """ # pragma: no cover -__version__ = '3.0.3' +__version__ = '3.1.1' diff --git a/libs/common/guessit/api.py b/libs/common/guessit/api.py index 3bf5aae2..8e306340 100644 --- a/libs/common/guessit/api.py +++ b/libs/common/guessit/api.py @@ -82,6 +82,19 @@ def properties(options=None): return default_api.properties(options) +def suggested_expected(titles, options=None): + """ + Return a list of suggested titles to be used as `expected_title` based on the list of titles + :param titles: the filename or release name + :type titles: list|set|dict + :param options: + :type options: str|dict + :return: + :rtype: list of str + """ + return default_api.suggested_expected(titles, options) + + class GuessItApi(object): """ An api class that can be configured with custom Rebulk configuration. @@ -228,5 +241,23 @@ class GuessItApi(object): ordered = self.rebulk.customize_properties(ordered) return ordered + def suggested_expected(self, titles, options=None): + """ + Return a list of suggested titles to be used as `expected_title` based on the list of titles + :param titles: the filename or release name + :type titles: list|set|dict + :param options: + :type options: str|dict + :return: + :rtype: list of str + """ + suggested = [] + for title in titles: + guess = self.guessit(title, options) + if len(guess) != 2 or 'title' not in guess: + suggested.append(title) + + return suggested + default_api = GuessItApi() diff --git a/libs/common/guessit/backports.py b/libs/common/guessit/backports.py index 3e94e27a..c149a6b5 100644 --- a/libs/common/guessit/backports.py +++ b/libs/common/guessit/backports.py @@ -4,7 +4,7 @@ Backports """ # pragma: no-cover -# pylint: disabled +# pylint: skip-file def cmp_to_key(mycmp): """functools.cmp_to_key backport""" diff --git a/libs/common/guessit/config/options.json b/libs/common/guessit/config/options.json index 11b17271..da7c7030 100644 --- a/libs/common/guessit/config/options.json +++ b/libs/common/guessit/config/options.json @@ -1,18 +1,19 @@ { "expected_title": [ - "OSS 117" + "OSS 117", + "This is Us" ], "allowed_countries": [ "au", - "us", - "gb" + "gb", + "us" ], "allowed_languages": [ + "ca", + "cs", "de", "en", "es", - "ca", - "cs", "fr", "he", "hi", @@ -20,7 +21,9 @@ "it", "ja", "ko", + "mul", "nl", + "no", "pl", "pt", "ro", @@ -28,18 +31,50 @@ "sv", "te", "uk", - "mul", "und" ], "advanced_config": { "common_words": [ + "ca", + "cat", "de", - "it" + "he", + "it", + "no", + "por", + "rum", + "se", + "st", + "sub" ], "groups": { "starting": "([{", "ending": ")]}" }, + "audio_codec": { + "audio_channels": { + "1.0": [ + "1ch", + "mono" + ], + "2.0": [ + "2ch", + "stereo", + "re:(2[\\W_]0(?:ch)?)(?=[^\\d]|$)" + ], + "5.1": [ + "5ch", + "6ch", + "re:(5[\\W_][01](?:ch)?)(?=[^\\d]|$)", + "re:(6[\\W_]0(?:ch)?)(?=[^\\d]|$)" + ], + "7.1": [ + "7ch", + "8ch", + "re:(7[\\W_][01](?:ch)?)(?=[^\\d]|$)" + ] + } + }, "container": { "subtitles": [ "srt", @@ -59,9 +94,10 @@ "avi", "divx", "flv", - "mk3d", + "iso", "m4v", "mk2", + "mk3d", "mka", "mkv", "mov", @@ -77,12 +113,11 @@ "ram", "rm", "ts", + "vob", "wav", "webm", "wma", - "wmv", - "iso", - "vob" + "wmv" ], "torrent": [ "torrent" @@ -255,7 +290,6 @@ ], "subtitle_prefixes": [ "st", - "v", "vost", "subforced", "fansub", @@ -297,12 +331,12 @@ }, "release_group": { "forbidden_names": [ - "rip", + "bonus", "by", "for", "par", "pour", - "bonus" + "rip" ], "ignored_seps": "[]{}()" }, @@ -311,6 +345,7 @@ "23.976", "24", "25", + "29.970", "30", "48", "50", @@ -329,6 +364,7 @@ "progressive": [ "360", "480", + "540", "576", "900", "1080", @@ -342,8 +378,8 @@ "website": { "safe_tlds": [ "com", - "org", - "net" + "net", + "org" ], "safe_subdomains": [ "www" @@ -351,12 +387,200 @@ "safe_prefixes": [ "co", "com", - "org", - "net" + "net", + "org" ], "prefixes": [ "from" ] + }, + "streaming_service": { + "A&E": [ + "AE", + "A&E" + ], + "ABC": "AMBC", + "ABC Australia": "AUBC", + "Al Jazeera English": "AJAZ", + "AMC": "AMC", + "Amazon Prime": [ + "AMZN", + "Amazon", + "re:Amazon-?Prime" + ], + "Adult Swim": [ + "AS", + "re:Adult-?Swim" + ], + "America's Test Kitchen": "ATK", + "Animal Planet": "ANPL", + "AnimeLab": "ANLB", + "AOL": "AOL", + "ARD": "ARD", + "BBC iPlayer": [ + "iP", + "re:BBC-?iPlayer" + ], + "BravoTV": "BRAV", + "Canal+": "CNLP", + "Cartoon Network": "CN", + "CBC": "CBC", + "CBS": "CBS", + "CNBC": "CNBC", + "Comedy Central": [ + "CC", + "re:Comedy-?Central" + ], + "Channel 4": "4OD", + "CHRGD": "CHGD", + "Cinemax": "CMAX", + "Country Music Television": "CMT", + "Comedians in Cars Getting Coffee": "CCGC", + "Crunchy Roll": [ + "CR", + "re:Crunchy-?Roll" + ], + "Crackle": "CRKL", + "CSpan": "CSPN", + "CTV": "CTV", + "CuriosityStream": "CUR", + "CWSeed": "CWS", + "Daisuki": "DSKI", + "DC Universe": "DCU", + "Deadhouse Films": "DHF", + "DramaFever": [ + "DF", + "DramaFever" + ], + "Digiturk Diledigin Yerde": "DDY", + "Discovery": [ + "DISC", + "Discovery" + ], + "Disney": [ + "DSNY", + "Disney" + ], + "DIY Network": "DIY", + "Doc Club": "DOCC", + "DPlay": "DPLY", + "E!": "ETV", + "ePix": "EPIX", + "El Trece": "ETTV", + "ESPN": "ESPN", + "Esquire": "ESQ", + "Family": "FAM", + "Family Jr": "FJR", + "Food Network": "FOOD", + "Fox": "FOX", + "Freeform": "FREE", + "FYI Network": "FYI", + "Global": "GLBL", + "GloboSat Play": "GLOB", + "Hallmark": "HLMK", + "HBO Go": [ + "HBO", + "re:HBO-?Go" + ], + "HGTV": "HGTV", + "History": [ + "HIST", + "History" + ], + "Hulu": "HULU", + "Investigation Discovery": "ID", + "IFC": "IFC", + "iTunes": "iTunes", + "ITV": "ITV", + "Knowledge Network": "KNOW", + "Lifetime": "LIFE", + "Motor Trend OnDemand": "MTOD", + "MBC": [ + "MBC", + "MBCVOD" + ], + "MSNBC": "MNBC", + "MTV": "MTV", + "National Geographic": [ + "NATG", + "re:National-?Geographic" + ], + "NBA TV": [ + "NBA", + "re:NBA-?TV" + ], + "NBC": "NBC", + "Netflix": [ + "NF", + "Netflix" + ], + "NFL": "NFL", + "NFL Now": "NFLN", + "NHL GameCenter": "GC", + "Nickelodeon": [ + "NICK", + "Nickelodeon" + ], + "Norsk Rikskringkasting": "NRK", + "OnDemandKorea": [ + "ODK", + "OnDemandKorea" + ], + "PBS": "PBS", + "PBS Kids": "PBSK", + "Playstation Network": "PSN", + "Pluzz": "PLUZ", + "RTE One": "RTE", + "SBS (AU)": "SBS", + "SeeSo": [ + "SESO", + "SeeSo" + ], + "Shomi": "SHMI", + "Spike": "SPIK", + "Spike TV": [ + "SPKE", + "re:Spike-?TV" + ], + "Sportsnet": "SNET", + "Sprout": "SPRT", + "Stan": "STAN", + "Starz": "STZ", + "Sveriges Television": "SVT", + "SwearNet": "SWER", + "Syfy": "SYFY", + "TBS": "TBS", + "TFou": "TFOU", + "The CW": [ + "CW", + "re:The-?CW" + ], + "TLC": "TLC", + "TubiTV": "TUBI", + "TV3 Ireland": "TV3", + "TV4 Sweeden": "TV4", + "TVING": "TVING", + "TV Land": [ + "TVL", + "re:TV-?Land" + ], + "UFC": "UFC", + "UKTV": "UKTV", + "Univision": "UNIV", + "USA Network": "USAN", + "Velocity": "VLCT", + "VH1": "VH1", + "Viceland": "VICE", + "Viki": "VIKI", + "Vimeo": "VMEO", + "VRV": "VRV", + "W Network": "WNET", + "WatchMe": "WME", + "WWE Network": "WWEN", + "Xbox Video": "XBOX", + "Yahoo": "YHOO", + "YouTube Red": "RED", + "ZDF": "ZDF" } } -} \ No newline at end of file +} diff --git a/libs/common/guessit/options.py b/libs/common/guessit/options.py index 50ee4235..8fa6825c 100644 --- a/libs/common/guessit/options.py +++ b/libs/common/guessit/options.py @@ -128,7 +128,7 @@ class ConfigurationException(Exception): """ Exception related to configuration file. """ - pass + pass # pylint:disable=unnecessary-pass def load_config(options): @@ -153,7 +153,7 @@ def load_config(options): cwd = os.getcwd() yaml_supported = False try: - import yaml # pylint: disable=unused-variable + import yaml # pylint:disable=unused-variable,unused-import yaml_supported = True except ImportError: pass @@ -252,7 +252,7 @@ def load_config_file(filepath): try: import yaml with open(filepath) as config_file_data: - return yaml.load(config_file_data) + return yaml.load(config_file_data, yaml.SafeLoader) except ImportError: # pragma: no cover raise ConfigurationException('Configuration file extension is not supported. ' 'PyYAML should be installed to support "%s" file' % ( diff --git a/libs/common/guessit/rules/common/formatters.py b/libs/common/guessit/rules/common/formatters.py index 434c20be..2a64dee9 100644 --- a/libs/common/guessit/rules/common/formatters.py +++ b/libs/common/guessit/rules/common/formatters.py @@ -25,7 +25,7 @@ def _potential_before(i, input_string): :return: :rtype: bool """ - return i - 2 >= 0 and input_string[i] in seps and input_string[i - 2] in seps and input_string[i - 1] not in seps + return i - 1 >= 0 and input_string[i] in seps and input_string[i - 2] in seps and input_string[i - 1] not in seps def _potential_after(i, input_string): diff --git a/libs/common/guessit/rules/common/validators.py b/libs/common/guessit/rules/common/validators.py index 0e79b989..0d0eb3eb 100644 --- a/libs/common/guessit/rules/common/validators.py +++ b/libs/common/guessit/rules/common/validators.py @@ -28,7 +28,7 @@ def int_coercable(string): return False -def compose(*validators): +def and_(*validators): """ Compose validators functions :param validators: @@ -49,3 +49,26 @@ def compose(*validators): return False return True return composed + + +def or_(*validators): + """ + Compose validators functions + :param validators: + :type validators: + :return: + :rtype: + """ + def composed(string): + """ + Composed validators function + :param string: + :type string: + :return: + :rtype: + """ + for validator in validators: + if validator(string): + return True + return False + return composed diff --git a/libs/common/guessit/rules/match_processors.py b/libs/common/guessit/rules/match_processors.py new file mode 100644 index 00000000..0b49372f --- /dev/null +++ b/libs/common/guessit/rules/match_processors.py @@ -0,0 +1,20 @@ +""" +Match processors +""" +from guessit.rules.common import seps + + +def strip(match, chars=seps): + """ + Strip given characters from match. + + :param chars: + :param match: + :return: + """ + while match.input_string[match.start] in chars: + match.start += 1 + while match.input_string[match.end - 1] in chars: + match.end -= 1 + if not match: + return False diff --git a/libs/common/guessit/rules/processors.py b/libs/common/guessit/rules/processors.py index cced26a5..5b018140 100644 --- a/libs/common/guessit/rules/processors.py +++ b/libs/common/guessit/rules/processors.py @@ -34,7 +34,9 @@ class EnlargeGroupMatches(CustomRule): for match in matches.ending(group.end - 1): ending.append(match) - return starting, ending + if starting or ending: + return starting, ending + return False def then(self, matches, when_response, context): starting, ending = when_response diff --git a/libs/common/guessit/rules/properties/audio_codec.py b/libs/common/guessit/rules/properties/audio_codec.py index a2566bce..815caff9 100644 --- a/libs/common/guessit/rules/properties/audio_codec.py +++ b/libs/common/guessit/rules/properties/audio_codec.py @@ -3,9 +3,8 @@ """ audio_codec, audio_profile and audio_channels property """ -from rebulk.remodule import re - from rebulk import Rebulk, Rule, RemoveMatch +from rebulk.remodule import re from ..common import dash from ..common.pattern import is_disabled @@ -23,7 +22,9 @@ def audio_codec(config): # pylint:disable=unused-argument :return: Created Rebulk object :rtype: Rebulk """ - rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]).string_defaults(ignore_case=True) + rebulk = Rebulk()\ + .regex_defaults(flags=re.IGNORECASE, abbreviations=[dash])\ + .string_defaults(ignore_case=True) def audio_codec_priority(match1, match2): """ @@ -61,7 +62,9 @@ def audio_codec(config): # pylint:disable=unused-argument rebulk.string('PCM', value='PCM') rebulk.string('LPCM', value='LPCM') - rebulk.defaults(name='audio_profile', disabled=lambda context: is_disabled(context, 'audio_profile')) + rebulk.defaults(clear=True, + name='audio_profile', + disabled=lambda context: is_disabled(context, 'audio_profile')) rebulk.string('MA', value='Master Audio', tags=['audio_profile.rule', 'DTS-HD']) rebulk.string('HR', 'HRA', value='High Resolution Audio', tags=['audio_profile.rule', 'DTS-HD']) rebulk.string('ES', value='Extended Surround', tags=['audio_profile.rule', 'DTS']) @@ -70,17 +73,19 @@ def audio_codec(config): # pylint:disable=unused-argument rebulk.string('HQ', value='High Quality', tags=['audio_profile.rule', 'Dolby Digital']) rebulk.string('EX', value='EX', tags=['audio_profile.rule', 'Dolby Digital']) - rebulk.defaults(name="audio_channels", disabled=lambda context: is_disabled(context, 'audio_channels')) - rebulk.regex(r'(7[\W_][01](?:ch)?)(?=[^\d]|$)', value='7.1', children=True) - rebulk.regex(r'(5[\W_][01](?:ch)?)(?=[^\d]|$)', value='5.1', children=True) - rebulk.regex(r'(2[\W_]0(?:ch)?)(?=[^\d]|$)', value='2.0', children=True) + rebulk.defaults(clear=True, + name="audio_channels", + disabled=lambda context: is_disabled(context, 'audio_channels')) rebulk.regex('7[01]', value='7.1', validator=seps_after, tags='weak-audio_channels') rebulk.regex('5[01]', value='5.1', validator=seps_after, tags='weak-audio_channels') rebulk.string('20', value='2.0', validator=seps_after, tags='weak-audio_channels') - rebulk.string('7ch', '8ch', value='7.1') - rebulk.string('5ch', '6ch', value='5.1') - rebulk.string('2ch', 'stereo', value='2.0') - rebulk.string('1ch', 'mono', value='1.0') + + for value, items in config.get('audio_channels').items(): + for item in items: + if item.startswith('re:'): + rebulk.regex(item[3:], value=value, children=True) + else: + rebulk.string(item, value=value) rebulk.rules(DtsHDRule, DtsRule, AacRule, DolbyDigitalRule, AudioValidatorRule, HqConflictRule, AudioChannelsValidatorRule) diff --git a/libs/common/guessit/rules/properties/bit_rate.py b/libs/common/guessit/rules/properties/bit_rate.py index 391f1d2f..d279c9f1 100644 --- a/libs/common/guessit/rules/properties/bit_rate.py +++ b/libs/common/guessit/rules/properties/bit_rate.py @@ -69,4 +69,6 @@ class BitRateTypeRule(Rule): else: to_rename.append(match) - return to_rename, to_remove + if to_rename or to_remove: + return to_rename, to_remove + return False diff --git a/libs/common/guessit/rules/properties/bonus.py b/libs/common/guessit/rules/properties/bonus.py index c4554cd0..54087aa3 100644 --- a/libs/common/guessit/rules/properties/bonus.py +++ b/libs/common/guessit/rules/properties/bonus.py @@ -26,7 +26,8 @@ def bonus(config): # pylint:disable=unused-argument rebulk = rebulk.regex_defaults(flags=re.IGNORECASE) rebulk.regex(r'x(\d+)', name='bonus', private_parent=True, children=True, formatter=int, - validator={'__parent__': lambda match: seps_surround}, + validator={'__parent__': seps_surround}, + validate_all=True, conflict_solver=lambda match, conflicting: match if conflicting.name in ('video_codec', 'episode') and 'weak-episode' not in conflicting.tags else '__default__') diff --git a/libs/common/guessit/rules/properties/container.py b/libs/common/guessit/rules/properties/container.py index 77599509..0f1860af 100644 --- a/libs/common/guessit/rules/properties/container.py +++ b/libs/common/guessit/rules/properties/container.py @@ -44,7 +44,8 @@ def container(config): rebulk.regex(r'\.'+build_or_pattern(torrent)+'$', exts=torrent, tags=['extension', 'torrent']) rebulk.regex(r'\.'+build_or_pattern(nzb)+'$', exts=nzb, tags=['extension', 'nzb']) - rebulk.defaults(name='container', + rebulk.defaults(clear=True, + name='container', validator=seps_surround, formatter=lambda s: s.lower(), conflict_solver=lambda match, other: match diff --git a/libs/common/guessit/rules/properties/episode_title.py b/libs/common/guessit/rules/properties/episode_title.py index d429c3e7..ece8921d 100644 --- a/libs/common/guessit/rules/properties/episode_title.py +++ b/libs/common/guessit/rules/properties/episode_title.py @@ -10,6 +10,7 @@ from rebulk import Rebulk, Rule, AppendMatch, RemoveMatch, RenameMatch, POST_PRO from ..common import seps, title_seps from ..common.formatters import cleanup from ..common.pattern import is_disabled +from ..common.validators import or_ from ..properties.title import TitleFromPosition, TitleBaseRule from ..properties.type import TypeProcessor @@ -133,8 +134,7 @@ class EpisodeTitleFromPosition(TitleBaseRule): def hole_filter(self, hole, matches): episode = matches.previous(hole, - lambda previous: any(name in previous.names - for name in self.previous_names), + lambda previous: previous.named(*self.previous_names), 0) crc32 = matches.named('crc32') @@ -179,8 +179,7 @@ class AlternativeTitleReplace(Rule): predicate=lambda match: 'title' in match.tags, index=0) if main_title: episode = matches.previous(main_title, - lambda previous: any(name in previous.names - for name in self.previous_names), + lambda previous: previous.named(*self.previous_names), 0) crc32 = matches.named('crc32') @@ -249,7 +248,7 @@ class Filepart3EpisodeTitle(Rule): if season: hole = matches.holes(subdirectory.start, subdirectory.end, - ignore=lambda match: 'weak-episode' in match.tags, + ignore=or_(lambda match: 'weak-episode' in match.tags, TitleBaseRule.is_ignored), formatter=cleanup, seps=title_seps, predicate=lambda match: match.value, index=0) if hole: @@ -292,7 +291,8 @@ class Filepart2EpisodeTitle(Rule): season = (matches.range(directory.start, directory.end, lambda match: match.name == 'season', 0) or matches.range(filename.start, filename.end, lambda match: match.name == 'season', 0)) if season: - hole = matches.holes(directory.start, directory.end, ignore=lambda match: 'weak-episode' in match.tags, + hole = matches.holes(directory.start, directory.end, + ignore=or_(lambda match: 'weak-episode' in match.tags, TitleBaseRule.is_ignored), formatter=cleanup, seps=title_seps, predicate=lambda match: match.value, index=0) if hole: diff --git a/libs/common/guessit/rules/properties/episodes.py b/libs/common/guessit/rules/properties/episodes.py index 97f060a2..345c785d 100644 --- a/libs/common/guessit/rules/properties/episodes.py +++ b/libs/common/guessit/rules/properties/episodes.py @@ -11,12 +11,13 @@ from rebulk.match import Match from rebulk.remodule import re from rebulk.utils import is_iterable +from guessit.rules import match_processors +from guessit.rules.common.numeral import parse_numeral, numeral from .title import TitleFromPosition from ..common import dash, alt_dash, seps, seps_no_fs from ..common.formatters import strip -from ..common.numeral import numeral, parse_numeral from ..common.pattern import is_disabled -from ..common.validators import compose, seps_surround, seps_before, int_coercable +from ..common.validators import seps_surround, int_coercable, and_ from ...reutils import build_or_pattern @@ -29,17 +30,12 @@ def episodes(config): :return: Created Rebulk object :rtype: Rebulk """ + # pylint: disable=too-many-branches,too-many-statements,too-many-locals def is_season_episode_disabled(context): """Whether season and episode rules should be enabled.""" return is_disabled(context, 'episode') or is_disabled(context, 'season') - rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE).string_defaults(ignore_case=True) - rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator', 'episodeMarker', 'seasonMarker']) - - episode_max_range = config['episode_max_range'] - season_max_range = config['season_max_range'] - def episodes_season_chain_breaker(matches): """ Break chains if there's more than 100 offset between two neighbor values. @@ -57,8 +53,6 @@ def episodes(config): return True return False - rebulk.chain_defaults(chain_breaker=episodes_season_chain_breaker) - def season_episode_conflict_solver(match, other): """ Conflict solver for episode/season patterns @@ -76,7 +70,6 @@ def episodes(config): if (other.name == 'audio_channels' and 'weak-audio_channels' not in other.tags and not match.initiator.children.named(match.name + 'Marker')) or ( other.name == 'screen_size' and not int_coercable(other.raw)): - return match if other.name in ('season', 'episode') and match.initiator != other.initiator: if (match.initiator.name in ('weak_episode', 'weak_duplicate') @@ -87,21 +80,6 @@ def episodes(config): return current return '__default__' - season_words = config['season_words'] - episode_words = config['episode_words'] - of_words = config['of_words'] - all_words = config['all_words'] - season_markers = config['season_markers'] - season_ep_markers = config['season_ep_markers'] - disc_markers = config['disc_markers'] - episode_markers = config['episode_markers'] - range_separators = config['range_separators'] - weak_discrete_separators = list(sep for sep in seps_no_fs if sep not in range_separators) - strong_discrete_separators = config['discrete_separators'] - discrete_separators = strong_discrete_separators + weak_discrete_separators - - max_range_gap = config['max_range_gap'] - def ordering_validator(match): """ Validator for season list. They should be in natural order to be validated. @@ -135,65 +113,18 @@ def episodes(config): lambda m: m.name == property_name + 'Separator') separator = match.children.previous(current_match, lambda m: m.name == property_name + 'Separator', 0) - if separator.raw not in range_separators and separator.raw in weak_discrete_separators: - if not 0 < current_match.value - previous_match.value <= max_range_gap + 1: - valid = False - if separator.raw in strong_discrete_separators: - valid = True - break + if separator: + if separator.raw not in range_separators and separator.raw in weak_discrete_separators: + if not 0 < current_match.value - previous_match.value <= max_range_gap + 1: + valid = False + if separator.raw in strong_discrete_separators: + valid = True + break previous_match = current_match return valid return is_consecutive('episode') and is_consecutive('season') - # S01E02, 01x02, S01S02S03 - rebulk.chain(formatter={'season': int, 'episode': int}, - tags=['SxxExx'], - abbreviations=[alt_dash], - children=True, - private_parent=True, - validate_all=True, - validator={'__parent__': ordering_validator}, - conflict_solver=season_episode_conflict_solver, - disabled=is_season_episode_disabled) \ - .regex(build_or_pattern(season_markers, name='seasonMarker') + r'(?P\d+)@?' + - build_or_pattern(episode_markers + disc_markers, name='episodeMarker') + r'@?(?P\d+)', - validate_all=True, - validator={'__parent__': seps_before}).repeater('+') \ - .regex(build_or_pattern(episode_markers + disc_markers + discrete_separators + range_separators, - name='episodeSeparator', - escape=True) + - r'(?P\d+)').repeater('*') \ - .chain() \ - .regex(r'(?P\d+)@?' + - build_or_pattern(season_ep_markers, name='episodeMarker') + - r'@?(?P\d+)', - validate_all=True, - validator={'__parent__': seps_before}) \ - .chain() \ - .regex(r'(?P\d+)@?' + - build_or_pattern(season_ep_markers, name='episodeMarker') + - r'@?(?P\d+)', - validate_all=True, - validator={'__parent__': seps_before}) \ - .regex(build_or_pattern(season_ep_markers + discrete_separators + range_separators, - name='episodeSeparator', - escape=True) + - r'(?P\d+)').repeater('*') \ - .chain() \ - .regex(build_or_pattern(season_markers, name='seasonMarker') + r'(?P\d+)', - validate_all=True, - validator={'__parent__': seps_before}) \ - .regex(build_or_pattern(season_markers + discrete_separators + range_separators, - name='seasonSeparator', - escape=True) + - r'(?P\d+)').repeater('*') - - # episode_details property - for episode_detail in ('Special', 'Pilot', 'Unaired', 'Final'): - rebulk.string(episode_detail, value=episode_detail, name='episode_details', - disabled=lambda context: is_disabled(context, 'episode_details')) - def validate_roman(match): """ Validate a roman match if surrounded by separators @@ -206,117 +137,203 @@ def episodes(config): return True return seps_surround(match) + season_words = config['season_words'] + episode_words = config['episode_words'] + of_words = config['of_words'] + all_words = config['all_words'] + season_markers = config['season_markers'] + season_ep_markers = config['season_ep_markers'] + disc_markers = config['disc_markers'] + episode_markers = config['episode_markers'] + range_separators = config['range_separators'] + weak_discrete_separators = list(sep for sep in seps_no_fs if sep not in range_separators) + strong_discrete_separators = config['discrete_separators'] + discrete_separators = strong_discrete_separators + weak_discrete_separators + episode_max_range = config['episode_max_range'] + season_max_range = config['season_max_range'] + max_range_gap = config['max_range_gap'] + + rebulk = Rebulk() \ + .regex_defaults(flags=re.IGNORECASE) \ + .string_defaults(ignore_case=True) \ + .chain_defaults(chain_breaker=episodes_season_chain_breaker) \ + .defaults(private_names=['episodeSeparator', 'seasonSeparator', 'episodeMarker', 'seasonMarker'], + formatter={'season': int, 'episode': int, 'version': int, 'count': int}, + children=True, + private_parent=True, + conflict_solver=season_episode_conflict_solver, + abbreviations=[alt_dash]) + + # S01E02, 01x02, S01S02S03 + rebulk.chain( + tags=['SxxExx'], + validate_all=True, + validator={'__parent__': and_(seps_surround, ordering_validator)}, + disabled=is_season_episode_disabled) \ + .defaults(tags=['SxxExx']) \ + .regex(build_or_pattern(season_markers, name='seasonMarker') + r'(?P\d+)@?' + + build_or_pattern(episode_markers + disc_markers, name='episodeMarker') + r'@?(?P\d+)')\ + .repeater('+') \ + .regex(build_or_pattern(episode_markers + disc_markers + discrete_separators + range_separators, + name='episodeSeparator', + escape=True) + + r'(?P\d+)').repeater('*') + + rebulk.chain(tags=['SxxExx'], + validate_all=True, + validator={'__parent__': and_(seps_surround, ordering_validator)}, + disabled=is_season_episode_disabled) \ + .defaults(tags=['SxxExx']) \ + .regex(r'(?P\d+)@?' + + build_or_pattern(season_ep_markers, name='episodeMarker') + + r'@?(?P\d+)').repeater('+') \ + + rebulk.chain(tags=['SxxExx'], + validate_all=True, + validator={'__parent__': and_(seps_surround, ordering_validator)}, + disabled=is_season_episode_disabled) \ + .defaults(tags=['SxxExx']) \ + .regex(r'(?P\d+)@?' + + build_or_pattern(season_ep_markers, name='episodeMarker') + + r'@?(?P\d+)') \ + .regex(build_or_pattern(season_ep_markers + discrete_separators + range_separators, + name='episodeSeparator', + escape=True) + + r'(?P\d+)').repeater('*') + + rebulk.chain(tags=['SxxExx'], + validate_all=True, + validator={'__parent__': and_(seps_surround, ordering_validator)}, + disabled=is_season_episode_disabled) \ + .defaults(tags=['SxxExx']) \ + .regex(build_or_pattern(season_markers, name='seasonMarker') + r'(?P\d+)') \ + .regex('(?PExtras)', name='other', value='Extras', tags=['no-release-group-prefix']).repeater('?') \ + .regex(build_or_pattern(season_markers + discrete_separators + range_separators, + name='seasonSeparator', + escape=True) + + r'(?P\d+)').repeater('*') + + # episode_details property + for episode_detail in ('Special', 'Pilot', 'Unaired', 'Final'): + rebulk.string(episode_detail, + private_parent=False, + children=False, + value=episode_detail, + name='episode_details', + disabled=lambda context: is_disabled(context, 'episode_details')) + rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator', 'episodeMarker', 'seasonMarker'], - validate_all=True, validator={'__parent__': seps_surround}, children=True, private_parent=True, + validate_all=True, + validator={'__parent__': and_(seps_surround, ordering_validator)}, + children=True, + private_parent=True, conflict_solver=season_episode_conflict_solver) - rebulk.chain(abbreviations=[alt_dash], + rebulk.chain(validate_all=True, + conflict_solver=season_episode_conflict_solver, formatter={'season': parse_numeral, 'count': parse_numeral}, - validator={'__parent__': compose(seps_surround, ordering_validator), + validator={'__parent__': and_(seps_surround, ordering_validator), 'season': validate_roman, 'count': validate_roman}, disabled=lambda context: context.get('type') == 'movie' or is_disabled(context, 'season')) \ - .defaults(validator=None) \ + .defaults(formatter={'season': parse_numeral, 'count': parse_numeral}, + validator={'season': validate_roman, 'count': validate_roman}, + conflict_solver=season_episode_conflict_solver) \ .regex(build_or_pattern(season_words, name='seasonMarker') + '@?(?P' + numeral + ')') \ .regex(r'' + build_or_pattern(of_words) + '@?(?P' + numeral + ')').repeater('?') \ .regex(r'@?' + build_or_pattern(range_separators + discrete_separators + ['@'], name='seasonSeparator', escape=True) + r'@?(?P\d+)').repeater('*') + rebulk.defaults(abbreviations=[dash]) + rebulk.regex(build_or_pattern(episode_words, name='episodeMarker') + r'-?(?P\d+)' + r'(?:v(?P\d+))?' + r'(?:-?' + build_or_pattern(of_words) + r'-?(?P\d+))?', # Episode 4 - abbreviations=[dash], formatter={'episode': int, 'version': int, 'count': int}, disabled=lambda context: context.get('type') == 'episode' or is_disabled(context, 'episode')) rebulk.regex(build_or_pattern(episode_words, name='episodeMarker') + r'-?(?P' + numeral + ')' + r'(?:v(?P\d+))?' + r'(?:-?' + build_or_pattern(of_words) + r'-?(?P\d+))?', # Episode 4 - abbreviations=[dash], validator={'episode': validate_roman}, - formatter={'episode': parse_numeral, 'version': int, 'count': int}, + formatter={'episode': parse_numeral}, disabled=lambda context: context.get('type') != 'episode' or is_disabled(context, 'episode')) rebulk.regex(r'S?(?P\d+)-?(?:xE|Ex|E|x)-?(?P' + build_or_pattern(all_words) + ')', tags=['SxxExx'], - abbreviations=[dash], - validator=None, - formatter={'season': int, 'other': lambda match: 'Complete'}, + formatter={'other': lambda match: 'Complete'}, disabled=lambda context: is_disabled(context, 'season')) # 12, 13 - rebulk.chain(tags=['weak-episode'], formatter={'episode': int, 'version': int}, + rebulk.chain(tags=['weak-episode'], disabled=lambda context: context.get('type') == 'movie' or is_disabled(context, 'episode')) \ - .defaults(validator=None) \ + .defaults(validator=None, tags=['weak-episode']) \ .regex(r'(?P\d{2})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?P[x-])(?P\d{2})').repeater('*') + .regex(r'(?P[x-])(?P\d{2})', abbreviations=None).repeater('*') # 012, 013 - rebulk.chain(tags=['weak-episode'], formatter={'episode': int, 'version': int}, + rebulk.chain(tags=['weak-episode'], disabled=lambda context: context.get('type') == 'movie' or is_disabled(context, 'episode')) \ - .defaults(validator=None) \ + .defaults(validator=None, tags=['weak-episode']) \ .regex(r'0(?P\d{1,2})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?P[x-])0(?P\d{1,2})').repeater('*') + .regex(r'(?P[x-])0(?P\d{1,2})', abbreviations=None).repeater('*') # 112, 113 rebulk.chain(tags=['weak-episode'], - formatter={'episode': int, 'version': int}, name='weak_episode', disabled=lambda context: context.get('type') == 'movie' or is_disabled(context, 'episode')) \ - .defaults(validator=None) \ + .defaults(validator=None, tags=['weak-episode'], name='weak_episode') \ .regex(r'(?P\d{3,4})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?P[x-])(?P\d{3,4})').repeater('*') + .regex(r'(?P[x-])(?P\d{3,4})', abbreviations=None).repeater('*') # 1, 2, 3 - rebulk.chain(tags=['weak-episode'], formatter={'episode': int, 'version': int}, + rebulk.chain(tags=['weak-episode'], disabled=lambda context: context.get('type') != 'episode' or is_disabled(context, 'episode')) \ - .defaults(validator=None) \ + .defaults(validator=None, tags=['weak-episode']) \ .regex(r'(?P\d)') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?P[x-])(?P\d{1,2})').repeater('*') + .regex(r'(?P[x-])(?P\d{1,2})', abbreviations=None).repeater('*') # e112, e113, 1e18, 3e19 - # TODO: Enhance rebulk for validator to be used globally (season_episode_validator) - rebulk.chain(formatter={'season': int, 'episode': int, 'version': int}, - disabled=lambda context: is_disabled(context, 'episode')) \ + rebulk.chain(disabled=lambda context: is_disabled(context, 'episode')) \ .defaults(validator=None) \ .regex(r'(?P\d{1,2})?(?Pe)(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?Pe|x|-)(?P\d{1,4})').repeater('*') + .regex(r'(?Pe|x|-)(?P\d{1,4})', abbreviations=None).repeater('*') # ep 112, ep113, ep112, ep113 - rebulk.chain(abbreviations=[dash], formatter={'episode': int, 'version': int}, - disabled=lambda context: is_disabled(context, 'episode')) \ + rebulk.chain(disabled=lambda context: is_disabled(context, 'episode')) \ .defaults(validator=None) \ .regex(r'ep-?(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?Pep|e|x|-)(?P\d{1,4})').repeater('*') + .regex(r'(?Pep|e|x|-)(?P\d{1,4})', abbreviations=None).repeater('*') # cap 112, cap 112_114 - rebulk.chain(abbreviations=[dash], - tags=['see-pattern'], - formatter={'season': int, 'episode': int}, + rebulk.chain(tags=['see-pattern'], disabled=is_season_episode_disabled) \ - .defaults(validator=None) \ + .defaults(validator=None, tags=['see-pattern']) \ .regex(r'(?Pcap)-?(?P\d{1,2})(?P\d{2})') \ .regex(r'(?P-)(?P\d{1,2})(?P\d{2})').repeater('?') # 102, 0102 rebulk.chain(tags=['weak-episode', 'weak-duplicate'], - formatter={'season': int, 'episode': int, 'version': int}, name='weak_duplicate', conflict_solver=season_episode_conflict_solver, disabled=lambda context: (context.get('episode_prefer_number', False) or context.get('type') == 'movie') or is_season_episode_disabled(context)) \ - .defaults(validator=None) \ + .defaults(tags=['weak-episode', 'weak-duplicate'], + name='weak_duplicate', + validator=None, + conflict_solver=season_episode_conflict_solver) \ .regex(r'(?P\d{1,2})(?P\d{2})') \ .regex(r'v(?P\d+)').repeater('?') \ - .regex(r'(?Px|-)(?P\d{2})').repeater('*') + .regex(r'(?Px|-)(?P\d{2})', abbreviations=None).repeater('*') - rebulk.regex(r'v(?P\d+)', children=True, private_parent=True, formatter=int, + rebulk.regex(r'v(?P\d+)', + formatter=int, disabled=lambda context: is_disabled(context, 'version')) rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator']) @@ -325,18 +342,23 @@ def episodes(config): # detached of X count (season/episode) rebulk.regex(r'(?P\d+)-?' + build_or_pattern(of_words) + r'-?(?P\d+)-?' + build_or_pattern(episode_words) + '?', - abbreviations=[dash], children=True, private_parent=True, formatter=int, + formatter=int, + pre_match_processor=match_processors.strip, disabled=lambda context: is_disabled(context, 'episode')) - rebulk.regex(r'Minisodes?', name='episode_format', value="Minisode", + rebulk.regex(r'Minisodes?', + children=False, + private_parent=False, + name='episode_format', + value="Minisode", disabled=lambda context: is_disabled(context, 'episode_format')) rebulk.rules(WeakConflictSolver, RemoveInvalidSeason, RemoveInvalidEpisode, SeePatternRange(range_separators + ['_']), EpisodeNumberSeparatorRange(range_separators), - SeasonSeparatorRange(range_separators), RemoveWeakIfMovie, RemoveWeakIfSxxExx, - RemoveWeakDuplicate, EpisodeDetailValidator, RemoveDetachedEpisodeNumber, VersionValidator, - RemoveWeak, RenameToAbsoluteEpisode, CountValidator, EpisodeSingleDigitValidator, RenameToDiscMatch) + SeasonSeparatorRange(range_separators), RemoveWeakIfMovie, RemoveWeakIfSxxExx, RemoveWeakDuplicate, + EpisodeDetailValidator, RemoveDetachedEpisodeNumber, VersionValidator, RemoveWeak(episode_words), + RenameToAbsoluteEpisode, CountValidator, EpisodeSingleDigitValidator, RenameToDiscMatch) return rebulk @@ -416,7 +438,9 @@ class WeakConflictSolver(Rule): if to_append: to_remove.extend(weak_dup_matches) - return to_remove, to_append + if to_remove or to_append: + return to_remove, to_append + return False class CountValidator(Rule): @@ -442,7 +466,9 @@ class CountValidator(Rule): season_count.append(count) else: to_remove.append(count) - return to_remove, episode_count, season_count + if to_remove or episode_count or season_count: + return to_remove, episode_count, season_count + return False class SeePatternRange(Rule): @@ -477,7 +503,9 @@ class SeePatternRange(Rule): to_remove.append(separator) - return to_remove, to_append + if to_remove or to_append: + return to_remove, to_append + return False class AbstractSeparatorRange(Rule): @@ -533,7 +561,9 @@ class AbstractSeparatorRange(Rule): previous_match = next_match - return to_remove, to_append + if to_remove or to_append: + return to_remove, to_append + return False class RenameToAbsoluteEpisode(Rule): @@ -629,20 +659,41 @@ class RemoveWeak(Rule): Remove weak-episode matches which appears after video, source, and audio matches. """ priority = 16 - consequence = RemoveMatch + consequence = RemoveMatch, AppendMatch + + def __init__(self, episode_words): + super(RemoveWeak, self).__init__() + self.episode_words = episode_words def when(self, matches, context): to_remove = [] + to_append = [] for filepart in matches.markers.named('path'): weaks = matches.range(filepart.start, filepart.end, predicate=lambda m: 'weak-episode' in m.tags) if weaks: - previous = matches.previous(weaks[0], predicate=lambda m: m.name in ( + weak = weaks[0] + previous = matches.previous(weak, predicate=lambda m: m.name in ( 'audio_codec', 'screen_size', 'streaming_service', 'source', 'video_profile', 'audio_channels', 'audio_profile'), index=0) if previous and not matches.holes( - previous.end, weaks[0].start, predicate=lambda m: m.raw.strip(seps)): + previous.end, weak.start, predicate=lambda m: m.raw.strip(seps)): + if previous.raw.lower() in self.episode_words: + try: + episode = copy.copy(weak) + episode.name = 'episode' + episode.value = int(weak.value) + episode.start = previous.start + episode.private = False + episode.tags = [] + + to_append.append(episode) + except ValueError: + pass + to_remove.extend(weaks) - return to_remove + if to_remove or to_append: + return to_remove, to_append + return False class RemoveWeakIfSxxExx(Rule): @@ -856,4 +907,6 @@ class RenameToDiscMatch(Rule): markers.append(marker) discs.extend(sorted(marker.initiator.children.named('episode'), key=lambda m: m.value)) - return discs, markers, to_remove + if discs or markers or to_remove: + return discs, markers, to_remove + return False diff --git a/libs/common/guessit/rules/properties/language.py b/libs/common/guessit/rules/properties/language.py index bcdbda8b..3f83bc34 100644 --- a/libs/common/guessit/rules/properties/language.py +++ b/libs/common/guessit/rules/properties/language.py @@ -72,6 +72,8 @@ def language(config, common_words): UNDETERMINED = babelfish.Language('und') +MULTIPLE = babelfish.Language('mul') +NON_SPECIFIC_LANGUAGES = frozenset([UNDETERMINED, MULTIPLE]) class GuessitConverter(babelfish.LanguageReverseConverter): # pylint: disable=missing-docstring @@ -388,7 +390,9 @@ class SubtitlePrefixLanguageRule(Rule): to_remove.extend(matches.conflicting(lang)) if prefix in to_remove: to_remove.remove(prefix) - return to_rename, to_remove + if to_rename or to_remove: + return to_rename, to_remove + return False def then(self, matches, when_response, context): to_rename, to_remove = when_response @@ -425,7 +429,9 @@ class SubtitleSuffixLanguageRule(Rule): to_append.append(lang) if suffix in to_remove: to_remove.remove(suffix) - return to_append, to_remove + if to_append or to_remove: + return to_append, to_remove + return False def then(self, matches, when_response, context): to_rename, to_remove = when_response @@ -478,6 +484,7 @@ class RemoveInvalidLanguages(Rule): """Remove language matches that matches the blacklisted common words.""" consequence = RemoveMatch + priority = 32 def __init__(self, common_words): """Constructor.""" diff --git a/libs/common/guessit/rules/properties/other.py b/libs/common/guessit/rules/properties/other.py index 330caa92..c7dc9a88 100644 --- a/libs/common/guessit/rules/properties/other.py +++ b/libs/common/guessit/rules/properties/other.py @@ -11,7 +11,7 @@ from rebulk.remodule import re from ..common import dash from ..common import seps from ..common.pattern import is_disabled -from ..common.validators import seps_after, seps_before, seps_surround, compose +from ..common.validators import seps_after, seps_before, seps_surround, and_ from ...reutils import build_or_pattern from ...rules.common.formatters import raw_cleanup @@ -35,11 +35,16 @@ def other(config): # pylint:disable=unused-argument,too-many-statements rebulk.regex('ws', 'wide-?screen', value='Widescreen') rebulk.regex('Re-?Enc(?:oded)?', value='Reencoded') - rebulk.string('Proper', 'Repack', 'Rerip', value='Proper', + rebulk.string('Repack', 'Rerip', value='Proper', tags=['streaming_service.prefix', 'streaming_service.suffix']) + rebulk.string('Proper', value='Proper', + tags=['has-neighbor', 'streaming_service.prefix', 'streaming_service.suffix']) rebulk.regex('Real-Proper', 'Real-Repack', 'Real-Rerip', value='Proper', tags=['streaming_service.prefix', 'streaming_service.suffix', 'real']) + rebulk.regex('Real', value='Proper', + tags=['has-neighbor', 'streaming_service.prefix', 'streaming_service.suffix', 'real']) + rebulk.string('Fix', 'Fixed', value='Fix', tags=['has-neighbor-before', 'has-neighbor-after', 'streaming_service.prefix', 'streaming_service.suffix']) rebulk.string('Dirfix', 'Nfofix', 'Prooffix', value='Fix', @@ -72,16 +77,18 @@ def other(config): # pylint:disable=unused-argument,too-many-statements private_names=['completeArticle', 'completeWordsBefore', 'completeWordsAfter'], value={'other': 'Complete'}, tags=['release-group-prefix'], - validator={'__parent__': compose(seps_surround, validate_complete)}) + validator={'__parent__': and_(seps_surround, validate_complete)}) rebulk.string('R5', value='Region 5') rebulk.string('RC', value='Region C') rebulk.regex('Pre-?Air', value='Preair') - rebulk.regex('(?:PS-?)?Vita', value='PS Vita') + rebulk.regex('(?:PS-?)Vita', value='PS Vita') + rebulk.regex('Vita', value='PS Vita', tags='has-neighbor') rebulk.regex('(HD)(?PRip)', value={'other': 'HD', 'another': 'Rip'}, private_parent=True, children=True, validator={'__parent__': seps_surround}, validate_all=True) - for value in ('Screener', 'Remux', '3D', 'PAL', 'SECAM', 'NTSC', 'XXX'): + for value in ('Screener', 'Remux', 'PAL', 'SECAM', 'NTSC', 'XXX'): rebulk.string(value, value=value) + rebulk.string('3D', value='3D', tags='has-neighbor') rebulk.string('HQ', value='High Quality', tags='uhdbluray-neighbor') rebulk.string('HR', value='High Resolution') @@ -90,6 +97,7 @@ def other(config): # pylint:disable=unused-argument,too-many-statements rebulk.string('mHD', 'HDLight', value='Micro HD') rebulk.string('LDTV', value='Low Definition') rebulk.string('HFR', value='High Frame Rate') + rebulk.string('VFR', value='Variable Frame Rate') rebulk.string('HD', value='HD', validator=None, tags=['streaming_service.prefix', 'streaming_service.suffix']) rebulk.regex('Full-?HD', 'FHD', value='Full HD', validator=None, @@ -128,13 +136,15 @@ def other(config): # pylint:disable=unused-argument,too-many-statements rebulk.regex('BT-?2020', value='BT.2020', tags='uhdbluray-neighbor') rebulk.string('Sample', value='Sample', tags=['at-end', 'not-a-release-group']) + rebulk.string('Extras', value='Extras', tags='has-neighbor') + rebulk.regex('Digital-?Extras?', value='Extras') rebulk.string('Proof', value='Proof', tags=['at-end', 'not-a-release-group']) rebulk.string('Obfuscated', 'Scrambled', value='Obfuscated', tags=['at-end', 'not-a-release-group']) rebulk.string('xpost', 'postbot', 'asrequested', value='Repost', tags='not-a-release-group') rebulk.rules(RenameAnotherToOther, ValidateHasNeighbor, ValidateHasNeighborAfter, ValidateHasNeighborBefore, ValidateScreenerRule, ValidateMuxRule, ValidateHardcodedSubs, ValidateStreamingServiceNeighbor, - ValidateAtEnd, ProperCountRule) + ValidateAtEnd, ValidateReal, ProperCountRule) return rebulk @@ -354,3 +364,20 @@ class ValidateAtEnd(Rule): to_remove.append(match) return to_remove + + +class ValidateReal(Rule): + """ + Validate Real + """ + consequence = RemoveMatch + priority = 64 + + def when(self, matches, context): + ret = [] + for filepart in matches.markers.named('path'): + for match in matches.range(filepart.start, filepart.end, lambda m: m.name == 'other' and 'real' in m.tags): + if not matches.range(filepart.start, match.start): + ret.append(match) + + return ret diff --git a/libs/common/guessit/rules/properties/part.py b/libs/common/guessit/rules/properties/part.py index ec038b18..c1123394 100644 --- a/libs/common/guessit/rules/properties/part.py +++ b/libs/common/guessit/rules/properties/part.py @@ -8,7 +8,7 @@ from rebulk.remodule import re from rebulk import Rebulk from ..common import dash from ..common.pattern import is_disabled -from ..common.validators import seps_surround, int_coercable, compose +from ..common.validators import seps_surround, int_coercable, and_ from ..common.numeral import numeral, parse_numeral from ...reutils import build_or_pattern @@ -41,6 +41,6 @@ def part(config): # pylint:disable=unused-argument rebulk.regex(build_or_pattern(prefixes) + r'-?(?P' + numeral + r')', prefixes=prefixes, validate_all=True, private_parent=True, children=True, formatter=parse_numeral, - validator={'part': compose(validate_roman, lambda m: 0 < m.value < 100)}) + validator={'part': and_(validate_roman, lambda m: 0 < m.value < 100)}) return rebulk diff --git a/libs/common/guessit/rules/properties/release_group.py b/libs/common/guessit/rules/properties/release_group.py index ff1ac660..ecff808b 100644 --- a/libs/common/guessit/rules/properties/release_group.py +++ b/libs/common/guessit/rules/properties/release_group.py @@ -9,8 +9,8 @@ from rebulk import Rebulk, Rule, AppendMatch, RemoveMatch from rebulk.match import Match from ..common import seps -from ..common.expected import build_expected_function from ..common.comparators import marker_sorted +from ..common.expected import build_expected_function from ..common.formatters import cleanup from ..common.pattern import is_disabled from ..common.validators import int_coercable, seps_surround @@ -50,7 +50,7 @@ def release_group(config): if string.lower().endswith(forbidden) and string[-len(forbidden) - 1:-len(forbidden)] in seps: string = string[:len(forbidden)] string = string.strip(groupname_seps) - return string + return string.strip() rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'release_group')) @@ -72,7 +72,9 @@ _scene_previous_names = ('video_codec', 'source', 'video_api', 'audio_codec', 'a 'audio_channels', 'screen_size', 'other', 'container', 'language', 'subtitle_language', 'subtitle_language.suffix', 'subtitle_language.prefix', 'language.suffix') -_scene_previous_tags = ('release-group-prefix', ) +_scene_previous_tags = ('release-group-prefix',) + +_scene_no_previous_tags = ('no-release-group-prefix',) class DashSeparatedReleaseGroup(Rule): @@ -193,7 +195,8 @@ class DashSeparatedReleaseGroup(Rule): if releasegroup.value: to_append.append(releasegroup) - return to_remove, to_append + if to_remove or to_append: + return to_remove, to_append class SceneReleaseGroup(Rule): @@ -212,6 +215,17 @@ class SceneReleaseGroup(Rule): super(SceneReleaseGroup, self).__init__() self.value_formatter = value_formatter + @staticmethod + def is_previous_match(match): + """ + Check if match can precede release_group + + :param match: + :return: + """ + return not match.tagged(*_scene_no_previous_tags) if match.name in _scene_previous_names else \ + match.tagged(*_scene_previous_tags) + def when(self, matches, context): # pylint:disable=too-many-locals # If a release_group is found before, ignore this kind of release_group rule. @@ -253,13 +267,12 @@ class SceneReleaseGroup(Rule): if match.start < filepart.start: return False - return not match.private or match.name in _scene_previous_names + return not match.private or self.is_previous_match(match) previous_match = matches.previous(last_hole, previous_match_filter, index=0) - if previous_match and (previous_match.name in _scene_previous_names or - any(tag in previous_match.tags for tag in _scene_previous_tags)) and \ + if previous_match and (self.is_previous_match(previous_match)) and \ not matches.input_string[previous_match.end:last_hole.start].strip(seps) \ and not int_coercable(last_hole.value.strip(seps)): @@ -300,11 +313,11 @@ class AnimeReleaseGroup(Rule): # If a release_group is found before, ignore this kind of release_group rule. if matches.named('release_group'): - return to_remove, to_append + return False if not matches.named('episode') and not matches.named('season') and matches.named('release_group'): # This doesn't seems to be an anime, and we already found another release_group. - return to_remove, to_append + return False for filepart in marker_sorted(matches.markers.named('path'), matches): @@ -328,4 +341,7 @@ class AnimeReleaseGroup(Rule): to_append.append(group) to_remove.extend(matches.range(empty_group.start, empty_group.end, lambda m: 'weak-language' in m.tags)) - return to_remove, to_append + + if to_remove or to_append: + return to_remove, to_append + return False diff --git a/libs/common/guessit/rules/properties/screen_size.py b/libs/common/guessit/rules/properties/screen_size.py index 83a797c1..77d5d052 100644 --- a/libs/common/guessit/rules/properties/screen_size.py +++ b/libs/common/guessit/rules/properties/screen_size.py @@ -24,8 +24,8 @@ def screen_size(config): :return: Created Rebulk object :rtype: Rebulk """ - interlaced = frozenset({res for res in config['interlaced']}) - progressive = frozenset({res for res in config['progressive']}) + interlaced = frozenset(config['interlaced']) + progressive = frozenset(config['progressive']) frame_rates = [re.escape(rate) for rate in config['frame_rates']] min_ar = config['min_ar'] max_ar = config['max_ar'] diff --git a/libs/common/guessit/rules/properties/source.py b/libs/common/guessit/rules/properties/source.py index ae9a7b03..2fe55618 100644 --- a/libs/common/guessit/rules/properties/source.py +++ b/libs/common/guessit/rules/properties/source.py @@ -12,7 +12,7 @@ from rebulk import AppendMatch, Rebulk, RemoveMatch, Rule from .audio_codec import HqConflictRule from ..common import dash, seps from ..common.pattern import is_disabled -from ..common.validators import seps_before, seps_after +from ..common.validators import seps_before, seps_after, or_ def source(config): # pylint:disable=unused-argument @@ -26,7 +26,10 @@ def source(config): # pylint:disable=unused-argument """ rebulk = Rebulk(disabled=lambda context: is_disabled(context, 'source')) rebulk = rebulk.regex_defaults(flags=re.IGNORECASE, abbreviations=[dash], private_parent=True, children=True) - rebulk.defaults(name='source', tags=['video-codec-prefix', 'streaming_service.suffix']) + rebulk = rebulk.defaults(name='source', + tags=['video-codec-prefix', 'streaming_service.suffix'], + validate_all=True, + validator={'__parent__': or_(seps_before, seps_after)}) rip_prefix = '(?PRip)-?' rip_suffix = '-?(?PRip)' @@ -42,7 +45,7 @@ def source(config): # pylint:disable=unused-argument def demote_other(match, other): # pylint: disable=unused-argument """Default conflict solver with 'other' property.""" - return other if other.name == 'other' else '__default__' + return other if other.name == 'other' or other.name == 'release_group' else '__default__' rebulk.regex(*build_source_pattern('VHS', suffix=rip_optional_suffix), value={'source': 'VHS', 'other': 'Rip'}) @@ -92,8 +95,9 @@ def source(config): # pylint:disable=unused-argument # WEBCap is a synonym to WEBRip, mostly used by non english rebulk.regex(*build_source_pattern('WEB-?(?PCap)', suffix=rip_optional_suffix), value={'source': 'Web', 'other': 'Rip', 'another': 'Rip'}) - rebulk.regex(*build_source_pattern('WEB-?DL', 'WEB-?U?HD', 'WEB', 'DL-?WEB', 'DL(?=-?Mux)'), + rebulk.regex(*build_source_pattern('WEB-?DL', 'WEB-?U?HD', 'DL-?WEB', 'DL(?=-?Mux)'), value={'source': 'Web'}) + rebulk.regex('(WEB)', value='Web', tags='weak.source') rebulk.regex(*build_source_pattern('HD-?DVD', suffix=rip_optional_suffix), value={'source': 'HD-DVD', 'other': 'Rip'}) @@ -118,7 +122,7 @@ def source(config): # pylint:disable=unused-argument rebulk.regex(*build_source_pattern('DSR?', 'SAT', suffix=rip_suffix), value={'source': 'Satellite', 'other': 'Rip'}) - rebulk.rules(ValidateSource, UltraHdBlurayRule) + rebulk.rules(ValidateSourcePrefixSuffix, ValidateWeakSource, UltraHdBlurayRule) return rebulk @@ -170,32 +174,62 @@ class UltraHdBlurayRule(Rule): to_remove.append(match) to_append.append(new_source) - return to_remove, to_append + if to_remove or to_append: + return to_remove, to_append + return False -class ValidateSource(Rule): +class ValidateSourcePrefixSuffix(Rule): """ - Validate source with screener property, with video_codec property or separated + Validate source with source prefix, source suffix. """ priority = 64 consequence = RemoveMatch def when(self, matches, context): ret = [] - for match in matches.named('source'): - match = match.initiator - if not seps_before(match) and \ - not matches.range(match.start - 1, match.start - 2, - lambda m: 'source-prefix' in m.tags): - if match.children: - ret.extend(match.children) - ret.append(match) - continue - if not seps_after(match) and \ - not matches.range(match.end, match.end + 1, - lambda m: 'source-suffix' in m.tags): - if match.children: - ret.extend(match.children) - ret.append(match) - continue + for filepart in matches.markers.named('path'): + for match in matches.range(filepart.start, filepart.end, predicate=lambda m: m.name == 'source'): + match = match.initiator + if not seps_before(match) and \ + not matches.range(match.start - 1, match.start - 2, + lambda m: 'source-prefix' in m.tags): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + if not seps_after(match) and \ + not matches.range(match.end, match.end + 1, + lambda m: 'source-suffix' in m.tags): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + + return ret + + +class ValidateWeakSource(Rule): + """ + Validate weak source + """ + dependency = [ValidateSourcePrefixSuffix] + priority = 64 + consequence = RemoveMatch + + def when(self, matches, context): + ret = [] + for filepart in matches.markers.named('path'): + for match in matches.range(filepart.start, filepart.end, predicate=lambda m: m.name == 'source'): + # if there are more than 1 source in this filepart, just before the year and with holes for the title + # most likely the source is part of the title + if 'weak.source' in match.tags \ + and matches.range(match.end, filepart.end, predicate=lambda m: m.name == 'source') \ + and matches.holes(filepart.start, match.start, + predicate=lambda m: m.value.strip(seps), index=-1): + if match.children: + ret.extend(match.children) + ret.append(match) + continue + return ret diff --git a/libs/common/guessit/rules/properties/streaming_service.py b/libs/common/guessit/rules/properties/streaming_service.py index 1302befb..f467f20a 100644 --- a/libs/common/guessit/rules/properties/streaming_service.py +++ b/libs/common/guessit/rules/properties/streaming_service.py @@ -25,133 +25,13 @@ def streaming_service(config): # pylint: disable=too-many-statements,unused-arg rebulk = rebulk.string_defaults(ignore_case=True).regex_defaults(flags=re.IGNORECASE, abbreviations=[dash]) rebulk.defaults(name='streaming_service', tags=['source-prefix']) - rebulk.string('AE', 'A&E', value='A&E') - rebulk.string('AMBC', value='ABC') - rebulk.string('AUBC', value='ABC Australia') - rebulk.string('AJAZ', value='Al Jazeera English') - rebulk.string('AMC', value='AMC') - rebulk.string('AMZN', 'Amazon', value='Amazon Prime') - rebulk.regex('Amazon-?Prime', value='Amazon Prime') - rebulk.string('AS', value='Adult Swim') - rebulk.regex('Adult-?Swim', value='Adult Swim') - rebulk.string('ATK', value="America's Test Kitchen") - rebulk.string('ANPL', value='Animal Planet') - rebulk.string('ANLB', value='AnimeLab') - rebulk.string('AOL', value='AOL') - rebulk.string('ARD', value='ARD') - rebulk.string('iP', value='BBC iPlayer') - rebulk.regex('BBC-?iPlayer', value='BBC iPlayer') - rebulk.string('BRAV', value='BravoTV') - rebulk.string('CNLP', value='Canal+') - rebulk.string('CN', value='Cartoon Network') - rebulk.string('CBC', value='CBC') - rebulk.string('CBS', value='CBS') - rebulk.string('CNBC', value='CNBC') - rebulk.string('CC', value='Comedy Central') - rebulk.string('4OD', value='Channel 4') - rebulk.string('CHGD', value='CHRGD') - rebulk.string('CMAX', value='Cinemax') - rebulk.string('CMT', value='Country Music Television') - rebulk.regex('Comedy-?Central', value='Comedy Central') - rebulk.string('CCGC', value='Comedians in Cars Getting Coffee') - rebulk.string('CR', value='Crunchy Roll') - rebulk.string('CRKL', value='Crackle') - rebulk.regex('Crunchy-?Roll', value='Crunchy Roll') - rebulk.string('CSPN', value='CSpan') - rebulk.string('CTV', value='CTV') - rebulk.string('CUR', value='CuriosityStream') - rebulk.string('CWS', value='CWSeed') - rebulk.string('DSKI', value='Daisuki') - rebulk.string('DHF', value='Deadhouse Films') - rebulk.string('DDY', value='Digiturk Diledigin Yerde') - rebulk.string('DISC', 'Discovery', value='Discovery') - rebulk.string('DSNY', 'Disney', value='Disney') - rebulk.string('DIY', value='DIY Network') - rebulk.string('DOCC', value='Doc Club') - rebulk.string('DPLY', value='DPlay') - rebulk.string('ETV', value='E!') - rebulk.string('EPIX', value='ePix') - rebulk.string('ETTV', value='El Trece') - rebulk.string('ESPN', value='ESPN') - rebulk.string('ESQ', value='Esquire') - rebulk.string('FAM', value='Family') - rebulk.string('FJR', value='Family Jr') - rebulk.string('FOOD', value='Food Network') - rebulk.string('FOX', value='Fox') - rebulk.string('FREE', value='Freeform') - rebulk.string('FYI', value='FYI Network') - rebulk.string('GLBL', value='Global') - rebulk.string('GLOB', value='GloboSat Play') - rebulk.string('HLMK', value='Hallmark') - rebulk.string('HBO', value='HBO Go') - rebulk.regex('HBO-?Go', value='HBO Go') - rebulk.string('HGTV', value='HGTV') - rebulk.string('HIST', 'History', value='History') - rebulk.string('HULU', value='Hulu') - rebulk.string('ID', value='Investigation Discovery') - rebulk.string('IFC', value='IFC') - rebulk.string('iTunes', 'iT', value='iTunes') - rebulk.string('ITV', value='ITV') - rebulk.string('KNOW', value='Knowledge Network') - rebulk.string('LIFE', value='Lifetime') - rebulk.string('MTOD', value='Motor Trend OnDemand') - rebulk.string('MNBC', value='MSNBC') - rebulk.string('MTV', value='MTV') - rebulk.string('NATG', value='National Geographic') - rebulk.regex('National-?Geographic', value='National Geographic') - rebulk.string('NBA', value='NBA TV') - rebulk.regex('NBA-?TV', value='NBA TV') - rebulk.string('NBC', value='NBC') - rebulk.string('NF', 'Netflix', value='Netflix') - rebulk.string('NFL', value='NFL') - rebulk.string('NFLN', value='NFL Now') - rebulk.string('GC', value='NHL GameCenter') - rebulk.string('NICK', 'Nickelodeon', value='Nickelodeon') - rebulk.string('NRK', value='Norsk Rikskringkasting') - rebulk.string('PBS', value='PBS') - rebulk.string('PBSK', value='PBS Kids') - rebulk.string('PSN', value='Playstation Network') - rebulk.string('PLUZ', value='Pluzz') - rebulk.string('RTE', value='RTE One') - rebulk.string('SBS', value='SBS (AU)') - rebulk.string('SESO', 'SeeSo', value='SeeSo') - rebulk.string('SHMI', value='Shomi') - rebulk.string('SPIK', value='Spike') - rebulk.string('SPKE', value='Spike TV') - rebulk.regex('Spike-?TV', value='Spike TV') - rebulk.string('SNET', value='Sportsnet') - rebulk.string('SPRT', value='Sprout') - rebulk.string('STAN', value='Stan') - rebulk.string('STZ', value='Starz') - rebulk.string('SVT', value='Sveriges Television') - rebulk.string('SWER', value='SwearNet') - rebulk.string('SYFY', value='Syfy') - rebulk.string('TBS', value='TBS') - rebulk.string('TFOU', value='TFou') - rebulk.string('CW', value='The CW') - rebulk.regex('The-?CW', value='The CW') - rebulk.string('TLC', value='TLC') - rebulk.string('TUBI', value='TubiTV') - rebulk.string('TV3', value='TV3 Ireland') - rebulk.string('TV4', value='TV4 Sweeden') - rebulk.string('TVL', value='TV Land') - rebulk.regex('TV-?Land', value='TV Land') - rebulk.string('UFC', value='UFC') - rebulk.string('UKTV', value='UKTV') - rebulk.string('UNIV', value='Univision') - rebulk.string('USAN', value='USA Network') - rebulk.string('VLCT', value='Velocity') - rebulk.string('VH1', value='VH1') - rebulk.string('VICE', value='Viceland') - rebulk.string('VMEO', value='Vimeo') - rebulk.string('VRV', value='VRV') - rebulk.string('WNET', value='W Network') - rebulk.string('WME', value='WatchMe') - rebulk.string('WWEN', value='WWE Network') - rebulk.string('XBOX', value='Xbox Video') - rebulk.string('YHOO', value='Yahoo') - rebulk.string('RED', value='YouTube Red') - rebulk.string('ZDF', value='ZDF') + for value, items in config.items(): + patterns = items if isinstance(items, list) else [items] + for pattern in patterns: + if pattern.startswith('re:'): + rebulk.regex(pattern, value=value) + else: + rebulk.string(pattern, value=value) rebulk.rules(ValidateStreamingService) @@ -161,7 +41,7 @@ def streaming_service(config): # pylint: disable=too-many-statements,unused-arg class ValidateStreamingService(Rule): """Validate streaming service matches.""" - priority = 32 + priority = 128 consequence = RemoveMatch def when(self, matches, context): diff --git a/libs/common/guessit/rules/properties/title.py b/libs/common/guessit/rules/properties/title.py index d1cafe2a..0d263016 100644 --- a/libs/common/guessit/rules/properties/title.py +++ b/libs/common/guessit/rules/properties/title.py @@ -8,7 +8,12 @@ from rebulk import Rebulk, Rule, AppendMatch, RemoveMatch, AppendTags from rebulk.formatters import formatters from .film import FilmTitleRule -from .language import SubtitlePrefixLanguageRule, SubtitleSuffixLanguageRule, SubtitleExtensionRule +from .language import ( + SubtitlePrefixLanguageRule, + SubtitleSuffixLanguageRule, + SubtitleExtensionRule, + NON_SPECIFIC_LANGUAGES +) from ..common import seps, title_seps from ..common.comparators import marker_sorted from ..common.expected import build_expected_function @@ -88,12 +93,19 @@ class TitleBaseRule(Rule): :rtype: """ cropped_holes = [] + group_markers = matches.markers.named('group') + for group_marker in group_markers: + path_marker = matches.markers.at_match(group_marker, predicate=lambda m: m.name == 'path', index=0) + if path_marker and path_marker.span == group_marker.span: + group_markers.remove(group_marker) + for hole in holes: - group_markers = matches.markers.named('group') cropped_holes.extend(hole.crop(group_markers)) + return cropped_holes - def is_ignored(self, match): + @staticmethod + def is_ignored(match): """ Ignore matches when scanning for title (hole). @@ -130,7 +142,8 @@ class TitleBaseRule(Rule): for outside in outside_matches: other_languages.extend(matches.range(outside.start, outside.end, lambda c_match: c_match.name == match.name and - c_match not in to_keep)) + c_match not in to_keep and + c_match.value not in NON_SPECIFIC_LANGUAGES)) if not other_languages and (not starting or len(match.raw) <= 3): return True @@ -239,7 +252,7 @@ class TitleBaseRule(Rule): to_remove = [] if matches.named(self.match_name, lambda match: 'expected' in match.tags): - return ret, to_remove + return False fileparts = [filepart for filepart in list(marker_sorted(matches.markers.named('path'), matches)) if not self.filepart_filter or self.filepart_filter(filepart, matches)] @@ -272,7 +285,9 @@ class TitleBaseRule(Rule): ret.extend(titles) to_remove.extend(to_remove_c) - return ret, to_remove + if ret or to_remove: + return ret, to_remove + return False class TitleFromPosition(TitleBaseRule): @@ -329,4 +344,6 @@ class PreferTitleWithYear(Rule): for title_match in titles: if title_match.value not in title_values: to_remove.append(title_match) - return to_remove, to_tag + if to_remove or to_tag: + return to_remove, to_tag + return False diff --git a/libs/common/guessit/rules/properties/video_codec.py b/libs/common/guessit/rules/properties/video_codec.py index b08ddcae..842a03c7 100644 --- a/libs/common/guessit/rules/properties/video_codec.py +++ b/libs/common/guessit/rules/properties/video_codec.py @@ -3,9 +3,8 @@ """ video_codec and video_profile property """ -from rebulk.remodule import re - from rebulk import Rebulk, Rule, RemoveMatch +from rebulk.remodule import re from ..common import dash from ..common.pattern import is_disabled @@ -43,7 +42,8 @@ def video_codec(config): # pylint:disable=unused-argument # http://blog.mediacoderhq.com/h264-profiles-and-levels/ # https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC - rebulk.defaults(name="video_profile", + rebulk.defaults(clear=True, + name="video_profile", validator=seps_surround, disabled=lambda context: is_disabled(context, 'video_profile')) @@ -66,7 +66,8 @@ def video_codec(config): # pylint:disable=unused-argument rebulk.string('DXVA', value='DXVA', name='video_api', disabled=lambda context: is_disabled(context, 'video_api')) - rebulk.defaults(name='color_depth', + rebulk.defaults(clear=True, + name='color_depth', validator=seps_surround, disabled=lambda context: is_disabled(context, 'color_depth')) rebulk.regex('12.?bits?', value='12-bit') diff --git a/libs/common/guessit/rules/properties/website.py b/libs/common/guessit/rules/properties/website.py index 00dfadd1..c1965311 100644 --- a/libs/common/guessit/rules/properties/website.py +++ b/libs/common/guessit/rules/properties/website.py @@ -67,7 +67,7 @@ def website(config): """ Validator for next website matches """ - return any(name in ['season', 'episode', 'year'] for name in match.names) + return match.named('season', 'episode', 'year') def when(self, matches, context): to_remove = [] @@ -80,7 +80,9 @@ def website(config): if not safe: suffix = matches.next(website_match, PreferTitleOverWebsite.valid_followers, 0) if suffix: - to_remove.append(website_match) + group = matches.markers.at_match(website_match, lambda marker: marker.name == 'group', 0) + if not group: + to_remove.append(website_match) return to_remove rebulk.rules(PreferTitleOverWebsite, ValidateWebsitePrefix) diff --git a/libs/common/guessit/test/enable_disable_properties.yml b/libs/common/guessit/test/enable_disable_properties.yml index 86c659d6..ada9c347 100644 --- a/libs/common/guessit/test/enable_disable_properties.yml +++ b/libs/common/guessit/test/enable_disable_properties.yml @@ -35,9 +35,9 @@ -cd: 1 -cd_count: 3 -? This.Is.Us +? This.is.Us : options: --exclude country - title: This Is Us + title: This is Us -country: US ? 2015.01.31 @@ -286,9 +286,9 @@ : options: --exclude website -website: wawa.co.uk -? movie.mkv +? movie.mp4 : options: --exclude mimetype - -mimetype: video/x-matroska + -mimetype: video/mp4 ? another movie.mkv : options: --exclude container diff --git a/libs/common/guessit/test/episodes.yml b/libs/common/guessit/test/episodes.yml index f7b5c3df..4bbbde4a 100644 --- a/libs/common/guessit/test/episodes.yml +++ b/libs/common/guessit/test/episodes.yml @@ -201,9 +201,9 @@ ? Series/My Name Is Earl/My.Name.Is.Earl.S01Extras.-.Bad.Karma.DVDRip.XviD.avi : title: My Name Is Earl season: 1 - episode_title: Extras - Bad Karma + episode_title: Bad Karma source: DVD - other: Rip + other: [Extras, Rip] video_codec: Xvid ? series/Freaks And Geeks/Season 1/Episode 4 - Kim Kelly Is My Friend-eng(1).srt @@ -1917,9 +1917,11 @@ ? Duck.Dynasty.S02E07.Streik.German.DOKU.DL.WS.DVDRiP.x264-CDP : episode: 7 - episode_title: Streik German + episode_title: Streik source: DVD - language: mul + language: + - German + - Multi other: [Documentary, Widescreen, Rip] release_group: CDP season: 2 @@ -1930,9 +1932,11 @@ ? Family.Guy.S13E14.JOLO.German.AC3D.DL.720p.WebHD.x264-CDD : audio_codec: Dolby Digital episode: 14 - episode_title: JOLO German + episode_title: JOLO source: Web - language: mul + language: + - German + - Multi release_group: CDD screen_size: 720p season: 13 @@ -3025,7 +3029,7 @@ title: Show Name episode: [493, 494, 495, 496, 497, 498, 500, 501, 502, 503, 504, 505, 506, 507] screen_size: 720p - subtitle_language: fr + other: Variable Frame Rate video_codec: H.264 audio_codec: AAC type: episode @@ -4524,4 +4528,166 @@ video_codec: H.264 audio_codec: MP2 release_group: KIDKAT + type: episode + +? Por Trece Razones - Temporada 2 [HDTV 720p][Cap.201][AC3 5.1 Castellano]/Por Trece Razones 2x01 [des202].mkv +: title: Por Trece Razones + season: 2 + source: HDTV + screen_size: 720p + episode: 1 + audio_codec: Dolby Digital + audio_channels: '5.1' + language: Catalan + release_group: des202 + container: mkv + type: episode + +? Cuerpo de Elite - Temporada 1 [HDTV 720p][Cap.113][AC3 5.1 Esp Castellano]\CuerpoDeElite720p_113_desca202.mkv +: title: Cuerpo de Elite + season: 1 + source: HDTV + screen_size: 720p + episode: 13 + audio_codec: Dolby Digital + audio_channels: '5.1' + language: + - Spanish + - Catalan + container: mkv + type: episode + +? Show.Name.S01E01.St.Patricks.Day.1080p.mkv +: title: Show Name + season: 1 + episode: 1 + episode_title: St Patricks Day + screen_size: 1080p + container: mkv + type: episode + +? Show.Name.S01E01.St.Patricks.Day.1080p-grp.mkv +: title: Show Name + season: 1 + episode: 1 + episode_title: St Patricks Day + screen_size: 1080p + release_group: grp + container: mkv + type: episode + +? Titans.2018.S01E09.Hank.And.Dawn.720p.DCU.WEB-DL.AAC2.0.H264-NTb +: title: Titans + year: 2018 + season: 1 + episode: 9 + episode_title: Hank And Dawn + screen_size: 720p + streaming_service: DC Universe + source: Web + audio_codec: AAC + audio_channels: '2.0' + video_codec: H.264 + release_group: NTb + type: episode + +? S.W.A.T.2017.S01E21.Treibjagd.German.Dubbed.DL.AmazonHD.x264-TVS +: title: S.W.A.T. + year: 2017 + season: 1 + episode: 21 + episode_title: Treibjagd + language: + - German + - Multi + streaming_service: Amazon Prime + other: HD + video_codec: H.264 + release_group: TVS + type: episode + +? S.W.A.T.2017.S01E16.READNFO.720p.HDTV.x264-KILLERS +: title: S.W.A.T. + year: 2017 + season: 1 + episode: 16 + other: Read NFO + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: KILLERS + type: episode + +? /mnt/NAS/NoSubsTVShows/Babylon 5/Season 01/Ep. 02 - Soul Hunter +: title: Babylon 5 + season: 1 + episode: 2 + episode_title: Soul Hunter + type: episode + +? This.is.Us.S01E01.HDTV.x264-KILLERS.mkv +: title: This is Us + season: 1 + episode: 1 + source: HDTV + video_codec: H.264 + release_group: KILLERS + container: mkv + type: episode + +? Videos/Office1080/The Office (US) (2005) Season 2 S02 + Extras (1080p AMZN WEB-DL x265 HEVC 10bit AAC 2.0 LION)/The Office (US) (2005) - S02E12 - The Injury (1080p AMZN WEB-DL x265 LION).mkv +: title: The Office + country: US + year: 2005 + season: 2 + other: Extras + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + video_codec: H.265 + video_profile: High Efficiency Video Coding + color_depth: 10-bit + audio_codec: AAC + audio_channels: '2.0' + release_group: LION + episode: 12 + episode_title: The Injury + container: mkv + type: episode + +? Thumping.Spike.2.E01.DF.WEBRip.720p-DRAMATV.mp4 +: title: Thumping Spike 2 + episode: 1 + source: Web + other: Rip + screen_size: 720p + streaming_service: DramaFever + release_group: DRAMATV + container: mp4 + mimetype: video/mp4 + type: episode + +? About.Time.E01.1080p.VIKI.WEB-DL-BLUEBERRY.mp4 +: title: About Time + episode: 1 + screen_size: 1080p + streaming_service: Viki + source: Web + release_group: BLUEBERRY + container: mp4 + mimetype: video/mp4 + type: episode + +? Eyes.Of.Dawn.1991.E01.480p.MBCVOD.AAC.x264-NOGPR.mp4 +: title: Eyes Of Dawn + year: 1991 + season: 1991 + episode: 1 + screen_size: 480p + streaming_service: MBC + audio_codec: AAC + video_codec: H.264 + release_group: NOGPR + container: mp4 + mimetype: video/mp4 type: episode \ No newline at end of file diff --git a/libs/common/guessit/test/movies.yml b/libs/common/guessit/test/movies.yml index 642012a9..a534ca0f 100644 --- a/libs/common/guessit/test/movies.yml +++ b/libs/common/guessit/test/movies.yml @@ -815,10 +815,12 @@ ? Das.Appartement.German.AC3D.DL.720p.BluRay.x264-TVP : audio_codec: Dolby Digital source: Blu-ray - language: mul + language: + - German + - Multi release_group: TVP screen_size: 720p - title: Das Appartement German + title: Das Appartement type: movie video_codec: H.264 @@ -1723,7 +1725,7 @@ ? Ant-Man.and.the.Wasp.2018.Digital.Extras.1080p.AMZN.WEB-DL.DDP5.1.H.264-NTG.mkv : title: Ant-Man and the Wasp year: 2018 - alternative_title: Digital Extras + other: Extras screen_size: 1080p streaming_service: Amazon Prime source: Web @@ -1770,4 +1772,15 @@ audio_channels: '5.1' video_codec: H.264 release_group: CMRG - type: movie \ No newline at end of file + type: movie + +? The.Girl.in.the.Spiders.Web.2019.1080p.WEB-DL.x264.AC3-EVO.mkv +: title: The Girl in the Spiders Web + year: 2019 + screen_size: 1080p + source: Web + video_codec: H.264 + audio_codec: Dolby Digital + release_group: EVO + container: mkv + type: movie diff --git a/libs/common/guessit/test/rules/common_words.yml b/libs/common/guessit/test/rules/common_words.yml new file mode 100644 index 00000000..d403a457 --- /dev/null +++ b/libs/common/guessit/test/rules/common_words.yml @@ -0,0 +1,467 @@ +? is +: title: is + +? it +: title: it + +? am +: title: am + +? mad +: title: mad + +? men +: title: men + +? man +: title: man + +? run +: title: run + +? sin +: title: sin + +? st +: title: st + +? to +: title: to + +? 'no' +: title: 'no' + +? non +: title: non + +? war +: title: war + +? min +: title: min + +? new +: title: new + +? car +: title: car + +? day +: title: day + +? bad +: title: bad + +? bat +: title: bat + +? fan +: title: fan + +? fry +: title: fry + +? cop +: title: cop + +? zen +: title: zen + +? gay +: title: gay + +? fat +: title: fat + +? one +: title: one + +? cherokee +: title: cherokee + +? got +: title: got + +? an +: title: an + +? as +: title: as + +? cat +: title: cat + +? her +: title: her + +? be +: title: be + +? hat +: title: hat + +? sun +: title: sun + +? may +: title: may + +? my +: title: my + +? mr +: title: mr + +? rum +: title: rum + +? pi +: title: pi + +? bb +: title: bb + +? bt +: title: bt + +? tv +: title: tv + +? aw +: title: aw + +? by +: title: by + +? md +: other: Mic Dubbed + +? mp +: title: mp + +? cd +: title: cd + +? in +: title: in + +? ad +: title: ad + +? ice +: title: ice + +? ay +: title: ay + +? at +: title: at + +? star +: title: star + +? so +: title: so + +? he +: title: he + +? do +: title: do + +? ax +: title: ax + +? mx +: title: mx + +? bas +: title: bas + +? de +: title: de + +? le +: title: le + +? son +: title: son + +? ne +: title: ne + +? ca +: title: ca + +? ce +: title: ce + +? et +: title: et + +? que +: title: que + +? mal +: title: mal + +? est +: title: est + +? vol +: title: vol + +? or +: title: or + +? mon +: title: mon + +? se +: title: se + +? je +: title: je + +? tu +: title: tu + +? me +: title: me + +? ma +: title: ma + +? va +: title: va + +? au +: country: AU + +? lu +: title: lu + +? wa +: title: wa + +? ga +: title: ga + +? ao +: title: ao + +? la +: title: la + +? el +: title: el + +? del +: title: del + +? por +: title: por + +? mar +: title: mar + +? al +: title: al + +? un +: title: un + +? ind +: title: ind + +? arw +: title: arw + +? ts +: source: Telesync + +? ii +: title: ii + +? bin +: title: bin + +? chan +: title: chan + +? ss +: title: ss + +? san +: title: san + +? oss +: title: oss + +? iii +: title: iii + +? vi +: title: vi + +? ben +: title: ben + +? da +: title: da + +? lt +: title: lt + +? ch +: title: ch + +? sr +: title: sr + +? ps +: title: ps + +? cx +: title: cx + +? vo +: title: vo + +? mkv +: container: mkv + +? avi +: container: avi + +? dmd +: title: dmd + +? the +: title: the + +? dis +: title: dis + +? cut +: title: cut + +? stv +: title: stv + +? des +: title: des + +? dia +: title: dia + +? and +: title: and + +? cab +: title: cab + +? sub +: title: sub + +? mia +: title: mia + +? rim +: title: rim + +? las +: title: las + +? une +: title: une + +? par +: title: par + +? srt +: container: srt + +? ano +: title: ano + +? toy +: title: toy + +? job +: title: job + +? gag +: title: gag + +? reel +: title: reel + +? www +: title: www + +? for +: title: for + +? ayu +: title: ayu + +? csi +: title: csi + +? ren +: title: ren + +? moi +: title: moi + +? sur +: title: sur + +? fer +: title: fer + +? fun +: title: fun + +? two +: title: two + +? big +: title: big + +? psy +: title: psy + +? air +: title: air + +? brazil +: title: brazil + +? jordan +: title: jordan + +? bs +: title: bs + +? kz +: title: kz + +? gt +: title: gt + +? im +: title: im + +? pt +: language: pt + +? scr +: title: scr + +? sd +: title: sd + +? hr +: other: High Resolution diff --git a/libs/common/guessit/test/rules/country.yml b/libs/common/guessit/test/rules/country.yml index 76383180..b3d4d8f1 100644 --- a/libs/common/guessit/test/rules/country.yml +++ b/libs/common/guessit/test/rules/country.yml @@ -5,8 +5,8 @@ : country: US title: this is title -? This.is.us.title -: title: This is us title +? This.is.Us +: title: This is Us ? This.Is.Us : options: --no-default-config diff --git a/libs/common/guessit/test/rules/other.yml b/libs/common/guessit/test/rules/other.yml index e2bea6e7..447f1787 100644 --- a/libs/common/guessit/test/rules/other.yml +++ b/libs/common/guessit/test/rules/other.yml @@ -48,7 +48,7 @@ proper_count: 3 -? Proper +? Proper.720p ? +Repack ? +Rerip : other: Proper @@ -80,7 +80,7 @@ ? Remux : other: Remux -? 3D +? 3D.2019 : other: 3D ? HD diff --git a/libs/common/guessit/test/suggested.json b/libs/common/guessit/test/suggested.json new file mode 100644 index 00000000..dc838ad0 --- /dev/null +++ b/libs/common/guessit/test/suggested.json @@ -0,0 +1,21 @@ +{ + "titles": [ + "13 Reasons Why", + "Star Wars: Episode VII - The Force Awakens", + "3%", + "The 100", + "3 Percent", + "This is Us", + "Open Season 2", + "Game of Thrones", + "The X-Files", + "11.22.63" + ], + "suggested": [ + "13 Reasons Why", + "Star Wars: Episode VII - The Force Awakens", + "The 100", + "Open Season 2", + "11.22.63" + ] +} \ No newline at end of file diff --git a/libs/common/guessit/test/test_api.py b/libs/common/guessit/test/test_api.py index 9abb84d9..391dbced 100644 --- a/libs/common/guessit/test/test_api.py +++ b/libs/common/guessit/test/test_api.py @@ -1,13 +1,14 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- # pylint: disable=no-self-use, pointless-statement, missing-docstring, invalid-name, pointless-string-statement - +import json import os +import sys import pytest import six -from ..api import guessit, properties, GuessitException +from ..api import guessit, properties, suggested_expected, GuessitException __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) @@ -27,12 +28,16 @@ def test_forced_binary(): assert ret and 'title' in ret and isinstance(ret['title'], six.binary_type) -@pytest.mark.skipif('sys.version_info < (3, 4)', reason="Path is not available") +@pytest.mark.skipif(sys.version_info < (3, 4), reason="Path is not available") def test_pathlike_object(): - from pathlib import Path - path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv') - ret = guessit(path) - assert ret and 'title' in ret + try: + from pathlib import Path + + path = Path('Fear.and.Loathing.in.Las.Vegas.FRENCH.ENGLISH.720p.HDDVD.DTS.x264-ESiR.mkv') + ret = guessit(path) + assert ret and 'title' in ret + except ImportError: # pragma: no-cover + pass def test_unicode_japanese(): @@ -69,3 +74,10 @@ def test_exception(): assert "An internal error has occured in guessit" in str(excinfo.value) assert "Guessit Exception Report" in str(excinfo.value) assert "Please report at https://github.com/guessit-io/guessit/issues" in str(excinfo.value) + + +def test_suggested_expected(): + with open(os.path.join(__location__, 'suggested.json'), 'r') as f: + content = json.load(f) + actual = suggested_expected(content['titles']) + assert actual == content['suggested'] diff --git a/libs/common/guessit/test/test_yml.py b/libs/common/guessit/test/test_yml.py index 4f58a056..040796de 100644 --- a/libs/common/guessit/test/test_yml.py +++ b/libs/common/guessit/test/test_yml.py @@ -7,9 +7,8 @@ import os from io import open # pylint: disable=redefined-builtin import babelfish -import pytest -import six -import yaml +import six # pylint:disable=wrong-import-order +import yaml # pylint:disable=wrong-import-order from rebulk.remodule import re from rebulk.utils import is_iterable @@ -21,13 +20,6 @@ logger = logging.getLogger(__name__) __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__))) -filename_predicate = None -string_predicate = None - - -# filename_predicate = lambda filename: 'episode_title' in filename -# string_predicate = lambda string: '-DVD.BlablaBla.Fix.Blablabla.XVID' in string - class EntryResult(object): def __init__(self, string, negates=False): @@ -134,7 +126,49 @@ class TestYml(object): options_re = re.compile(r'^([ +-]+)(.*)') - files, ids = files_and_ids(filename_predicate) + def _get_unique_id(self, collection, base_id): + ret = base_id + i = 2 + while ret in collection: + suffix = "-" + str(i) + ret = base_id + suffix + i += 1 + return ret + + def pytest_generate_tests(self, metafunc): + if 'yml_test_case' in metafunc.fixturenames: + entries = [] + entry_ids = [] + entry_set = set() + + for filename, _ in zip(*files_and_ids()): + with open(os.path.join(__location__, filename), 'r', encoding='utf-8') as infile: + data = yaml.load(infile, OrderedDictYAMLLoader) + + last_expected = None + for string, expected in reversed(list(data.items())): + if expected is None: + data[string] = last_expected + else: + last_expected = expected + + default = None + try: + default = data['__default__'] + del data['__default__'] + except KeyError: + pass + + for string, expected in data.items(): + TestYml.set_default(expected, default) + string = TestYml.fix_encoding(string, expected) + + entries.append((filename, string, expected)) + unique_id = self._get_unique_id(entry_set, '[' + filename + '] ' + str(string)) + entry_set.add(unique_id) + entry_ids.append(unique_id) + + metafunc.parametrize('yml_test_case', entries, ids=entry_ids) @staticmethod def set_default(expected, default): @@ -143,34 +177,8 @@ class TestYml(object): if k not in expected: expected[k] = v - @pytest.mark.parametrize('filename', files, ids=ids) - def test(self, filename, caplog): - caplog.set_level(logging.INFO) - with open(os.path.join(__location__, filename), 'r', encoding='utf-8') as infile: - data = yaml.load(infile, OrderedDictYAMLLoader) - entries = Results() - - last_expected = None - for string, expected in reversed(list(data.items())): - if expected is None: - data[string] = last_expected - else: - last_expected = expected - - default = None - try: - default = data['__default__'] - del data['__default__'] - except KeyError: - pass - - for string, expected in data.items(): - TestYml.set_default(expected, default) - entry = self.check_data(filename, string, expected) - entries.append(entry) - entries.assert_ok() - - def check_data(self, filename, string, expected): + @classmethod + def fix_encoding(cls, string, expected): if six.PY2: if isinstance(string, six.text_type): string = string.encode('utf-8') @@ -183,16 +191,23 @@ class TestYml(object): expected[k] = v if not isinstance(string, str): string = str(string) - if not string_predicate or string_predicate(string): # pylint: disable=not-callable - entry = self.check(string, expected) - if entry.ok: - logger.debug('[%s] %s', filename, entry) - elif entry.warning: - logger.warning('[%s] %s', filename, entry) - elif entry.error: - logger.error('[%s] %s', filename, entry) - for line in entry.details: - logger.error('[%s] %s', filename, ' ' * 4 + line) + return string + + def test_entry(self, yml_test_case): + filename, string, expected = yml_test_case + result = self.check_data(filename, string, expected) + assert not result.error + + def check_data(self, filename, string, expected): + entry = self.check(string, expected) + if entry.ok: + logger.debug('[%s] %s', filename, entry) + elif entry.warning: + logger.warning('[%s] %s', filename, entry) + elif entry.error: + logger.error('[%s] %s', filename, entry) + for line in entry.details: + logger.error('[%s] %s', filename, ' ' * 4 + line) return entry def check(self, string, expected): diff --git a/libs/common/guessit/test/various.yml b/libs/common/guessit/test/various.yml index 5e689e0b..6fb58deb 100644 --- a/libs/common/guessit/test/various.yml +++ b/libs/common/guessit/test/various.yml @@ -946,3 +946,254 @@ source: Blu-ray audio_codec: DTS-HD type: movie + +? Mr Robot - S03E01 - eps3 0 power-saver-mode h (1080p AMZN WEB-DL x265 HEVC 10bit EAC3 6.0 RCVR).mkv +: title: Mr Robot + season: 3 + episode: 1 + episode_title: eps3 0 power-saver-mode h + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + video_codec: H.265 + video_profile: High Efficiency Video Coding + color_depth: 10-bit + audio_codec: Dolby Digital Plus + audio_channels: '5.1' + release_group: RCVR + container: mkv + type: episode + +? Panorama.15-05-2018.Web-DL.540p.H264.AAC.Subs.mp4 +: title: Panorama + date: 2018-05-15 + source: Web + screen_size: 540p + video_codec: H.264 + audio_codec: AAC + subtitle_language: und + container: mp4 + type: episode + +? Shaolin 2011.720p.BluRay.x264-x0r.mkv +: title: Shaolin + year: 2011 + screen_size: 720p + source: Blu-ray + video_codec: H.264 + release_group: x0r + container: mkv + type: movie + +? '[ Engineering Catastrophes S02E10 1080p AMZN WEB-DL DD+ 2.0 x264-TrollHD ]' +: title: Engineering Catastrophes + season: 2 + episode: 10 + screen_size: 1080p + streaming_service: Amazon Prime + source: Web + audio_codec: Dolby Digital Plus + audio_channels: '2.0' + video_codec: H.264 + release_group: TrollHD + type: episode + +? A Very Harold & Kumar 3D Christmas (2011).mkv +: title: A Very Harold & Kumar 3D Christmas + year: 2011 + container: mkv + type: movie + +? Cleveland.Hustles.S01E03.Downward.Dogs.and.Proper.Pigs.720p.HDTV.x264-W4F +: title: Cleveland Hustles + season: 1 + episode: 3 + episode_title: Downward Dogs and Proper Pigs + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode + +? Pawn.Stars.S12E20.The.Pawn.Awakens.REAL.READ.NFO.720p.HDTV.x264-DHD +: title: Pawn Stars + season: 12 + episode: 20 + episode_title: The Pawn Awakens + other: + - Proper + - Read NFO + proper_count: 2 + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? Pawn.Stars.S12E22.Racing.Revolution.REAL.720p.HDTV.x264-DHD +: title: Pawn Stars + season: 12 + episode: 22 + episode_title: Racing Revolution + other: Proper + proper_count: 2 + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? Luksusfellen.S18E02.REAL.NORWEGiAN.720p.WEB.h264-NORPiLT +: title: Luksusfellen + season: 18 + episode: 2 + other: Proper + proper_count: 2 + language: Norwegian + screen_size: 720p + source: Web + video_codec: H.264 + release_group: NORPiLT + type: episode + +? The.Exorcist.S02E07.REAL.FRENCH.720p.HDTV.x264-SH0W +: title: The Exorcist + season: 2 + episode: 7 + other: Proper + proper_count: 2 + language: fr + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: SH0W + type: episode + +? Outrageous.Acts.of.Science.S05E02.Is.This.for.Real.720p.HDTV.x264-DHD +: title: Outrageous Acts of Science + season: 5 + episode: 2 +# corner case +# episode_title: Is This for Real + screen_size: 720p + source: HDTV + video_codec: H.264 + release_group: DHD + type: episode + +? How.the.Universe.Works.S06E08.Strange.Lives.of.Dwarf.Planets.REAL.720p.WEB.x264-DHD +: title: How the Universe Works + season: 6 + episode: 8 + episode_title: Strange Lives of Dwarf Planets + other: Proper + proper_count: 2 + screen_size: 720p + source: Web + video_codec: H.264 + release_group: DHD + type: episode + +? Vampirina.S01E16.REAL.HDTV.x264-W4F +: title: Vampirina + season: 1 + episode: 16 + other: Proper + proper_count: 2 + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode + +? Test.S01E16.Some Real Episode Title.HDTV.x264-W4F +: title: Test + season: 1 + episode: 16 + episode_title: Some Real Episode Title + source: HDTV + video_codec: H.264 + release_group: W4F + type: episode + +? NOS4A2.S01E01.The.Shorter.Way.REPACK.720p.AMZN.WEB-DL.DDP5.1.H.264-NTG.mkv +: title: NOS4A2 + season: 1 + episode: 1 + episode_title: The Shorter Way + other: Proper + proper_count: 1 + screen_size: 720p + streaming_service: Amazon Prime + source: Web + audio_codec: Dolby Digital Plus + audio_channels: '5.1' + video_codec: H.264 + release_group: NTG + container: mkv + type: episode + +? Star Trek DS9 Ep 2x03 The Siege (Part III) +: title: Star Trek DS9 + season: 2 + episode: 3 + episode_title: The Siege + part: 3 + type: episode + +? The.Red.Line.S01E01 +: title: The Red Line + season: 1 + episode: 1 + type: episode + +? Show.S01E01.WEB.x264-METCON.mkv +: title: Show + season: 1 + episode: 1 + source: Web + video_codec: H.264 + release_group: METCON + container: mkv + type: episode + +? Show.S01E01.WEB.x264-TCMEON.mkv +: title: Show + season: 1 + episode: 1 + source: Web + video_codec: H.264 + release_group: TCMEON + container: mkv + type: episode + +? Show.S01E01.WEB.x264-MEONTC.mkv +: title: Show + season: 1 + episode: 1 + source: Web + video_codec: H.264 + release_group: MEONTC + container: mkv + type: episode + +? '[TorrentCouch.com].Westworld.S02.Complete.720p.WEB-DL.x264.[MP4].[5.3GB].[Season.2.Full]/[TorrentCouch.com].Westworld.S02E03.720p.WEB-DL.x264.mp4' +: website: TorrentCouch.com + title: Westworld + season: 2 + other: Complete + screen_size: 720p + source: Web + video_codec: H.264 + container: mp4 + size: 5.3GB + episode: 3 + type: episode + +? Vita.&.Virginia.2018.720p.H.264.YTS.LT.mp4 +: title: Vita & Virginia + year: 2018 + screen_size: 720p + video_codec: H.264 + release_group: YTS.LT + container: mp4 + type: movie \ No newline at end of file diff --git a/libs/common/guessit/yamlutils.py b/libs/common/guessit/yamlutils.py index 01ac7778..d04be641 100644 --- a/libs/common/guessit/yamlutils.py +++ b/libs/common/guessit/yamlutils.py @@ -10,19 +10,19 @@ except ImportError: # pragma: no-cover from ordereddict import OrderedDict # pylint:disable=import-error import babelfish -import yaml +import yaml # pylint:disable=wrong-import-order from .rules.common.quantity import BitRate, FrameRate, Size -class OrderedDictYAMLLoader(yaml.Loader): +class OrderedDictYAMLLoader(yaml.SafeLoader): """ A YAML loader that loads mappings into ordered dictionaries. From https://gist.github.com/enaeseth/844388 """ def __init__(self, *args, **kwargs): - yaml.Loader.__init__(self, *args, **kwargs) + yaml.SafeLoader.__init__(self, *args, **kwargs) self.add_constructor(u'tag:yaml.org,2002:map', type(self).construct_yaml_map) self.add_constructor(u'tag:yaml.org,2002:omap', type(self).construct_yaml_map) @@ -58,7 +58,7 @@ class CustomDumper(yaml.SafeDumper): """ Custom YAML Dumper. """ - pass + pass # pylint:disable=unnecessary-pass def default_representer(dumper, data): diff --git a/libs/common/rebulk/__version__.py b/libs/common/rebulk/__version__.py index 1f96b77a..939c554c 100644 --- a/libs/common/rebulk/__version__.py +++ b/libs/common/rebulk/__version__.py @@ -4,4 +4,4 @@ Version module """ # pragma: no cover -__version__ = '1.0.0' +__version__ = '2.0.1' diff --git a/libs/common/rebulk/builder.py b/libs/common/rebulk/builder.py new file mode 100644 index 00000000..c91420aa --- /dev/null +++ b/libs/common/rebulk/builder.py @@ -0,0 +1,217 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +""" +Base builder class for Rebulk +""" +from abc import ABCMeta, abstractmethod +from copy import deepcopy +from logging import getLogger + +from six import add_metaclass + +from .loose import set_defaults +from .pattern import RePattern, StringPattern, FunctionalPattern + +log = getLogger(__name__).log + + +@add_metaclass(ABCMeta) +class Builder(object): + """ + Base builder class for patterns + """ + + def __init__(self): + self._defaults = {} + self._regex_defaults = {} + self._string_defaults = {} + self._functional_defaults = {} + self._chain_defaults = {} + + def reset(self): + """ + Reset all defaults. + + :return: + """ + self.__init__() + + def defaults(self, **kwargs): + """ + Define default keyword arguments for all patterns + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(kwargs, self._defaults, override=True) + return self + + def regex_defaults(self, **kwargs): + """ + Define default keyword arguments for functional patterns. + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(kwargs, self._regex_defaults, override=True) + return self + + def string_defaults(self, **kwargs): + """ + Define default keyword arguments for string patterns. + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(kwargs, self._string_defaults, override=True) + return self + + def functional_defaults(self, **kwargs): + """ + Define default keyword arguments for functional patterns. + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(kwargs, self._functional_defaults, override=True) + return self + + def chain_defaults(self, **kwargs): + """ + Define default keyword arguments for patterns chain. + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(kwargs, self._chain_defaults, override=True) + return self + + def build_re(self, *pattern, **kwargs): + """ + Builds a new regular expression pattern + + :param pattern: + :type pattern: + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(self._regex_defaults, kwargs) + set_defaults(self._defaults, kwargs) + return RePattern(*pattern, **kwargs) + + def build_string(self, *pattern, **kwargs): + """ + Builds a new string pattern + + :param pattern: + :type pattern: + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(self._string_defaults, kwargs) + set_defaults(self._defaults, kwargs) + return StringPattern(*pattern, **kwargs) + + def build_functional(self, *pattern, **kwargs): + """ + Builds a new functional pattern + + :param pattern: + :type pattern: + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + set_defaults(self._functional_defaults, kwargs) + set_defaults(self._defaults, kwargs) + return FunctionalPattern(*pattern, **kwargs) + + def build_chain(self, **kwargs): + """ + Builds a new patterns chain + + :param pattern: + :type pattern: + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + from .chain import Chain + set_defaults(self._chain_defaults, kwargs) + set_defaults(self._defaults, kwargs) + chain = Chain(self, **kwargs) + chain._defaults = deepcopy(self._defaults) # pylint: disable=protected-access + chain._regex_defaults = deepcopy(self._regex_defaults) # pylint: disable=protected-access + chain._functional_defaults = deepcopy(self._functional_defaults) # pylint: disable=protected-access + chain._string_defaults = deepcopy(self._string_defaults) # pylint: disable=protected-access + chain._chain_defaults = deepcopy(self._chain_defaults) # pylint: disable=protected-access + return chain + + @abstractmethod + def pattern(self, *pattern): + """ + Register a list of Pattern instance + :param pattern: + :return: + """ + pass + + def regex(self, *pattern, **kwargs): + """ + Add re pattern + + :param pattern: + :type pattern: + :return: self + :rtype: Rebulk + """ + return self.pattern(self.build_re(*pattern, **kwargs)) + + def string(self, *pattern, **kwargs): + """ + Add string pattern + + :param pattern: + :type pattern: + :return: self + :rtype: Rebulk + """ + return self.pattern(self.build_string(*pattern, **kwargs)) + + def functional(self, *pattern, **kwargs): + """ + Add functional pattern + + :param pattern: + :type pattern: + :return: self + :rtype: Rebulk + """ + functional = self.build_functional(*pattern, **kwargs) + return self.pattern(functional) + + def chain(self, **kwargs): + """ + Add patterns chain, using configuration of this rebulk + + :param pattern: + :type pattern: + :param kwargs: + :type kwargs: + :return: + :rtype: + """ + chain = self.build_chain(**kwargs) + self.pattern(chain) + return chain diff --git a/libs/common/rebulk/chain.py b/libs/common/rebulk/chain.py index dfb6ea44..ba31ec9a 100644 --- a/libs/common/rebulk/chain.py +++ b/libs/common/rebulk/chain.py @@ -6,9 +6,10 @@ Chain patterns and handle repetiting capture group # pylint: disable=super-init-not-called import itertools -from .loose import call, set_defaults +from .builder import Builder +from .loose import call from .match import Match, Matches -from .pattern import Pattern, filter_match_kwargs +from .pattern import Pattern, filter_match_kwargs, BasePattern from .remodule import re @@ -19,150 +20,46 @@ class _InvalidChainException(Exception): pass -class Chain(Pattern): +class Chain(Pattern, Builder): """ Definition of a pattern chain to search for. """ - def __init__(self, rebulk, chain_breaker=None, **kwargs): - call(super(Chain, self).__init__, **kwargs) + def __init__(self, parent, chain_breaker=None, **kwargs): + Builder.__init__(self) + call(Pattern.__init__, self, **kwargs) self._kwargs = kwargs self._match_kwargs = filter_match_kwargs(kwargs) - self._defaults = {} - self._regex_defaults = {} - self._string_defaults = {} - self._functional_defaults = {} if callable(chain_breaker): self.chain_breaker = chain_breaker else: self.chain_breaker = None - self.rebulk = rebulk + self.parent = parent self.parts = [] - def defaults(self, **kwargs): + def pattern(self, *pattern): """ - Define default keyword arguments for all patterns - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._defaults = kwargs - return self - - def regex_defaults(self, **kwargs): - """ - Define default keyword arguments for functional patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._regex_defaults = kwargs - return self - - def string_defaults(self, **kwargs): - """ - Define default keyword arguments for string patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._string_defaults = kwargs - return self - - def functional_defaults(self, **kwargs): - """ - Define default keyword arguments for functional patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._functional_defaults = kwargs - return self - - def chain(self): - """ - Add patterns chain, using configuration from this chain - - :return: - :rtype: - """ - # pylint: disable=protected-access - chain = self.rebulk.chain(**self._kwargs) - chain._defaults = dict(self._defaults) - chain._regex_defaults = dict(self._regex_defaults) - chain._functional_defaults = dict(self._functional_defaults) - chain._string_defaults = dict(self._string_defaults) - return chain - - def regex(self, *pattern, **kwargs): - """ - Add re pattern :param pattern: - :type pattern: - :param kwargs: - :type kwargs: :return: - :rtype: """ - set_defaults(self._kwargs, kwargs) - set_defaults(self._regex_defaults, kwargs) - set_defaults(self._defaults, kwargs) - pattern = self.rebulk.build_re(*pattern, **kwargs) - part = ChainPart(self, pattern) - self.parts.append(part) - return part - - def functional(self, *pattern, **kwargs): - """ - Add functional pattern - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._kwargs, kwargs) - set_defaults(self._functional_defaults, kwargs) - set_defaults(self._defaults, kwargs) - pattern = self.rebulk.build_functional(*pattern, **kwargs) - part = ChainPart(self, pattern) - self.parts.append(part) - return part - - def string(self, *pattern, **kwargs): - """ - Add string pattern - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._kwargs, kwargs) - set_defaults(self._functional_defaults, kwargs) - set_defaults(self._defaults, kwargs) - pattern = self.rebulk.build_string(*pattern, **kwargs) - part = ChainPart(self, pattern) + if not pattern: + raise ValueError("One pattern should be given to the chain") + if len(pattern) > 1: + raise ValueError("Only one pattern can be given to the chain") + part = ChainPart(self, pattern[0]) self.parts.append(part) return part def close(self): """ - Close chain builder to continue registering other pattern - - :return: - :rtype: + Deeply close the chain + :return: Rebulk instance """ - return self.rebulk + parent = self.parent + while isinstance(parent, Chain): + parent = parent.parent + return parent def _match(self, pattern, input_string, context=None): # pylint: disable=too-many-locals,too-many-nested-blocks @@ -173,42 +70,20 @@ class Chain(Pattern): chain_found = False current_chain_matches = [] valid_chain = True - is_chain_start = True for chain_part in self.parts: try: - chain_part_matches, raw_chain_part_matches = Chain._match_chain_part(is_chain_start, chain_part, - chain_input_string, - context) - - Chain._fix_matches_offset(chain_part_matches, input_string, offset) - Chain._fix_matches_offset(raw_chain_part_matches, input_string, offset) - - if raw_chain_part_matches: - grouped_matches_dict = dict() - for match_index, match in itertools.groupby(chain_part_matches, - lambda m: m.match_index): - grouped_matches_dict[match_index] = list(match) - - grouped_raw_matches_dict = dict() - for match_index, raw_match in itertools.groupby(raw_chain_part_matches, - lambda m: m.match_index): - grouped_raw_matches_dict[match_index] = list(raw_match) - - for match_index, grouped_raw_matches in grouped_raw_matches_dict.items(): - chain_found = True - offset = grouped_raw_matches[-1].raw_end - chain_input_string = input_string[offset:] - if not chain_part.is_hidden: - grouped_matches = grouped_matches_dict.get(match_index, []) - if self._chain_breaker_eval(current_chain_matches + grouped_matches): - current_chain_matches.extend(grouped_matches) + chain_part_matches, raw_chain_part_matches = chain_part.matches(chain_input_string, + context, + with_raw_matches=True) + chain_found, chain_input_string, offset = \ + self._to_next_chain_part(chain_part, chain_part_matches, raw_chain_part_matches, chain_found, + input_string, chain_input_string, offset, current_chain_matches) except _InvalidChainException: valid_chain = False if current_chain_matches: offset = current_chain_matches[0].raw_end break - is_chain_start = False if not chain_found: break if current_chain_matches and valid_chain: @@ -217,38 +92,66 @@ class Chain(Pattern): return chain_matches - def _match_parent(self, match, yield_parent): + def _to_next_chain_part(self, chain_part, chain_part_matches, raw_chain_part_matches, chain_found, + input_string, chain_input_string, offset, current_chain_matches): + Chain._fix_matches_offset(chain_part_matches, input_string, offset) + Chain._fix_matches_offset(raw_chain_part_matches, input_string, offset) + + if raw_chain_part_matches: + grouped_matches_dict = self._group_by_match_index(chain_part_matches) + grouped_raw_matches_dict = self._group_by_match_index(raw_chain_part_matches) + + for match_index, grouped_raw_matches in grouped_raw_matches_dict.items(): + chain_found = True + offset = grouped_raw_matches[-1].raw_end + chain_input_string = input_string[offset:] + + if not chain_part.is_hidden: + grouped_matches = grouped_matches_dict.get(match_index, []) + if self._chain_breaker_eval(current_chain_matches + grouped_matches): + current_chain_matches.extend(grouped_matches) + return chain_found, chain_input_string, offset + + def _process_match(self, match, match_index, child=False): """ - Handle a parent match + Handle a match :param match: :type match: - :param yield_parent: - :type yield_parent: + :param match_index: + :type match_index: + :param child: + :type child: :return: :rtype: """ - ret = super(Chain, self)._match_parent(match, yield_parent) - original_children = Matches(match.children) - original_end = match.end - while not ret and match.children: - last_pattern = match.children[-1].pattern - last_pattern_children = [child for child in match.children if child.pattern == last_pattern] - last_pattern_groups_iter = itertools.groupby(last_pattern_children, lambda child: child.match_index) - last_pattern_groups = {} - for index, matches in last_pattern_groups_iter: - last_pattern_groups[index] = list(matches) + # pylint: disable=too-many-locals + ret = super(Chain, self)._process_match(match, match_index, child=child) + if ret: + return True - for index in reversed(list(last_pattern_groups)): - last_matches = list(last_pattern_groups[index]) - for last_match in last_matches: - match.children.remove(last_match) - match.end = match.children[-1].end if match.children else match.start - ret = super(Chain, self)._match_parent(match, yield_parent) - if ret: - return True - match.children = original_children - match.end = original_end - return ret + if match.children: + last_pattern = match.children[-1].pattern + last_pattern_groups = self._group_by_match_index( + [child_ for child_ in match.children if child_.pattern == last_pattern] + ) + + if last_pattern_groups: + original_children = Matches(match.children) + original_end = match.end + + for index in reversed(list(last_pattern_groups)): + last_matches = last_pattern_groups[index] + for last_match in last_matches: + match.children.remove(last_match) + match.end = match.children[-1].end if match.children else match.start + ret = super(Chain, self)._process_match(match, match_index, child=child) + if ret: + return True + + match.children = original_children + match.end = original_end + + return False def _build_chain_match(self, current_chain_matches, input_string): start = None @@ -282,46 +185,11 @@ class Chain(Pattern): Chain._fix_matches_offset(chain_part_match.children, input_string, offset) @staticmethod - def _match_chain_part(is_chain_start, chain_part, chain_input_string, context): - chain_part_matches, raw_chain_part_matches = chain_part.pattern.matches(chain_input_string, context, - with_raw_matches=True) - chain_part_matches = Chain._truncate_chain_part_matches(is_chain_start, chain_part_matches, chain_part, - chain_input_string) - raw_chain_part_matches = Chain._truncate_chain_part_matches(is_chain_start, raw_chain_part_matches, chain_part, - chain_input_string) - - Chain._validate_chain_part_matches(raw_chain_part_matches, chain_part) - return chain_part_matches, raw_chain_part_matches - - @staticmethod - def _truncate_chain_part_matches(is_chain_start, chain_part_matches, chain_part, chain_input_string): - if not chain_part_matches: - return chain_part_matches - - if not is_chain_start: - separator = chain_input_string[0:chain_part_matches[0].initiator.raw_start] - if separator: - return [] - - j = 1 - for i in range(0, len(chain_part_matches) - 1): - separator = chain_input_string[chain_part_matches[i].initiator.raw_end: - chain_part_matches[i + 1].initiator.raw_start] - if separator: - break - j += 1 - truncated = chain_part_matches[:j] - if chain_part.repeater_end is not None: - truncated = [m for m in truncated if m.match_index < chain_part.repeater_end] - return truncated - - @staticmethod - def _validate_chain_part_matches(chain_part_matches, chain_part): - max_match_index = -1 - if chain_part_matches: - max_match_index = max([m.match_index for m in chain_part_matches]) - if max_match_index + 1 < chain_part.repeater_start: - raise _InvalidChainException + def _group_by_match_index(matches): + grouped_matches_dict = dict() + for match_index, match in itertools.groupby(matches, lambda m: m.match_index): + grouped_matches_dict[match_index] = list(match) + return grouped_matches_dict @property def match_options(self): @@ -338,7 +206,7 @@ class Chain(Pattern): return "<%s%s:%s>" % (self.__class__.__name__, defined, self.parts) -class ChainPart(object): +class ChainPart(BasePattern): """ Part of a pattern chain. """ @@ -350,6 +218,51 @@ class ChainPart(object): self.repeater_end = 1 self._hidden = False + @property + def _is_chain_start(self): + return self._chain.parts[0] == self + + def matches(self, input_string, context=None, with_raw_matches=False): + matches, raw_matches = self.pattern.matches(input_string, context=context, with_raw_matches=True) + + matches = self._truncate_repeater(matches, input_string) + raw_matches = self._truncate_repeater(raw_matches, input_string) + + self._validate_repeater(raw_matches) + + if with_raw_matches: + return matches, raw_matches + + return matches + + def _truncate_repeater(self, matches, input_string): + if not matches: + return matches + + if not self._is_chain_start: + separator = input_string[0:matches[0].initiator.raw_start] + if separator: + return [] + + j = 1 + for i in range(0, len(matches) - 1): + separator = input_string[matches[i].initiator.raw_end: + matches[i + 1].initiator.raw_start] + if separator: + break + j += 1 + truncated = matches[:j] + if self.repeater_end is not None: + truncated = [m for m in truncated if m.match_index < self.repeater_end] + return truncated + + def _validate_repeater(self, matches): + max_match_index = -1 + if matches: + max_match_index = max([m.match_index for m in matches]) + if max_match_index + 1 < self.repeater_start: + raise _InvalidChainException + def chain(self): """ Add patterns chain, using configuration from this chain diff --git a/libs/common/rebulk/formatters.py b/libs/common/rebulk/formatters.py index 47046942..7175a54a 100644 --- a/libs/common/rebulk/formatters.py +++ b/libs/common/rebulk/formatters.py @@ -15,9 +15,19 @@ def formatters(*chained_formatters): :return: :rtype: """ + def formatters_chain(input_string): # pylint:disable=missing-docstring for chained_formatter in chained_formatters: input_string = chained_formatter(input_string) return input_string return formatters_chain + + +def default_formatter(input_string): + """ + Default formatter + :param input_string: + :return: + """ + return input_string diff --git a/libs/common/rebulk/introspector.py b/libs/common/rebulk/introspector.py index 64b9836f..bfefcb75 100644 --- a/libs/common/rebulk/introspector.py +++ b/libs/common/rebulk/introspector.py @@ -3,7 +3,7 @@ """ Introspect rebulk object to retrieve capabilities. """ -from abc import ABCMeta, abstractproperty +from abc import ABCMeta, abstractmethod from collections import defaultdict import six @@ -16,7 +16,8 @@ class Description(object): """ Abstract class for a description. """ - @abstractproperty + @property + @abstractmethod def properties(self): # pragma: no cover """ Properties of described object. diff --git a/libs/common/rebulk/loose.py b/libs/common/rebulk/loose.py index 427b69a0..423b4ea7 100644 --- a/libs/common/rebulk/loose.py +++ b/libs/common/rebulk/loose.py @@ -4,12 +4,12 @@ Various utilities functions """ - import sys -import inspect +from inspect import isclass try: from inspect import getfullargspec as getargspec + _fullargspec_supported = True except ImportError: _fullargspec_supported = False @@ -55,8 +55,8 @@ def call(function, *args, **kwargs): :return: sale vakye as default function call :rtype: object """ - func = constructor_args if inspect.isclass(function) else function_args - call_args, call_kwargs = func(function, *args, **kwargs) + func = constructor_args if isclass(function) else function_args + call_args, call_kwargs = func(function, *args, ignore_unused=True, **kwargs) # @see #20 return function(*call_args, **call_kwargs) @@ -145,6 +145,8 @@ if not _fullargspec_supported: else: call_args = args[:len(argspec.args) - (1 if constructor else 0)] return call_args, call_kwarg + + argspec_args = argspec_args_legacy @@ -215,9 +217,12 @@ def filter_index(collection, predicate=None, index=None): return collection -def set_defaults(defaults, kwargs): +def set_defaults(defaults, kwargs, override=False): """ Set defaults from defaults dict to kwargs dict + + :param override: + :type override: :param defaults: :type defaults: :param kwargs: @@ -225,12 +230,13 @@ def set_defaults(defaults, kwargs): :return: :rtype: """ + if 'clear' in defaults.keys() and defaults.pop('clear'): + kwargs.clear() for key, value in defaults.items(): - if key not in kwargs and value is not None: + if key in kwargs: + if isinstance(value, list) and isinstance(kwargs[key], list): + kwargs[key] = list(value) + kwargs[key] + elif isinstance(value, dict) and isinstance(kwargs[key], dict): + set_defaults(value, kwargs[key]) + if key not in kwargs or override: kwargs[key] = value - elif isinstance(value, list) and isinstance(kwargs[key], list): - kwargs[key] = list(value) + kwargs[key] - elif isinstance(value, dict) and isinstance(kwargs[key], dict): - set_defaults(value, kwargs[key]) - elif key in kwargs and value is None: - kwargs[key] = None diff --git a/libs/common/rebulk/match.py b/libs/common/rebulk/match.py index 8bf41245..d8e72df4 100644 --- a/libs/common/rebulk/match.py +++ b/libs/common/rebulk/match.py @@ -815,6 +815,24 @@ class Match(object): return filter_index(ret, predicate, index) + def tagged(self, *tags): + """ + Check if this match has at least one of the provided tags + + :param tags: + :return: True if at least one tag is defined, False otherwise. + """ + return any(tag in self.tags for tag in tags) + + def named(self, *names): + """ + Check if one of the children match has one of the provided name + + :param names: + :return: True if at least one child is named with a given name is defined, False otherwise. + """ + return any(name in self.names for name in names) + def __len__(self): return self.end - self.start diff --git a/libs/common/rebulk/pattern.py b/libs/common/rebulk/pattern.py index 57b274e8..beb8b273 100644 --- a/libs/common/rebulk/pattern.py +++ b/libs/common/rebulk/pattern.py @@ -10,14 +10,39 @@ from abc import ABCMeta, abstractmethod, abstractproperty import six from . import debug +from .formatters import default_formatter from .loose import call, ensure_list, ensure_dict from .match import Match from .remodule import re, REGEX_AVAILABLE from .utils import find_all, is_iterable, get_first_defined +from .validators import allways_true @six.add_metaclass(ABCMeta) -class Pattern(object): +class BasePattern(object): + """ + Base class for Pattern like objects + """ + + @abstractmethod + def matches(self, input_string, context=None, with_raw_matches=False): + """ + Computes all matches for a given input + + :param input_string: the string to parse + :type input_string: str + :param context: the context + :type context: dict + :param with_raw_matches: should return details + :type with_raw_matches: dict + :return: matches based on input_string for this pattern + :rtype: iterator[Match] + """ + pass + + +@six.add_metaclass(ABCMeta) +class Pattern(BasePattern): """ Definition of a particular pattern to search for. """ @@ -25,7 +50,7 @@ class Pattern(object): def __init__(self, name=None, tags=None, formatter=None, value=None, validator=None, children=False, every=False, private_parent=False, private_children=False, private=False, private_names=None, ignore_names=None, marker=False, format_all=False, validate_all=False, disabled=lambda context: False, log_level=None, - properties=None, post_processor=None, **kwargs): + properties=None, post_processor=None, pre_match_processor=None, post_match_processor=None, **kwargs): """ :param name: Name of this pattern :type name: str @@ -66,15 +91,19 @@ class Pattern(object): :type disabled: bool|function :param log_lvl: Log level associated to this pattern :type log_lvl: int - :param post_process: Post processing function + :param post_processor: Post processing function :type post_processor: func + :param pre_match_processor: Pre match processing function + :type pre_match_processor: func + :param post_match_processor: Post match processing function + :type post_match_processor: func """ # pylint:disable=too-many-locals,unused-argument self.name = name self.tags = ensure_list(tags) - self.formatters, self._default_formatter = ensure_dict(formatter, lambda x: x) + self.formatters, self._default_formatter = ensure_dict(formatter, default_formatter) self.values, self._default_value = ensure_dict(value, None) - self.validators, self._default_validator = ensure_dict(validator, lambda match: True) + self.validators, self._default_validator = ensure_dict(validator, allways_true) self.every = every self.children = children self.private = private @@ -96,6 +125,14 @@ class Pattern(object): self.post_processor = None else: self.post_processor = post_processor + if not callable(pre_match_processor): + self.pre_match_processor = None + else: + self.pre_match_processor = pre_match_processor + if not callable(post_match_processor): + self.post_match_processor = None + else: + self.post_match_processor = post_match_processor @property def log_level(self): @@ -106,83 +143,6 @@ class Pattern(object): """ return self._log_level if self._log_level is not None else debug.LOG_LEVEL - def _yield_children(self, match): - """ - Does this match has children - :param match: - :type match: - :return: - :rtype: - """ - return match.children and (self.children or self.every) - - def _yield_parent(self): - """ - Does this mat - :param match: - :type match: - :return: - :rtype: - """ - return not self.children or self.every - - def _match_parent(self, match, yield_parent): - """ - Handle a parent match - :param match: - :type match: - :param yield_parent: - :type yield_parent: - :return: - :rtype: - """ - if not match or match.value == "": - return False - - pattern_value = get_first_defined(self.values, [match.name, '__parent__', None], - self._default_value) - if pattern_value: - match.value = pattern_value - - if yield_parent or self.format_all: - match.formatter = get_first_defined(self.formatters, [match.name, '__parent__', None], - self._default_formatter) - if yield_parent or self.validate_all: - validator = get_first_defined(self.validators, [match.name, '__parent__', None], - self._default_validator) - if validator and not validator(match): - return False - return True - - def _match_child(self, child, yield_children): - """ - Handle a children match - :param child: - :type child: - :param yield_children: - :type yield_children: - :return: - :rtype: - """ - if not child or child.value == "": - return False - - pattern_value = get_first_defined(self.values, [child.name, '__children__', None], - self._default_value) - if pattern_value: - child.value = pattern_value - - if yield_children or self.format_all: - child.formatter = get_first_defined(self.formatters, [child.name, '__children__', None], - self._default_formatter) - - if yield_children or self.validate_all: - validator = get_first_defined(self.validators, [child.name, '__children__', None], - self._default_validator) - if validator and not validator(child): - return False - return True - def matches(self, input_string, context=None, with_raw_matches=False): """ Computes all matches for a given input @@ -200,41 +160,168 @@ class Pattern(object): matches = [] raw_matches = [] + for pattern in self.patterns: - yield_parent = self._yield_parent() - match_index = -1 + match_index = 0 for match in self._match(pattern, input_string, context): - match_index += 1 - match.match_index = match_index raw_matches.append(match) - yield_children = self._yield_children(match) - if not self._match_parent(match, yield_parent): - continue - validated = True - for child in match.children: - if not self._match_child(child, yield_children): - validated = False - break - if validated: - if self.private_parent: - match.private = True - if self.private_children: - for child in match.children: - child.private = True - if yield_parent or self.private_parent: - matches.append(match) - if yield_children or self.private_children: - for child in match.children: - child.match_index = match_index - matches.append(child) - matches = self._matches_post_process(matches) - self._matches_privatize(matches) - self._matches_ignore(matches) + matches.extend(self._process_matches(match, match_index)) + match_index += 1 + + matches = self._post_process_matches(matches) + if with_raw_matches: return matches, raw_matches return matches - def _matches_post_process(self, matches): + @property + def _should_include_children(self): + """ + Check if children matches from this pattern should be included in matches results. + :param match: + :type match: + :return: + :rtype: + """ + return self.children or self.every + + @property + def _should_include_parent(self): + """ + Check is a match from this pattern should be included in matches results. + :param match: + :type match: + :return: + :rtype: + """ + return not self.children or self.every + + @staticmethod + def _match_config_property_keys(match, child=False): + if match.name: + yield match.name + if child: + yield '__children__' + else: + yield '__parent__' + yield None + + @staticmethod + def _process_match_index(match, match_index): + """ + Process match index from this pattern process state. + + :param match: + :return: + """ + match.match_index = match_index + + def _process_match_private(self, match, child=False): + """ + Process match privacy from this pattern configuration. + + :param match: + :param child: + :return: + """ + + if match.name and match.name in self.private_names or \ + not child and self.private_parent or \ + child and self.private_children: + match.private = True + + def _process_match_value(self, match, child=False): + """ + Process match value from this pattern configuration. + :param match: + :return: + """ + keys = self._match_config_property_keys(match, child=child) + pattern_value = get_first_defined(self.values, keys, self._default_value) + if pattern_value: + match.value = pattern_value + + def _process_match_formatter(self, match, child=False): + """ + Process match formatter from this pattern configuration. + + :param match: + :return: + """ + included = self._should_include_children if child else self._should_include_parent + if included or self.format_all: + keys = self._match_config_property_keys(match, child=child) + match.formatter = get_first_defined(self.formatters, keys, self._default_formatter) + + def _process_match_validator(self, match, child=False): + """ + Process match validation from this pattern configuration. + + :param match: + :return: True if match is validated by the configured validator, False otherwise. + """ + included = self._should_include_children if child else self._should_include_parent + if included or self.validate_all: + keys = self._match_config_property_keys(match, child=child) + validator = get_first_defined(self.validators, keys, self._default_validator) + if validator and not validator(match): + return False + return True + + def _process_match(self, match, match_index, child=False): + """ + Process match from this pattern by setting all properties from defined configuration + (index, private, value, formatter, validator, ...). + + :param match: + :type match: + :return: True if match is validated by the configured validator, False otherwise. + :rtype: + """ + self._process_match_index(match, match_index) + self._process_match_private(match, child) + self._process_match_value(match, child) + self._process_match_formatter(match, child) + return self._process_match_validator(match, child) + + @staticmethod + def _process_match_processor(match, processor): + if processor: + ret = processor(match) + if ret is not None: + return ret + return match + + def _process_matches(self, match, match_index): + """ + Process and generate all matches for the given unprocessed match. + :param match: + :param match_index: + :return: Process and dispatched matches. + """ + match = self._process_match_processor(match, self.pre_match_processor) + if not match: + return + + if not self._process_match(match, match_index): + return + + for child in match.children: + if not self._process_match(child, match_index, child=True): + return + + match = self._process_match_processor(match, self.post_match_processor) + if not match: + return + + if (self._should_include_parent or self.private_parent) and match.name not in self.ignore_names: + yield match + if self._should_include_children or self.private_children: + children = [x for x in match.children if x.name not in self.ignore_names] + for child in children: + yield child + + def _post_process_matches(self, matches): """ Post process matches with user defined function :param matches: @@ -246,32 +333,6 @@ class Pattern(object): return self.post_processor(matches, self) return matches - def _matches_privatize(self, matches): - """ - Mark matches included in private_names with private flag. - :param matches: - :type matches: - :return: - :rtype: - """ - if self.private_names: - for match in matches: - if match.name in self.private_names: - match.private = True - - def _matches_ignore(self, matches): - """ - Ignore matches included in ignore_names. - :param matches: - :type matches: - :return: - :rtype: - """ - if self.ignore_names: - for match in list(matches): - if match.name in self.ignore_names: - matches.remove(match) - @abstractproperty def patterns(self): # pragma: no cover """ @@ -306,7 +367,7 @@ class Pattern(object): @abstractmethod def _match(self, pattern, input_string, context=None): # pragma: no cover """ - Computes all matches for a given pattern and input + Computes all unprocess matches for a given pattern and input. :param pattern: the pattern to use :param input_string: the string to parse @@ -350,7 +411,9 @@ class StringPattern(Pattern): def _match(self, pattern, input_string, context=None): for index in find_all(input_string, pattern, **self._kwargs): - yield Match(index, index + len(pattern), pattern=self, input_string=input_string, **self._match_kwargs) + match = Match(index, index + len(pattern), pattern=self, input_string=input_string, **self._match_kwargs) + if match: + yield match class RePattern(Pattern): @@ -411,15 +474,18 @@ class RePattern(Pattern): for start, end in match_object.spans(i): child_match = Match(start, end, name=name, parent=main_match, pattern=self, input_string=input_string, **self._children_match_kwargs) - main_match.children.append(child_match) + if child_match: + main_match.children.append(child_match) else: start, end = match_object.span(i) if start > -1 and end > -1: child_match = Match(start, end, name=name, parent=main_match, pattern=self, input_string=input_string, **self._children_match_kwargs) - main_match.children.append(child_match) + if child_match: + main_match.children.append(child_match) - yield main_match + if main_match: + yield main_match class FunctionalPattern(Pattern): @@ -457,14 +523,18 @@ class FunctionalPattern(Pattern): if self._match_kwargs: options = self._match_kwargs.copy() options.update(args) - yield Match(pattern=self, input_string=input_string, **options) + match = Match(pattern=self, input_string=input_string, **options) + if match: + yield match else: kwargs = self._match_kwargs if isinstance(args[-1], dict): kwargs = dict(kwargs) kwargs.update(args[-1]) args = args[:-1] - yield Match(*args, pattern=self, input_string=input_string, **kwargs) + match = Match(*args, pattern=self, input_string=input_string, **kwargs) + if match: + yield match def filter_match_kwargs(kwargs, children=False): diff --git a/libs/common/rebulk/rebulk.py b/libs/common/rebulk/rebulk.py index 42fb6440..a6a0fd2f 100644 --- a/libs/common/rebulk/rebulk.py +++ b/libs/common/rebulk/rebulk.py @@ -5,20 +5,16 @@ Entry point functions and classes for Rebulk """ from logging import getLogger +from .builder import Builder from .match import Matches - -from .pattern import RePattern, StringPattern, FunctionalPattern -from .chain import Chain - from .processors import ConflictSolver, PrivateRemover -from .loose import set_defaults -from .utils import extend_safe from .rules import Rules +from .utils import extend_safe log = getLogger(__name__).log -class Rebulk(object): +class Rebulk(Builder): r""" Regular expression, string and function based patterns are declared in a ``Rebulk`` object. It use a fluent API to chain ``string``, ``regex``, and ``functional`` methods to define various patterns types. @@ -44,6 +40,7 @@ class Rebulk(object): >>> bulk.matches("the lakers are from la") [, ] """ + # pylint:disable=protected-access def __init__(self, disabled=lambda context: False, default_rules=True): @@ -56,6 +53,7 @@ class Rebulk(object): :return: :rtype: """ + super(Rebulk, self).__init__() if not callable(disabled): self.disabled = lambda context: disabled else: @@ -64,11 +62,6 @@ class Rebulk(object): self._rules = Rules() if default_rules: self.rules(ConflictSolver, PrivateRemover) - self._defaults = {} - self._regex_defaults = {} - self._string_defaults = {} - self._functional_defaults = {} - self._chain_defaults = {} self._rebulks = [] def pattern(self, *pattern): @@ -83,172 +76,6 @@ class Rebulk(object): self._patterns.extend(pattern) return self - def defaults(self, **kwargs): - """ - Define default keyword arguments for all patterns - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._defaults = kwargs - return self - - def regex_defaults(self, **kwargs): - """ - Define default keyword arguments for functional patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._regex_defaults = kwargs - return self - - def regex(self, *pattern, **kwargs): - """ - Add re pattern - - :param pattern: - :type pattern: - :return: self - :rtype: Rebulk - """ - self.pattern(self.build_re(*pattern, **kwargs)) - return self - - def build_re(self, *pattern, **kwargs): - """ - Builds a new regular expression pattern - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._regex_defaults, kwargs) - set_defaults(self._defaults, kwargs) - return RePattern(*pattern, **kwargs) - - def string_defaults(self, **kwargs): - """ - Define default keyword arguments for string patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._string_defaults = kwargs - return self - - def string(self, *pattern, **kwargs): - """ - Add string pattern - - :param pattern: - :type pattern: - :return: self - :rtype: Rebulk - """ - self.pattern(self.build_string(*pattern, **kwargs)) - return self - - def build_string(self, *pattern, **kwargs): - """ - Builds a new string pattern - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._string_defaults, kwargs) - set_defaults(self._defaults, kwargs) - return StringPattern(*pattern, **kwargs) - - def functional_defaults(self, **kwargs): - """ - Define default keyword arguments for functional patterns. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._functional_defaults = kwargs - return self - - def functional(self, *pattern, **kwargs): - """ - Add functional pattern - - :param pattern: - :type pattern: - :return: self - :rtype: Rebulk - """ - self.pattern(self.build_functional(*pattern, **kwargs)) - return self - - def build_functional(self, *pattern, **kwargs): - """ - Builds a new functional pattern - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._functional_defaults, kwargs) - set_defaults(self._defaults, kwargs) - return FunctionalPattern(*pattern, **kwargs) - - def chain_defaults(self, **kwargs): - """ - Define default keyword arguments for patterns chain. - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - self._chain_defaults = kwargs - return self - - def chain(self, **kwargs): - """ - Add patterns chain, using configuration of this rebulk - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - chain = self.build_chain(**kwargs) - self._patterns.append(chain) - return chain - - def build_chain(self, **kwargs): - """ - Builds a new patterns chain - - :param pattern: - :type pattern: - :param kwargs: - :type kwargs: - :return: - :rtype: - """ - set_defaults(self._chain_defaults, kwargs) - set_defaults(self._defaults, kwargs) - return Chain(self, **kwargs) - def rules(self, *rules): """ Add rules as a module, class or instance. diff --git a/libs/common/rebulk/test/test_chain.py b/libs/common/rebulk/test/test_chain.py index 2715abc2..f3995546 100644 --- a/libs/common/rebulk/test/test_chain.py +++ b/libs/common/rebulk/test/test_chain.py @@ -2,11 +2,11 @@ # -*- coding: utf-8 -*- # pylint: disable=no-self-use, pointless-statement, missing-docstring, no-member, len-as-condition import re - from functools import partial +from rebulk.pattern import FunctionalPattern, StringPattern, RePattern +from ..rebulk import Rebulk from ..validators import chars_surround -from ..rebulk import Rebulk, FunctionalPattern, RePattern, StringPattern def test_chain_close(): @@ -63,18 +63,61 @@ def test_build_chain(): def test_chain_defaults(): rebulk = Rebulk() - rebulk.defaults(validator=lambda x: True, ignore_names=['testIgnore'], children=True) + rebulk.defaults(validator=lambda x: x.value.startswith('t'), ignore_names=['testIgnore'], children=True) - rebulk.chain()\ + rebulk.chain() \ .regex("(?Ptest)") \ .regex(" ").repeater("*") \ + .regex("(?Pbest)") \ + .regex(" ").repeater("*") \ .regex("(?PtestIgnore)") - matches = rebulk.matches("test testIgnore") + matches = rebulk.matches("test best testIgnore") assert len(matches) == 1 assert matches[0].name == "test" +def test_chain_with_validators(): + def chain_validator(match): + return match.value.startswith('t') and match.value.endswith('t') + + def default_validator(match): + return match.value.startswith('t') and match.value.endswith('g') + + def custom_validator(match): + return match.value.startswith('b') and match.value.endswith('t') + + rebulk = Rebulk() + rebulk.defaults(children=True, validator=default_validator) + + rebulk.chain(validate_all=True, validator={'__parent__': chain_validator}) \ + .regex("(?Ptesting)", validator=default_validator).repeater("+") \ + .regex(" ").repeater("+") \ + .regex("(?Pbest)", validator=custom_validator).repeater("+") + matches = rebulk.matches("some testing best end") + + assert len(matches) == 2 + assert matches[0].name == "test" + assert matches[1].name == "best" + + +def test_matches_docs(): + rebulk = Rebulk().regex_defaults(flags=re.IGNORECASE) \ + .defaults(children=True, formatter={'episode': int, 'version': int}) \ + .chain() \ + .regex(r'e(?P\d{1,4})').repeater(1) \ + .regex(r'v(?P\d+)').repeater('?') \ + .regex(r'[ex-](?P\d{1,4})').repeater('*') \ + .close() # .repeater(1) could be omitted as it's the default behavior + + result = rebulk.matches("This is E14v2-15-16-17").to_dict() # converts matches to dict + + assert 'episode' in result + assert result['episode'] == [14, 15, 16, 17] + assert 'version' in result + assert result['version'] == 2 + + def test_matches(): rebulk = Rebulk() @@ -144,8 +187,8 @@ def test_matches(): def test_matches_2(): rebulk = Rebulk() \ .regex_defaults(flags=re.IGNORECASE) \ - .chain(children=True, formatter={'episode': int}) \ - .defaults(formatter={'version': int}) \ + .defaults(children=True, formatter={'episode': int, 'version': int}) \ + .chain() \ .regex(r'e(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ .regex(r'[ex-](?P\d{1,4})').repeater('*') \ @@ -173,25 +216,32 @@ def test_matches_2(): def test_matches_3(): alt_dash = (r'@', r'[\W_]') # abbreviation - rebulk = Rebulk() + match_names = ['season', 'episode'] + other_names = ['screen_size', 'video_codec', 'audio_codec', 'audio_channels', 'container', 'date'] - rebulk.chain(formatter={'season': int, 'episode': int}, - tags=['SxxExx'], - abbreviations=[alt_dash], - private_names=['episodeSeparator', 'seasonSeparator'], - children=True, - private_parent=True, - conflict_solver=lambda match, other: match - if match.name in ['season', 'episode'] and other.name in - ['screen_size', 'video_codec', 'audio_codec', - 'audio_channels', 'container', 'date'] - else '__default__') \ + rebulk = Rebulk() + rebulk.defaults(formatter={'season': int, 'episode': int}, + tags=['SxxExx'], + abbreviations=[alt_dash], + private_names=['episodeSeparator', 'seasonSeparator'], + children=True, + private_parent=True, + conflict_solver=lambda match, other: match + if match.name in match_names and other.name in other_names + else '__default__') + + rebulk.chain() \ + .defaults(children=True, private_parent=True) \ .regex(r'(?P\d+)@?x@?(?P\d+)') \ .regex(r'(?Px|-|\+|&)(?P\d+)').repeater('*') \ + .close() \ .chain() \ + .defaults(children=True, private_parent=True) \ .regex(r'S(?P\d+)@?(?:xE|Ex|E|x)@?(?P\d+)') \ .regex(r'(?:(?PxE|Ex|E|x|-|\+|&)(?P\d+))').repeater('*') \ + .close() \ .chain() \ + .defaults(children=True, private_parent=True) \ .regex(r'S(?P\d+)') \ .regex(r'(?PS|-|\+|&)(?P\d+)').repeater('*') @@ -240,11 +290,11 @@ def test_matches_4(): rebulk = Rebulk() rebulk.regex_defaults(flags=re.IGNORECASE) - rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator'], validate_all=True, - validator={'__parent__': seps_surround}, children=True, private_parent=True) + rebulk.defaults(validate_all=True, children=True) + rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator'], private_parent=True) - rebulk.chain(formatter={'episode': int, 'version': int}) \ - .defaults(validator=None) \ + rebulk.chain(validator={'__parent__': seps_surround}, formatter={'episode': int, 'version': int}) \ + .defaults(formatter={'episode': int, 'version': int}) \ .regex(r'e(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ .regex(r'(?Pe|x|-)(?P\d{1,4})').repeater('*') @@ -262,11 +312,11 @@ def test_matches_5(): rebulk = Rebulk() rebulk.regex_defaults(flags=re.IGNORECASE) - rebulk.defaults(private_names=['episodeSeparator', 'seasonSeparator'], validate_all=True, - validator={'__parent__': seps_surround}, children=True, private_parent=True) - rebulk.chain(formatter={'episode': int, 'version': int}) \ - .defaults(validator=None) \ + rebulk.chain(private_names=['episodeSeparator', 'seasonSeparator'], validate_all=True, + validator={'__parent__': seps_surround}, children=True, private_parent=True, + formatter={'episode': int, 'version': int}) \ + .defaults(children=True, private_parent=True) \ .regex(r'e(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ .regex(r'(?Pe|x|-)(?P\d{1,4})').repeater('{2,3}') @@ -288,7 +338,7 @@ def test_matches_6(): validator=None, children=True, private_parent=True) rebulk.chain(formatter={'episode': int, 'version': int}) \ - .defaults(validator=None) \ + .defaults(children=True, private_parent=True) \ .regex(r'e(?P\d{1,4})') \ .regex(r'v(?P\d+)').repeater('?') \ .regex(r'(?Pe|x|-)(?P\d{1,4})').repeater('{2,3}') diff --git a/libs/common/rebulk/test/test_debug.py b/libs/common/rebulk/test/test_debug.py index cd9e556d..8abdac5f 100644 --- a/libs/common/rebulk/test/test_debug.py +++ b/libs/common/rebulk/test/test_debug.py @@ -2,19 +2,15 @@ # -*- coding: utf-8 -*- # pylint: disable=no-self-use, pointless-statement, missing-docstring, protected-access, invalid-name, len-as-condition +from .default_rules_module import RuleRemove0 +from .. import debug +from ..match import Match from ..pattern import StringPattern from ..rebulk import Rebulk -from ..match import Match -from .. import debug -from .default_rules_module import RuleRemove0 class TestDebug(object): - - - #request.addfinalizer(disable_debug) - - + # request.addfinalizer(disable_debug) debug.DEBUG = True pattern = StringPattern(1, 3, value="es") @@ -38,43 +34,43 @@ class TestDebug(object): debug.DEBUG = False def test_pattern(self): - assert self.pattern.defined_at.lineno == 20 + assert self.pattern.defined_at.lineno > 0 assert self.pattern.defined_at.name == 'rebulk.test.test_debug' assert self.pattern.defined_at.filename.endswith('test_debug.py') - assert str(self.pattern.defined_at) == 'test_debug.py#L20' - assert repr(self.pattern) == '' + assert str(self.pattern.defined_at).startswith('test_debug.py#L') + assert repr(self.pattern).startswith(' 0 assert self.match.defined_at.name == 'rebulk.test.test_debug' assert self.match.defined_at.filename.endswith('test_debug.py') - assert str(self.match.defined_at) == 'test_debug.py#L22' + assert str(self.match.defined_at).startswith('test_debug.py#L') def test_rule(self): - assert self.rule.defined_at.lineno == 23 + assert self.rule.defined_at.lineno > 0 assert self.rule.defined_at.name == 'rebulk.test.test_debug' assert self.rule.defined_at.filename.endswith('test_debug.py') - assert str(self.rule.defined_at) == 'test_debug.py#L23' - assert repr(self.rule) == '' + assert str(self.rule.defined_at).startswith('test_debug.py#L') + assert repr(self.rule).startswith(' 0 assert self.rebulk._patterns[0].defined_at.name == 'rebulk.test.test_debug' assert self.rebulk._patterns[0].defined_at.filename.endswith('test_debug.py') - assert str(self.rebulk._patterns[0].defined_at) in ['test_debug.py#L26', 'test_debug.py#L27'] + assert str(self.rebulk._patterns[0].defined_at).startswith('test_debug.py#L') - assert self.rebulk._patterns[1].defined_at.lineno in [27, 28] + assert self.rebulk._patterns[1].defined_at.lineno > 0 assert self.rebulk._patterns[1].defined_at.name == 'rebulk.test.test_debug' assert self.rebulk._patterns[1].defined_at.filename.endswith('test_debug.py') - assert str(self.rebulk._patterns[1].defined_at) in ['test_debug.py#L27', 'test_debug.py#L28'] + assert str(self.rebulk._patterns[1].defined_at).startswith('test_debug.py#L') assert self.matches[0].defined_at == self.rebulk._patterns[0].defined_at assert self.matches[1].defined_at == self.rebulk._patterns[1].defined_at diff --git a/libs/common/rebulk/test/test_match.py b/libs/common/rebulk/test/test_match.py index 87273d54..8750733a 100644 --- a/libs/common/rebulk/test/test_match.py +++ b/libs/common/rebulk/test/test_match.py @@ -116,6 +116,9 @@ class TestMatchesClass(object): assert "tag1" in matches.tags assert "tag2" in matches.tags + assert self.match3.tagged("tag1") + assert not self.match3.tagged("start") + tag1 = matches.tagged("tag1") assert len(tag1) == 2 assert tag1[0] == self.match2 diff --git a/libs/common/rebulk/validators.py b/libs/common/rebulk/validators.py index 5fd3dcb6..b8959c54 100644 --- a/libs/common/rebulk/validators.py +++ b/libs/common/rebulk/validators.py @@ -62,9 +62,20 @@ def validators(*chained_validators): :return: :rtype: """ + def validator_chain(match): # pylint:disable=missing-docstring for chained_validator in chained_validators: if not chained_validator(match): return False return True + return validator_chain + + +def allways_true(match): # pylint:disable=unused-argument + """ + A validator which is allways true + :param match: + :return: + """ + return True