# -*- coding: utf-8 -*-
# Phatch - Photo Batch Processor
# Copyright (C) 2007-2008 www.stani.be
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see http://www.gnu.org/licenses/
#
# Phatch recommends SPE (http://pythonide.stani.be) for editing python files.

# Embedded icon is from Blender (copyrighted property of NaN Holding B.V)
# (http://www.blender.org/blenderorg/blender-foundation/logo/).

# Follows PEP8

import os
import re
import shutil
import tempfile

from core import models
from core.config import PATHS
from lib import system
from lib.reverse_translation import _t

BLENDER_VERSIONS = ['2.45', '2.46', '2.47', '2.48', '2.49']
RE_BLENDER_VERSION = re.compile('|'.join([x.replace('.', '[.]')
    for x in BLENDER_VERSIONS]))
BLENDER_VERSIONS = ', '.join(BLENDER_VERSIONS)

COMMAND = \
"""%%(blender)s -b %%(blend)s -P %%(runner)s -- \
input_image_1:%%(filein)s render_path:file_out.png \
script:%%(script)s script_path:%%(script_path)s \
render_width:%%(render_width)s render_height:%%(render_height)s \
image_size:%%(image_size)s \
object:%%(object)s \
amount_of_input_images:%%(amount_of_input_images)s \
input_image_2:%%(input_image_2)s \
%s \
gradient_top:%%(gradient_top)s \
gradient_bottom:%%(gradient_bottom)s \
alpha:%%(alpha)s \
stars:%%(stars)s stars_color:%%(stars_color)s \
mist:%%(mist)s \
use_floor:%%(use_floor)s floor_color:%%(floor_color)s \
floor_reflection:%%(floor_reflection)s \
floor_opacity:%%(floor_opacity)s \
camera_lens_angle:%%(camera_lens_angle)s \
camera_distance:%%(camera_distance)s \
rotation_x:%%(camera_roll)s rotation_y:%%(camera_vertical_rotation)s \
rotation_z:%%(camera_horizontal_rotation)s"""

FIT_IMAGE = _t('Fit Image')
LETTERBOX = _t('Letterbox')
SCALE_IMAGE = _t('Scale Image')
SCALE_MODEL = _t('Scale Model')
SIZE_CHOICES = (FIT_IMAGE, LETTERBOX, SCALE_IMAGE, SCALE_MODEL)


# TODO: add arg generators to all classes!!!

class BlenderObject(object):
    image_size_choices = ()
    extra_options = ()

    def get_name(self):
        return self.__class__.__name__
    name = property(get_name)

    def interface(self, action, fields):
        pass

    def get_relevant(self, action):
        return []

    def set_args(self, action, values):
        # XXX: hack to set valid value to to image_size
        if len(self.image_size_choices) == 1:
            values['image_size'] = self.image_size_choices[0]

    def get_command(self, values):
        arg_str = ''

        for extra_option in self.extra_options:
            delim_name = extra_option.lower().replace(' ', '_')
            arg_str += delim_name + ':%(' + delim_name + ')s '

        # Add "'s as otherwise args get parsed as separate
        for k, v in values.items():
            if isinstance(v, str) and len(v.split()) > 1:
                values[k] = system.fix_quotes(v)

        # XXX: hack for image size (code above should catch this!!!)
        image_size = values['image_size']
        if len(image_size.split()) > 1:
            values['image_size'] = system.fix_quotes(image_size)

        return COMMAND % arg_str % values


class Book(BlenderObject):
    image_size_choices = (SCALE_IMAGE, )
    extra_options = ('Cover Color', 'Page Mapping', 'Left Page')

    def interface(self, action, fields):
        mapping_choices = (_t('Wrap Both'), _t('Separate'))

        fields[_t('Cover Color')] = action.ColorField('#FFFFFF')
        fields[_t('Page Mapping')] = action.ChoiceField(mapping_choices[0],
            choices=mapping_choices)
        fields[_t('Left Page')] = action.EmptyFileField(' ')

    def get_relevant(self, action):
        ret = ['Cover Color', 'Page Mapping', ]

        page_mapping = action.get_field_string('Page Mapping')
        if page_mapping == 'Separate':
            ret.append('Left Page')

        return ret

    def set_args(self, action, values):
        super(Book, self).set_args(action, values)

        values['amount_of_input_images'] += 1

        page_mapping = action.get_field_string('Page Mapping')
        if page_mapping == 'Separate':
            values['input_image_2'] = action.get_field_string('Left Page')


class Box(BlenderObject):
    image_size_choices = SIZE_CHOICES
    extra_options = ('Box Color', 'Box Depth')

    def interface(self, action, fields):
        fields[_t('Box Color')] = action.ColorField('#FFFFFF')
        fields[_t('Box Depth')] = action.PixelField('30%')

    def get_relevant(self, action):
        return ['Box Color', 'Box Depth']


class Can(BlenderObject):
    image_size_choices = (SCALE_IMAGE, )


class Cd(BlenderObject):
    image_size_choices = (FIT_IMAGE, LETTERBOX, SCALE_IMAGE, )
    extra_options = ('Lid Rotation', )

    def interface(self, action, fields):
        fields[_t('Lid Rotation')] = action.SliderField(0, 0, 300)

    def get_relevant(self, action):
        return ['Lid Rotation', ]


class Lcd(BlenderObject):
    image_size_choices = SIZE_CHOICES


class Sphere(BlenderObject):
    image_size_choices = (SCALE_IMAGE, )


class BlenderObjects(list):

    def __init__(self):
        self.extend([Book(), Box(), Can(), Cd(), Lcd(), Sphere()])

    def interface(self, action, fields):
        for object in self:
            object.interface(action, fields)

    def get_selected_object(self, action):
        object_name = action.get_field_string('Object')

        return self._find(object_name)

    def _find(self, name):
        for obj in self:
            if name == obj.name:
                return obj


class Camera:

    def interface(self, action, fields):
        fields[_t('Camera')] = action.BlenderRotationField('Hori -30 Vert 0')
        fields[_t('Camera Horizontal Rotation')] = \
            action.SliderField(30, -180, 180)
        fields[_t('Camera Vertical Rotation')] = action.SliderField(0, 0, 90)
        fields[_t('Camera Roll')] = action.SliderField(0, -90, 90)
        fields[_t('Camera Lens Angle')] = action.SliderField(51, 8, 172)
        # TODO: provide bigger range for distance with 0.5 or 0.25 steps?
        fields[_t('Camera Distance')] = action.SliderField(2, 0, 10)

    def get_relevant(self, action):
        ret = ['Camera']

        camera_str = action.get_field_string('Camera')

        if camera_str == 'User':
            ret.extend(['Camera Horizontal Rotation',
                'Camera Vertical Rotation', 'Camera Roll', 'Camera Lens Angle',
                'Camera Distance'])
        else:
            split_rotation = camera_str.split()

            action.set_field_as_string_dirty('Camera Horizontal Rotation',
                split_rotation[1])
            action.set_field_as_string_dirty('Camera Vertical Rotation',
                split_rotation[3])

            # TODO: set camera roll, lens angle and distance to default values
            # used to generate previews!
            # Initial, not tested code.
            action.set_field_as_string_dirty('Camera Roll', '0')
            action.set_field_as_string_dirty('Camera Lens Angle', '51')
            action.set_field_as_string_dirty('Camera Distance', '2')

        return ret

    def set_args(self, action, values):
        filename = os.path.split(values['camera'])[1]
        filename_without_ext = filename.rsplit('.')[0]

        if filename_without_ext.lower() != 'user':
            split_filename = filename_without_ext.split('_')

            values['camera_horizontal_rotation'] = split_filename[1]
            values['camera_vertical_rotation'] = split_filename[3]


class Floor:

    def interface(self, action, fields):
        fields[_t('Show Floor Options')] = action.BooleanField(False)
        fields[_t('Use Floor')] = action.BooleanField(True)
        fields[_t('Floor Color')] = action.ColorField('#11133A')
        fields[_t('Floor Reflection')] = action.SliderField(70, 0, 100)
        fields[_t('Floor Opacity')] = action.SliderField(100, 0, 100)

    def get_relevant(self, action):
        ret = ['Show Floor Options', ]

        if action.is_field_true('Show Floor Options'):
            ret.extend(['Use Floor'])

            if action.is_field_true('Use Floor'):
                ret.extend(['Floor Color', 'Floor Reflection',
                    'Floor Opacity'])

        return ret


class Background:

    def interface(self, action, fields):
        fields[_t('Transparent Background')] = action.BooleanField(False)
        fields[_t('Show Background Options')] = action.BooleanField(False)
        fields[_t('Background')] = action.ChoiceField('Gradient',
            choices=(_t('Color'), _t('Gradient'), _t('Transparent')))
        fields[_t('Background Color')] = action.ColorField('#11133A')
        fields[_t('Gradient Top')] = action.ColorField('#11133A')
        fields[_t('Gradient Bottom')] = action.ColorField('#5B86B5')
        fields[_t('Auto Crop')] = action.BooleanField(True)
        fields[_t('Stars')] = action.BooleanField(False)
        fields[_t('Stars Color')] = action.ColorField('#FFFFFF')
        fields[_t('Mist')] = action.BooleanField(False)

    def get_relevant(self, action):
        ret = ['Transparent Background', ]

        if action.is_field_true('Transparent Background'):
            ret.append('Auto Crop')
        else:
            ret.append('Show Background Options')

            if action.is_field_true('Show Background Options'):
                ret.append('Background')

                background = action.get_field_string('Background')
                if background == 'Color':
                    ret.append('Background Color')
                elif background == 'Transparent':
                    ret.extend(['Auto Crop'])
                else:
                    ret.extend(['Gradient Top', 'Gradient Bottom'])

                if background != 'Transparent':
                    ret.extend(['Stars', 'Mist'])

                    if action.is_field_true('Stars'):
                        ret.extend(['Stars Color'])

        return ret

    def set_args(self, action, values):
        if values['background'] == 'Color':
            values['gradient_top'] = values['background_color']
            values['gradient_bottom'] = values['background_color']

        values['alpha'] = values['background'] == 'Transparent'

        if values['transparent_background']:
            values['alpha'] = True
            values['use_floor'] = False


class Action(models.Action):
    label = _t('Blender')
    author = 'Juho Vepsäläinen'
    email = 'bebraw@gmail.com'
    version = '0.4'
    tags = [_t('plugin')]
    __doc__ = _t('3D Objects')
    metadata = ['mode']
    _objects = BlenderObjects()
    _background = Background()
    _floor = Floor()
    _camera = Camera()

    def init(self):
        global imtools
        from lib import imtools
        self.find_exe('blender')
        out, err = system.shell((self.exe, '-v'))
        if not RE_BLENDER_VERSION.search(out):
            raise Exception(
                _('Sorry, you have the wrong version of Blender installed.') +
                ' ' + _('Blender %s is required.') % BLENDER_VERSIONS)

    def interface(self, fields):
        fields[_t('Render Width')] = self.PixelField('800px')
        fields[_t('Render Height')] = self.PixelField('600px')
        fields[_t('Object')] = self.BlenderObjectField('Box')
        fields[_t('Image Size')] = self.ChoiceField(SIZE_CHOICES[0],
            choices=SIZE_CHOICES)

        self._objects.interface(self, fields)
        self._camera.interface(self, fields)
        self._background.interface(self, fields)
        self._floor.interface(self, fields)

    def get_relevant_field_labels(self):
        """If this method is present, Phatch will only show relevant
        options.

        :returns: list of the field labels which are relevant
        :rtype: list of strings

        .. note::

            It is very important that the list of labels has EXACTLY
            the same order as defined in the interface method.
        """
        relevant = ['Render Width', 'Render Height', 'Object', 'Image Size']

        image_size = self._get_field('Image Size')
        # mark as dirty so it gets updated
        image_size.dirty = True

        selected_object = self._objects.get_selected_object(self)
        relevant.extend(selected_object.get_relevant(self))
        image_size.set_choices(selected_object.image_size_choices)

        relevant.extend(self._camera.get_relevant(self))
        relevant.extend(self._background.get_relevant(self))
        relevant.extend(self._floor.get_relevant(self))

        camera = self._get_field('Camera')
        camera.selected_object = self.get_field_string('Object')
        # important the dialog title should change for every object
        # otherwise same dialog is used
        camera.dialog = _('Select Rotation for %s') % _(
            camera.selected_object)
        camera.init_dictionary()

        return relevant

    def apply(self, photo, setting, cache):
        info = photo.info
        w, h = info['size']
        values = self.values(info, pixel_fields={
            'Render Width': w,
            'Render Height': h,
            'Box Depth': h,
        })

        mode = info['mode']
        if mode in ('RGBA', 'LA') or mode == 'P' and 'transparency' in info:
            values['filein'] = 'file_in.png'
            mode = 'RGBA'
        else:
            values['filein'] = 'file_in.bmp'
            mode = 'RGB'

        command = self.construct_command(values)

        #we need to create our temp folder explicitly as
        #blender renders to a folder and not to a filename
        output_dir = tempfile.mkdtemp()
        output_filename = os.path.join(output_dir, '0001.png')

        photo.call(command, output_filename=output_filename, mode=mode)

        #remove temp folder (should be done by same process)
        shutil.rmtree(output_dir)

        if self.get_field('Auto Crop', info):
            layer = photo.get_layer()
            layer.image = imtools.auto_crop(layer.image)

        return photo

    def construct_command(self, values):
        blender_path = PATHS['PHATCH_BLENDER_PATH']

        values['amount_of_input_images'] = 1
        values['input_image_2'] = ''

        selected_object = self._objects.get_selected_object(self)
        values['object'] = selected_object.name

        selected_object.set_args(self, values)
        values['blend'] = os.path.join(blender_path,
            selected_object.name.lower() + '.blend')

        values['blender'] = self.exe['blender']
        values['runner'] = os.path.join(blender_path, 'runner.py')

        # TODO: get rid of values['script'] = 'box'. It should not be needed!
        values['script'] = 'box'

        values['script_path'] = os.path.join(blender_path, 'object.py')

        self._background.set_args(self, values)
        self._camera.set_args(self, values)

        return selected_object.get_command(values)

    icon = \
'x\xda\x01s\x15\x8c\xea\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x000\x00\
\x00\x000\x08\x06\x00\x00\x00W\x02\xf9\x87\x00\x00\x00\x04sBIT\x08\x08\x08\
\x08|\x08d\x88\x00\x00\x15*IDATh\x81\xcd\x99i\x94U\xd5\xb5\xef\x7fk\xed\xeet\
u\xaa\xa3\x8a\xaa\xa2\xef\x8aN\x04\x81\x00*Q\x11PA\xa37*$\x1a\xf5\x8a\r*b\
\x13\x13\xaf\xc6\xa1\xd1\x98\x80]\x8c1\x08\x1a1F\xa2Q\x94\x90`\xc4\x0e\x94\
\xc4&\x8a\x18\x1aQ\x1aQ(\x04\n\xaa\xa8\xfe\xb4\xfb\x9c\xdd\xcc\xf7\x01\xdf{F\
\xf1\x8d\x971H\xee\xfd\x7f\xd9k\xac1\xf6\x9c\xf3\xbf\xd7\x9cs\xcf5\xa7\xc1\
\x11\x80,\x87;fa\xde\x1d[i\x06\xeb\x7f/w\xf7\xd8\xafgO\xef\xa5\x8f^v\x8e\x9a\
T\xb9\xd3Y\xfb\xf8\xbb\xca\xec{\x87\x9aY\xe7\x1a\x9b\x17kv\r>Wm^\xb5V\x8e\
\x84\xee#\x82\xb2k_V%\xb7\xfd\xc5\x82\x0f\xe9Xg\xe9\x8e\xabq\xe4\x05L\xd9\
\x891s\xef8\x8d\x88BD3n\xa5\x01\x135\x80\xfc\xcf1\x9fC\xd6t\x1e\xd0\xa9\xc5\
\x96\x11\x88\xa1\x10\x01\x11e[\xfd\xad\x8c\x16C&T\xd8+O\'\xf2\\z\x94\xbeW"v\
\x8b\x10\xf9\xef6\xf9\x1fq\xcb\'\x9c\x7f\xd9\xa9v\xe7/\xb0\x10A\xb7\x14\xa2\
\x88\x18\xf3\xe5C\xcd\x0f~\x11\xef5\xa9\xfb!\x83_\x12s\xeawD\xc9\x8cg\xec#\
\xa5\xda<"R\xbaUr\xd2\xdc:\xaft\x1d\x06\xa3\xe7F\xc2\r\x0f\xb9\xf7\x1do\xd5f\
C\x7f\xe2U\xae\xaa\xb7\x95D\xfc\xa1li\x9f>\xfa\x85g\xd8\x98\x01\xf1\xe1\xbc#\
\xa2Z\x1f\t!\x95\xd7\x94\xb3\xf2\x19\xcc\xb5v?d\xc31n\xd5\xf0A%\x07\xf2\xfe\
\xf4\xa1I&-:Z\xaa\x7f9\ngj-\x13J\x8f\xdexe\xaf)\xf4\xe9)w\x1d\xd2;L\xc8\x12C\
\x00\x01\xf8\xaf\x7f>0\x8e\x08\x81\xd6\x1b\x14\xdf\x1cP\xad\x8e=n\x97A\xfe2\
\xa7\xa5\xc9M\xd4D\x19;s\x18\xc7\xed\xcdqtk\x8e\xee\xe3\xaai\xfb\xe1p\xfa\
\xcd\x0f\xb9\xb1\xb1\xffK\xc7T\xacX\x13]\xfb\xfdi\xce\xa0\x8f\xb2\xc6C\xbf\
\xedi\x8dx\xa5\xc1\xbe\xe7\xf4\x1f\xfe\xd3\xaeud\\h28\x03\xb2!%\xc0F\xd4\xf8\
\x9a}\xbe\x1b\x10oLQV^\x81U\xf4\xa8\xb3|\xc6W\xb8\xfc\xf1[\x95\xf8\xeb\xac\
\xb7\xe7\xcc\xbfy\xeak\x13\xde\xdc\xb2\xf4\xc7wwO^sOs\xfe\x8f\x9f\r3\xbf=`[\
\xfe\xa6\x7fR\xb5:"\x04\xda\x04\xe2\x18\x1f;\xf5a\xfdS\x9f\x94\xa8\x8c\x04\
\xdc\xd0m\xea\xb9u\xedg\xddq\x9c\x8c\xed\x91 \x91i\xe7\x80e\x11\xcf\x15Y\xd3\
Cq\xe0\xddv\xfa.\xdb\xce\xa7\x8f\xec\xbd\xe3\x91\x80\xdb]P\xa1<EL]@\xee\x9fQ\
m\x1c\t\xfb\x97\'\xba8\x7f\xd7"}|\xf8\xae\xac\xee15x\xf2\xf8\x0b5{\xbb\xb7\
\xef\xdc\xf0V\xfe\xad\xbd8\x13*\xfd\xda~uD;<\x82\xb2\x18\x03\xdb\xe3D\x06$\
\xd86\xa1/\x03\xaa\x9c7\x8e\xdd\xae\x1f?\xf8qWg\xd3\xb8\xba\xb3\xad\xd6\xfb\
\x1e\xf1\xfe\xed\x04F\xf8k\xd5\xec\xec\x0e\xf3\x84\xebV\xcb\xbcK.\ro\x9b5L\
\xbfq\xc9\x93n\xaf\xbd\xf9\xce\xa5\xcd\xdd\x0f,\xd9cXe\x197~J=\xe5Y\x9b\xca\
\x98\x87\xe9F(\xedR|xj\x7f\x9c\xa3\x13]\'\x8e\xbft^\xb1y\xde\xa2\xed|\xd5+\
\xfe\x9f^r\xd8 \x16\x1f\x8ab#\x8cEd!4\x8a\x86\xb4\xb2\xb9\xc1\x80\x13L\x98l\
\xc0$\x13{\xaa\x899\xc5\xbc\x8d9\xa6:\xf6u\xf5V\x95\xa3\xe7|\xef2\xa7\xeb\
\x8c\x0e\xd4\x1f\x1f\xe5\xe2\x07\xf7\xa4O\x9c\x1cn)\xef\xe8|\xfc\xba\xed\x95\
\xef\xcc{\x87\x03\x91<\r9\x85\xb6}\x86V\x0b\xa3[\x0f\x92>\xb5\x1b\r/M\xf4gN.\
\xe3\x12\xc09E\x95+\x90C?\xc8v\x91\xd4&Gq\xff\xe7\x19J\x04>\x14X(\xc8\x07_\
\xc3N\x04nz\xea<{F\xc5\xd3\xf2\x8d\x8b\'\x97\xfc\xe7\x84\xfd\'\x0fM5\xf6(\
\xb4\x9b\xa1\x17u\x15(\x11\r\xa1\xfe\xfcuK\x13QZ\xa1\xe3h;0B:)\xb6\x15\xdct\
\xb3\x99\xa7\xc4\xb7\xbcD\xa4\xac\xab\xa8J\xdc\\~\xe4\xa9\xf5t\xbb`\x14\xed\
\xe9\x00[\x85\x88\xd64\x19\xc2.\xe5\x12\xb4d\xe8\xf6\xf0;\xec}`K\xe92\xe8\
\xda;\xe1\x83\xd5\xe6y\xa5+\xcc\xaa\xd2\xce`\xd6\x15\xa3\xe4\xc5\xaa\x1b\xe5\
\xde\x87V\x84\xab^=\xdd\xe4T\xd3\xbbk\xa62\x0fO`\x01,\x9f\xfb\x86un\xe2\xac\
\xea\x87\xc7v\xdd>\xa9FFu\x8bP\xb4\x15A\x10PD#\xca$P\x8a\xc0P\x84\xca"(h\xfc\
b\x11\xdf\xb4\xf1\x94\x8d\x04.\x05<\xdc\xa8\x8d\xa9\x1cL\xb1I\xa7\n\x14U\x0c\
\x15\x8dc\x14;I%m$\xeb\xe1g]\xfc$\xe8\xb8\x89\x91U\x94,\xd9L\xf9\xf5\xabJ\
\x1e\x15Imd\xae\xa3\x13\x1b\x96\x9a\x999g\x8b?\x08\xf4+Jw\xb6;^\xe5\xf7\xf3\
\n\xd9\xf55\'0\x04\xd4\x94\x8f\x13?\xde:\xfc\x96\x1b\x87\xf8\x17\x86\xedlM\
\x17\x910N%1DkB\x0c\x02\x0cB1\t\xb4B\x0c\x08t\x80o\x84H\xa81L\x071-<\x0f\x9a\
\xd0(\xed\xe3\xaa<\xaem\xa0\x0c\x13[\xe2H\xdeGBM\xc16\xc8*M\xe0\x87\x18A@\
\xae\xbc\x14\xef\xaf\xeb9~aC\xed\xd2?\x0c\x9a\xff\x92\xfc\xf9\xe2\xbc*\x1c\
\xa7f\xbfy\t\xbf\xfe\xfd\xe5&\xe7\x11\xf6\xb9\xe0\\\xbdg\xeb\xb2\xe0\xeb\x03\
\xa4\xc7\xd5\xdd\x16\x8cx\xe4\xfe\xb9C\x82q\xbb\xf7\x93\xa9)\xa3\xb2\xcd\xa7\
5f\xe1\xa0\t\xc5 D\x13*E\x88F\x0c\x13\x15:D=\x8dR!m\xe2\xd3\x12\xf8\xe4D(X\
\x11\xc4R\xa0=\x02\x17\x02\xadq\xf1Q(r\x96\xc6\xf7\x15\x96\xafA\x1b\xf8hTW\
\x81li\t\xb9\xc6]\xd4\xaf\xdc\x19o\xb8\xf5\xaf\xdf\\Z\xbf\xe9\xe5\x96\x1d;q\
\xf8v\xde\xdd57f\xf5\xbb\x00_\x9dvc\xf8\xf5\x04\xfa\xaf\x8a\xcdP\xa7\xddq\
\xcf\xe4pZ\x9f\x1abY\x85\x0e\x15\x99\xb8\xc2@\x11b|^\x01(\x04MP\xc8\xe3\xfa\
\x01\xbaDh\xf6\x8b\xa4R\nmFPv\x1b\x99\xacE>\xa5\xb0J-\x0cm\x121\x1d$(\xe2w\
\xb8\x14L\x85\xc4#\x88a\xe1b\x91\xb5\xf3\xd0\x9c\'0\x1d\xb2\x956Vs+\xb9\xd5;\
T\x9f\x03]\xb2d\xfb\xbb\x1b\xb7.\xfd\xcd s\xc3\xfe\x84\x7f\xcc\xc9(ev\xfa\
\x87\' \x1bx{\xc9\xcc\xd2\xe9\x17\xcb\xa0\x94\xed\x9f;\xad\xdfg\x03lC9Q_\x07\
\xf90\x14Q\xa0P\x04\xa6RZ\x02\xadC\xa2\xc7\xf7\xa2\xc7\x99c\xf8{\xdc J\x06U\
\xaaps\x01\x86D \x1e\x01\xaf\x08\xb1\x80O\xdd\x90\x0f\x1b\xb3\xecNT\xabB"\
\x10\xa9\xb0\xa8\xf4\x02U\x9f-JM1$j\x1b\xe4\xcbb\xa8\x82\x89\xd3\x91\xa3+\
\xa1\xb1q\x08\x1ex\x05\xe3\xd3\x03<\xfb\xbb]\xb2c\xc7\x07\xd3\xf5\xf4\xe3\
\xd6\xd2\xf9\xca>\xe3\xb0\x04\x0e>\t\xcf\x99Xs\xef<&\xc1\xbe\xd6\xde\xa4\xdb\
k!j\x11\xad\xd2HN\x1c\xb7S\x17b\xfd!\x92S\xa5\xde\x8e\xfaK\xebe\xe2\x0f\xc6a\
%\xe2\x04m\x1e\xe9r\x1b;\xf4\tl\xc1\xcc\x9b\x94\x12\xf0z`\xb0\xa2\xf6\xe7\
\xf5\xdbaG0cLoc\xd9\xe8i\xf2\xd0\xa3=e\xeeC\xb7\n\xd7(6]\xaf\xba\r\x10\xe9\
\xef\x96s\x92-T;\x01m\xc5<bF\t\xbbbXv\x0e\xe7\x17\xaf"\xf3\xde\x1ft\x7f\x89\
\xec\xc8\xfet\xfd\x8f\xd0c\'\x1d>\x88K?\xfb\x80\xa2\x12\x9d\xef}\x93,8aM,\
\x13x\xd6\x96\x83\x18k\xdc2\xedv\xef\'\xa1\xb7%\xbc|\x8a\x1d}\xe3\x81\xec\t\
\x0f\x9d.\x17\x0e\x1a\x8c\n\x8ad\rMEQh/\xb1I6\xe50K,\xeaZm~0d\x14o\xabf\xc9\
\x9e`\xbc\x11{c\xfaIJ\r\xa4\xeb\xd0I\x8b\xbe\x11\xe4^\x949\xb0\xa1o\xb8\xb7_\
\x83Q\xb8M%Z*\xf8n\xd0@]e\x15^S\x16)/\xa7\xe0\x15)H\x9e^S\x1e\xd1\xdb\xca\
\xd6\xd7?\xbd\xa6\xdf\xf6@}*_\x13\xc4\x1d!(\xa5\x83\xcd\xb6\xd2\xed\x81~\xea\
\xcdA\xe1\x85\xdf\xbfM\x86?\xf9\x07u\xdc1\xb7\xdb\x8b?\xb9\xc2\xf9\xce\xcf\
\xd7\xcd\xbc\xe5\x04\xe6\xf4\xefN\x97\xe9\x13t\x80\xe7(\xdc\x84I\xaf\xa6\x1c\
\xf9d\x84Z\xaf\xdc\xfeQ\xf5\xad\x85\xe7r+\x94\x11;Y4/\xbeb\xb2\xb5z\x10\x8d\
\x1bF\xa3\xca\xbaQL\xfbX\xba\x81\xd2\xd8\xe6\xd9\xc7lk\xfa\xf5E\xf3\x8a\x8aB\
 \x13\x9d\xd8\xc1\x19\xc5\xab\xacFJT\r\x86\x9b&+ \xb5I\n\xbf\xff;\xbd\x7f\
\xb5\x89\xa7\xde;\x9d\x0f\xd4]\xa2\x0fO`\xb90\xd1\xdd\xa3\xdf\xaa\xef\xab\
\xaf^q\x94,\xfa\xd9f\x03\x08n{j6+g/\xee7c\x10\x97|k$\x93{\xf6\xc0\r\x84\x10\
\x97"\n\xa7\x10\x12\x8b\x1b\xa8 \xc4)O\xb2T\xdf)\xf3\xe5^\xe5\xa8\x9b(p\xf6}\
uDKo\xa0\xb2\xef\x08b\xb1\x04\xe2\xbb\x14\xb3\x19pB\x8a~H.\xb7Z\xc9\x89\xcb\
\xc3\'*[\x95\x88\xb8\x0f\xaa\xbat\x8e\x8b\xcb="\x07\x0c\x82\xa4G\xa1\xd3Gj\
\xa2\x94\xcfz\xcelh\x97\x01O\xbcr\xf6\xf6\xf0\xf0\xf7\x81\xb3\xa1\xe7\xf9\
\xefA\x97\xe8E\xd1\t\n\x08\xfepJ\xa2$\xbeh\xf1\t7L\xe4\xce\xeb\'pZ\xcf\x1a\
\x8a9\x8fb1\x87\xe0\x900\xc1q\x1ctZaa\xb3w]\xcf\x91\xbfa=\xf6\x83\x03\xceU%\
\x8fI\x15\xc9\x9a\'\xa8\xe85\x11\x82\x18\x1d\xbb\x9bq;;\tsE\x0c\xdf\xa4$a`x\
\'I\xf6\xc9[\xd5\x82\xfd\xe5\xd2\xa0\xe2\x91Ir\xd0\xf3\xcc\xf5n\x82\xcax\x81\
t\xa81u\x15\xca\x0e\xc9L\xe9\xeb\xf7lK}\xdc\x8f\x9f(O\xbf\xbd\x01\x84\x15\
\x80\xc0j\x01Y\xc2\x92W\xce\xd4\xab\xdb&(\xfa \\Y\x1d\xd2\xe3\xb8\xd8\xfa\
\xa6\xec\x99%\x0e7\xcf\x18\xcc\xc8\x8e\x04y\xc7\'Z\xea\x11\xb1-\x9c\xb0HDA4\
\xe5\x93\xad)\xa1\xd47y\xe1;#\x1e\xef\x92\x19G\xeb1\xe7\xf4\xb0\xd3o\xff\xee\
\xe7\x84A\x1f\x9c\x84\x8f\x11\xc4(\xeb\xdd\x9b ^K\xa4\xae\x9aH\xdc$H\x19T\
\xd7D\x190v8[V\x9eQ\x18\x1fx\xaci\xb1$\xe6\xef\x0c:\xe8\x0c\x93t\x93\x04\x86\
\x9d%\xbe\xa7\x84pX\r1\xed\x95\xd7.\x90>\xa6^\xf5\xeaO\xcc\x9e/\x9dez\r\x83\
\x9c?V\x9eVb\xd3\xa2k\xbc\x06\xbb\xf5\xa1\x89\x92\x1a\xf8\xba\xe6{\x07\xfa>\
\xd8\xe7\xc3[\xce\x1f\xc6\xf5\x17\x8c\xa0gk\x81\xf62\x9f\x98\x1b\x92\xeb0P\
\x95\x16\xc9\xce\x10?\xb0\tJc\x94\xee\xf5h\xafN\xf3a\xcfc\xc7\x84\xdfn\xd8\
\xec}\xf3\xba)\xb5\xe4\xd3\xe3(\xads\xc8w|\x83 \x18B\xbec\x0c*7\x9e\\\xeb82]\
\xa3\x08t\r\x99l\x84LW\x16\xb7\xfa\xc4K\xae8\'\xc97\xa3\xc1#\x17\xd4\xed\xf5\
,\xe2\xb6\x85\xe5\x85H\x85\x8f\x94f\xf1z\xd7\xe1\r\x91\x8e!\xd7\\\xb5\x1b}\
\xf3\xe3\xfd\xe5\xc1\xc6\x9e\xba\xfe\xfd\xc0\xe8v\xcc\xab\xee\x87\x93~ht\xfc\
pY\xf0\xc0\xed\x9fEK{_3\xf4\x85`\xc9/g\r\xcc\x9cUc\x12v\x84x\xb12z\xa5\x1d\
\x8a\x07]21\x8bhs\x17~w\x1b?\x84P\x14n\x99\x85y\xd0\xach\xfb\x1b\xa3Y\x81\n\
\x8cL\xba/\xda\xac\xa1\x98\xedE!\x05D"\xb8n\x08(4\x0e\xf9tw\xdc\xae\xa1\x18\
\xd2\x8bD\xb2\x0c\xed\xf5\xdc\x93\xe9\xad\x9f\x9a\xff\x17\xff\xa7\xb5\xfb\
\x0b(B#\xa4\xb7\xd6\xa0\xa2\x14]\x93HE\x14\xdf*\xa3\x1b\xcfZI\xfd\xe4\xab\
\xab\xacs"\x8d\xd2p\xe6.o\xdb}\xb3u\xfd_\x08\xbf{\xf3\xb6\xd27{\xab\xd3V\r\
\xdf\xbah\xfa\xe0`x\xda\xc3\xf7\xe3\xd8\xdd51\x95\xa1\xb9\x90\xc6\xe8\x15\
\xa1\xd4\xb4\xb0\x8d(\xd9t\x8cJ-\xf8\x01x\xb6\xc2\xde\x12/\xcf\xb2m\xbc\x12\
\x04)\xe4\x0c\xcc\xa8\x8de+\x94\x86l\x0e\x02S\xf0\x02\x85\'\n\'&\x88\x8e\xe3\
f\x07\xe0\xb9=\x88E\xed\x8f\x9c1\xc1\x9eW\x87[\x88(\xc7\xd6\xc5\x10z\xa0\xb0\
\x04\x14&\x96\x13%LTPN\xc6O\xea\xabv<\x1e\xaaw\xaf\t\xe5\x892+w\xe3\xc3\x0c\
\xea\xd6\xa3\xea\xc7\x8f]1\xe7\xae\x11\xdc0\xae\x07\xdd\xf6\xe6\xc8F+\x89\
\x1a@s\x8e\xce\x10b\xa5q\xfc\xc5\xef\x11\xd9\xdeJ\x90\xf4p\x8c\x80\x8c2Q\x98\
\x88\x1f"\xfd#\re\x0c]T\x84YZ\xc5\xfbo\xc6\xcde)d}0-\x82\\\x013\xaa\xf1\xc3\
\x00/\x08\xf1\x94&4B\x02m\x90\xc9V\xe0\x17\xf6w\x0e\x9b\x16\x9e\x98]\xed\x03\
\xe2J\x18\x0f4\xb6\xa1\x89\xe4\xc1\n\x1d\x0c\x02\xb4\xe3`a\xd68\xfa\xa3\xd3L\
\xafu\xc2"c\xdf\x15\x8e\xf7\xfd^\x93z]2\xa0\xf1\x8e[\x86\xb5\\QUE\xa5\'Pfb\
\xb6\xe4\xc8Y\x8a\x98\xd2\x849\xc8\xce_\x87\xf5\xb3\xad}vT\x9a\xc8\xc1.\xda\
\x13\x06\x11ea\x08\x18>d\xaa\xacp\x94`\xe8\xda[\xae\x92\xe0\xd1\x93\xf7\x91k\
y\x9aL\xda\xc2\x88\x06\x049\x07\xf1\x14*\x04m\x80_\x04\x14\x04\x02n\xce\xa6k\
\xe7\x8b\\T\x95\x99p\xedU\x11\xf9Ki\xf7\\\x81\xfe\xda\xa4\xa8!i\x9b\x10\x80\
\x81\xfby\x05f\x9f*z\xeb\xeb\xb6\xd5-\xe1\xfb\xdf\xf9\xc6\xb8\xf1K\x07\xbdy\
\xf7\xe5#\x99\xd2\x0c-\xe9\x08*\xf4\xc9K\x81\xb0\x16\xc2N\x9f\x8e\xa4E\xe5}\
\xaf\xd1~\xef\xfe\t\x8b\x06\x1bmks\n\'\xd9\x8d\x8a\x8e(\xbea\x00\x1a#4)P`\
\xe8\x9a\x0b\x13v\xc7\xbcqZ@\r\x9a}\xdb\xad$\xaa6\x92J\x05D\xcb|\xcc@0M\x85\
\xf6\x15\x96\x164\n\x8dGi\xf9\xa6\x99w\xdc\xf8B\xd5\x93w\x1a\xb9\x9fX\xd6\
\x8e\xbf\x87CkJp\xc2\x00\t\x03b\x8e\x83x!&!\xe2\x16\x81\x9e\xe3\x0b\xfa\xdc\
\x93\x8b\xfe\xa5\xd7\xd7N\xbb\xa7\xef\xca{N\x19\xc0Q6\x84\xe2\x13F=|\x95$\
\xe6z\x14\x8c\x08\xd1\x86,\xe6y/\xb2\xeeW\x9f\x94,\xfe\xc6\xce\xb5/\x7f6bDCg\
\x13-b\x92\x8c\xe6(z\x8a\xa2\xd6H$I"%\x1c{\xd4\xc0`L\x01\xc2\x1dO\x8c\x8a\
\xbd\x7ff\xb9W~lf\x1a"\x8fR\xb42\x14\x94\xa2hj\x02_!\xb6\xa2\xa0\xf7\x91\xeb\
\x9c?\xf6\xe2\xd3\xcezv\xb0\xca\x8c\xb9\xf0\xa0N<\x13/V\x85\x99\xb3\x8a\x11\
\x12: O\x04\x95\xd7D\xac\x0c\xc1\x01!\xbe\xf5\x83\xf8\xc1\x89\xbf\x9b\xd3\
\xa9\xe9=\xbe\xe7y\xe3\x9b\xae;\xb6\x9a\xaa\xae<\xe9\x8c\x8bW\x01\x96i\xe2\
\xa5R\x98\xdd\xab\x89\xbe\xba\x9b\xcc\xacw\xec\xbf\xbd\xf6Y\xddc\xd3\xbe\xd5\
{}\xb5KK\xf6\xcd\xe1;\xd6y4\x89\x89\x189R\x86\x89a\xf8\xb8V+\x9dV5\x15\xb9\
\x8a\xec\x8f\xe5\xa6h\x8f_\xfdmd\xd1\xdc\xd4I\xc7\xbd\xe7uq~\xea\xbf\x98\xec\
M\xa0\xba\xfbeX\xe9[)\x06\xb7\xe3\xb4~;\x16\xeb5\xe1\x86\xbf^v\xff\xdfG\xab\
\xb6R\x99\x17}E-\xcc\x85\xf9\x8e\xefI\x82\x13M\x83\x03\xe9$\x15\x96O\xd0\x91\
!W\x11!\xfa\xf1~J\x1b\xd4\xa0\xdd\x93j)\x9a\xd3"m\xc3\xc7U\xd3\xeb@\x1b\xfb\
\x12Ij\xa2\x112n\x81Z\xaf@\xa6g\x15\xd9G6\xa9\x969ow[S\x1f)\xae\xf6G\xcd\xda\
\xd5\xf7\xe6\xa1\x85\x9f-\xbf@\xf5\xb4\xbbu\xbcq\xa0l\xdf\xec\xa1\x9d\x03sB\
\xb5Y gE\x08\xa8 \x11)\x90\t=bM\xfd\xdd\xf9\xf3\xfc?\xff(~\x8c\xec\xcf=\xe0\
\xd8\xd6\xa4\xd06/W;Y\xee\xedTEB\x80S@/\x97\x8a\x88^\x902\xdc\x16\x1d\xbf\
\xf6\xd1\x85\xde\xa0\x07\xb9$\x15\xe3\x06\xd14\x16\xa0[<G;\x9a\\\xda\xa4\xbc\
.K\xf8\xc1~h\xd1{?\xfaiV<\xbd\'\xdfd\xba\x1aq\xe2\xf4\xf6\x02\xdc\xc6.\x1c3\
\xa41\xaf\xc8^\xf7\xb2\xbd{\xce\x86\x92?\xf7\xef\x19YYv\xfa=[\x17v\xcdk\xdfW\
\x1b)\xc4\xee\x1a\x15\x96\xaf\xb9\xbb\xe3\xadu\xbc\xbbu\xbf*\x96\x94RT\x1a]\
\xd08\x9d\n_\x07\xf8Z\xd1\x1a1\x18\'A\xc7\x03{~\xab\xce^y\xc6Y\xa6\x95\xf0\
\xd3\xbc\\\x14U\xc8X?\xb9z\x88\x13\xcc8)\xd2g\xf1j]\xb2\xb8\xad\x10W~z\xe1|\
\xea\xead\xff\xad]Q.\r-v;yD\xe5Ii\x07C\x02\xc2\x84\x89\xd1T\xc0~\xfe\x13ZF\
\x8dmkb \xbe\xde\xb2/\xf1\xe9S\xeb\xd9]U\x81\xee^J\xac\xbe\x0e\xa3\xd9\xa4\
\xfb\xd5oX;\x7f\xbb=\\rY\xaf\xd4\x0b)\xa7\xd7\x8e\xd7\x9e\xbe"Sz\x1f\xc9|\
\xbf\xbe\xfe\xbeA\x1b\x83\x89\x17%\xc8\x90|\xff\xa7\xef\xca\xb6\xc66\xd2\x86\
\x87\xa5\x04\xc7r\xc9\x85\x11\xc20J\xa5\xed\xd1\x18\x943\xa0\xb4\xc0\xcd3V/{\
\xa4\xe1q\xae~g\x9e\xaa\xdf\xa1\xe2\xe1{\x0b\xb7\x15\xd7^\xbc\xc7\xfb\xf4\
\xf5\xa9\xb1\x8fk\xf4I\x07\x97\xb0\xd0\x1b\x10.\xcc\xc1T\xdbd\xbf\xefR\xae\r\
\xdcd\x0e/\xe5 ~\x01jB\x82\xdfn\xd2%\xef6\x96\xae}o\xde\xadm\xa2\x94\xa3\xa6\
\\j\xd6\xbd\xb6|\xe8\xe9\x93\xbb\x7fx\xd2I\x95Tnj&\xb5\xbc\xc1\xd8AU\xc5\xda\
\x8a\xe6\xe9\x1b\xdb\x1f\xbe<++\x8e\xef|{\x93i_\xd5\xf4k\xb9w\xd5\x9f\xec\
\xe9c\x9f/J\xa5\xc1\xb5\xcf\xa9\xe8\x82\x9f\x9d<\xed\xc1\xe4\x9a\xd9\xb3\x8e\
\xc7\x96\x12\xa2\xd8\xa8\x8c\xe6`U\x9cD\xa7\xc2\x8bh\x82h\x9aT\xca\xa1\xc2\
\x88S\xa2|\x94\xa5I\x175Y+K`\xda\xf40L\xa2Y\xa1\xd5\xd3\xb4&\x02TW\x94\xee\
\xb1,)\xcb\xc4\xd8\x0f\xd1~\xcdlv\x03\xdcO<\x06\xcf\xb8\xdf\xf8\xe8\xe3\xe8\
\x85\x0f\x1a\xfb\x1e\xc8\xfb\xce\xdc\xac\x82i\x96\xe2\xaf5\x82\x0c\x81\xb0\
\x1aT\x07\xe8\x03\x90\xdf\x83\xa6\x8b\x10\xff\xcb\xc5\xaa\t\xda\x87\x90C\x99\
\xbc\x9b2\xd4\x8c\xc7\xcf\xd2\xe7\xcc\x1c\x16$3QD9\x14-\x87 \x0cq%\x82\xd2\
\x1a1\x0c$P\x18\xa1\x81\xd2\x10\x1a!"\x8264a\x18 \x01(\xc3 \xf4\x15Z<B\xcbG\
\xb4`\x16\n\xa4\xc2\x02\x07\xf7\xb5\x92\xb8a9\xf2\xfa\xce\xc4\x83\x17M\xba\
\xf2\xc3%\xc9\x15\xf2\x9bY\xb3\x02\x03\xba\x04\x8ay\xf0Z!\xdc\r\xf2\x19H3\
\x84)\xe4P\xa0}\x01\n \xfc\xbf\r1\x11\xc8\x85\x12O}\xb0\xdf\xa9\x1asTa\xc8\
\xe08\xf8\x19\xb2I\x85\xca\x96\x92\x8cx\xb8a\x08\x02\x9e!\xb8\xca\'\x0c=\x0c\
\x1d\x12\x06B\x10\x1ax\x81E \x06F\xa8\xd1v\x9et\xd4\xa4\xa4\xa0)Kw\xd0j\xbb\
\xb4y\x0ee\xd7.%X\xbf\xa7lIn\xc6\xc8\x9d\xa5\xe3\x96f\xfb?\xbc;\x1cu\xe5\xd4\
\x7fhl\xa9C55\xea\x0bk\xf9\xc2\x9a\xc3\xac\x0f\xa1\xa4$V\xde\xc3<Z>NM\xbf\
\xfb\xdc\xe0\xd8\x0bFR\xde%\xd8e\x01\x9f\xb9=\xa864Y\x81@\x0b\xc4MD\x99\xf8\
\xa1M\xb4\xe0S\xf4|<<\x02+@\x99\x82\x91\r\x88\xf8!\x81S\xc4\x88\xdb\xb8\x9b\
\x1ah\xba\xf7y]\xb2\xec\xd3\xf0i=\xf5\xf4u\xe1\xe4\x95\xedr\x93\xf2\x01\xceP\
"_\xd7\xdc\x95x\x1c\xbc\xaf\xf6\x89\x0f{\x83\xbb=Q\xf4\xd3C.\xea\xfa\xc4\x8d\
v\xbe\xb2\xb6\xb9\xab\xa5\xd3)\x1f\\\xed9%\xb5\x94FZIK\xfe\xf36\x18\x88\x1b\
\x12\xe4\x8b\x10\xb8\x88\x19\x10\x98!\x86\xf2\x88\xe9"1<\xe2Q\x85\x15\x11\
\x8a\xcdi\xb2\x8f\xbd\x8ew\xf7\xaad\xeb\xeb\x07k\xff\xd0\xd3\x19\xfc^\x8f\
\x8f\xa7\xb4.\x9f{q\xb8\xea]\xccg\x07\x9e\x1f<q\xcdY\xa2:;Q\x89\x04d\xb3\xd0\
\xd5\x05uu\x87\x9e\x95\x95\xc8\x97\x0c\xff\xf2\xfc\xe7\xff\xec\xadX\x88\x8eD\
\xb1O;\xe6\x1a\xfb\xa8\x99\x0b\xfa\xb6e\xba\x8f\xf0\xd2j\xd4\xcd\xa3\x9bN\
\x9c4\x01c`\x15]\xc98F\xa1HI\xd1\xc3C\x91\xf5\x02\x8a\xa1&\xaa5\xb6i\xe2Z\
\x8aL\x10\xe2w\xb4c-\xdd\x80\xf1\xc8\x9b\xc6\xee\xcf\xcazm\x0b\x8a\xed\xef\
\xfdg\xe1\xce]\xe3n\xf9Aj\xf7\x8d\xcf\xeb{;\xcf\xf0\xe6<0W=\xac\x17\xf8-?.3\
\xd4\x86\r\xe8?\xfd\t5v,r\xe6\x99\x88\x08(\x05J}\xc5\xe0\xaf#\xc2\xed\xccS\
\x83\xbf{\x8by\xfej\xfc-?W\xc9\xa3~y|T\xda\xf3}h\xb5\xea\xc9\xbf?t\xca\x10\
\x190\xb9^\xba\x8f\xef\x8b\xaa+C,\x8dV\x16\xa6c \xbe\x87\xd7\xd4A\xb0\xbd\
\x11\xb5\xf3 \xc6c\x1f\xb0c\x7f*\xbaE\x1b\xee\x86o\x15\xa4\xf1\xd2\xe1\xc6\
\x813\x17\x07r\xd5\xb1\xcf\x15g??\x935\xff!\xb2\xf8\xdce\xe6G\xcbf\x86ZM\x93\
#3\xa19<b\n\x92Be\x15\x84u\x90\xab\x81Be\x89E2ic+\x0b+\x14B\xcf\xa7\xd8Q\xa0\
\xe8\xfb\xd6AH\x1e\x84\xb6F\xe0\x00\xd0\t\xe4\xe1\xabY\xf0\x8b\xf8W\x12\xe0\
\x8a\xd9\xe8\xee\xfd\x88/|ZYm\x9f\xf4v"^*^N:\x1e\x95\xb8\xd5\x14\x0e\n\x84&\
\xd3\xa3\xd5\x0b\xb0\nR]\xefR=0\xc3G\xcff\x00\xf7\x0bb\xbe\x9cH\xfe-\x04\x14\
\xc0\xc9c\x94zf\xb9\x18\xa37\x1e\x1f6\xdey\xb9\xc2\xed\xa7iX*\xd3j\x87\xf2\
\xfa\x95Q\xb3v\xebU\x9c4\xde\xa7\xe7H\xd8\x1cG\xcc\x91\x04\x7fR\xfc\xef\xd4\
\xa1\xe1+i\xfc_\x8e\x7f\xf8 \x83\x19}\xe8Z\x89@J\xe8\'\xff\xa1~)\xc3\xf4\x13\
\x82\xf1T\x16C\x04\xedKRo\xb8\xf3~Sf-5e\xe4\x86\xaf\x1b\xfb\xfeK=\xe5\xffC\
\xd1x j0\x12\xf5\xa4\xc0\x99\xb2@\xc9\xe7\x1e\xa16\n\xdb\x10\xe5!Z\x90\xc3\
\xa7\x8e\x7f#\xfe\x81\xc0\x8am\xb0\xb9\x19[\x04S\xa4\xf2\xf3\xd3\x08\x99\x96\
\xe80EP\x17\x0b\xc6C\x82^%\x98\x9e`n\x7f\x91/\x0f\xba\xd5\x97e~\x19\xff\x0bA\
{\x15\x9a\xb6#k\x02\x00\x00\x00\x00IEND\xaeB`\x82\xcc\x1d\xac\x1c'
